mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged HEAD (5.2) to 5.2.N (5.2.1)
126548 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 124180 jvonka: RA-896: Fix filter by "where=(isFile=false and isFolder=false)" - when listing node children - will list cmobject, including sub-types (except cm:folder & cm:content, including sub-types) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126894 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1042,8 +1042,8 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
final List<String> includeParam = parameters.getInclude();
|
final List<String> includeParam = parameters.getInclude();
|
||||||
|
|
||||||
boolean includeFolders = true;
|
Boolean includeFolders = null;
|
||||||
boolean includeFiles = true;
|
Boolean includeFiles = null;
|
||||||
|
|
||||||
QName filterNodeTypeQName = null;
|
QName filterNodeTypeQName = null;
|
||||||
|
|
||||||
@@ -1061,20 +1061,14 @@ public class NodesImpl implements Nodes
|
|||||||
Boolean isFolder = propertyWalker.getProperty(PARAM_ISFOLDER, WhereClauseParser.EQUALS, Boolean.class);
|
Boolean isFolder = propertyWalker.getProperty(PARAM_ISFOLDER, WhereClauseParser.EQUALS, Boolean.class);
|
||||||
Boolean isFile = propertyWalker.getProperty(PARAM_ISFILE, WhereClauseParser.EQUALS, Boolean.class);
|
Boolean isFile = propertyWalker.getProperty(PARAM_ISFILE, WhereClauseParser.EQUALS, Boolean.class);
|
||||||
|
|
||||||
if ((isFolder != null) && (isFile != null))
|
if (isFolder != null)
|
||||||
{
|
{
|
||||||
includeFiles = isFile;
|
|
||||||
includeFolders = isFolder;
|
includeFolders = isFolder;
|
||||||
}
|
}
|
||||||
else if (isFolder != null)
|
|
||||||
{
|
if (isFile != null)
|
||||||
includeFiles = !isFolder;
|
|
||||||
includeFolders = isFolder;
|
|
||||||
}
|
|
||||||
else if (isFile != null)
|
|
||||||
{
|
{
|
||||||
includeFiles = isFile;
|
includeFiles = isFile;
|
||||||
includeFolders = !isFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String nodeTypeStr = propertyWalker.getProperty(PARAM_NODETYPE, WhereClauseParser.EQUALS, String.class);
|
String nodeTypeStr = propertyWalker.getProperty(PARAM_NODETYPE, WhereClauseParser.EQUALS, String.class);
|
||||||
@@ -1119,14 +1113,14 @@ public class NodesImpl implements Nodes
|
|||||||
PagingRequest pagingRequest = Util.getPagingRequest(paging);
|
PagingRequest pagingRequest = Util.getPagingRequest(paging);
|
||||||
|
|
||||||
final PagingResults<FileInfo> pagingResults;
|
final PagingResults<FileInfo> pagingResults;
|
||||||
if ((filterNodeTypeQName != null) || (includeFolders && includeFiles))
|
if ((filterNodeTypeQName != null) || (Boolean.FALSE.equals(includeFiles) && Boolean.FALSE.equals(includeFolders)))
|
||||||
{
|
{
|
||||||
if (filterNodeTypeQName == null)
|
if (filterNodeTypeQName == null)
|
||||||
{
|
{
|
||||||
filterNodeTypeQName = ContentModel.TYPE_CMOBJECT;
|
filterNodeTypeQName = ContentModel.TYPE_CMOBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<Set<QName>, Set<QName>> pair = buildSearchTypesAndIgnoreAspects(filterNodeTypeQName, filterIncludeSubTypes, ignoreQNames);
|
Pair<Set<QName>, Set<QName>> pair = buildSearchTypesAndIgnoreAspects(filterNodeTypeQName, filterIncludeSubTypes, ignoreQNames, includeFiles, includeFolders);
|
||||||
Set<QName> searchTypeQNames = pair.getFirst();
|
Set<QName> searchTypeQNames = pair.getFirst();
|
||||||
Set<QName> ignoreAspectQNames = pair.getSecond();
|
Set<QName> ignoreAspectQNames = pair.getSecond();
|
||||||
|
|
||||||
@@ -1134,7 +1128,20 @@ public class NodesImpl implements Nodes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// files *or* folders only
|
// files and/or folders only
|
||||||
|
if ((includeFiles == null) && (includeFolders == null))
|
||||||
|
{
|
||||||
|
// no filtering
|
||||||
|
includeFiles = true;
|
||||||
|
includeFolders = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// some filtering
|
||||||
|
includeFiles = (includeFiles != null ? includeFiles : false);
|
||||||
|
includeFolders = (includeFolders != null ? includeFolders : false);
|
||||||
|
}
|
||||||
|
|
||||||
pagingResults = fileFolderService.list(parentNodeRef, includeFiles, includeFolders, ignoreQNames, sortProps, pagingRequest);
|
pagingResults = fileFolderService.list(parentNodeRef, includeFiles, includeFolders, ignoreQNames, sortProps, pagingRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,27 +1200,75 @@ public class NodesImpl implements Nodes
|
|||||||
return new Pair<>(filterNodeTypeQName, filterIncludeSubTypes);
|
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 nodeTypeQName, boolean includeSubTypes, Set<QName> ignoreQNameTypes, Boolean includeFiles, Boolean includeFolders)
|
||||||
{
|
{
|
||||||
Set<QName> searchTypeQNames = new HashSet<QName>(100);
|
Set<QName> searchTypeQNames = new HashSet<QName>(100);
|
||||||
Set<QName> ignoreAspectQNames = null;
|
Set<QName> ignoreAspectQNames = null;
|
||||||
|
|
||||||
// Build a list of (sub-)types
|
// Build a list of (sub-)types
|
||||||
if (filterIncludeSubTypes)
|
if (includeSubTypes)
|
||||||
{
|
{
|
||||||
Collection<QName> qnames = dictionaryService.getSubTypes(filterNodeTypeQName, true);
|
Collection<QName> qnames = dictionaryService.getSubTypes(nodeTypeQName, true);
|
||||||
searchTypeQNames.addAll(qnames);
|
searchTypeQNames.addAll(qnames);
|
||||||
}
|
}
|
||||||
searchTypeQNames.add(filterNodeTypeQName);
|
searchTypeQNames.add(nodeTypeQName);
|
||||||
|
|
||||||
// Remove 'system' folders
|
// Remove 'system' folders
|
||||||
if (filterIncludeSubTypes)
|
if (includeSubTypes)
|
||||||
{
|
{
|
||||||
Collection<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true);
|
Collection<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_SYSTEM_FOLDER, true);
|
||||||
searchTypeQNames.removeAll(qnames);
|
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<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true);
|
||||||
|
searchTypeQNames.addAll(qnames);
|
||||||
|
}
|
||||||
|
searchTypeQNames.add(ContentModel.TYPE_CONTENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Collection<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true);
|
||||||
|
searchTypeQNames.removeAll(qnames);
|
||||||
|
searchTypeQNames.remove(ContentModel.TYPE_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeFolders != null)
|
||||||
|
{
|
||||||
|
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<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_FOLDER, true);
|
||||||
|
searchTypeQNames.addAll(qnames);
|
||||||
|
}
|
||||||
|
searchTypeQNames.add(ContentModel.TYPE_FOLDER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Collection<QName> qnames = dictionaryService.getSubTypes(ContentModel.TYPE_FOLDER, true);
|
||||||
|
searchTypeQNames.removeAll(qnames);
|
||||||
|
searchTypeQNames.remove(ContentModel.TYPE_FOLDER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ignoreQNameTypes != null)
|
if (ignoreQNameTypes != null)
|
||||||
{
|
{
|
||||||
Set<QName> ignoreQNamesNotSearchTypes = new HashSet<QName>(ignoreQNameTypes);
|
Set<QName> ignoreQNamesNotSearchTypes = new HashSet<QName>(ignoreQNameTypes);
|
||||||
|
@@ -1646,7 +1646,147 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
post(getNodeChildrenUrl(myNodeId), user1, RestApiUtil.toJsonAsStringNonNull(n), 409);
|
post(getNodeChildrenUrl(myNodeId), user1, RestApiUtil.toJsonAsStringNonNull(n), 409);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO test custom type with properties (sub-type of cm:cmobject)
|
// TODO test custom types with properties (sub-type of cm:cmobject)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListChildrenIsFileIsFolderFilter() throws Exception
|
||||||
|
{
|
||||||
|
String myNodeId = getMyNodeId(user1);
|
||||||
|
String myChildrenUrl = getNodeChildrenUrl(myNodeId);
|
||||||
|
|
||||||
|
long timeNow = System.currentTimeMillis();
|
||||||
|
|
||||||
|
int folderCnt = 2;
|
||||||
|
int fileCnt = 3;
|
||||||
|
int objCnt = 4;
|
||||||
|
|
||||||
|
// create some folders
|
||||||
|
List<String> folderIds = new ArrayList<>(folderCnt);
|
||||||
|
|
||||||
|
for (int i = 1; i <= folderCnt; i++)
|
||||||
|
{
|
||||||
|
folderIds.add(createFolder(user1, myNodeId, "folder "+i+" "+timeNow).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// create some files
|
||||||
|
List<String> fileIds = new ArrayList<>(fileCnt);
|
||||||
|
for (int i = 1; i <= fileCnt; i++)
|
||||||
|
{
|
||||||
|
fileIds.add(createTextFile(user1, myNodeId, "file "+i+" "+timeNow, "The quick brown fox jumps over the lazy dog "+i).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// create some nodes (cmobject)
|
||||||
|
List<String> objIds = new ArrayList<>(objCnt);
|
||||||
|
for (int i = 1; i <= objCnt; i++)
|
||||||
|
{
|
||||||
|
Node obj = new Node();
|
||||||
|
obj.setName("obj "+i+" "+timeNow);
|
||||||
|
obj.setNodeType("cm:cmobject");
|
||||||
|
|
||||||
|
// create node/object
|
||||||
|
HttpResponse response = post(myChildrenUrl, user1, toJsonAsStringNonNull(obj), 201);
|
||||||
|
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
|
||||||
|
objIds.add(nodeResp.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> allIds = new ArrayList<>(objCnt+folderCnt+fileCnt);
|
||||||
|
allIds.addAll(folderIds);
|
||||||
|
allIds.addAll(fileIds);
|
||||||
|
allIds.addAll(objIds);
|
||||||
|
|
||||||
|
List<String> folderAndFileIds = new ArrayList<>(folderCnt+fileCnt);
|
||||||
|
folderAndFileIds.addAll(folderIds);
|
||||||
|
folderAndFileIds.addAll(fileIds);
|
||||||
|
|
||||||
|
Paging paging = getPaging(0, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
// filtering, via where clause - folders
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("where", "(nodeType='cm:folder')");
|
||||||
|
|
||||||
|
HttpResponse response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
List<Node> nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, folderIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFolder=true)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, folderIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFolder=true AND isFile=false)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, folderIds);
|
||||||
|
|
||||||
|
// filtering, via where clause - files
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(nodeType='cm:content')");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, fileIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFile=true)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, fileIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFile=true AND isFolder=false)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, fileIds);
|
||||||
|
|
||||||
|
// filtering, via where clause - files and folders
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFile=true AND isFolder=true)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, folderAndFileIds);
|
||||||
|
|
||||||
|
// filtering, via where clause - non-folders / non-files
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(nodeType='cm:cmobject')");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, objIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(nodeType='cm:cmobject INCLUDESUBTYPES')");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, allIds);
|
||||||
|
|
||||||
|
params = new HashMap<>();
|
||||||
|
params.put("where", "(isFile=false AND isFolder=false)");
|
||||||
|
|
||||||
|
response = getAll(myChildrenUrl, user1, paging, params, 200);
|
||||||
|
nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||||
|
checkNodeIds(nodes, objIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNodeIds(List<Node> nodes, List<String> nodeIds)
|
||||||
|
{
|
||||||
|
assertEquals(nodeIds.size(), nodes.size());
|
||||||
|
for (Node node : nodes)
|
||||||
|
{
|
||||||
|
assertTrue(nodeIds.contains(node.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// note: app:folderlink & app:filelink both extend cm:link (which in turn extends cm:cmobject)
|
// note: app:folderlink & app:filelink both extend cm:link (which in turn extends cm:cmobject)
|
||||||
// (see applicationModel.xml / contentModel.xml)
|
// (see applicationModel.xml / contentModel.xml)
|
||||||
|
Reference in New Issue
Block a user