mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	40292: FRENCH: Translation update based on EN 40202
   40293: ITALIAN: Translation update based on EN 40202
   40295: Merged V3.4-BUG-FIX to V4.1-BUG-FIX
      40294: ALF-9540: Fix potential NPE
   40296: Merged V4.1 to V4.1-BUG-FIX
      40169: CloudSync: fix ALF-15380 - source file is deleted (or unsync with delete) but an unpulled target update causes target to remain synced (and/or not deleted)
      - fixed as per PM expected behaviour + unit tests
      40176: CloudSync: add simple rename test (file + folder sync)
      40182: ALF-15424: Merged PATCHES/V4.0.2 to V4.1
         40181: Merged PATCHES/V4.0.1 to PATCHES/V4.0.2    
            40180: ALF15009: QNames that do not exist yet cause a "java.sql.SQLException: Invalid column type"       
               - getQNameId will now return a -1 instead of null. This will allow the SQL to execute and return no rows.
      40276: ALF-15472: Updates help links to 4.1 & also fixes ALF-11929 - the video tutorial link now points to a video tutorial.
      40282: CloudSync: ALF-15468 - Can't create cloud sync connection from Enterprise 4.1 to Alfresco "in the cloud" !
      - fix the RemoteAlfrescoTicketService (to set the remote system request headers)
      40285: ALF-15474: alfresco-opencmis-extension jar is missing from the share war (error in build.properties)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@40298 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
	
		
			
				
	
	
		
			299 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			299 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2005-2011 Alfresco Software Limited.
 | |
|  *
 | |
|  * This file is part of Alfresco
 | |
|  *
 | |
|  * 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/>.
 | |
|  */
 | |
| package org.alfresco.repo.query;
 | |
| 
 | |
| import java.util.ArrayList;
 | |
| import java.util.Comparator;
 | |
| import java.util.List;
 | |
| 
 | |
| import org.alfresco.model.ContentModel;
 | |
| import org.alfresco.query.AbstractCannedQueryFactory;
 | |
| import org.alfresco.query.CannedQueryPageDetails;
 | |
| import org.alfresco.query.CannedQuerySortDetails;
 | |
| import org.alfresco.query.PagingRequest;
 | |
| 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.security.permissions.impl.acegi.MethodSecurityBean;
 | |
| import org.alfresco.repo.tenant.TenantService;
 | |
| import org.alfresco.service.cmr.repository.InvalidNodeRefException;
 | |
| import org.alfresco.service.cmr.repository.NodeRef;
 | |
| import org.alfresco.service.namespace.QName;
 | |
| import org.alfresco.util.Pair;
 | |
| import org.alfresco.util.PropertyCheck;
 | |
| import org.apache.commons.logging.Log;
 | |
| import org.apache.commons.logging.LogFactory;
 | |
| 
 | |
| /**
 | |
|  * An intermediate {@link AbstractCannedQueryFactory} layer, for various 
 | |
|  * implementations that need to know about QName IDs and similar
 | |
|  * 
 | |
|  * @author Nick Burch
 | |
|  * @since 4.0
 | |
|  */
 | |
| public abstract class AbstractQNameAwareCannedQueryFactory<R> extends AbstractCannedQueryFactory<R>
 | |
| {
 | |
|     private Log logger = LogFactory.getLog(getClass());
 | |
| 
 | |
|     protected MethodSecurityBean<R> methodSecurity;
 | |
|     protected NodeDAO nodeDAO;
 | |
|     protected QNameDAO qnameDAO;
 | |
|     protected TenantService tenantService;
 | |
|     protected CannedQueryDAO cannedQueryDAO;
 | |
| 
 | |
|     public void setNodeDAO(NodeDAO nodeDAO)
 | |
|     {
 | |
|        this.nodeDAO = nodeDAO;
 | |
|     }
 | |
| 
 | |
|     public void setQnameDAO(QNameDAO qnameDAO)
 | |
|     {
 | |
|        this.qnameDAO = qnameDAO;
 | |
|     }
 | |
| 
 | |
|     public void setCannedQueryDAO(CannedQueryDAO cannedQueryDAO)
 | |
|     {
 | |
|        this.cannedQueryDAO = cannedQueryDAO;
 | |
|     }
 | |
| 
 | |
|     public void setTenantService(TenantService tenantService)
 | |
|     {
 | |
|        this.tenantService = tenantService;
 | |
|     }
 | |
| 
 | |
|     public void setMethodSecurity(MethodSecurityBean<R> methodSecurity)
 | |
|     {
 | |
|        this.methodSecurity = methodSecurity;
 | |
|     }
 | |
|    
 | |
|     @Override
 | |
|     public void afterPropertiesSet() throws Exception
 | |
|     {
 | |
|         super.afterPropertiesSet();
 | |
|         
 | |
|         PropertyCheck.mandatory(this, "methodSecurity", methodSecurity);
 | |
|         PropertyCheck.mandatory(this, "nodeDAO", nodeDAO);
 | |
|         PropertyCheck.mandatory(this, "qnameDAO", qnameDAO);
 | |
|         PropertyCheck.mandatory(this, "cannedQueryDAO", cannedQueryDAO);
 | |
|         PropertyCheck.mandatory(this, "tenantService", tenantService);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Creates a Canned Query sort details, for the given list of properties
 | |
|      *  and if they should be Ascending or Descending
 | |
|      */
 | |
|     protected CannedQuerySortDetails createCQSortDetails(List<Pair<QName,Boolean>> sort)
 | |
|     {
 | |
|         List<Pair<? extends Object,SortOrder>> details = new ArrayList<Pair<? extends Object, SortOrder>>();
 | |
|         for(Pair<QName,Boolean> sortProp : sort)
 | |
|         {
 | |
|            details.add(new Pair<QName, SortOrder>(
 | |
|                  sortProp.getFirst(),
 | |
|                  (sortProp.getSecond() ? SortOrder.ASCENDING : SortOrder.DESCENDING)
 | |
|            ));
 | |
|         }
 | |
|         return new CannedQuerySortDetails(details);
 | |
|     }
 | |
|     
 | |
|     protected CannedQueryPageDetails createCQPageDetails(PagingRequest pagingReq)
 | |
|     {
 | |
|         int skipCount = pagingReq.getSkipCount();
 | |
|         if (skipCount == -1)
 | |
|         {
 | |
|             skipCount = CannedQueryPageDetails.DEFAULT_SKIP_RESULTS;
 | |
|         }
 | |
|         
 | |
|         int maxItems = pagingReq.getMaxItems();
 | |
|         if (maxItems == -1)
 | |
|         {
 | |
|             maxItems  = CannedQueryPageDetails.DEFAULT_PAGE_SIZE;
 | |
|         }
 | |
|         
 | |
|         // page details
 | |
|         CannedQueryPageDetails cqpd = new CannedQueryPageDetails(skipCount, maxItems);
 | |
|         return cqpd;
 | |
|     }
 | |
|     
 | |
|     protected Long getQNameId(QName qname)
 | |
|     {
 | |
|         Pair<Long, QName> qnamePair = qnameDAO.getQName(qname);
 | |
|         if (qnamePair == null)
 | |
|         {
 | |
|             if (logger.isTraceEnabled())
 | |
|             {
 | |
|                 logger.trace("QName does not exist: " + qname); // possible ... eg. blg:blogPost if a blog has never been posted externally
 | |
|             }
 | |
|             return -1L;
 | |
|         }
 | |
|         return qnamePair.getFirst();
 | |
|     }
 | |
|     
 | |
|     protected Long getNodeId(NodeRef nodeRef)
 | |
|     {
 | |
|         Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(tenantService.getName(nodeRef));
 | |
|         if (nodePair == null)
 | |
|         {
 | |
|             throw new InvalidNodeRefException("Node ref does not exist: " + nodeRef, nodeRef);
 | |
|         }
 | |
|         return nodePair.getFirst();
 | |
|     }
 | |
|     
 | |
|     public CannedQuerySortDetails createDateAscendingCQSortDetails()
 | |
|     {
 | |
|         List<Pair<? extends Object,SortOrder>> sort = new ArrayList<Pair<? extends Object, SortOrder>>();
 | |
|         sort.add(new Pair<QName, SortOrder>(ContentModel.PROP_CREATED, SortOrder.ASCENDING)); 
 | |
|         sort.add(new Pair<QName, SortOrder>(ContentModel.PROP_MODIFIED, SortOrder.ASCENDING));
 | |
|         
 | |
|         return new CannedQuerySortDetails(sort);
 | |
|     }
 | |
|     
 | |
|     public CannedQuerySortDetails createDateDescendingCQSortDetails()
 | |
|     {
 | |
|         List<Pair<? extends Object,SortOrder>> sort = new ArrayList<Pair<? extends Object, SortOrder>>();
 | |
|         sort.add(new Pair<QName, SortOrder>(ContentModel.PROP_CREATED, SortOrder.DESCENDING)); 
 | |
|         sort.add(new Pair<QName, SortOrder>(ContentModel.PROP_MODIFIED, SortOrder.DESCENDING));
 | |
|         
 | |
|         return new CannedQuerySortDetails(sort);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Utility class to sort Entities on the basis of a Comparable property.
 | |
|      * Comparisons of two null properties are considered 'equal' by this comparator.
 | |
|      * Comparisons involving one null and one non-null property will return the null property as
 | |
|      * being 'before' the non-null property.
 | |
|      * 
 | |
|      * Note that it is the responsibility of the calling code to ensure that the specified
 | |
|      * property values actually implement Comparable themselves.
 | |
|      */
 | |
|     public static abstract class PropertyBasedComparator<R> implements Comparator<R>
 | |
|     {
 | |
|         protected QName comparableProperty;
 | |
|         
 | |
|         public PropertyBasedComparator(QName comparableProperty)
 | |
|         {
 | |
|             this.comparableProperty = comparableProperty;
 | |
|         }
 | |
|         
 | |
|         @SuppressWarnings("unchecked")
 | |
|         protected abstract Comparable getProperty(R entity);
 | |
|         
 | |
|         @SuppressWarnings("unchecked")
 | |
|         @Override
 | |
|         public int compare(R r1, R r2)
 | |
|         {
 | |
|             Comparable prop1 = getProperty(r1);
 | |
|             Comparable prop2 = getProperty(r2);
 | |
|             
 | |
|             if (prop1 == null && prop2 == null)
 | |
|             {
 | |
|                 return 0;
 | |
|             }
 | |
|             else if (prop1 == null && prop2 != null)
 | |
|             {
 | |
|                 return -1;
 | |
|             }
 | |
|             else if (prop1 != null && prop2 == null)
 | |
|             {
 | |
|                 return 1;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return prop1.compareTo(prop2);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * An instance of a {@link PropertyBasedComparator} for a {@link NodeBackedEntity}
 | |
|      */
 | |
|     public static class NodeBackedEntityComparator extends PropertyBasedComparator<NodeBackedEntity>
 | |
|     {
 | |
|        public NodeBackedEntityComparator(QName comparableProperty)
 | |
|        {
 | |
|           super(comparableProperty);
 | |
|        }
 | |
|        
 | |
|        @SuppressWarnings("unchecked")
 | |
|        @Override
 | |
|        protected Comparable getProperty(NodeBackedEntity entity) {
 | |
|           if (comparableProperty.equals(ContentModel.PROP_CREATED))
 | |
|           {
 | |
|              return entity.getCreatedDate();
 | |
|           }
 | |
|           else if (comparableProperty.equals(ContentModel.PROP_MODIFIED))
 | |
|           {
 | |
|              return entity.getModifiedDate();
 | |
|           }
 | |
|           else if (comparableProperty.equals(ContentModel.PROP_CREATOR))
 | |
|           {
 | |
|              return entity.getCreator();
 | |
|           }
 | |
|           else if (comparableProperty.equals(ContentModel.PROP_MODIFIER))
 | |
|           {
 | |
|              return entity.getModifier();
 | |
|           }
 | |
|           else if (comparableProperty.equals(ContentModel.PROP_NAME))
 | |
|           {
 | |
|              return entity.getName();
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|              throw new IllegalArgumentException("Unsupported calendar sort property: "+comparableProperty);
 | |
|           }
 | |
|        }
 | |
|     }
 | |
|     
 | |
|     public static class NestedComparator<R> implements Comparator<R>
 | |
|     {
 | |
|         private List<Pair<Comparator<R>, SortOrder>> comparators;
 | |
|         
 | |
|         public NestedComparator(List<Pair<Comparator<R>, SortOrder>> comparators)
 | |
|         {
 | |
|            this.comparators = comparators;
 | |
|         }
 | |
| 
 | |
|         @Override
 | |
|         public int compare(R entry1, R entry2) {
 | |
|            for(Pair<Comparator<R>, SortOrder> pc : comparators)
 | |
|            {
 | |
|               int result = pc.getFirst().compare(entry1, entry2);
 | |
|               if(result != 0)
 | |
|               {
 | |
|                  // Sorts differ, return
 | |
|                  if(pc.getSecond() == SortOrder.ASCENDING)
 | |
|                  {
 | |
|                     return result;
 | |
|                  }
 | |
|                  else
 | |
|                  {
 | |
|                     return 0 - result;
 | |
|                  }
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                  // Sorts are the same, try the next along
 | |
|               }
 | |
|            }
 | |
|            // No difference on any
 | |
|            return 0;
 | |
|         }
 | |
|     }
 | |
| }
 |