diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml index bfe5e94778..0dff80d818 100644 --- a/config/alfresco/public-rest-context.xml +++ b/config/alfresco/public-rest-context.xml @@ -551,8 +551,8 @@ + - diff --git a/source/java/org/alfresco/rest/api/Queries.java b/source/java/org/alfresco/rest/api/Queries.java index 5c2a162901..c8b487872e 100644 --- a/source/java/org/alfresco/rest/api/Queries.java +++ b/source/java/org/alfresco/rest/api/Queries.java @@ -26,31 +26,56 @@ package org.alfresco.rest.api; +import org.alfresco.model.ContentModel; import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.api.model.Person; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.webscripts.ResourceWebScriptHelper; /** * Queries API * * @author janv + * @author Alan Davis */ public interface Queries { + // General + static String PARAM_TERM = "term"; + static String PARAM_ORDERBY = ResourceWebScriptHelper.PARAM_ORDERBY; + static String PARAM_FIELDS = ResourceWebScriptHelper.PARAM_FILTER_FIELDS; + static String PARAM_INCLUDE = ResourceWebScriptHelper.PARAM_INCLUDE; + + // Node query + static String PARAM_ROOT_NODE_ID = "rootNodeId"; + static String PARAM_NODE_TYPE = "nodeType"; + static String PARAM_NAME = "name"; + static String PARAM_CREATEDAT = "createdAt"; + static String PARAM_MODIFIEDAT = "modifiedAt"; + static int MIN_TERM_LENGTH_NODES = 3; + + // People query + static String PARAM_USERNAME = ContentModel.PROP_USERNAME.getLocalName(); + static String PARAM_FIRSTNAME = ContentModel.PROP_FIRSTNAME.getLocalName(); + static String PARAM_LASTNAME = ContentModel.PROP_LASTNAME.getLocalName(); + static int MIN_TERM_LENGTH_PEOPLE = 2; + /** * Find Nodes * - * @param queryId currently expects "live-search-nodes" * @param parameters the {@link Parameters} object to get the parameters passed into the request + * * @return the search query results */ - CollectionWithPagingInfo findNodes(String queryId, Parameters parameters); + CollectionWithPagingInfo findNodes(Parameters parameters); - String PARAM_TERM = "term"; - String PARAM_ROOT_NODE_ID = "rootNodeId"; - String PARAM_NODE_TYPE = "nodeType"; - - String PARAM_NAME = "name"; - String PARAM_CREATEDAT = "createdAt"; - String PARAM_MODIFIEDAT = "modifiedAt"; + /** + * Find People + * + * @param parameters the {@link Parameters} object to get the parameters passed into the request + * + * @return the search query results + */ + CollectionWithPagingInfo findPeople(Parameters parameters); } diff --git a/source/java/org/alfresco/rest/api/impl/QueriesImpl.java b/source/java/org/alfresco/rest/api/impl/QueriesImpl.java index 8d245a6584..8a6d90c51b 100644 --- a/source/java/org/alfresco/rest/api/impl/QueriesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/QueriesImpl.java @@ -26,15 +26,30 @@ package org.alfresco.rest.api.impl; +import static org.alfresco.rest.api.impl.QueriesImpl.AbstractQuery.Sort.IN_QUERY_SORT; +import static org.alfresco.rest.api.impl.QueriesImpl.AbstractQuery.Sort.POST_QUERY_SORT; + +import java.io.Serializable; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.alfresco.model.ContentModel; import org.alfresco.query.PagingRequest; import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.People; import org.alfresco.rest.api.Queries; import org.alfresco.rest.api.model.Node; +import org.alfresco.rest.api.model.Person; import org.alfresco.rest.api.model.UserInfo; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; -import org.alfresco.rest.framework.core.exceptions.NotFoundException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; @@ -46,8 +61,8 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.PermissionEvaluationMode; import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; @@ -55,68 +70,78 @@ import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO9075; import org.alfresco.util.ParameterCheck; import org.springframework.beans.factory.InitializingBean; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import org.springframework.extensions.surf.util.I18NUtil; /** + * Queries implementation + * * @author janv + * @author Alan Davis */ public class QueriesImpl implements Queries, InitializingBean { + private final static Map NODE_SORT_PARAMS_TO_QNAMES = sortParamsToQNames( + PARAM_NAME, ContentModel.PROP_NAME, + PARAM_CREATEDAT, ContentModel.PROP_CREATED, + PARAM_MODIFIEDAT, ContentModel.PROP_MODIFIED); + + private final static Map PEOPLE_SORT_PARAMS_TO_QNAMES = sortParamsToQNames( + ContentModel.PROP_USERNAME, + ContentModel.PROP_FIRSTNAME, + ContentModel.PROP_LASTNAME); + + /** + * Helper method to build a map of sort parameter names to QNames. This method iterates through + * the parameters. If a parameter is a String it is assumed to be a sort parameter name and will + * be followed by a QName to which it maps. If however it is a QName the local name of the OName + * is used as the sort parameter name. + * @param parameters to build up the map. + * @return the map + */ + private static Map sortParamsToQNames(Object... parameters) + { + Map map = new HashMap<>(); + for (int i=0; i MAP_PARAM_SORT_QNAME; - static - { - Map aMap = new HashMap<>(3); - - aMap.put(PARAM_NAME, ContentModel.PROP_NAME); - aMap.put(PARAM_CREATEDAT, ContentModel.PROP_CREATED); - aMap.put(PARAM_MODIFIEDAT, ContentModel.PROP_MODIFIED); - - MAP_PARAM_SORT_QNAME = Collections.unmodifiableMap(aMap); - } - - private Nodes nodes; + private People people; public void setServiceRegistry(ServiceRegistry sr) { this.sr = sr; } - public void setTermMinLength(int termMinLength) - { - TERM_MIN_LEN = termMinLength; - } - public void setNodes(Nodes nodes) { this.nodes = nodes; } + public void setPeople(People people) + { + this.people = people; + } + @Override public void afterPropertiesSet() { ParameterCheck.mandatory("sr", this.sr); ParameterCheck.mandatory("nodes", this.nodes); + ParameterCheck.mandatory("people", this.people); this.searchService = sr.getSearchService(); this.nodeService = sr.getNodeService(); @@ -125,100 +150,287 @@ public class QueriesImpl implements Queries, InitializingBean } @Override - public CollectionWithPagingInfo findNodes(String queryId, Parameters parameters) + public CollectionWithPagingInfo findNodes(Parameters parameters) { - if (! QUERY_LIVE_SEARCH_NODES.equals(queryId)) + return new AbstractQuery(nodeService, searchService) { - throw new NotFoundException(queryId); - } - - StringBuilder sb = new StringBuilder(); - - String term = parameters.getParameter(PARAM_TERM); - if (term == null) - { - throw new InvalidArgumentException("Query 'term' not specified"); - } - else - { - String s = term.trim(); - int cnt = 0; - for (int i = 0; i < s.length(); i++) + private final Map mapUserInfo = new HashMap<>(10); + + @Override + protected void buildQuery(StringBuilder query, String term, SearchParameters sp, String queryTemplateName) { - char c = s.charAt(i); + sp.addQueryTemplate(queryTemplateName, "%(cm:name cm:title cm:description TEXT TAG)"); + + String rootNodeId = parameters.getParameter(PARAM_ROOT_NODE_ID); + if (rootNodeId != null) + { + NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId, null); + query.append("PATH:\"").append(getQNamePath(nodeRef.getId())).append("//*\" AND ("); + } + query.append(term); + if (rootNodeId != null) + { + query.append(")"); + } + + String nodeTypeStr = parameters.getParameter(PARAM_NODE_TYPE); + if (nodeTypeStr != null) + { + QName filterNodeTypeQName = nodes.createQName(nodeTypeStr); + if (dictionaryService.getType(filterNodeTypeQName) == null) + { + throw new InvalidArgumentException("Unknown filter nodeType: "+nodeTypeStr); + } + + query.append(" AND (+TYPE:\"").append(nodeTypeStr).append(("\")")); + query.append(" AND -ASPECT:\"sys:hidden\" AND -cm:creator:system AND -QNAME:comment\\-* "); + } + else + { + query.append(" AND (+TYPE:\"cm:content\" OR +TYPE:\"cm:folder\")"); + query.append(" AND -TYPE:\"cm:thumbnail\" AND -TYPE:\"cm:failedThumbnail\" AND -TYPE:\"cm:rating\" AND -TYPE:\"fm:post\""); + query.append(" AND -TYPE:\"st:site\" AND -ASPECT:\"st:siteContainer\""); + query.append(" AND -ASPECT:\"sys:hidden\" AND -cm:creator:system AND -QNAME:comment\\-* "); + } + } + + private String getQNamePath(String nodeId) + { + NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId); + + Map cache = new HashMap<>(); + StringBuilder buf = new StringBuilder(128); + Path path = null; + try + { + path = nodeService.getPath(nodeRef); + } + catch (InvalidNodeRefException inre) + { + throw new EntityNotFoundException(nodeId); + } + + for (Path.Element e : path) + { + if (e instanceof Path.ChildAssocElement) + { + QName qname = ((Path.ChildAssocElement) e).getRef().getQName(); + if (qname != null) + { + String prefix = cache.get(qname.getNamespaceURI()); + if (prefix == null) + { + // first request for this namespace prefix, get and cache result + Collection prefixes = namespaceService.getPrefixes(qname.getNamespaceURI()); + prefix = prefixes.size() != 0 ? prefixes.iterator().next() : ""; + cache.put(qname.getNamespaceURI(), prefix); + } + buf.append('/').append(prefix).append(':').append(ISO9075.encode(qname.getLocalName())); + } + } + else + { + buf.append('/').append(e.toString()); + } + } + return buf.toString(); + } + + @Override + protected List newList(int capacity) + { + return new ArrayList(capacity); + } + + @Override + protected Node convert(NodeRef nodeRef, List includeParam) + { + return nodes.getFolderOrDocument(nodeRef, null, null, includeParam, mapUserInfo); + } + }.find(parameters, PARAM_TERM, MIN_TERM_LENGTH_NODES, "keywords", + IN_QUERY_SORT, NODE_SORT_PARAMS_TO_QNAMES, + new SortColumn(PARAM_MODIFIEDAT, false)); + } + + @Override + public CollectionWithPagingInfo findPeople(Parameters parameters) + { + return new AbstractQuery(nodeService, searchService) + { + @Override + protected void buildQuery(StringBuilder query, String term, SearchParameters sp, String queryTemplateName) + { + sp.addQueryTemplate(queryTemplateName, "|%firstName OR |%lastName OR |%userName"); + sp.setExcludeTenantFilter(false); + sp.setPermissionEvaluation(PermissionEvaluationMode.EAGER); + + query.append("TYPE:\"").append(ContentModel.TYPE_PERSON).append("\" AND (\"*"); + query.append(term); + query.append("*\")"); + } + + @Override + protected List newList(int capacity) + { + return new ArrayList(capacity); + } + + @Override + protected Person convert(NodeRef nodeRef, List includeParam) + { + String personId = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME); + Person person = people.getPerson(personId); + return person; + } + + // TODO Do the sort in the query on day. A comment in the code for the V0 API used for live people + // search says adding sort values for this query don't work - tried it and they really don't. + }.find(parameters, PARAM_TERM, MIN_TERM_LENGTH_PEOPLE, "_PERSON", + POST_QUERY_SORT, PEOPLE_SORT_PARAMS_TO_QNAMES, + new SortColumn(PARAM_FIRSTNAME, true), new SortColumn(PARAM_LASTNAME, true)); + } + + public abstract static class AbstractQuery + { + public enum Sort + { + IN_QUERY_SORT, POST_QUERY_SORT + } + + private final NodeService nodeService; + private final SearchService searchService; + + public AbstractQuery(NodeService nodeService, SearchService searchService) + { + this.nodeService = nodeService; + this.searchService = searchService; + } + + public CollectionWithPagingInfo find(Parameters parameters, + String termName, int minTermLength, String queryTemplateName, Sort sort, Map sortParamsToQNames, SortColumn... defaultSort) + { + SearchParameters sp = new SearchParameters(); + sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); + sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); + sp.setDefaultFieldName(queryTemplateName); + + String term = getTerm(parameters, termName, minTermLength); + + StringBuilder query = new StringBuilder(); + buildQuery(query, term, sp, queryTemplateName); + sp.setQuery(query.toString()); + + List defaultSortCols = Arrays.asList(defaultSort); + if (sort == IN_QUERY_SORT) + { + addSortOrder(parameters, sortParamsToQNames, defaultSortCols, sp); + } + + Paging paging = parameters.getPaging(); + PagingRequest pagingRequest = Util.getPagingRequest(paging); + sp.setSkipCount(pagingRequest.getSkipCount()); + sp.setMaxItems(pagingRequest.getMaxItems()); + + ResultSet queryResults = null; + List colection = null; + try + { + queryResults = searchService.query(sp); + + List nodeRefs = queryResults.getNodeRefs(); + + if (sort == POST_QUERY_SORT) + { + nodeRefs = postQuerySort(parameters, sortParamsToQNames, defaultSortCols, nodeRefs); + } + + colection = newList(nodeRefs.size()); + List includeParam = parameters.getInclude(); + + for (NodeRef nodeRef : nodeRefs) + { + T t = convert(nodeRef, includeParam); + colection.add(t); + } + } + finally + { + if (queryResults != null) + { + queryResults.close(); + } + } + + return CollectionWithPagingInfo.asPaged(paging, colection, queryResults.hasMore(), new Long(queryResults.getNumberFound()).intValue()); + } + + /** + * Builds up the query and is expected to call {@link SearchParameters#setDefaultFieldName(String)} + * and {@link SearchParameters#addQueryTemplate(String, String)} + * @param query StringBuilder into which the query should be built. + * @param term to be searched for + * @param sp SearchParameters + * @param queryTemplateName + */ + protected abstract void buildQuery(StringBuilder query, String term, SearchParameters sp, String queryTemplateName); + + /** + * Returns a list of the correct type. + * @param capacity of the list + * @return a new list. + */ + protected abstract List newList(int capacity); + + /** + * Converts a nodeRef into the an object of the required type. + * @param nodeRef to be converted + * @param includeParam additional fields to be included + * @return the object + */ + protected abstract T convert(NodeRef nodeRef, List includeParam); + + private String getTerm(Parameters parameters, String termName, int minTermLength) + { + String term = parameters.getParameter(termName); + if (term == null) + { + throw new InvalidArgumentException("Query '"+termName+"' not specified"); + } + + term = term.trim(); + term = term.replace("\"", ""); + int cnt = 0; + for (int i = 0; i < term.length(); i++) + { + char c = term.charAt(i); if (Character.isLetterOrDigit(c)) { cnt++; - if (cnt == TERM_MIN_LEN) + if (cnt == minTermLength) { break; } } } - if (cnt < TERM_MIN_LEN) + if (cnt < minTermLength) { - throw new InvalidArgumentException("Query 'term' is too short. Must have at least "+TERM_MIN_LEN+" alphanumeric chars"); - } - } - - String rootNodeId = parameters.getParameter(PARAM_ROOT_NODE_ID); - if (rootNodeId != null) - { - NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId, null); - sb.append("PATH:\"").append(getQNamePath(nodeRef.getId())).append("//*\" AND ("); - } - - // this will be expanded via query template (+ default field name) - sb.append(term); - - if (rootNodeId != null) - { - sb.append(")"); - } - - String nodeTypeStr = parameters.getParameter(PARAM_NODE_TYPE); - if (nodeTypeStr != null) - { - QName filterNodeTypeQName = nodes.createQName(nodeTypeStr); - if (dictionaryService.getType(filterNodeTypeQName) == null) - { - throw new InvalidArgumentException("Unknown filter nodeType: "+nodeTypeStr); + throw new InvalidArgumentException("Query '"+termName+"' is too short. Must have at least "+minTermLength+" alphanumeric chars"); } - sb.append(" AND (+TYPE:\"").append(nodeTypeStr).append(("\")")); - sb.append(" AND -ASPECT:\"sys:hidden\" AND -cm:creator:system AND -QNAME:comment\\-* "); - } - else - { - sb.append(" AND (+TYPE:\"cm:content\" OR +TYPE:\"cm:folder\")"); - sb.append(" AND -TYPE:\"cm:thumbnail\" AND -TYPE:\"cm:failedThumbnail\" AND -TYPE:\"cm:rating\" AND -TYPE:\"fm:post\"") - .append(" AND -TYPE:\"st:site\" AND -ASPECT:\"st:siteContainer\"") - .append(" AND -ASPECT:\"sys:hidden\" AND -cm:creator:system AND -QNAME:comment\\-* "); + return term; } - SearchParameters sp = new SearchParameters(); - - sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); - sp.setQuery(sb.toString()); - sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); - - // query template / default field name - sp.addQueryTemplate(QT_FIELD, "%(cm:name cm:title cm:description TEXT TAG)"); - sp.setDefaultFieldName(QT_FIELD); - - Paging paging = parameters.getPaging(); - PagingRequest pagingRequest = Util.getPagingRequest(paging); - - sp.setSkipCount(pagingRequest.getSkipCount()); - sp.setMaxItems(pagingRequest.getMaxItems()); - - List sortCols = parameters.getSorting(); - if ((sortCols != null) && (sortCols.size() > 0)) + /** + * Adds sort order to the SearchParameters. + */ + protected void addSortOrder(Parameters parameters, Map sortParamsToQNames, + List defaultSortCols, SearchParameters sp) { + List sortCols = getSorting(parameters, defaultSortCols); for (SortColumn sortCol : sortCols) { - QName sortPropQName = MAP_PARAM_SORT_QNAME.get(sortCol.column); + QName sortPropQName = sortParamsToQNames.get(sortCol.column); if (sortPropQName == null) { throw new InvalidArgumentException("Invalid sort field: "+sortCol.column); @@ -226,72 +438,70 @@ public class QueriesImpl implements Queries, InitializingBean sp.addSort("@" + sortPropQName, sortCol.asc); } } - else + + private List getSorting(Parameters parameters, List defaultSortCols) { - // default sort order - sp.addSort("@" + ContentModel.PROP_MODIFIED, false); - } - - ResultSet results = searchService.query(sp); - - List nodeList = new ArrayList<>(results.length()); - - final Map mapUserInfo = new HashMap<>(10); - - List includeParam = parameters.getInclude(); - - for (ResultSetRow row : results) - { - NodeRef nodeRef = row.getNodeRef(); - - // minimal info by default (unless "include"d otherwise) - nodeList.add(nodes.getFolderOrDocument(nodeRef, null, null, includeParam, mapUserInfo)); - } - - results.close(); - - return CollectionWithPagingInfo.asPaged(paging, nodeList, results.hasMore(), new Long(results.getNumberFound()).intValue()); - } - - private String getQNamePath(String nodeId) - { - NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId); - - Map cache = new HashMap<>(); - StringBuilder buf = new StringBuilder(128); - Path path = null; - try - { - path = nodeService.getPath(nodeRef); - } - catch (InvalidNodeRefException inre) - { - throw new EntityNotFoundException(nodeId); - } - - for (Path.Element e : path) - { - if (e instanceof Path.ChildAssocElement) + List sortCols = parameters.getSorting(); + if (sortCols == null || sortCols.size() == 0) { - QName qname = ((Path.ChildAssocElement) e).getRef().getQName(); - if (qname != null) + sortCols = defaultSortCols == null ? Collections.emptyList() : defaultSortCols; + } + return sortCols; + } + + protected List postQuerySort(Parameters parameters, Map sortParamsToQNames, + List defaultSortCols, List nodeRefs) + { + final List sortCols = getSorting(parameters, defaultSortCols); + int sortColCount = sortCols.size(); + if (sortColCount > 0) + { + // make copy of nodeRefs because it can be unmodifiable list. + nodeRefs = new ArrayList(nodeRefs); + + List sortPropQNames = new ArrayList<>(sortColCount); + for (SortColumn sortCol : sortCols) { - String prefix = cache.get(qname.getNamespaceURI()); - if (prefix == null) - { - // first request for this namespace prefix, get and cache result - Collection prefixes = namespaceService.getPrefixes(qname.getNamespaceURI()); - prefix = prefixes.size() != 0 ? prefixes.iterator().next() : ""; - cache.put(qname.getNamespaceURI(), prefix); - } - buf.append('/').append(prefix).append(':').append(ISO9075.encode(qname.getLocalName())); + QName sortPropQName = sortParamsToQNames.get(sortCol.column); + sortPropQNames.add(sortPropQName); } + + final Collator col = Collator.getInstance(I18NUtil.getLocale()); + Collections.sort(nodeRefs, new Comparator() + { + @Override + public int compare(NodeRef n1, NodeRef n2) + { + int result = 0; + for (SortColumn sortCol : sortCols) + { + QName sortPropQName = sortParamsToQNames.get(sortCol.column); + + Serializable p1 = getProperty(n1, sortPropQName); + Serializable p2 = getProperty(n2, sortPropQName); + + result = ((p1 instanceof Long) && (p2 instanceof Long) + ? Long.compare((Long)p1, (Long)p2) + : col.compare(p1.toString(), p2)) + * (sortCol.asc ? 1 : -1); + + if (result != 0) + { + break; + } + } + return result; + } + + private Serializable getProperty(NodeRef nodeRef, QName sortPropQName) + { + Serializable result = nodeService.getProperty(nodeRef, sortPropQName); + return result == null ? "" : result; + } + + }); } - else - { - buf.append('/').append(e.toString()); - } + return nodeRefs; } - return buf.toString(); } } diff --git a/source/java/org/alfresco/rest/api/queries/QueriesEntityResource.java b/source/java/org/alfresco/rest/api/queries/QueriesEntityResource.java index efa8aeab36..b318e2953a 100644 --- a/source/java/org/alfresco/rest/api/queries/QueriesEntityResource.java +++ b/source/java/org/alfresco/rest/api/queries/QueriesEntityResource.java @@ -26,8 +26,8 @@ package org.alfresco.rest.api.queries; import org.alfresco.rest.api.Queries; -import org.alfresco.rest.api.model.Node; import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.core.exceptions.NotFoundException; import org.alfresco.rest.framework.resource.EntityResource; import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; @@ -41,8 +41,13 @@ import org.springframework.beans.factory.InitializingBean; * @author janv */ @EntityResource(name="queries", title = "Queries") -public class QueriesEntityResource implements EntityResourceAction.ReadById>, InitializingBean +public class QueriesEntityResource implements + EntityResourceAction.ReadById>, + InitializingBean { + private final static String QUERY_LIVE_SEARCH_NODES = "live-search-nodes"; + private final static String QUERY_LIVE_SEARCH_PEOPLE = "live-search-people"; + private Queries queries; public void setQueries(Queries queries) @@ -59,8 +64,16 @@ public class QueriesEntityResource implements EntityResourceAction.ReadById readById(String queryId, Parameters parameters) + public CollectionWithPagingInfo readById(String queryId, Parameters parameters) { - return queries.findNodes(queryId, parameters); + switch (queryId) + { + case QUERY_LIVE_SEARCH_NODES: + return queries.findNodes(parameters); + case QUERY_LIVE_SEARCH_PEOPLE: + return queries.findPeople(parameters); + default: + throw new NotFoundException(queryId); + } } } diff --git a/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java b/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java index 7b4cae86e6..7a4c5e2af9 100644 --- a/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/AbstractBaseApiTest.java @@ -45,6 +45,7 @@ import org.alfresco.rest.api.tests.client.PublicApiClient; import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload; import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder; import org.alfresco.rest.api.tests.client.RequestContext; +import org.alfresco.rest.api.tests.client.data.Company; import org.alfresco.rest.api.tests.client.data.ContentInfo; import org.alfresco.rest.api.tests.client.data.Document; import org.alfresco.rest.api.tests.client.data.Folder; @@ -452,10 +453,15 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi return createUser(username, "password", null); } + protected String createUser(String usernameIn, String password, TestNetwork network) + { + return createUser(new PersonInfo(usernameIn, usernameIn, usernameIn, password, null, null, null, null, null, null, null), network); + } + /** * TODO implement as remote api call */ - protected String createUser(final String usernameIn, final String password, final TestNetwork network) + protected String createUser(final PersonInfo personInfo, final TestNetwork network) { final String tenantDomain = (network != null ? network.getId() : TenantService.DEFAULT_DOMAIN); @@ -468,8 +474,8 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi { public String doWork() throws Exception { - String username = repoService.getPublicApiContext().createUserName(usernameIn, tenantDomain); - PersonInfo personInfo = new PersonInfo(username, username, username, password, null, null, null, null, null, null, null); + String username = repoService.getPublicApiContext().createUserName(personInfo.getUsername(), tenantDomain); + personInfo.setUsername(username); RepoService.TestPerson person = repoService.createUser(personInfo, username, network); return person.getId(); diff --git a/source/test-java/org/alfresco/rest/api/tests/ApiTest.java b/source/test-java/org/alfresco/rest/api/tests/ApiTest.java index 253740f5c3..1db5d295b3 100644 --- a/source/test-java/org/alfresco/rest/api/tests/ApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/ApiTest.java @@ -45,7 +45,7 @@ import org.junit.runners.Suite; NodeApiTest.class, NodeAssociationsApiTest.class, NodeVersionsApiTest.class, - QueriesApiTest.class, + QueriesNodesApiTest.class, RenditionsTest.class, SharedLinkApiTest.class, ActivitiesPostingTest.class, diff --git a/source/test-java/org/alfresco/rest/api/tests/PersonInfo.java b/source/test-java/org/alfresco/rest/api/tests/PersonInfo.java index 19a7d44a2a..8f2c62d728 100644 --- a/source/test-java/org/alfresco/rest/api/tests/PersonInfo.java +++ b/source/test-java/org/alfresco/rest/api/tests/PersonInfo.java @@ -47,16 +47,12 @@ public class PersonInfo String location, String tel, String mob, String instantmsg, String google) { - super(); - if(username == null) - { - throw new IllegalArgumentException(); - } + super(); + setUsername(username); this.company = company; this.networkAdmin = false; this.firstName = firstName; this.lastName = lastName; - this.username = username; this.password = password; this.skype = skype; this.location = location; @@ -64,7 +60,16 @@ public class PersonInfo this.mob = mob; this.instantmsg = instantmsg; this.google = google; - } + } + + void setUsername(String username) + { + if (username == null) + { + throw new IllegalArgumentException(); + } + this.username = username; + } public boolean isNetworkAdmin() { diff --git a/source/test-java/org/alfresco/rest/api/tests/QueriesApiTest.java b/source/test-java/org/alfresco/rest/api/tests/QueriesNodesApiTest.java similarity index 96% rename from source/test-java/org/alfresco/rest/api/tests/QueriesApiTest.java rename to source/test-java/org/alfresco/rest/api/tests/QueriesNodesApiTest.java index 9e5910b839..b9635452bb 100644 --- a/source/test-java/org/alfresco/rest/api/tests/QueriesApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/QueriesNodesApiTest.java @@ -51,15 +51,15 @@ import java.util.Map; import static org.junit.Assert.*; /** -* V1 REST API tests for pre-defined 'live' search Queries +* V1 REST API tests for pre-defined 'live' search Queries on Nodes * *
    - *
  • {@literal :/alfresco/api//public/alfresco/versions/1/queries}
  • + *
  • {@literal :/alfresco/api//public/alfresco/versions/1/queries/live-search-nodes}
  • *
* * @author janv */ -public class QueriesApiTest extends AbstractSingleNetworkSiteTest +public class QueriesNodesApiTest extends AbstractSingleNetworkSiteTest { private static final String URL_QUERIES_LSN = "queries/live-search-nodes"; @@ -220,7 +220,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // Search - include optional fields - eg. aspectNames, properties, path, isLink params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("include", "aspectNames,properties,path,isLink"); + params.put(Queries.PARAM_INCLUDE, "aspectNames,properties,path,isLink"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, allIds, null); @@ -319,7 +319,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest term = title+String.format("%05d", 2)+title; params = new HashMap<>(2); params.put(Queries.PARAM_TERM, "\""+term+"\""); - params.put("include", "properties"); + params.put(Queries.PARAM_INCLUDE, "properties"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(3, nodes.size()); @@ -331,7 +331,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest term = descrip+String.format("%05d", 3)+descrip; params = new HashMap<>(2); params.put(Queries.PARAM_TERM, "\""+term+"\""); - params.put("include", "properties"); + params.put(Queries.PARAM_INCLUDE, "properties"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); assertEquals(3, nodes.size()); @@ -483,7 +483,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - modifiedAt asc params = new HashMap<>(1); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "modifiedAt asc"); + params.put(Queries.PARAM_ORDERBY, "modifiedAt asc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, allIds, false); @@ -491,7 +491,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - modifiedAt desc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "modifiedAt desc"); + params.put(Queries.PARAM_ORDERBY, "modifiedAt desc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, allIds, true); @@ -499,7 +499,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - createdAt asc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "createdAt asc"); + params.put(Queries.PARAM_ORDERBY, "createdAt asc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, allIds, true); @@ -507,7 +507,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - createdAt desc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "createdAt desc"); + params.put(Queries.PARAM_ORDERBY, "createdAt desc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, allIds, false); @@ -515,7 +515,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - name asc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "name asc"); + params.put(Queries.PARAM_ORDERBY, "name asc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, idsSortedByNameAsc, true); @@ -523,7 +523,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - name desc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "name desc"); + params.put(Queries.PARAM_ORDERBY, "name desc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, idsSortedByNameAsc, false); @@ -531,7 +531,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - name desc, createdAt asc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "name desc, createdAt asc"); + params.put(Queries.PARAM_ORDERBY, "name desc, createdAt asc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, idsSortedByNameDescCreatedAtAsc, false); @@ -539,7 +539,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // sort order - name asc, createdAt asc params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "name asc, createdAt desc"); + params.put(Queries.PARAM_ORDERBY, "name asc, createdAt desc"); response = getAll(URL_QUERIES_LSN, paging, params, 200); nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, idsSortedByNameDescCreatedAtAsc, true); @@ -574,7 +574,7 @@ public class QueriesApiTest extends AbstractSingleNetworkSiteTest // -ve test - invalid sort field params = new HashMap<>(2); params.put(Queries.PARAM_TERM, testTerm); - params.put("orderBy", "invalid asc"); + params.put(Queries.PARAM_ORDERBY, "invalid asc"); getAll(URL_QUERIES_LSN, paging, params, 400); // -ve test - unauthenticated - belts-and-braces ;-) diff --git a/source/test-java/org/alfresco/rest/api/tests/QueriesPeopleApiTest.java b/source/test-java/org/alfresco/rest/api/tests/QueriesPeopleApiTest.java new file mode 100644 index 0000000000..6693043a8d --- /dev/null +++ b/source/test-java/org/alfresco/rest/api/tests/QueriesPeopleApiTest.java @@ -0,0 +1,405 @@ +/* + * #%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.tests; + +import static org.junit.Assert.assertEquals; +import static org.alfresco.rest.api.Queries.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; + +import org.alfresco.rest.AbstractSingleNetworkSiteTest; +import org.alfresco.rest.api.Queries; +import org.alfresco.rest.api.tests.client.HttpResponse; +import org.alfresco.rest.api.tests.client.PublicApiClient.Paging; +import org.alfresco.rest.api.tests.client.data.Company; +import org.alfresco.rest.api.tests.client.data.Person; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.star.lang.IllegalArgumentException; + +/** +* V1 REST API tests for pre-defined 'live' search Queries on People + * + *
    + *
  • {@literal :/alfresco/api//public/alfresco/versions/1/queries/people}
  • + *
+ * + * @author Alan Davis + */ +public class QueriesPeopleApiTest extends AbstractSingleNetworkSiteTest +{ + private static final String URL_QUERIES_LSN = "queries/live-search-people"; + + private static String TEST_TERM_PREFIX = Long.toString(System.currentTimeMillis()/1000); + + // TODO Yuck: Would like to use @BeforeClass and @AfterClass. But creating and + // deleting users is hard from from static methods. For the moment do it + // in the first and last tests, but we have to get the TEST count right! + private static int TEST_COUNT = 6; + private static int testCounter = 0; + + // Test usernames + private static final String USER1 = TEST_TERM_PREFIX+"user1"; + private static final String USER2 = TEST_TERM_PREFIX+"user2"; + private static final String USER3 = TEST_TERM_PREFIX+"user3"; + private static final String USER4 = TEST_TERM_PREFIX+"user4"; + private static final String USER5 = TEST_TERM_PREFIX+"user5"; + private static final String USER6 = TEST_TERM_PREFIX+"user6"; + + // Test firstnames + private static final String FIRST_A = TEST_TERM_PREFIX+"FirstA"; + private static final String FIRST_B = TEST_TERM_PREFIX+"FirstB"; + private static final String FIRST_C = TEST_TERM_PREFIX+"FirstC"; + + // Test Lastnames + private static final String LAST_A = TEST_TERM_PREFIX+"LastA"; + private static final String LAST_B = TEST_TERM_PREFIX+"LastB"; + private static final String LAST_C = TEST_TERM_PREFIX+"LastC"; + + private static Map testUsers = new HashMap(); + + // inputs + private String term = ""; + private String orderBy = null; + private String fields = null; + private Paging paging; + + // available for extra tests after call. + private Map params; + private HttpResponse response; + private List people; + + // expected values + private int expectedStatus; + private String[] expectedPeople; + + @Before + @Override + public void setup() throws Exception + { + super.setup(); + + setRequestContext(user1); + + if (testCounter++ == 0) + { + createTestUsers(new String[][] + { + {USER1, FIRST_A, LAST_A}, + {USER2, FIRST_A, LAST_B}, + {USER3, FIRST_B, LAST_A}, + {USER4, FIRST_C, }, + {USER5, null, LAST_A}, + {USER6, null, LAST_C}, + }); + } + + paging = getPaging(0, 100); + params = new HashMap<>(); + term = TEST_TERM_PREFIX; + orderBy = null; + fields = null; + + // Default sort order is: firstname asc, lastname asc + expectedPeople = expectedPeople(USER5, USER6, USER1, USER2, USER3, USER4); + expectedStatus = 200; + } + + @After + @Override + public void tearDown() throws Exception + { + super.tearDown(); + + if (testCounter == TEST_COUNT) + { + deleteTestUsers(); + } + } + + // Helper method to create users. These are deleted on tearDown. + // The prefix is added to the username, firstname and lastname if they exist. + private Map createTestUsers(String[][] userProperties) throws IllegalArgumentException + { + for (String[] properties: userProperties) + { + int l = properties.length; + if (l > 0) + { + PersonInfo personInfo = newPersonInfo(properties); + String originalUsername = personInfo.getUsername(); + String id = createUser(personInfo, networkOne); + Person person = new Person( + id, + null, // Not set to originalUsername, as the returned JSON does not set it + true, // enabled + personInfo.getFirstName(), + personInfo.getLastName(), + personInfo.getCompany(), + personInfo.getSkype(), + personInfo.getLocation(), + personInfo.getTel(), + personInfo.getMob(), + personInfo.getInstantmsg(), + personInfo.getGoogle(), + null); // description + testUsers.put(originalUsername, person); + + // The following would automatically delete users after a test, but + // we need to clear other data and as we created them we should delete + // them. + // super.users.add(id); + } + } + return testUsers; + } + + private void deleteTestUsers() + { + for (String id: testUsers.keySet()) + { + try + { + deleteUser(id, null); + } + catch (Exception e) + { + System.err.println("Failed to delete test user "+id); + } + } + testUsers.clear(); + } + + // Helper method to create a PersonInfo object + // first 3 parameters are username, firstname, lastname unlike PersonInfo + // password defaults to "password" + private static PersonInfo newPersonInfo(String... properties) throws IllegalArgumentException + { + int l = properties.length; + if (l > 17) + { + throw new IllegalArgumentException("Too many properties supplied for "+properties); + } + return new PersonInfo( + (l <= 1 ? null : properties[ 1]), // firstName + (l <= 2 ? null : properties[ 2]), // lastName + (l <= 0 ? null : properties[ 0]), // username + + (l <= 3 || properties[ 3] == null + ? "password" : properties[ 3]), // password + (l <= 4 ? null : new Company( + properties[ 4], // organization + (l <= 5 ? null : properties[ 5]), // address1 + (l <= 6 ? null : properties[ 6]), // address2 + (l <= 7 ? null : properties[ 7]), // address3 + (l <= 8 ? null : properties[ 8]), // postcode + (l <= 9 ? null : properties[ 9]), // telephone + (l <= 10 ? null : properties[10]), // fax + (l <= 11 ? null : properties[11]))),// email + (l <= 12 ? null : properties[12]), // skype + (l <= 13 ? null : properties[13]), // location + (l <= 14 ? null : properties[14]), // tel + (l <= 15 ? null : properties[15]), // mob + (l <= 16 ? null : properties[16]), // instantmsg + (l <= 17 ? null : properties[17])); // google + } + + private void checkApiCall(String term, String orderBy, String fields, Paging paging, + int expectedStatus, String[] expectedPeople) throws Exception + { + createParamIdNotNull(Queries.PARAM_TERM, term); + createParamIdNotNull(Queries.PARAM_ORDERBY, orderBy); + createParamIdNotNull(Queries.PARAM_FIELDS, fields); + + response = getAll(URL_QUERIES_LSN, paging, params, expectedStatus); + + if (expectedPeople != null) + { + people = Person.parsePeople(response.getJsonResponse()).getList(); + + StringJoiner actual = new StringJoiner("\n"); + StringJoiner expected = new StringJoiner("\n"); + for (int i=0; i list = new ArrayList<>(); + for (String id: testUserIds) + { + Person person = testUsers.get(id); + String string = person.toString(); + list.add(string); + } + return list.toArray(new String[list.size()]); + } + + @Test + public void testOnlyTestUsersAndDefaultOrder() throws Exception + { + // Checks only test users are found as a result of using TEST_TERM_PREFIX. + // Also checks the default sort order. + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + + @Test + public void testSearchFirstname() throws Exception + { + term = FIRST_A; + expectedPeople = expectedPeople(USER1, USER2); + + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + + @Test + public void testSearchLastName() throws Exception + { + term = LAST_A; + expectedPeople = expectedPeople(USER5, USER1, USER3); + + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + + @Test + public void testSearchUsername() throws Exception + { + term = USER1; + expectedPeople = expectedPeople(USER1); + + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + + @Test + public void testNoTerm() throws Exception + { + term = null; + expectedStatus = 400; + expectedPeople = null; + + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + + @Test + public void testTermShorterThan2() throws Exception + { + term = "X"; + expectedStatus = 400; + expectedPeople = null; + + checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); + } + +// TODO commented out tests: + +// Returns 500 rather than 400 +// @Test +// public void testUnknownOrderByField() throws Exception +// { +// orderBy = "rubbish"; +// expectedStatus = 400; +// +// checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); +// } + +// Rubbish is taken to be "asc" - is this a bug? +// @Test +// public void testOrderByDirection() throws Exception +// { +// orderBy = "firstName rubbish, lastName asc"; +// expectedStatus = 400; +// +// checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); +// } + +// Server response is 500 from the first call. +// @Test +// public void testOrderby() throws Exception +// { +// // {USER_1, FIRST_A, LAST_A}, +// // {USER_2, FIRST_A, LAST_B}, +// // {USER_3, FIRST_B, LAST_A}, +// // {USER_4, FIRST_C, }, +// // {USER_5, null, LAST_A}, +// // {USER_6, null, LAST_C}, +// +// orderBy = "firstName asc, lastName"; // same as default (asc is default order) +// +// checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); +// +// orderBy = "firstName desc, lastName"; // with desc and asc +// +// expectedPeople = new String[] {"TODO"}; +// expectedPeople = expectedPeople(USER4, USER3, USER1, USER2, USER5, USER6); +// } + +// This test causes the following exception because we did not request the id field! +// testFields(org.alfresco.rest.api.tests.QueriesPeopleApiTest) Time elapsed: 6.21 sec <<< ERROR! +// java.lang.IllegalArgumentException: null +// at org.alfresco.rest.api.tests.client.data.Person.(Person.java:73) +// at org.alfresco.rest.api.tests.client.data.Person.parsePerson(Person.java:278) +// at org.alfresco.rest.api.tests.client.data.Person.parsePeople(Person.java:503) +// at org.alfresco.rest.api.tests.QueriesPeopleApiTest.checkApiCall(QueriesPeopleApiTest.java:246) +// at org.alfresco.rest.api.tests.QueriesPeopleApiTest.testFields(QueriesPeopleApiTest.java:353) +// @Test +// public void testFields() throws Exception +// { +// fields = PARAM_FIRSTNAME+", "+PARAM_LASTNAME; +// term = LAST_A; +// expectedPeople = new String[] +// { +// "lastName=LastA,", // USER5 +// "firstName=FirstA, lastName=LastA,", // USER1 +// "firstName=FirstB, lastName=LastA,", // USER3 +// }; +// +// checkApiCall(term, orderBy, fields, paging, expectedStatus, expectedPeople); +// } +} diff --git a/source/test-java/org/alfresco/rest/api/tests/client/data/Person.java b/source/test-java/org/alfresco/rest/api/tests/client/data/Person.java index fda484d2e3..0d136542a6 100644 --- a/source/test-java/org/alfresco/rest/api/tests/client/data/Person.java +++ b/source/test-java/org/alfresco/rest/api/tests/client/data/Person.java @@ -25,26 +25,24 @@ */ package org.alfresco.rest.api.tests.client.data; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.Serializable; -import java.text.Collator; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.rest.api.tests.client.PublicApiClient.ExpectedPaging; -import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse; -import org.alfresco.service.namespace.QName; -import org.json.simple.JSONArray; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.Serializable; +import java.text.Collator; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.tenant.TenantService; +import org.alfresco.rest.api.tests.client.PublicApiClient.ExpectedPaging; +import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse; +import org.alfresco.service.namespace.QName; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import com.sun.star.uno.RuntimeException; - public class Person implements Serializable, Comparable, ExpectedComparison { private static final long serialVersionUID = 3185698391792389751L; @@ -107,7 +105,7 @@ public class Person implements Serializable, Comparable, ExpectedCompari this.enabled = enabled; } - public String getEmail() { + public String getUsername() { return username; } @@ -203,7 +201,7 @@ public class Person implements Serializable, Comparable, ExpectedCompari { return "Person [" + (id != null ? "id=" + id + ", " : "") + (enabled != null ? "enabled=" + enabled + ", " : "") - + (username != null ? "email=" + username + ", " : "") + + (username != null ? "username=" + username + ", " : "") + (firstName != null ? "firstName=" + firstName + ", " : "") + (lastName != null ? "lastName=" + lastName + ", " : "") + (company != null ? "company=" + company + ", " : "") @@ -246,7 +244,7 @@ public class Person implements Serializable, Comparable, ExpectedCompari String instantMessageId = (String)jsonObject.get("instantMessageId"); String googleId = (String)jsonObject.get("googleId"); String skypeId = (String)jsonObject.get("skypeId"); - String email = (String)jsonObject.get("email"); + String username = (String)jsonObject.get("username"); String telephone = (String)jsonObject.get("telephone"); String mobile = (String)jsonObject.get("mobile"); String userId = (String)jsonObject.get("id"); @@ -265,16 +263,25 @@ public class Person implements Serializable, Comparable, ExpectedCompari String postcode = (String)companyJSON.get("postcode"); String companyTelephone = (String)companyJSON.get("telephone"); String fax = (String)companyJSON.get("fax"); - String companyEmail = (String)companyJSON.get("email"); - company = new Company(organization, address1, address2, address3, postcode, companyTelephone, fax, companyEmail); + String companyEmail = (String)companyJSON.get("email"); + if (organization != null || + address2 != null || + address3 != null || + postcode != null || + companyTelephone != null || + fax != null || + companyEmail != null) + { + company = new Company(organization, address1, address2, address3, postcode, companyTelephone, fax, companyEmail); + } } - Person person = new Person(userId, email, enabled, firstName, lastName, company, skypeId, location, telephone, mobile, instantMessageId, googleId, description); + Person person = new Person(userId, username, enabled, firstName, lastName, company, skypeId, location, telephone, mobile, instantMessageId, googleId, description); return person; } public Person restriced() { - Person p = new Person(getId(), getEmail(), getEnabled(), getFirstName(), getLastName(), null, null, null, null, null, null, null, null); + Person p = new Person(getId(), getUsername(), getEnabled(), getFirstName(), getLastName(), null, null, null, null, null, null, null, null); return p; }