Merged HEAD (5.2) to 5.2.N (5.2.1)

126451 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
      122140 jvonka: Nodes (FileFolder) API - update listChildren 'where' filtering (inc tests) for nodeType + optionally including sub-types
      - for example: where=(nodeType='cm:link includeSubTypes')
      RA-811, RA-634


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126796 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ancuta Morarasu
2016-05-11 11:22:40 +00:00
parent 5b8acc631d
commit c7c51c4ec4
2 changed files with 54 additions and 23 deletions

View File

@@ -249,7 +249,8 @@ public class NodesImpl implements Nodes
private final static String PARAM_ISFOLDER = "isFolder"; private final static String PARAM_ISFOLDER = "isFolder";
private final static String PARAM_ISCONTENT = "isContent"; private final static String PARAM_ISCONTENT = "isContent";
private final static String PARAM_SUBTYPES = "subTypes";
private final static String PARAM_INCLUDE_SUBTYPES = "INCLUDESUBTYPES";
private final static String PARAM_NAME = "name"; private final static String PARAM_NAME = "name";
private final static String PARAM_CREATEDAT = "createdAt"; private final static String PARAM_CREATEDAT = "createdAt";
@@ -280,7 +281,7 @@ public class NodesImpl implements Nodes
// list children filtering (via where clause) // list children filtering (via where clause)
private final static Set<String> LIST_FOLDER_CHILDREN_EQUALS_QUERY_PROPERTIES = private final static Set<String> LIST_FOLDER_CHILDREN_EQUALS_QUERY_PROPERTIES =
new HashSet<>(Arrays.asList(new String[] {PARAM_ISFOLDER, PARAM_ISCONTENT, PARAM_NODETYPE, PARAM_SUBTYPES})); new HashSet<>(Arrays.asList(new String[] {PARAM_ISFOLDER, PARAM_ISCONTENT, PARAM_NODETYPE}));
/* /*
* Validates that node exists. * Validates that node exists.
@@ -955,24 +956,9 @@ public class NodesImpl implements Nodes
String nodeTypeStr = propertyWalker.getProperty(PARAM_NODETYPE, WhereClauseParser.EQUALS, String.class); String nodeTypeStr = propertyWalker.getProperty(PARAM_NODETYPE, WhereClauseParser.EQUALS, String.class);
if ((nodeTypeStr != null) && (! nodeTypeStr.isEmpty())) if ((nodeTypeStr != null) && (! nodeTypeStr.isEmpty()))
{ {
filterIncludeSubTypes = false; // default nodeType filtering is without subTypes (unless subTypes = true) Pair<QName, Boolean> pair = parseNodeTypeFilter(nodeTypeStr);
filterNodeTypeQName = pair.getFirst();
filterNodeTypeQName = createQName(nodeTypeStr); filterIncludeSubTypes = pair.getSecond();
if (dictionaryService.getType(filterNodeTypeQName) == null)
{
throw new InvalidArgumentException("Unknown filter nodeType: "+nodeTypeStr);
}
}
// optionally used with nodeType filter (default is *not* to include sub-types)
Boolean subTypes = propertyWalker.getProperty(PARAM_SUBTYPES, WhereClauseParser.EQUALS, Boolean.class);
if (subTypes != null)
{
if (nodeTypeStr == null)
{
throw new InvalidArgumentException("Expected nodeType and subTypes (not just subTypes) filter: "+parentNodeRef.getId());
}
filterIncludeSubTypes = subTypes;
} }
} }
@@ -1052,6 +1038,30 @@ public class NodesImpl implements Nodes
return CollectionWithPagingInfo.asPaged(paging, nodes, pagingResults.hasMoreItems(), pagingResults.getTotalResultCount().getFirst()); return CollectionWithPagingInfo.asPaged(paging, nodes, pagingResults.hasMoreItems(), pagingResults.getTotalResultCount().getFirst());
} }
private Pair<QName,Boolean> parseNodeTypeFilter(String nodeTypeStr)
{
boolean filterIncludeSubTypes = false; // default nodeType filtering is without subTypes (unless nodeType value is suffixed with ' INCLUDESUBTYPES')
int idx = nodeTypeStr.lastIndexOf(' ');
if (idx > 0)
{
String suffix = nodeTypeStr.substring(idx);
if (suffix.equalsIgnoreCase(" "+PARAM_INCLUDE_SUBTYPES))
{
filterIncludeSubTypes = true;
nodeTypeStr = nodeTypeStr.substring(0, idx);
}
}
QName filterNodeTypeQName = createQName(nodeTypeStr);
if (dictionaryService.getType(filterNodeTypeQName) == null)
{
throw new InvalidArgumentException("Unknown filter nodeType: "+nodeTypeStr);
}
return new Pair<>(filterNodeTypeQName, filterIncludeSubTypes);
}
protected Pair<Set<QName>, Set<QName>> buildSearchTypesAndIgnoreAspects(QName filterNodeTypeQName, boolean filterIncludeSubTypes, Set<QName> ignoreQNameTypes) protected Pair<Set<QName>, Set<QName>> buildSearchTypesAndIgnoreAspects(QName filterNodeTypeQName, boolean filterIncludeSubTypes, Set<QName> ignoreQNameTypes)
{ {
Set<QName> searchTypeQNames = new HashSet<QName>(100); Set<QName> searchTypeQNames = new HashSet<QName>(100);

View File

@@ -1484,7 +1484,7 @@ public class NodeApiTest extends AbstractBaseApiTest
n1.expected(nodeResp); n1.expected(nodeResp);
// filtering, via where clause (nodeType + subTypes) // filtering, via where clause (nodeType + optionally including sub-types)
// note: subtle issue - in order to filter by "cm:link" the qname must have been created in the DB (in a write txn) // note: subtle issue - in order to filter by "cm:link" the qname must have been created in the DB (in a write txn)
// otherwise query will not match a missing qname (hmm). Workaround here by forcing the create of an explicit "cm:link". // otherwise query will not match a missing qname (hmm). Workaround here by forcing the create of an explicit "cm:link".
@@ -1505,11 +1505,23 @@ public class NodeApiTest extends AbstractBaseApiTest
response = getAll(getChildrenUrl(f2Id), user1, paging, params, 200); response = getAll(getChildrenUrl(f2Id), user1, paging, params, 200);
List<Node> nodes = jacksonUtil.parseEntries(response.getJsonResponse(), Node.class); List<Node> nodes = jacksonUtil.parseEntries(response.getJsonResponse(), Node.class);
assertEquals(1, nodes.size()); assertEquals(1, nodes.size());
// filter by including sub-types - note: includesubtypes is case-insensitive
params = new HashMap<>(); params = new HashMap<>();
params.put("where", "(nodeType='cm:link' and subTypes=true)"); params.put("where", "(nodeType='cm:link INCLUDESUBTYPES')");
paging = getPaging(0, Integer.MAX_VALUE);
response = getAll(getChildrenUrl(f2Id), user1, paging, params, 200);
nodes = jacksonUtil.parseEntries(response.getJsonResponse(), Node.class);
assertEquals(3, nodes.size());
assertTrue(linkIds.contains(nodes.get(0).getId()));
assertTrue(linkIds.contains(nodes.get(1).getId()));
params = new HashMap<>();
params.put("where", "(nodeType='cm:link includeSubTypes')");
paging = getPaging(0, Integer.MAX_VALUE); paging = getPaging(0, Integer.MAX_VALUE);
@@ -1549,6 +1561,15 @@ public class NodeApiTest extends AbstractBaseApiTest
params = new HashMap<>(); params = new HashMap<>();
params.put("where", "(nodeType='my:unknown'"); params.put("where", "(nodeType='my:unknown'");
getAll(getChildrenUrl(f2Id), user1, paging, params, 400); getAll(getChildrenUrl(f2Id), user1, paging, params, 400);
// -ver test - invalid node type localname format and suffix is not ' includesubtypes'
params = new HashMap<>();
params.put("where", "(nodeType='cm:link ')");
getAll(getChildrenUrl(f2Id), user1, paging, params, 400);
params = new HashMap<>();
params.put("where", "(nodeType='cm:link blah')");
getAll(getChildrenUrl(f2Id), user1, paging, params, 400);
} }