From eb8f85a4fde3e34cb208af85efc3cbab2d2e2c14 Mon Sep 17 00:00:00 2001 From: Jan Vonka Date: Mon, 21 Nov 2011 16:56:26 +0000 Subject: [PATCH] Merged DEV to HEAD: (ALF-11606) 31637: THOR-358: update CMIS getChildren (V3.x => CMISServicesImpl) 31700: THOR-358: update CMIS getChildren (V3.x => CMISServicesImpl) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32155 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../java/org/alfresco/cmis/CMISServices.java | 32 +++- .../cmis/mapping/CMISServicesImpl.java | 142 +++++++++++++++++- 2 files changed, 161 insertions(+), 13 deletions(-) diff --git a/source/java/org/alfresco/cmis/CMISServices.java b/source/java/org/alfresco/cmis/CMISServices.java index 91a16a65f5..83a8c3947c 100644 --- a/source/java/org/alfresco/cmis/CMISServices.java +++ b/source/java/org/alfresco/cmis/CMISServices.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2011 Alfresco Software Limited. * * This file is part of Alfresco * @@ -20,11 +20,14 @@ package org.alfresco.cmis; import java.io.InputStream; import java.io.Serializable; +import java.math.BigInteger; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import org.alfresco.query.PagingResults; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; @@ -103,19 +106,38 @@ public interface CMISServices throws CMISFilterNotValidException; /** - * Query for node children + * Get node children * * @param parent - * node to query children for + * parent node * @param typesFilter * types filter * @param orderBy - * comma-separated list of query names and the ascending modifier "ASC" or the descending modifier "DESC" - * for each query name + * comma-separated list of sort names and the ascending modifier "ASC" or the descending modifier "DESC" + * for each sort name * @return children of node */ public NodeRef[] getChildren(NodeRef parent, CMISTypesFilterEnum typesFilter, String orderBy) throws CMISInvalidArgumentException; + + /** + * Get node children + * + * @param parent + * parent node + * @param typesFilter + * types filter + * @param maxItems + * number of items (in page) + * @param skipCount + * number of items to skip (page starts at next item) + * @param orderBy + * comma-separated list of sort names and the ascending modifier "ASC" or the descending modifier "DESC" + * for each sort name + * @return children of node + */ + public PagingResults getChildren(NodeRef parent, CMISTypesFilterEnum typesFilter, BigInteger maxItems, BigInteger skipCount, String orderBy) + throws CMISInvalidArgumentException; /** * Query for checked out items diff --git a/source/java/org/alfresco/cmis/mapping/CMISServicesImpl.java b/source/java/org/alfresco/cmis/mapping/CMISServicesImpl.java index baba3ac0a8..d9fd68ea75 100644 --- a/source/java/org/alfresco/cmis/mapping/CMISServicesImpl.java +++ b/source/java/org/alfresco/cmis/mapping/CMISServicesImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2011 Alfresco Software Limited. * * This file is part of Alfresco * @@ -20,6 +20,7 @@ package org.alfresco.cmis.mapping; import java.io.InputStream; import java.io.Serializable; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -62,7 +63,11 @@ import org.alfresco.cmis.PropertyFilter; import org.alfresco.cmis.dictionary.CMISFolderTypeDefinition; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.query.EmptyPagingResults; +import org.alfresco.query.PagingRequest; +import org.alfresco.query.PagingResults; import org.alfresco.repo.model.Repository; +import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery; import org.alfresco.repo.search.QueryParameterDefImpl; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; @@ -79,6 +84,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.InvalidAspectException; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -101,6 +107,9 @@ import org.alfresco.service.cmr.version.VersionType; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.util.Pair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -117,10 +126,12 @@ import org.springframework.extensions.surf.util.AbstractLifecycleBean; */ public class CMISServicesImpl implements CMISServices, ApplicationContextAware, ApplicationListener, TenantDeployer { + private static Log logger = LogFactory.getLog(CMISServicesImpl.class); + /** Query Parameters */ private static final QName PARAM_PARENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "parent"); private static final QName PARAM_USERNAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "username"); - + private static final String LUCENE_QUERY_CHECKEDOUT = "+@cm\\:workingCopyOwner:${cm:username}"; @@ -161,7 +172,7 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware, // data types for query private DataTypeDefinition nodeRefDataType; private DataTypeDefinition textDataType; - + /** * Sets the supported version of the CMIS specification @@ -525,11 +536,9 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware, } /* - * (non-Javadoc) - * @see org.alfresco.cmis.CMISServices#getChildren(org.alfresco.service.cmr.repository.NodeRef, - * org.alfresco.cmis.CMISTypesFilterEnum, java.lang.String) + * Lucene based getChildren - deactivated */ - public NodeRef[] getChildren(NodeRef parent, CMISTypesFilterEnum typesFilter, String orderBy) + public NodeRef[] XgetChildren(NodeRef parent, CMISTypesFilterEnum typesFilter, String orderBy) throws CMISInvalidArgumentException { if (typesFilter == CMISTypesFilterEnum.POLICIES) @@ -577,7 +586,124 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware, if (resultSet != null) resultSet.close(); } } - + + /* + * (non-Javadoc) + * @see org.alfresco.cmis.CMISServices#getChildren(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.cmis.CMISTypesFilterEnum, java.lang.String) + */ + public NodeRef[] getChildren(NodeRef folderNodeRef, CMISTypesFilterEnum typesFilter, String orderBy) + throws CMISInvalidArgumentException + { + PagingResults pageOfNodeInfos = getChildren(folderNodeRef, typesFilter, BigInteger.valueOf(Integer.MAX_VALUE), BigInteger.valueOf(0), orderBy); + + int pageCnt = pageOfNodeInfos.getPage().size(); + NodeRef[] result = new NodeRef[pageCnt]; + + int idx = 0; + for (FileInfo child : pageOfNodeInfos.getPage()) + { + result[idx] = child.getNodeRef(); + idx++; + } + + return result; + } + + public PagingResults getChildren(NodeRef folderNodeRef, CMISTypesFilterEnum typesFilter, BigInteger maxItems, BigInteger skipCount, String orderBy) + throws CMISInvalidArgumentException + { + if (typesFilter == CMISTypesFilterEnum.POLICIES) + { + return new EmptyPagingResults(); + } + + long start = System.currentTimeMillis(); + + boolean listFiles = (typesFilter != CMISTypesFilterEnum.FOLDERS); + boolean listFolders = (typesFilter != CMISTypesFilterEnum.DOCUMENTS); + + // convert BigIntegers to int + int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue()); + int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue()); + + // convert orderBy to sortProps + List> sortProps = null; + if (orderBy != null) + { + sortProps = new ArrayList>(1); + + String[] parts = orderBy.split(","); + int len = parts.length; + final int origLen = len; + + if (origLen > 0) + { + int maxSortProps = GetChildrenCannedQuery.MAX_FILTER_SORT_PROPS; + if (len > maxSortProps) + { + if (logger.isDebugEnabled()) + { + logger.debug("Too many sort properties in 'orderBy' - ignore those above max (max=" + + maxSortProps + ",actual=" + len + ")"); + } + len = maxSortProps; + } + for (int i = 0; i < len; i++) + { + String[] sort = parts[i].split(" +"); + + if (sort.length > 0) + { + CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(sort[0]); + if (propDef != null) + { + QName sortProp = propDef.getPropertyAccessor().getMappedProperty(); + if (sortProp != null) + { + boolean sortAsc = (sort.length == 1) || sort[1].equalsIgnoreCase("asc"); + sortProps.add(new Pair(sortProp, sortAsc)); + } else + { + if (logger.isDebugEnabled()) + { + logger.debug("Ignore sort property '" + sort[0] + " - mapping not found"); + } + } + } else + { + if (logger.isDebugEnabled()) + { + logger.debug("Ignore sort property '" + sort[0] + " - query name not found"); + } + } + } + } + } + + if (sortProps.size() < origLen) + { + logger.warn("Sort properties trimmed - either too many and/or not found: \n" + " orig: " + orderBy + + "\n" + " final: " + sortProps); + } + } + + PagingRequest pageRequest = new PagingRequest(skip, max, null); + pageRequest.setRequestTotalCountMax(skip + 10000); // TODO make this + // optional/configurable + // - affects whether + // numItems may be + // returned + + PagingResults result = fileFolderService.list(folderNodeRef, listFiles, listFolders, null, sortProps, pageRequest); + + if (logger.isDebugEnabled()) + { + logger.debug("getChildren: " + result.getPage().size() + " in " + (System.currentTimeMillis() - start) + " msecs"); + } + + return result; + } + /* * (non-Javadoc) * @see org.alfresco.cmis.CMISServices#getCheckedOut(java.lang.String, org.alfresco.service.cmr.repository.NodeRef,