mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	125606 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2)
      125515 slanglois: MNT-16155 Update source headers - add new Copyrights for Java and JSP source files + automatic check in the build
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125788 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
	
		
			
				
	
	
		
			388 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			388 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * #%L
 | |
|  * Alfresco Repository
 | |
|  * %%
 | |
|  * 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 <http://www.gnu.org/licenses/>.
 | |
|  * #L%
 | |
|  */
 | |
| package org.alfresco.repo.security.person;
 | |
| 
 | |
| import java.util.ArrayList;
 | |
| import java.util.HashMap;
 | |
| import java.util.List;
 | |
| import java.util.Map;
 | |
| import java.util.Set;
 | |
| 
 | |
| import org.alfresco.error.AlfrescoRuntimeException;
 | |
| import org.alfresco.model.ContentModel;
 | |
| import org.alfresco.query.AbstractCannedQuery;
 | |
| import org.alfresco.query.CannedQueryParameters;
 | |
| import org.alfresco.query.CannedQuerySortDetails;
 | |
| import org.alfresco.query.CannedQuerySortDetails.SortOrder;
 | |
| import org.alfresco.repo.domain.node.NodeDAO;
 | |
| import org.alfresco.repo.domain.qname.QNameDAO;
 | |
| import org.alfresco.repo.domain.query.CannedQueryDAO;
 | |
| import org.alfresco.repo.tenant.TenantService;
 | |
| import org.alfresco.service.cmr.repository.InvalidNodeRefException;
 | |
| import org.alfresco.service.cmr.repository.NodeRef;
 | |
| import org.alfresco.service.cmr.repository.NodeService;
 | |
| import org.alfresco.service.cmr.repository.StoreRef;
 | |
| import org.alfresco.service.cmr.security.AuthorityService;
 | |
| import org.alfresco.service.namespace.QName;
 | |
| import org.alfresco.util.Pair;
 | |
| import org.alfresco.util.ParameterCheck;
 | |
| import org.apache.commons.logging.Log;
 | |
| import org.apache.commons.logging.LogFactory;
 | |
| 
 | |
| /**
 | |
|  * GetPeople canned query
 | |
|  * 
 | |
|  * To get paged list of children of a parent node filtered by child type.
 | |
|  * Also optionally filtered and/or sorted by one or more properties (up to three).
 | |
|  *
 | |
|  * @author janv
 | |
|  * @since 4.1.2
 | |
|  */
 | |
| public class GetPeopleCannedQuery extends AbstractCannedQuery<NodeRef>
 | |
| {
 | |
|     private Log logger = LogFactory.getLog(getClass());
 | |
|     
 | |
|     private static final String QUERY_NAMESPACE = "alfresco.query.people";
 | |
|     private static final String QUERY_SELECT_GET_PEOPLE = "select_GetPeopleCannedQuery";
 | |
|     
 | |
|     public static final int MAX_FILTER_SORT_PROPS = 3;
 | |
|     
 | |
|     private static final int MAX_EXPECTED_ADMINS = 5; // TODO refine non-admin paging
 | |
|     
 | |
|     private NodeDAO nodeDAO;
 | |
|     private QNameDAO qnameDAO;
 | |
|     private CannedQueryDAO cannedQueryDAO;
 | |
|     private TenantService tenantService;
 | |
|     private NodeService nodeService;
 | |
|     private AuthorityService authorityService;
 | |
|     
 | |
|     public GetPeopleCannedQuery(
 | |
|             NodeDAO nodeDAO,
 | |
|             QNameDAO qnameDAO,
 | |
|             CannedQueryDAO cannedQueryDAO,
 | |
|             TenantService tenantService,
 | |
|             NodeService nodeService,
 | |
|             AuthorityService authorityService,
 | |
|             CannedQueryParameters params)
 | |
|     {
 | |
|         super(params);
 | |
|         
 | |
|         this.nodeDAO = nodeDAO;
 | |
|         this.qnameDAO = qnameDAO;
 | |
|         this.cannedQueryDAO = cannedQueryDAO;
 | |
|         this.tenantService = tenantService;
 | |
|         this.nodeService = nodeService;
 | |
|         this.authorityService = authorityService;
 | |
|         
 | |
|     }
 | |
|     
 | |
|     @Override
 | |
|     protected List<NodeRef> queryAndFilter(CannedQueryParameters parameters)
 | |
|     {
 | |
|         Long start = (logger.isDebugEnabled() ? System.currentTimeMillis() : null);
 | |
|         
 | |
|         // Get parameters
 | |
|         GetPeopleCannedQueryParams paramBean = (GetPeopleCannedQueryParams)parameters.getParameterBean();
 | |
|         
 | |
|         // Get parent node
 | |
|         NodeRef parentRef = paramBean.getParentRef();
 | |
|         ParameterCheck.mandatory("nodeRef", parentRef);
 | |
|         Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(parentRef);
 | |
|         if (nodePair == null)
 | |
|         {
 | |
|             throw new InvalidNodeRefException("Parent node does not exist: " + parentRef, parentRef);
 | |
|         }
 | |
|         Long parentNodeId = nodePair.getFirst();
 | |
|         
 | |
|         // Set query params - note: currently using SortableChildEntity to hold (supplemental-) query params
 | |
|         FilterSortPersonEntity params = new FilterSortPersonEntity();
 | |
|         
 | |
|         // Set parent node id
 | |
|         params.setParentNodeId(parentNodeId);
 | |
|         
 | |
|         // Get filter details
 | |
|         final List<QName> filterProps = paramBean.getFilterProps();
 | |
|         
 | |
|         // Get sort details
 | |
|         CannedQuerySortDetails sortDetails = parameters.getSortDetails();
 | |
|         @SuppressWarnings({ "unchecked", "rawtypes" })
 | |
|         final List<Pair<QName, SortOrder>> sortPairs = (List)sortDetails.getSortPairs();
 | |
|         
 | |
|         String pattern = paramBean.getPattern();
 | |
|         if ((pattern == null) || (pattern.equals("")))
 | |
|         {
 | |
|             // note: although no pattern means no filtering required, set to match all in case sort required
 | |
|             pattern = "%";
 | |
|         }
 | |
|         else if ((! pattern.endsWith("%")) && (! pattern.endsWith("*")))
 | |
|         {
 | |
|             // implicit startsWith match
 | |
|             pattern = pattern + "%";
 | |
|         }
 | |
|         
 | |
|         // Set filter pattern (should not be null)
 | |
|         params.setPattern(pattern);
 | |
|         
 | |
|         if (paramBean.getExclusiveAspects() != null)
 | |
|         {
 | |
|             Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(paramBean.getExclusiveAspects(), false);
 | |
|             params.setExcludeAspectIds(new ArrayList<Long>(qnamesIds));
 | |
|         }
 | |
|         
 | |
|         if (paramBean.getInclusiveAspects() != null)
 | |
|         {
 | |
|             Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(paramBean.getInclusiveAspects(), false);
 | |
|             params.setIncludeAspectIds(new ArrayList<Long>(qnamesIds));
 | |
|         }
 | |
|         
 | |
|         // Set sort / filter params
 | |
|         // Note - need to keep the sort properties in their requested order
 | |
|         List<QName> sortFilterProps = new ArrayList<QName>(MAX_FILTER_SORT_PROPS);
 | |
|         Map<QName, Boolean> sortAsc = new HashMap<QName, Boolean>(MAX_FILTER_SORT_PROPS);
 | |
|         
 | |
|         // add sort props first
 | |
|         for (Pair<QName, SortOrder> sort : sortPairs)
 | |
|         {
 | |
|             QName sortQName = sort.getFirst();
 | |
|             if ((filterProps.size() > 0) && (! filterProps.contains(sortQName)))
 | |
|             {
 | |
|                 throw new AlfrescoRuntimeException("GetPeople: cannot sort by a non-filter property: "+sortQName+" (filterStringProps="+filterProps+")");
 | |
|             }
 | |
|             
 | |
|             if (! sortFilterProps.contains(sortQName))
 | |
|             {
 | |
|                sortFilterProps.add(sortQName);
 | |
|                sortAsc.put(sortQName, sort.getSecond().equals(SortOrder.ASCENDING));
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // add any additional filter props (not part of sort)
 | |
|         for (QName filterQName : filterProps)
 | |
|         {
 | |
|             if (! sortFilterProps.contains(filterQName))
 | |
|             {
 | |
|                sortFilterProps.add(filterQName);
 | |
|                sortAsc.put(filterQName, null);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         int filterSortPropCnt = sortFilterProps.size();
 | |
|         
 | |
|         if (filterSortPropCnt > MAX_FILTER_SORT_PROPS)
 | |
|         {
 | |
|             throw new AlfrescoRuntimeException("GetPeople: exceeded maximum number filter/sort properties: (max="+MAX_FILTER_SORT_PROPS+", actual="+filterSortPropCnt);
 | |
|         }
 | |
|         
 | |
|         filterSortPropCnt = setFilterSortParams(sortFilterProps, sortAsc, params);
 | |
|         
 | |
|         // filtered and/or sorted - note: permissions not applicable for getPeople
 | |
|         List<NodeRef> result = new ArrayList<NodeRef>(100);
 | |
|         final PersonQueryCallback c = new DefaultPersonQueryCallback(result, paramBean.getIncludeAdministrators());
 | |
|         PersonResultHandler resultHandler = new PersonResultHandler(c);
 | |
|         
 | |
|         int offset = parameters.getPageDetails().getSkipResults();
 | |
|         int totalResultCountMax = parameters.getTotalResultCountMax();
 | |
|         
 | |
|         int origOffset = offset;
 | |
|         int origLimit = totalResultCountMax > 0 ? totalResultCountMax : parameters.getPageDetails().getPageSize();
 | |
|         
 | |
|         long newLimit = (long)origLimit;
 | |
|         
 | |
|         // to enable hasMore flag
 | |
|         newLimit++;
 | |
|         
 | |
|         boolean excludeAdmins = (! paramBean.getIncludeAdministrators());
 | |
|         if (excludeAdmins)
 | |
|         {
 | |
|             // TODO refine - non-admin paging
 | |
|             offset = 0;
 | |
|             newLimit = offset + (long)newLimit + MAX_EXPECTED_ADMINS;
 | |
|         }
 | |
|         
 | |
|         if (newLimit > Integer.MAX_VALUE)
 | |
|         {
 | |
|             newLimit = Integer.MAX_VALUE;
 | |
|         }
 | |
|         
 | |
|         cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_PEOPLE, params, offset, (int)newLimit, resultHandler);
 | |
|         resultHandler.done();
 | |
|         
 | |
|         if (start != null)
 | |
|         {
 | |
|             logger.debug("Base query: "+result.size()+" in "+(System.currentTimeMillis()-start)+" msecs");
 | |
|         }
 | |
|         
 | |
|         if (excludeAdmins)
 | |
|         {
 | |
|             // TODO refine - non-admin paging
 | |
|             long max = origOffset + (long)origLimit;
 | |
|             if (max > result.size())
 | |
|             {
 | |
|                 max = result.size();
 | |
|             }
 | |
|             result = result.subList(origOffset, (int)max);
 | |
|         }
 | |
|         
 | |
|         return result;
 | |
|     }
 | |
|     
 | |
|     // Set filter/sort props (between 0 and 3)
 | |
|     private int setFilterSortParams(List<QName> filterSortProps, Map<QName, Boolean> sortAsc, FilterSortPersonEntity params)
 | |
|     {
 | |
|         int cnt = 0;
 | |
|         int propCnt = 0;
 | |
|         
 | |
|         for (QName filterSortProp : filterSortProps)
 | |
|         {
 | |
|             Long sortQNameId = getQNameId(filterSortProp);
 | |
|             Boolean sortOrder = sortAsc.get(filterSortProp); // true = ascending, false = descending, null = unsorted
 | |
|             
 | |
|             if (sortQNameId != null)
 | |
|             {
 | |
|                 if (propCnt == 0)
 | |
|                 {
 | |
|                     params.setProp1qnameId(sortQNameId);
 | |
|                     params.setSort1asc(sortOrder);
 | |
|                 }
 | |
|                 else if (propCnt == 1)
 | |
|                 {
 | |
|                     params.setProp2qnameId(sortQNameId);
 | |
|                     params.setSort2asc(sortOrder);
 | |
|                 }
 | |
|                 else if (propCnt == 2)
 | |
|                 {
 | |
|                     params.setProp3qnameId(sortQNameId);
 | |
|                     params.setSort3asc(sortOrder);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     // belts and braces
 | |
|                     throw new AlfrescoRuntimeException("GetPeople: unexpected - cannot set sort parameter: "+cnt);
 | |
|                 }
 | |
|                 
 | |
|                 propCnt++;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 logger.warn("Skipping filter/sort param - cannot find: "+filterSortProp);
 | |
|                 break;
 | |
|             }
 | |
|             
 | |
|             cnt++;
 | |
|         }
 | |
|         
 | |
|         return cnt;
 | |
|     }
 | |
|     
 | |
|     private Long getQNameId(QName sortPropQName)
 | |
|     {
 | |
|         Pair<Long, QName> qnamePair = qnameDAO.getQName(sortPropQName);
 | |
|         return (qnamePair == null ? null : qnamePair.getFirst());
 | |
|     }
 | |
|     
 | |
|     @Override
 | |
|     protected boolean isApplyPostQuerySorting()
 | |
|     {
 | |
|         // note: sorted as part of the query impl
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     @Override
 | |
|     protected boolean isApplyPostQueryPermissions()
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     @Override
 | |
|     protected boolean isApplyPostQueryPaging()
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     @Override
 | |
|     protected Pair<Integer, Integer> getTotalResultCount(List<NodeRef> results)
 | |
|     {
 | |
|         int offset = super.getParameters().getPageDetails().getSkipResults();
 | |
|         Integer size = offset + results.size();
 | |
|         return new Pair<Integer, Integer>(size, size);
 | |
|     }
 | |
|     
 | |
|     protected interface PersonQueryCallback
 | |
|     {
 | |
|         boolean handle(NodeRef personRef);
 | |
|     }
 | |
|     
 | |
|     protected class DefaultPersonQueryCallback implements PersonQueryCallback
 | |
|     {
 | |
|         private List<NodeRef> children;
 | |
|         private boolean includeAdministrators;
 | |
|         
 | |
|         public DefaultPersonQueryCallback(final List<NodeRef> children, boolean includeAdministrators)
 | |
|         {
 | |
|             this.children = children;
 | |
|             this.includeAdministrators = includeAdministrators;
 | |
|         }
 | |
|         
 | |
|         @Override
 | |
|         public boolean handle(NodeRef personRef)
 | |
|         {
 | |
|             // TODO refine - return username as part of query
 | |
|             if (includeAdministrators == false)
 | |
|             {
 | |
|                 String userName = (String) nodeService.getProperty(personRef, ContentModel.PROP_USERNAME);
 | |
|                 if (authorityService.isAdminAuthority(userName))
 | |
|                 {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             children.add(tenantService.getBaseName(personRef));
 | |
|             
 | |
|             // More results
 | |
|             return true;
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     protected class PersonResultHandler implements CannedQueryDAO.ResultHandler<String>
 | |
|     {
 | |
|         private final PersonQueryCallback resultsCallback;
 | |
|         
 | |
|         private PersonResultHandler(PersonQueryCallback resultsCallback)
 | |
|         {
 | |
|             this.resultsCallback = resultsCallback;
 | |
|         }
 | |
|         
 | |
|         public boolean handleResult(String uuid)
 | |
|         {
 | |
|             // Call back
 | |
|             return resultsCallback.handle(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, uuid));
 | |
|         }
 | |
|         
 | |
|         public void done()
 | |
|         {
 | |
|         }
 | |
|     }
 | |
| } |