From d6e678d2c202c34e7cc5521a81682b90794d902b Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 14:04:21 +0000 Subject: [PATCH] Merged 5.2.N (5.2.1) to HEAD (5.2) 132107 gjames: SEARCH-227: Adding additional display information for facetting api git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132335 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/public-rest-context.xml | 40 +++++++++ .../org/alfresco/rest/api/impl/NodesImpl.java | 2 +- .../api/lookups/MimeTypePropertyLookup.java | 71 +++++++++++++++ .../api/lookups/PersonPropertyLookup.java | 76 ++++++++++++++++ .../rest/api/lookups/PropertyLookup.java | 52 +++++++++++ .../api/lookups/PropertyLookupRegistry.java | 88 +++++++++++++++++++ .../rest/api/search/SearchApiWebscript.java | 8 +- .../api/search/context/FacetFieldContext.java | 9 +- .../rest/api/search/impl/ResultMapper.java | 22 +++-- .../rest/api/search/ResultMapperTests.java | 5 +- .../search/SearchQuerySerializerTests.java | 6 +- 11 files changed, 362 insertions(+), 17 deletions(-) create mode 100644 source/java/org/alfresco/rest/api/lookups/MimeTypePropertyLookup.java create mode 100644 source/java/org/alfresco/rest/api/lookups/PersonPropertyLookup.java create mode 100644 source/java/org/alfresco/rest/api/lookups/PropertyLookup.java create mode 100644 source/java/org/alfresco/rest/api/lookups/PropertyLookupRegistry.java diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index c7e8094d58..c6b8a48c28 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -736,6 +736,39 @@ + + + + + cm:content.mimetype + content.mimetype + + + + + + + + + cm:creator + cm:modifier + cm:owner + creator + modifier + owner + + + + + + + + + + + + + @@ -858,7 +891,14 @@ + + + + + + + PROPS_USERLOOKUP = Arrays.asList( + public static final List PROPS_USERLOOKUP = Arrays.asList( ContentModel.PROP_CREATOR, ContentModel.PROP_MODIFIER, ContentModel.PROP_OWNER, diff --git a/source/java/org/alfresco/rest/api/lookups/MimeTypePropertyLookup.java b/source/java/org/alfresco/rest/api/lookups/MimeTypePropertyLookup.java new file mode 100644 index 0000000000..b289a545c0 --- /dev/null +++ b/source/java/org/alfresco/rest/api/lookups/MimeTypePropertyLookup.java @@ -0,0 +1,71 @@ +/*- + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.api.lookups; + +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Looks up mimetype values + * Pass in a mimetype value and a display string is returned. + * @author Gethin James + */ +public class MimeTypePropertyLookup implements PropertyLookup +{ + private Set supported = new HashSet<>(); + private ServiceRegistry serviceRegistry; + + @Override + public String lookup(String propertyValue) + { + Map mimetypes = serviceRegistry.getMimetypeService().getDisplaysByMimetype(); + return mimetypes.get(propertyValue); + } + + @Override + public Set supports() + { + return supported; + } + + public void setServiceRegistry(ServiceRegistry serviceRegistry) + { + this.serviceRegistry = serviceRegistry; + } + + public void setSupported(List supported) + { + this.supported.add(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content.mimetype").toString()); + this.supported.addAll(supported); + } + +} diff --git a/source/java/org/alfresco/rest/api/lookups/PersonPropertyLookup.java b/source/java/org/alfresco/rest/api/lookups/PersonPropertyLookup.java new file mode 100644 index 0000000000..041d8bb830 --- /dev/null +++ b/source/java/org/alfresco/rest/api/lookups/PersonPropertyLookup.java @@ -0,0 +1,76 @@ +/*- + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.api.lookups; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.transaction.TransactionalResourceHelper; +import org.alfresco.rest.api.impl.NodesImpl; +import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.api.model.UserInfo; +import org.alfresco.service.ServiceRegistry; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Looks up information about a person. + * Pass in a userId and the display name is returned. + * + * @author Gethin James + */ +public class PersonPropertyLookup implements PropertyLookup +{ + private Set supported = new HashSet<>(); + private ServiceRegistry serviceRegistry; + + @Override + public String lookup(String propertyValue) + { + Map mapUserInfo = TransactionalResourceHelper.getMap("PERSON_PROPERTY_LOOKUP_USER_INFO_CACHE"); + UserInfo user = Node.lookupUserInfo(propertyValue, mapUserInfo, serviceRegistry.getPersonService()); + if (user != null) return user.getDisplayName(); + return null; + } + + @Override + public Set supports() + { + return supported; + } + + public void setSupported(List supported) + { + NodesImpl.PROPS_USERLOOKUP.forEach(entry -> this.supported.add(entry.toString())); + this.supported.addAll(supported); + } + + public void setServiceRegistry(ServiceRegistry serviceRegistry) + { + this.serviceRegistry = serviceRegistry; + } +} diff --git a/source/java/org/alfresco/rest/api/lookups/PropertyLookup.java b/source/java/org/alfresco/rest/api/lookups/PropertyLookup.java new file mode 100644 index 0000000000..1931338475 --- /dev/null +++ b/source/java/org/alfresco/rest/api/lookups/PropertyLookup.java @@ -0,0 +1,52 @@ +/*- + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.lookups; + + +import java.util.List; +import java.util.Set; + +/** + * Looks up property values for the api + * + * @author Gethin James + */ +public interface PropertyLookup +{ + /** + * The list of property keys that are supported by this class + * @return Set property keys + */ + public Set supports(); + + /** + * Lookup the property value with a new value. + * @param propertyValue + * @return a new value or null if the property value isn't found. + */ + public T lookup(String propertyValue); +} diff --git a/source/java/org/alfresco/rest/api/lookups/PropertyLookupRegistry.java b/source/java/org/alfresco/rest/api/lookups/PropertyLookupRegistry.java new file mode 100644 index 0000000000..50dc956546 --- /dev/null +++ b/source/java/org/alfresco/rest/api/lookups/PropertyLookupRegistry.java @@ -0,0 +1,88 @@ +/*- + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.lookups; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.extensions.surf.util.AbstractLifecycleBean; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Acts as a central point for property lookups + * + * @author Gethin James + */ +public class PropertyLookupRegistry +{ + private static Log logger = LogFactory.getLog(PropertyLookupRegistry.class); + Map propertyLookups = new HashMap<>(); + + /** + * Set the supported property lookup classes. + * @param lookups + */ + public void setLookups(List lookups) + { + lookups.forEach(entry -> + { + entry.supports().forEach( propKey -> propertyLookups.put((String) propKey, entry) ); + }); + } + + /** + * The list of property keys that are supported by this class + * @return Set property keys + */ + public Set supports() + { + return propertyLookups.keySet(); + } + + /** + * Looks up the property value using a PropertyLookup + * @param propertyName the property name/type + * @param propertyValue the value to lookup + * @return Object to be serialized as json + */ + public Object lookup(String propertyName, String propertyValue) + { + PropertyLookup lookup = propertyLookups.get(propertyName); + if (lookup != null) + { + return lookup.lookup(propertyValue); + } + return null; + } +} diff --git a/source/java/org/alfresco/rest/api/search/SearchApiWebscript.java b/source/java/org/alfresco/rest/api/search/SearchApiWebscript.java index 4ec3dd47fe..23b12c3b1e 100644 --- a/source/java/org/alfresco/rest/api/search/SearchApiWebscript.java +++ b/source/java/org/alfresco/rest/api/search/SearchApiWebscript.java @@ -66,7 +66,6 @@ public class SearchApiWebscript extends AbstractWebScript implements RecognizedP { private ServiceRegistry serviceRegistry; private SearchService searchService; - private Nodes nodes; private SearchMapper searchMapper; private ResultMapper resultMapper; protected ApiAssistant assistant; @@ -78,10 +77,8 @@ public class SearchApiWebscript extends AbstractWebScript implements RecognizedP PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry); this.searchService = serviceRegistry.getSearchService(); ParameterCheck.mandatory("assistant", this.assistant); - ParameterCheck.mandatory("nodes", this.nodes); searchMapper = new SearchMapper(); - resultMapper = new ResultMapper(nodes); } @Override @@ -145,8 +142,9 @@ public class SearchApiWebscript extends AbstractWebScript implements RecognizedP return Params.valueOf(null, recognizedParams, null, webScriptRequest); } - public void setNodes(Nodes nodes) { - this.nodes = nodes; + public void setResultMapper(ResultMapper resultMapper) + { + this.resultMapper = resultMapper; } public void setAssistant(ApiAssistant assistant) { diff --git a/source/java/org/alfresco/rest/api/search/context/FacetFieldContext.java b/source/java/org/alfresco/rest/api/search/context/FacetFieldContext.java index beab27e49a..5ea1ca483f 100644 --- a/source/java/org/alfresco/rest/api/search/context/FacetFieldContext.java +++ b/source/java/org/alfresco/rest/api/search/context/FacetFieldContext.java @@ -55,11 +55,18 @@ public class FacetFieldContext { private final String label; private final int count; + private final Object display; - public Bucket(String label, int count) + public Bucket(String label, int count, Object display) { this.label = label; this.count = count; + this.display = display; + } + + public Object getDisplay() + { + return display; } public String getLabel() diff --git a/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java b/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java index 3a373f412a..66164c5095 100644 --- a/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java +++ b/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java @@ -28,22 +28,22 @@ package org.alfresco.rest.api.search.impl; import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.lookups.PropertyLookupRegistry; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.api.model.UserInfo; import org.alfresco.rest.api.search.context.FacetFieldContext; import org.alfresco.rest.api.search.context.FacetFieldContext.Bucket; +import org.alfresco.rest.api.search.context.FacetQueryContext; +import org.alfresco.rest.api.search.context.SearchContext; import org.alfresco.rest.api.search.context.SpellCheckContext; import org.alfresco.rest.api.search.model.HighlightEntry; import org.alfresco.rest.api.search.model.SearchEntry; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; -import org.alfresco.rest.api.search.context.SearchContext; -import org.alfresco.rest.api.search.context.FacetQueryContext; import org.alfresco.rest.framework.resource.parameters.Params; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SpellCheckResult; import org.alfresco.util.Pair; -import org.alfresco.util.ParameterCheck; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -62,12 +62,21 @@ public class ResultMapper { private Nodes nodes; + private PropertyLookupRegistry propertyLookup; private static Log logger = LogFactory.getLog(ResultMapper.class); - public ResultMapper(Nodes nodes) + public ResultMapper() + { + } + + public void setNodes(Nodes nodes) { this.nodes = nodes; - ParameterCheck.mandatory("nodes", this.nodes); + } + + public void setPropertyLookup(PropertyLookupRegistry propertyLookup) + { + this.propertyLookup = propertyLookup; } /** @@ -179,7 +188,8 @@ public class ResultMapper List buckets = new ArrayList<>(facet.getValue().size()); for (Pair buck:facet.getValue()) { - buckets.add(new Bucket(buck.getFirst(), buck.getSecond())); + Object display = propertyLookup.lookup(facet.getKey(), buck.getFirst()); + buckets.add(new Bucket(buck.getFirst(), buck.getSecond(), display)); } ffcs.add(new FacetFieldContext(facet.getKey(), buckets)); } diff --git a/source/test-java/org/alfresco/rest/api/search/ResultMapperTests.java b/source/test-java/org/alfresco/rest/api/search/ResultMapperTests.java index be66f585c1..36bcc743ff 100644 --- a/source/test-java/org/alfresco/rest/api/search/ResultMapperTests.java +++ b/source/test-java/org/alfresco/rest/api/search/ResultMapperTests.java @@ -38,6 +38,7 @@ import org.alfresco.repo.search.EmptyResultSet; import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.rest.api.impl.NodesImpl; +import org.alfresco.rest.api.lookups.PropertyLookupRegistry; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.api.model.UserInfo; import org.alfresco.rest.api.search.context.FacetFieldContext; @@ -119,7 +120,9 @@ public class ResultMapperTests return new Node(aNode, (NodeRef)args[1], nodeProps, mapUserInfo, sr); } }); - mapper = new ResultMapper(nodes); + mapper = new ResultMapper(); + mapper.setNodes(nodes); + mapper.setPropertyLookup(new PropertyLookupRegistry()); } @Test diff --git a/source/test-java/org/alfresco/rest/api/search/SearchQuerySerializerTests.java b/source/test-java/org/alfresco/rest/api/search/SearchQuerySerializerTests.java index 03c030fb72..1b94920683 100644 --- a/source/test-java/org/alfresco/rest/api/search/SearchQuerySerializerTests.java +++ b/source/test-java/org/alfresco/rest/api/search/SearchQuerySerializerTests.java @@ -143,7 +143,7 @@ public class SearchQuerySerializerTests { ExecutionResult exec1 = new ExecutionResult(new Farmer("180"),null); - FacetFieldContext ffc = new FacetFieldContext("theLabel", Arrays.asList(new Bucket("b1", 23), new Bucket("b2", 34))); + FacetFieldContext ffc = new FacetFieldContext("theLabel", Arrays.asList(new Bucket("b1", 23, "displayText1"), new Bucket("b2", 34, "displayText2"))); SearchContext searchContext = new SearchContext(23l, Arrays.asList(new FacetQueryContext("f1", 15), new FacetQueryContext("f2", 20)), Arrays.asList(ffc), new SpellCheckContext("aFlag", Arrays.asList("bish", "bash"))); @@ -155,8 +155,8 @@ public class SearchQuerySerializerTests assertTrue("There must 'facetQueries f2' json output", out.contains("{\"label\":\"f2\",\"count\":20}")); assertTrue("There must 'spellCheck' json output", out.contains("\"spellCheck\":{\"type\":\"aFlag\",\"suggestions\":[\"bish\",\"bash\"]}")); assertTrue("There must 'facetsFields' json output", out.contains("\"facetsFields\":[{\"label\":\"theLabel\",\"buckets\"")); - assertTrue("There must 'bucket1' json output", out.contains("{\"label\":\"b1\",\"count\":23}")); - assertTrue("There must 'bucket2' json output", out.contains("{\"label\":\"b2\",\"count\":34}")); + assertTrue("There must 'bucket1' json output", out.contains("{\"label\":\"b1\",\"count\":23,\"display\":\"displayText1\"}")); + assertTrue("There must 'bucket2' json output", out.contains("{\"label\":\"b2\",\"count\":34,\"display\":\"displayText2\"}")); searchContext = new SearchContext(-1, null, null, null); coll = CollectionWithPagingInfo.asPaged(null, Arrays.asList(exec1), false, 2, null, searchContext);