From c7678ccd653626125414a5eb7434d192a44eec5a Mon Sep 17 00:00:00 2001 From: Ancuta Morarasu Date: Wed, 11 May 2016 12:13:21 +0000 Subject: [PATCH] Merged HEAD (5.2) to 5.2.N (5.2.1) 126589 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 124819 jvonka: RA-896 - List Node Children filtering - additional fixes & tests, when filtering by isFile &/or isFolder git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/rest/api/impl/NodesImpl.java | 108 ++++++++++-------- .../alfresco/rest/api/tests/NodeApiTest.java | 24 ++++ 2 files changed, 87 insertions(+), 45 deletions(-) diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 8e2f604d0a..5d0149f179 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -1115,12 +1115,12 @@ public class NodesImpl implements Nodes if (isFile != null) { - includeFiles = isFile; + includeFiles = isFile; } if (Boolean.TRUE.equals(includeFiles) && Boolean.TRUE.equals(includeFolders)) { - throw new InvalidArgumentException("Invalid filter (isFile=true and isFolder = true) - a node cannot be both a file and a folder"); + throw new InvalidArgumentException("Invalid filter (isFile=true and isFolder=true) - a node cannot be both a file and a folder"); } String nodeTypeStr = propertyWalker.getProperty(PARAM_NODETYPE, WhereClauseParser.EQUALS, String.class); @@ -1135,8 +1135,6 @@ public class NodesImpl implements Nodes filterNodeTypeQName = pair.getFirst(); filterIncludeSubTypes = pair.getSecond(); } - - } List sortCols = parameters.getSorting(); @@ -1172,30 +1170,49 @@ public class NodesImpl implements Nodes PagingRequest pagingRequest = Util.getPagingRequest(paging); final PagingResults pagingResults; - if (((includeFiles == null) && (includeFolders == null)) || - (filterNodeTypeQName != null) || - (Boolean.FALSE.equals(includeFiles) && Boolean.FALSE.equals(includeFolders))) + + // notes (see also earlier validation checks): + // - node type filtering is mutually exclusive from isFile/isFolder, can optionally also include sub-types + // - isFile & isFolder cannot both be true + // - (isFile=false) means any other types/sub-types (other than files) + // - (isFolder=false) means any other types/sub-types (other than folders) + // - (isFile=false and isFolder=false) means any types/sub-types (other than files or folders) + + if (filterNodeTypeQName == null) { - // either no filtering or some filtering (but not just files or folders) - if (filterNodeTypeQName == null) + if (Boolean.FALSE.equals(includeFiles) && Boolean.FALSE.equals(includeFolders)) { + includeFiles = false; + includeFolders = false; + filterNodeTypeQName = ContentModel.TYPE_CMOBJECT; } - Pair, Set> pair = buildSearchTypesAndIgnoreAspects(filterNodeTypeQName, filterIncludeSubTypes, ignoreQNames, includeFiles, includeFolders); - Set searchTypeQNames = pair.getFirst(); - Set ignoreAspectQNames = pair.getSecond(); + if (includeFiles != null) + { + if ((! includeFiles) && (includeFolders == null)) + { + // isFile=false + filterNodeTypeQName = ContentModel.TYPE_CMOBJECT; + } + } - pagingResults = fileFolderService.list(parentNodeRef, searchTypeQNames, ignoreAspectQNames, sortProps, pagingRequest); + if (includeFolders != null) + { + if ((! includeFolders) && (includeFiles == null)) + { + // isFolder=false + filterNodeTypeQName = ContentModel.TYPE_CMOBJECT; + } + } } - else - { - // files or folders only - includeFiles = (includeFiles != null ? includeFiles : false); - includeFolders = (includeFolders != null ? includeFolders : false); - pagingResults = fileFolderService.list(parentNodeRef, includeFiles, includeFolders, ignoreQNames, sortProps, pagingRequest); - } + Pair, Set> pair = buildSearchTypesAndIgnoreAspects(filterNodeTypeQName, filterIncludeSubTypes, ignoreQNames, includeFiles, includeFolders); + Set searchTypeQNames = pair.getFirst(); + Set ignoreAspectQNames = pair.getSecond(); + + pagingResults = fileFolderService.list(parentNodeRef, searchTypeQNames, ignoreAspectQNames, sortProps, pagingRequest); + final Map mapUserInfo = new HashMap<>(10); @@ -1253,34 +1270,32 @@ public class NodesImpl implements Nodes protected Pair, Set> buildSearchTypesAndIgnoreAspects(QName nodeTypeQName, boolean includeSubTypes, Set ignoreQNameTypes, Boolean includeFiles, Boolean includeFolders) { - Set searchTypeQNames = new HashSet(100); + Set searchTypeQNames = new HashSet<>(100); Set ignoreAspectQNames = null; - // Build a list of (sub-)types - if (includeSubTypes) + if (nodeTypeQName != null) { - Collection qnames = dictionaryService.getSubTypes(nodeTypeQName, true); - searchTypeQNames.addAll(qnames); - } - searchTypeQNames.add(nodeTypeQName); + // Build a list of (sub-)types + if (includeSubTypes) + { + Collection qnames = dictionaryService.getSubTypes(nodeTypeQName, true); + searchTypeQNames.addAll(qnames); + } + searchTypeQNames.add(nodeTypeQName); - // Remove 'system' folders - if (includeSubTypes) - { - Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true); - searchTypeQNames.removeAll(qnames); + // Remove 'system' folders + if (includeSubTypes) + { + Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true); + searchTypeQNames.removeAll(qnames); + } + searchTypeQNames.remove(ContentModel.TYPE_SYSTEM_FOLDER); } - searchTypeQNames.remove(ContentModel.TYPE_SYSTEM_FOLDER); if (includeFiles != null) { if (includeFiles) { - if (! dictionaryService.isSubClass(ContentModel.TYPE_CONTENT, nodeTypeQName)) - { - throw new InvalidArgumentException("Cannot filter for isFile since not sub-type of: "+nodeTypeQName); - } - if (includeSubTypes) { Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true); @@ -1300,17 +1315,20 @@ public class NodesImpl implements Nodes { if (includeFolders) { - if (! dictionaryService.isSubClass(ContentModel.TYPE_FOLDER, nodeTypeQName)) - { - throw new InvalidArgumentException("Cannot filter for isFolder since not sub-type of: "+nodeTypeQName); - } - if (includeSubTypes) { Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_FOLDER, true); searchTypeQNames.addAll(qnames); } searchTypeQNames.add(ContentModel.TYPE_FOLDER); + + // Remove 'system' folders + if (includeSubTypes) + { + Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true); + searchTypeQNames.removeAll(qnames); + } + searchTypeQNames.remove(ContentModel.TYPE_SYSTEM_FOLDER); } else { @@ -1322,7 +1340,7 @@ public class NodesImpl implements Nodes if (ignoreQNameTypes != null) { - Set ignoreQNamesNotSearchTypes = new HashSet(ignoreQNameTypes); + Set ignoreQNamesNotSearchTypes = new HashSet<>(ignoreQNameTypes); ignoreQNamesNotSearchTypes.removeAll(searchTypeQNames); ignoreQNamesNotSearchTypes.remove(ContentModel.TYPE_SYSTEM_FOLDER); @@ -1339,7 +1357,7 @@ public class NodesImpl implements Nodes private Set getAspectsToIgnore(Set ignoreQNames) { - Set ignoreQNameAspects = new HashSet(ignoreQNames.size()); + Set ignoreQNameAspects = new HashSet<>(ignoreQNames.size()); for (QName qname : ignoreQNames) { if (dictionaryService.getAspect(qname) != null) diff --git a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java index 4860fe707e..0aedb15cd9 100644 --- a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -1737,6 +1737,14 @@ public class NodeApiTest extends AbstractBaseApiTest folderAndFileIds.addAll(folderIds); folderAndFileIds.addAll(fileIds); + List notFileIds = new ArrayList<>(folderCnt+objCnt); + notFileIds.addAll(folderIds); + notFileIds.addAll(objIds); + + List notFolderIds = new ArrayList<>(fileCnt+objCnt); + notFolderIds.addAll(fileIds); + notFolderIds.addAll(objIds); + Paging paging = getPaging(0, Integer.MAX_VALUE); // no filtering @@ -1814,6 +1822,22 @@ public class NodeApiTest extends AbstractBaseApiTest nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); checkNodeIds(nodes, objIds); + // filtering, via where clause - not files + params = new HashMap<>(); + params.put("where", "(isFile=false)"); + + response = getAll(myChildrenUrl, user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + checkNodeIds(nodes, notFileIds); + + // filtering, via where clause - not folders + params = new HashMap<>(); + params.put("where", "(isFolder=false)"); + + response = getAll(myChildrenUrl, user1, paging, params, 200); + nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class); + checkNodeIds(nodes, notFolderIds); + // -ve - node cannot be both a file and a folder params = new HashMap<>(); params.put("where", "(isFile=true AND isFolder=true)");