mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	104860: Merged 5.0.N (5.0.2) to HEAD-BUG-FIX (5.1/Cloud)
      104812: Merged V4.2-BUG-FIX (4.2.5) to 5.0.N (5.0.2)
         104736: Merged DEV to V4.2-BUG-FIX (4.2.5).
            103329: MNT-13907: CMIS Bulk Update Properties will fail if number of worker threads is 1.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@104883 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
	
		
			
				
	
	
		
			3034 lines
		
	
	
		
			113 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			3034 lines
		
	
	
		
			113 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2005-2015 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.opencmis;
 | 
						|
 | 
						|
import java.io.BufferedInputStream;
 | 
						|
import java.io.File;
 | 
						|
import java.io.FileInputStream;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.Serializable;
 | 
						|
import java.math.BigInteger;
 | 
						|
import java.nio.charset.Charset;
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Arrays;
 | 
						|
import java.util.Collection;
 | 
						|
import java.util.Collections;
 | 
						|
import java.util.EnumSet;
 | 
						|
import java.util.HashMap;
 | 
						|
import java.util.HashSet;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
import java.util.Set;
 | 
						|
import java.util.concurrent.ConcurrentHashMap;
 | 
						|
 | 
						|
import javax.servlet.http.HttpServletRequest;
 | 
						|
 | 
						|
import net.sf.acegisecurity.Authentication;
 | 
						|
 | 
						|
import org.alfresco.model.ContentModel;
 | 
						|
import org.alfresco.opencmis.dictionary.CMISNodeInfo;
 | 
						|
import org.alfresco.opencmis.dictionary.CMISObjectVariant;
 | 
						|
import org.alfresco.opencmis.dictionary.FolderTypeDefintionWrapper;
 | 
						|
import org.alfresco.opencmis.dictionary.PropertyDefinitionWrapper;
 | 
						|
import org.alfresco.opencmis.dictionary.TypeDefinitionWrapper;
 | 
						|
import org.alfresco.query.PagingRequest;
 | 
						|
import org.alfresco.query.PagingResults;
 | 
						|
import org.alfresco.repo.batch.BatchProcessWorkProvider;
 | 
						|
import org.alfresco.repo.batch.BatchProcessor;
 | 
						|
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
 | 
						|
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
 | 
						|
import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
 | 
						|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
 | 
						|
import org.alfresco.repo.security.authentication.Authorization;
 | 
						|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
 | 
						|
import org.alfresco.repo.version.VersionModel;
 | 
						|
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;
 | 
						|
import org.alfresco.service.cmr.repository.ContentIOException;
 | 
						|
import org.alfresco.service.cmr.repository.ContentWriter;
 | 
						|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
 | 
						|
import org.alfresco.service.cmr.repository.NodeRef;
 | 
						|
import org.alfresco.service.cmr.search.ResultSet;
 | 
						|
import org.alfresco.service.cmr.search.SearchParameters;
 | 
						|
import org.alfresco.service.cmr.search.SearchService;
 | 
						|
import org.alfresco.service.cmr.version.Version;
 | 
						|
import org.alfresco.service.cmr.version.VersionHistory;
 | 
						|
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.alfresco.util.TempFileProvider;
 | 
						|
import org.apache.chemistry.opencmis.commons.PropertyIds;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.Acl;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ContentStream;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectList;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.Properties;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.RenditionData;
 | 
						|
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
 | 
						|
import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
 | 
						|
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
 | 
						|
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
 | 
						|
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
 | 
						|
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
 | 
						|
import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderContainerImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderDataImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectParentDataImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.impl.server.RenditionInfoImpl;
 | 
						|
import org.apache.chemistry.opencmis.commons.server.CallContext;
 | 
						|
import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
 | 
						|
import org.apache.chemistry.opencmis.commons.server.RenditionInfo;
 | 
						|
import org.apache.chemistry.opencmis.commons.spi.Holder;
 | 
						|
import org.apache.commons.logging.Log;
 | 
						|
import org.apache.commons.logging.LogFactory;
 | 
						|
 | 
						|
/**
 | 
						|
 * OpenCMIS service implementation
 | 
						|
 * 
 | 
						|
 * @author florian.mueller
 | 
						|
 * @author Derek Hulley
 | 
						|
 * @since 4.0
 | 
						|
 */
 | 
						|
public class AlfrescoCmisServiceImpl extends AbstractCmisService implements AlfrescoCmisService
 | 
						|
{
 | 
						|
    private static Log logger = LogFactory.getLog(AlfrescoCmisService.class);
 | 
						|
 | 
						|
    private static final String MIN_FILTER = "cmis:name,cmis:baseTypeId,cmis:objectTypeId,"
 | 
						|
            + "cmis:createdBy,cmis:creationDate,cmis:lastModifiedBy,cmis:lastModificationDate,"
 | 
						|
            + "cmis:contentStreamLength,cmis:contentStreamMimeType,cmis:contentStreamFileName,"
 | 
						|
            + "cmis:contentStreamId";
 | 
						|
 | 
						|
    private CMISConnector connector;
 | 
						|
    private Authentication authentication;
 | 
						|
    private Map<String, CMISNodeInfo> nodeInfoMap;
 | 
						|
    private Map<String, ObjectInfo> objectInfoMap;
 | 
						|
 | 
						|
    public AlfrescoCmisServiceImpl(CMISConnector connector)
 | 
						|
    {
 | 
						|
        this.connector = connector;
 | 
						|
        nodeInfoMap = new HashMap<String, CMISNodeInfo>();
 | 
						|
        objectInfoMap = new HashMap<String, ObjectInfo>();
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void open(CallContext context)
 | 
						|
    {
 | 
						|
        AlfrescoCmisServiceCall.set(context);
 | 
						|
    }
 | 
						|
    
 | 
						|
    protected CallContext getContext()
 | 
						|
    {
 | 
						|
    	CallContext context = AlfrescoCmisServiceCall.get();
 | 
						|
    	return context;
 | 
						|
    }
 | 
						|
    
 | 
						|
    @Override
 | 
						|
    public void close()
 | 
						|
    {
 | 
						|
        AlfrescoCmisServiceCall.clear();
 | 
						|
 | 
						|
        // Put these resources on the transactions
 | 
						|
        nodeInfoMap.clear();
 | 
						|
        objectInfoMap.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfoImpl createNodeInfo(NodeRef nodeRef)
 | 
						|
    {
 | 
						|
        return createNodeInfo(nodeRef, null);
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfoImpl createNodeInfo(NodeRef nodeRef, VersionHistory versionHistory)
 | 
						|
    {
 | 
						|
        CMISNodeInfoImpl result = connector.createNodeInfo(nodeRef, versionHistory);
 | 
						|
        nodeInfoMap.put(result.getObjectId(), result);
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
    
 | 
						|
    protected CMISNodeInfo createNodeInfo(AssociationRef assocRef)
 | 
						|
    {
 | 
						|
        CMISNodeInfoImpl result = connector.createNodeInfo(assocRef);
 | 
						|
        nodeInfoMap.put(result.getObjectId(), result);
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfo getOrCreateNodeInfo(String objectId)
 | 
						|
    {
 | 
						|
        CMISNodeInfo result = nodeInfoMap.get(objectId);
 | 
						|
        if (result == null)
 | 
						|
        {
 | 
						|
            result = connector.createNodeInfo(objectId);
 | 
						|
            nodeInfoMap.put(objectId, result);
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfo getOrCreateNodeInfo(String objectId, String what)
 | 
						|
    {
 | 
						|
        CMISNodeInfo result = getOrCreateNodeInfo(objectId);
 | 
						|
        if (result instanceof CMISNodeInfoImpl)
 | 
						|
        {
 | 
						|
            ((CMISNodeInfoImpl) result).checkIfUseful(what);
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfo getOrCreateFolderInfo(String folderId, String what)
 | 
						|
    {
 | 
						|
        CMISNodeInfo result = getOrCreateNodeInfo(folderId);
 | 
						|
        if (result instanceof CMISNodeInfoImpl)
 | 
						|
        {
 | 
						|
            ((CMISNodeInfoImpl) result).checkIfFolder(what);
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    protected CMISNodeInfo addNodeInfo(CMISNodeInfo info)
 | 
						|
    {
 | 
						|
        nodeInfoMap.put(info.getObjectId(), info);
 | 
						|
 | 
						|
        return info;
 | 
						|
    }
 | 
						|
 | 
						|
    // --- repository service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<RepositoryInfo> getRepositoryInfos(ExtensionsData extension)
 | 
						|
    {
 | 
						|
    	CmisVersion cmisVersion = getContext().getCmisVersion();
 | 
						|
        return Collections.singletonList(connector.getRepositoryInfo(cmisVersion));
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
    	CmisVersion cmisVersion = getContext().getCmisVersion();
 | 
						|
        return connector.getRepositoryInfo(cmisVersion);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public TypeDefinitionList getTypeChildren(
 | 
						|
            String repositoryId, String typeId, Boolean includePropertyDefinitions,
 | 
						|
            BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // convert BigIntegers to int
 | 
						|
        int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
 | 
						|
        int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
 | 
						|
 | 
						|
        // set up the result
 | 
						|
        TypeDefinitionListImpl result = new TypeDefinitionListImpl();
 | 
						|
        List<TypeDefinition> list = new ArrayList<TypeDefinition>();
 | 
						|
        result.setList(list);
 | 
						|
 | 
						|
        // get the types from the dictionary
 | 
						|
        List<TypeDefinitionWrapper> childrenList;
 | 
						|
        if (typeId == null)
 | 
						|
        {
 | 
						|
            childrenList = connector.getOpenCMISDictionaryService().getBaseTypes(true);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
        	TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
 | 
						|
        	if (tdw == null)
 | 
						|
        	{
 | 
						|
        		throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
 | 
						|
        	}
 | 
						|
        	childrenList = connector.getOpenCMISDictionaryService().getChildren(typeId);
 | 
						|
//            childrenList = tdw.getChildren();
 | 
						|
        }
 | 
						|
 | 
						|
        // create result
 | 
						|
        if (max > 0)
 | 
						|
        {
 | 
						|
            int lastIndex = (max + skip > childrenList.size() ? childrenList.size() : max + skip) - 1;
 | 
						|
            for (int i = skip; i <= lastIndex; i++)
 | 
						|
            {
 | 
						|
                list.add(childrenList.get(i).getTypeDefinition(includePropertyDefinitions));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        result.setHasMoreItems(childrenList.size() - skip > result.getList().size());
 | 
						|
        result.setNumItems(BigInteger.valueOf(childrenList.size()));
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public TypeDefinition getTypeDefinition(String repositoryId, String typeId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // find the type
 | 
						|
        TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
 | 
						|
        if (tdw == null)
 | 
						|
        {
 | 
						|
            throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
 | 
						|
        }
 | 
						|
 | 
						|
        // return type definition
 | 
						|
        return tdw.getTypeDefinition(true);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<TypeDefinitionContainer> getTypeDescendants(
 | 
						|
            String repositoryId, String typeId, BigInteger depth,
 | 
						|
            Boolean includePropertyDefinitions, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>();
 | 
						|
 | 
						|
        // check depth
 | 
						|
        int d = (depth == null ? -1 : depth.intValue());
 | 
						|
        if (d == 0)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Depth must not be 0!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (typeId == null)
 | 
						|
        {
 | 
						|
            for (TypeDefinitionWrapper tdw : connector.getOpenCMISDictionaryService().getBaseTypes(true))
 | 
						|
            {
 | 
						|
                result.add(getTypesDescendants(d, tdw, includePropertyDefinitions));
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
 | 
						|
            if (tdw == null)
 | 
						|
            {
 | 
						|
                throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
 | 
						|
            }
 | 
						|
        	List<TypeDefinitionWrapper> children = connector.getOpenCMISDictionaryService().getChildren(typeId);
 | 
						|
            if(children != null)
 | 
						|
            {
 | 
						|
                for (TypeDefinitionWrapper child : children)
 | 
						|
                {
 | 
						|
                    result.add(getTypesDescendants(d, child, includePropertyDefinitions));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gathers the type descendants tree.
 | 
						|
     */
 | 
						|
    private TypeDefinitionContainer getTypesDescendants(
 | 
						|
            int depth, TypeDefinitionWrapper tdw, boolean includePropertyDefinitions)
 | 
						|
    {
 | 
						|
        TypeDefinitionContainerImpl result = new TypeDefinitionContainerImpl();
 | 
						|
 | 
						|
        result.setTypeDefinition(tdw.getTypeDefinition(includePropertyDefinitions));
 | 
						|
 | 
						|
        if (depth != 0)
 | 
						|
        {
 | 
						|
        	String typeId = tdw.getTypeId();
 | 
						|
        	List<TypeDefinitionWrapper> children = connector.getOpenCMISDictionaryService().getChildren(typeId);
 | 
						|
            if (children != null)
 | 
						|
            {
 | 
						|
                result.setChildren(new ArrayList<TypeDefinitionContainer>());
 | 
						|
                for (TypeDefinitionWrapper tdc : children)
 | 
						|
                {
 | 
						|
                    result.getChildren().add(
 | 
						|
                            getTypesDescendants(depth < 0 ? -1 : depth - 1, tdc, includePropertyDefinitions));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    // --- navigation service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectInFolderList getChildren(
 | 
						|
            String repositoryId, String folderId, String filter, String orderBy,
 | 
						|
            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
 | 
						|
            Boolean includePathSegment, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        long start = System.currentTimeMillis();
 | 
						|
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // convert BigIntegers to int
 | 
						|
        int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
 | 
						|
        int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
 | 
						|
 | 
						|
        ObjectInFolderListImpl result = new ObjectInFolderListImpl();
 | 
						|
        List<ObjectInFolderData> list = new ArrayList<ObjectInFolderData>();
 | 
						|
        result.setObjects(list);
 | 
						|
 | 
						|
        // get the children references
 | 
						|
        NodeRef folderNodeRef = getOrCreateFolderInfo(folderId, "Folder").getNodeRef();
 | 
						|
 | 
						|
        // convert orderBy to sortProps
 | 
						|
        List<Pair<QName, Boolean>> sortProps = null;
 | 
						|
        if (orderBy != null)
 | 
						|
        {
 | 
						|
            sortProps = new ArrayList<Pair<QName, Boolean>>(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)
 | 
						|
                    {
 | 
						|
                        // MNT-10529: Leading spaces result in an empty string value after the split operation. Leading spaces may occur in the 'orderBy' statement when the
 | 
						|
                        // elements of statement separated by a comma and a space(s)
 | 
						|
                        int index = (sort[0].isEmpty()) ? (1) : (0);
 | 
						|
 | 
						|
                        Pair<QName, Boolean> sortProp = connector.getSortProperty(sort[index], sort.length > (index + 1) ? sort[index + 1] : null);
 | 
						|
                        sortProps.add(sortProp);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            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 
 | 
						|
        Set<QName> typeqnames = new HashSet<QName>();
 | 
						|
        List<TypeDefinitionWrapper> allTypes = connector.getOpenCMISDictionaryService().getAllTypes();
 | 
						|
        for (TypeDefinitionWrapper type : allTypes)
 | 
						|
        {
 | 
						|
        	typeqnames.add(type.getAlfrescoClass());
 | 
						|
        }
 | 
						|
        PagingResults<FileInfo> pageOfNodeInfos = connector.getChildren(folderNodeRef, typeqnames, sortProps, pageRequest);
 | 
						|
 | 
						|
        if (max > 0)
 | 
						|
        {
 | 
						|
            for (FileInfo child : pageOfNodeInfos.getPage())
 | 
						|
            {
 | 
						|
                try
 | 
						|
                {
 | 
						|
                	// TODO this will break the paging if filtering is performed...
 | 
						|
                    if(connector.filter(child.getNodeRef()))
 | 
						|
                    {
 | 
						|
                        continue;
 | 
						|
                    }
 | 
						|
 | 
						|
                    // create a child CMIS object
 | 
						|
                    CMISNodeInfo ni = createNodeInfo(child.getNodeRef());
 | 
						|
 | 
						|
                    if (getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships)==null)
 | 
						|
                    {
 | 
						|
                        // ignore invalid children
 | 
						|
                        continue;
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (CMISObjectVariant.NOT_A_CMIS_OBJECT.equals(ni.getObjectVariant()))
 | 
						|
                    {
 | 
						|
                        continue;  //Skip non-cmis objects
 | 
						|
                    }
 | 
						|
                    
 | 
						|
                    ObjectData object = connector.createCMISObject(ni, child, filter, includeAllowableActions,
 | 
						|
                            includeRelationships, renditionFilter, false, false/*, getContext().getCmisVersion()*/);
 | 
						|
 | 
						|
                	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                    if (isObjectInfoRequired)
 | 
						|
                    {
 | 
						|
                        getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
 | 
						|
                    }
 | 
						|
 | 
						|
                    ObjectInFolderDataImpl childData = new ObjectInFolderDataImpl();
 | 
						|
                    childData.setObject(object);
 | 
						|
 | 
						|
                    // include path segment
 | 
						|
                    if (includePathSegment)
 | 
						|
                    {
 | 
						|
                        childData.setPathSegment(child.getName());
 | 
						|
                    }
 | 
						|
 | 
						|
                    // add it
 | 
						|
                    list.add(childData);
 | 
						|
                }
 | 
						|
                catch (InvalidNodeRefException e)
 | 
						|
                {
 | 
						|
                    // ignore invalid children
 | 
						|
                }
 | 
						|
                catch(CmisObjectNotFoundException e)
 | 
						|
                {
 | 
						|
                    // ignore objects that have not been found (perhaps because their type is unknown to CMIS)
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // has more ?
 | 
						|
        result.setHasMoreItems(pageOfNodeInfos.hasMoreItems());
 | 
						|
 | 
						|
        // total count ?
 | 
						|
        Pair<Integer, Integer> totalCounts = pageOfNodeInfos.getTotalResultCount();
 | 
						|
        if (totalCounts != null)
 | 
						|
        {
 | 
						|
            Integer totalCountLower = totalCounts.getFirst();
 | 
						|
            Integer totalCountUpper = totalCounts.getSecond();
 | 
						|
            if ((totalCountLower != null) && (totalCountLower.equals(totalCountUpper)))
 | 
						|
            {
 | 
						|
                result.setNumItems(BigInteger.valueOf(totalCountLower));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (logger.isDebugEnabled())
 | 
						|
        {
 | 
						|
            logger.debug("getChildren: " + list.size() + " in " + (System.currentTimeMillis() - start) + " msecs");
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<ObjectInFolderContainer> getDescendants(
 | 
						|
            String repositoryId, String folderId, BigInteger depth,
 | 
						|
            String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
 | 
						|
            String renditionFilter, Boolean includePathSegment, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        List<ObjectInFolderContainer> result = new ArrayList<ObjectInFolderContainer>();
 | 
						|
 | 
						|
        getDescendantsTree(
 | 
						|
                repositoryId,
 | 
						|
                getOrCreateFolderInfo(folderId, "Folder").getNodeRef(),
 | 
						|
                depth.intValue(),
 | 
						|
                filter,
 | 
						|
                includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, false,
 | 
						|
                result);
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<ObjectInFolderContainer> getFolderTree(
 | 
						|
            String repositoryId, String folderId, BigInteger depth,
 | 
						|
            String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
 | 
						|
            String renditionFilter, Boolean includePathSegment, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        List<ObjectInFolderContainer> result = new ArrayList<ObjectInFolderContainer>();
 | 
						|
 | 
						|
        getDescendantsTree(
 | 
						|
                repositoryId,
 | 
						|
                getOrCreateFolderInfo(folderId, "Folder").getNodeRef(),
 | 
						|
                depth.intValue(),
 | 
						|
                filter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, true,
 | 
						|
                result);
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    private void getDescendantsTree(
 | 
						|
            String repositoryId, NodeRef folderNodeRef, int depth, String filter,
 | 
						|
            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
 | 
						|
            Boolean includePathSegment, boolean foldersOnly, List<ObjectInFolderContainer> list)
 | 
						|
    {
 | 
						|
        // get the children references
 | 
						|
        List<ChildAssociationRef> childrenList = connector.getNodeService().getChildAssocs(folderNodeRef);
 | 
						|
        for (ChildAssociationRef child : childrenList)
 | 
						|
        {
 | 
						|
            try
 | 
						|
            {
 | 
						|
                TypeDefinitionWrapper type = connector.getType(child.getChildRef());
 | 
						|
                if (type == null)
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
 | 
						|
                boolean isFolder = (type instanceof FolderTypeDefintionWrapper);
 | 
						|
 | 
						|
                if (foldersOnly && !isFolder)
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
                
 | 
						|
                if(isFolder && type.getAlfrescoClass().equals(ContentModel.TYPE_SYSTEM_FOLDER))
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
                
 | 
						|
                if(connector.isHidden(child.getChildRef()))
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
 | 
						|
                if(connector.filter(child.getChildRef()))
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
                
 | 
						|
            	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
 | 
						|
                // create a child CMIS object
 | 
						|
                ObjectInFolderDataImpl object = new ObjectInFolderDataImpl();
 | 
						|
                CMISNodeInfo ni = createNodeInfo(child.getChildRef());
 | 
						|
                object.setObject(connector.createCMISObject(
 | 
						|
                        ni, filter, includeAllowableActions, includeRelationships,
 | 
						|
                        renditionFilter, false, false));
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
 | 
						|
                }
 | 
						|
 | 
						|
                if (includePathSegment)
 | 
						|
                {
 | 
						|
                    object.setPathSegment(connector.getName(child.getChildRef()));
 | 
						|
                }
 | 
						|
 | 
						|
                // create the container
 | 
						|
                ObjectInFolderContainerImpl container = new ObjectInFolderContainerImpl();
 | 
						|
                container.setObject(object);
 | 
						|
 | 
						|
                if ((depth != 1) && isFolder)
 | 
						|
                {
 | 
						|
                    container.setChildren(new ArrayList<ObjectInFolderContainer>());
 | 
						|
                    getDescendantsTree(
 | 
						|
                            repositoryId,
 | 
						|
                            child.getChildRef(),
 | 
						|
                            depth - 1, filter, includeAllowableActions,
 | 
						|
                            includeRelationships, renditionFilter, includePathSegment, foldersOnly,
 | 
						|
                            container.getChildren());
 | 
						|
                }
 | 
						|
 | 
						|
                // add it
 | 
						|
                list.add(container);
 | 
						|
            }
 | 
						|
            catch (InvalidNodeRefException e)
 | 
						|
            {
 | 
						|
                // ignore invalid children
 | 
						|
            }
 | 
						|
            catch(CmisObjectNotFoundException e)
 | 
						|
            {
 | 
						|
                // ignore objects that have not been found (perhaps because their type is unknown to CMIS)
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectData getFolderParent(String repositoryId, String folderId, String filter, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get the node ref
 | 
						|
        CMISNodeInfo info = getOrCreateFolderInfo(folderId, "Folder");
 | 
						|
 | 
						|
        // the root folder has no parent
 | 
						|
        if (info.isRootFolder())
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Root folder has no parent!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get the parent
 | 
						|
        List<CMISNodeInfo> parentInfos = info.getParents();
 | 
						|
        if (parentInfos.isEmpty())
 | 
						|
        {
 | 
						|
            throw new CmisRuntimeException("Folder has no parent and is not the root folder?!");
 | 
						|
        }
 | 
						|
 | 
						|
        CMISNodeInfo parentInfo = addNodeInfo(parentInfos.get(0));
 | 
						|
 | 
						|
        ObjectData result = connector.createCMISObject(
 | 
						|
                parentInfo, filter, false, IncludeRelationships.NONE,
 | 
						|
                CMISConnector.RENDITION_NONE, false, false);
 | 
						|
    	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
        if (isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            getObjectInfo(
 | 
						|
                    repositoryId,
 | 
						|
                    parentInfo.getObjectId(),
 | 
						|
                    IncludeRelationships.NONE);
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<ObjectParentData> getObjectParents(
 | 
						|
            String repositoryId, String objectId, String filter,
 | 
						|
            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
 | 
						|
            Boolean includeRelativePathSegment, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        List<ObjectParentData> result = new ArrayList<ObjectParentData>();
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // relationships are not filed
 | 
						|
        if (info.isRelationship())
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not fileable!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (info.isItem() || (info.isFolder() && !info.isRootFolder()))
 | 
						|
        {
 | 
						|
            List<CMISNodeInfo> parentInfos = info.getParents();
 | 
						|
            if (!parentInfos.isEmpty())
 | 
						|
            {
 | 
						|
                CMISNodeInfo parentInfo = addNodeInfo(parentInfos.get(0));
 | 
						|
 | 
						|
                ObjectData object = connector.createCMISObject(
 | 
						|
                        parentInfo, filter, includeAllowableActions,
 | 
						|
                        includeRelationships, renditionFilter, false, false);
 | 
						|
            	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, object.getId(), includeRelationships);
 | 
						|
                }
 | 
						|
 | 
						|
                ObjectParentDataImpl objectParent = new ObjectParentDataImpl();
 | 
						|
                objectParent.setObject(object);
 | 
						|
 | 
						|
                // include relative path segment
 | 
						|
                if (includeRelativePathSegment)
 | 
						|
                {
 | 
						|
                    objectParent.setRelativePathSegment(info.getName());
 | 
						|
                }
 | 
						|
 | 
						|
                result.add(objectParent);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else if (info.isCurrentVersion() || info.isPWC())
 | 
						|
        {
 | 
						|
            List<CMISNodeInfo> parentInfos = info.getParents();
 | 
						|
            for (CMISNodeInfo parentInfo : parentInfos)
 | 
						|
            {
 | 
						|
                addNodeInfo(parentInfo);
 | 
						|
 | 
						|
                ObjectData object = connector.createCMISObject(
 | 
						|
                        parentInfo, filter, includeAllowableActions,
 | 
						|
                        includeRelationships, renditionFilter, false, false);
 | 
						|
            	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, object.getId(), includeRelationships);
 | 
						|
                }
 | 
						|
 | 
						|
                ObjectParentDataImpl objectParent = new ObjectParentDataImpl();
 | 
						|
                objectParent.setObject(object);
 | 
						|
 | 
						|
                // include relative path segment
 | 
						|
                if (includeRelativePathSegment)
 | 
						|
                {
 | 
						|
                    objectParent.setRelativePathSegment(info.getName());
 | 
						|
                }
 | 
						|
 | 
						|
                result.add(objectParent);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectList getCheckedOutDocs(
 | 
						|
            String repositoryId, String folderId, String filter, String orderBy,
 | 
						|
            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
 | 
						|
            BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // convert BigIntegers to int
 | 
						|
        int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
 | 
						|
        int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
 | 
						|
 | 
						|
        // prepare query
 | 
						|
        SearchParameters params = new SearchParameters();
 | 
						|
        params.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
 | 
						|
       
 | 
						|
        if (folderId == null)
 | 
						|
        {
 | 
						|
            params.setQuery("+=cm:workingCopyOwner:\""+AuthenticationUtil.getFullyAuthenticatedUser()+"\"");
 | 
						|
            params.addStore(connector.getRootStoreRef());
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            CMISNodeInfo folderInfo = getOrCreateFolderInfo(folderId, "Folder");
 | 
						|
 | 
						|
            params.setQuery("+=cm:workingCopyOwner:\""+AuthenticationUtil.getFullyAuthenticatedUser()+"\" AND +=PARENT:\""+folderInfo.getNodeRef().toString()+"\"");
 | 
						|
            params.addStore(folderInfo.getNodeRef().getStoreRef());
 | 
						|
        }
 | 
						|
 | 
						|
        // set up order
 | 
						|
        if (orderBy != null)
 | 
						|
        {
 | 
						|
            String[] parts = orderBy.split(",");
 | 
						|
            for (int i = 0; i < parts.length; i++)
 | 
						|
            {
 | 
						|
                String[] sort = parts[i].split(" +");
 | 
						|
 | 
						|
                if (sort.length < 1)
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
 | 
						|
                PropertyDefinitionWrapper propDef = connector.getOpenCMISDictionaryService().findPropertyByQueryName(sort[0]);
 | 
						|
                if (propDef != null)
 | 
						|
                {
 | 
						|
                    if (propDef.getPropertyDefinition().isOrderable())
 | 
						|
                    {
 | 
						|
                        QName sortProp = propDef.getPropertyAccessor().getMappedProperty();
 | 
						|
                        if (sortProp != null)
 | 
						|
                        {
 | 
						|
                            boolean sortAsc = (sort.length == 1) || sort[1].equalsIgnoreCase("asc");
 | 
						|
                            params.addSort(propDef.getPropertyLuceneBuilder().getLuceneFieldName(), 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] + " - not orderable");
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    if (logger.isDebugEnabled())
 | 
						|
                    {
 | 
						|
                        logger.debug("Ignore sort property '" + sort[0] + " - query name not found");
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // execute query
 | 
						|
        ResultSet resultSet = null;
 | 
						|
        List<NodeRef> nodeRefs;
 | 
						|
        try
 | 
						|
        {
 | 
						|
            resultSet = connector.getSearchService().query(params);
 | 
						|
            nodeRefs = resultSet.getNodeRefs();
 | 
						|
        }
 | 
						|
        finally
 | 
						|
        {
 | 
						|
            if (resultSet != null)
 | 
						|
            {
 | 
						|
                resultSet.close();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // collect results
 | 
						|
        ObjectListImpl result = new ObjectListImpl();
 | 
						|
        List<ObjectData> list = new ArrayList<ObjectData>();
 | 
						|
        result.setObjects(list);
 | 
						|
 | 
						|
        int skipCounter = skip;
 | 
						|
        if (max > 0)
 | 
						|
        {
 | 
						|
            for (NodeRef nodeRef : nodeRefs)
 | 
						|
            {
 | 
						|
                // TODO - perhaps filter by path in the query instead?
 | 
						|
                if(connector.filter(nodeRef))
 | 
						|
                {
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
 | 
						|
                if (skipCounter > 0)
 | 
						|
                {
 | 
						|
                    skipCounter--;
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
 | 
						|
                if (list.size() == max)
 | 
						|
                {
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    // create a CMIS object
 | 
						|
                    CMISNodeInfo ni = createNodeInfo(nodeRef);
 | 
						|
                    ObjectData object = connector.createCMISObject(
 | 
						|
                            ni, filter, includeAllowableActions,
 | 
						|
                            includeRelationships, renditionFilter, false, false);
 | 
						|
 | 
						|
                	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                    if (isObjectInfoRequired)
 | 
						|
                    {
 | 
						|
                        getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
 | 
						|
                    }
 | 
						|
 | 
						|
                    // add it
 | 
						|
                    list.add(object);
 | 
						|
                }
 | 
						|
                catch (InvalidNodeRefException e)
 | 
						|
                {
 | 
						|
                    // ignore invalid objects
 | 
						|
                }
 | 
						|
                catch(CmisObjectNotFoundException e)
 | 
						|
                {
 | 
						|
                    // ignore objects that have not been found (perhaps because their type is unknown to CMIS)
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // has more ?
 | 
						|
        result.setHasMoreItems(nodeRefs.size() - skip > list.size());
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    // --- object service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String create(
 | 
						|
            String repositoryId, Properties properties, String folderId, ContentStream contentStream,
 | 
						|
            VersioningState versioningState, List<String> policies, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // check properties
 | 
						|
        if (properties == null || properties.getProperties() == null)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Properties must be set!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get the type
 | 
						|
        String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
 | 
						|
        // find the type
 | 
						|
        TypeDefinitionWrapper type = connector.getOpenCMISDictionaryService().findType(objectTypeId);
 | 
						|
        if (type == null)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Type '" + objectTypeId + "' is unknown!");
 | 
						|
        }
 | 
						|
 | 
						|
        // create object
 | 
						|
        String newId = null;
 | 
						|
        switch (type.getBaseTypeId())
 | 
						|
        {
 | 
						|
        case CMIS_DOCUMENT:
 | 
						|
            newId = createDocument(repositoryId, properties, folderId, contentStream, versioningState, policies, null,
 | 
						|
                    null, extension);
 | 
						|
            break;
 | 
						|
        case CMIS_FOLDER:
 | 
						|
            newId = createFolder(repositoryId, properties, folderId, policies, null, null, extension);
 | 
						|
            break;
 | 
						|
        case CMIS_POLICY:
 | 
						|
            newId = createPolicy(repositoryId, properties, folderId, policies, null, null, extension);
 | 
						|
            break;
 | 
						|
        case CMIS_ITEM:
 | 
						|
        	newId = createItem(repositoryId, properties, folderId, policies, null, null, extension);
 | 
						|
            
 | 
						|
        }
 | 
						|
 | 
						|
        // check new object id
 | 
						|
        if (newId == null)
 | 
						|
        {
 | 
						|
            throw new CmisRuntimeException("Creation failed!");
 | 
						|
        }
 | 
						|
 | 
						|
    	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
        if (isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            try
 | 
						|
            {
 | 
						|
                getObjectInfo(repositoryId, newId, "*", IncludeRelationships.NONE);
 | 
						|
            }
 | 
						|
            catch (InvalidNodeRefException e)
 | 
						|
            {
 | 
						|
                throw new CmisRuntimeException("Creation failed! New object not found!");
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // return the new object id
 | 
						|
        return newId;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createFolder(String repositoryId, final Properties properties, String folderId,
 | 
						|
            final List<String> policies, final Acl addAces, final Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get the parent folder node ref
 | 
						|
        final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Folder");
 | 
						|
 | 
						|
        // get name and type
 | 
						|
        final String name = connector.getNameProperty(properties, null);
 | 
						|
        final String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
        final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_FOLDER);
 | 
						|
 | 
						|
        connector.checkChildObjectType(parentInfo, type.getTypeId());
 | 
						|
 | 
						|
        // run transaction
 | 
						|
        FileInfo fileInfo = connector.getFileFolderService().create(
 | 
						|
                parentInfo.getNodeRef(), name, type.getAlfrescoClass());
 | 
						|
        NodeRef nodeRef = fileInfo.getNodeRef();
 | 
						|
 | 
						|
        connector.setProperties(nodeRef, type, properties, new String[] { PropertyIds.NAME, PropertyIds.OBJECT_TYPE_ID });
 | 
						|
        connector.applyPolicies(nodeRef, type, policies);
 | 
						|
        connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
        
 | 
						|
        connector.getActivityPoster().postFileFolderAdded(nodeRef);
 | 
						|
 | 
						|
        String objectId = connector.createObjectId(nodeRef);
 | 
						|
        return objectId;
 | 
						|
    }
 | 
						|
    
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createItem(String repositoryId, Properties properties, String folderId, List<String> policies,
 | 
						|
            Acl addAces, Acl removeAces, ExtensionsData extension) 
 | 
						|
    {
 | 
						|
    	checkRepositoryId(repositoryId);
 | 
						|
    	
 | 
						|
        // get the parent folder node ref
 | 
						|
        final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Folder");
 | 
						|
 | 
						|
        // get name and type
 | 
						|
        final String name = connector.getNameProperty(properties, null);
 | 
						|
        final String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
        final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_ITEM);
 | 
						|
 | 
						|
        connector.checkChildObjectType(parentInfo, type.getTypeId());
 | 
						|
        
 | 
						|
        /**
 | 
						|
         * The above code specifies a folder - so the contents of a folder (as defined by the alfresco model) are 
 | 
						|
         * ASSOC cm:contains to a TYPE sys:base
 | 
						|
         */
 | 
						|
        QName assocQName = QName.createQName(
 | 
						|
                NamespaceService.CONTENT_MODEL_1_0_URI,
 | 
						|
                QName.createValidLocalName(name));
 | 
						|
        
 | 
						|
        Map<QName, Serializable> props = new HashMap<QName, Serializable>(11);
 | 
						|
        props.put(ContentModel.PROP_NAME, (Serializable) assocQName.getLocalName());
 | 
						|
        
 | 
						|
        ChildAssociationRef newRef = connector.getNodeService().createNode(
 | 
						|
        		parentInfo.getNodeRef(), 
 | 
						|
        		ContentModel.ASSOC_CONTAINS, 
 | 
						|
        		assocQName, 
 | 
						|
        		type.getAlfrescoClass(),
 | 
						|
        		props);
 | 
						|
        
 | 
						|
        NodeRef nodeRef = newRef.getChildRef();
 | 
						|
        
 | 
						|
        connector.setProperties(nodeRef, type, properties, new String[] { PropertyIds.NAME, PropertyIds.OBJECT_TYPE_ID });
 | 
						|
        connector.getNodeService().setProperty(nodeRef, ContentModel.PROP_NAME, assocQName.getLocalName());
 | 
						|
 | 
						|
        connector.applyPolicies(nodeRef, type, policies);
 | 
						|
        connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
 | 
						|
        String objectId = connector.createObjectId(nodeRef);
 | 
						|
        return objectId;
 | 
						|
    	
 | 
						|
    }
 | 
						|
 | 
						|
    private String parseMimeType(ContentStream contentStream)
 | 
						|
    {
 | 
						|
    	String mimeType = null;
 | 
						|
 | 
						|
    	String tmp = contentStream.getMimeType();
 | 
						|
    	if(tmp != null)
 | 
						|
    	{
 | 
						|
    		int idx = tmp.indexOf(";");
 | 
						|
    		if(idx != -1)
 | 
						|
    		{
 | 
						|
    			mimeType = tmp.substring(0, idx).trim();
 | 
						|
    		}
 | 
						|
    		else
 | 
						|
    		{
 | 
						|
    			mimeType = tmp;
 | 
						|
    		}
 | 
						|
    	}
 | 
						|
 | 
						|
    	return mimeType;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createDocument(
 | 
						|
            String repositoryId, final Properties properties, String folderId,
 | 
						|
            final ContentStream contentStream, final VersioningState versioningState, final List<String> policies,
 | 
						|
            final Acl addAces, final Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
        
 | 
						|
        // get the parent folder node ref
 | 
						|
        final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Parent folder");
 | 
						|
 | 
						|
        // get name and type
 | 
						|
        final String name = connector.getNameProperty(properties, null);
 | 
						|
        final String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
        final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_DOCUMENT);
 | 
						|
 | 
						|
        connector.checkChildObjectType(parentInfo, type.getTypeId());
 | 
						|
 | 
						|
        DocumentTypeDefinition docType = (DocumentTypeDefinition) type.getTypeDefinition(false);
 | 
						|
 | 
						|
        if ((docType.getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED) && (contentStream != null))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("This document type does not support content!");
 | 
						|
        }
 | 
						|
 | 
						|
        if ((docType.getContentStreamAllowed() == ContentStreamAllowed.REQUIRED) && (contentStream == null))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("This document type does requires content!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (docType.isVersionable() && (versioningState == VersioningState.NONE))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("This document type is versionable!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (!docType.isVersionable() && (versioningState != VersioningState.NONE))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("This document type is not versionable!");
 | 
						|
        }
 | 
						|
 | 
						|
        FileInfo fileInfo = connector.getFileFolderService().create(
 | 
						|
                parentInfo.getNodeRef(), name, type.getAlfrescoClass());
 | 
						|
        NodeRef nodeRef = fileInfo.getNodeRef();
 | 
						|
        connector.setProperties(nodeRef, type, properties, new String[] { PropertyIds.NAME, PropertyIds.OBJECT_TYPE_ID });
 | 
						|
        connector.applyPolicies(nodeRef, type, policies);
 | 
						|
        connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
 | 
						|
        // handle content
 | 
						|
        File tempFile = null;
 | 
						|
        try
 | 
						|
        {
 | 
						|
	        if (contentStream != null)
 | 
						|
	        {
 | 
						|
	            // write content
 | 
						|
	            String mimeType = parseMimeType(contentStream);
 | 
						|
 | 
						|
	            // copy stream to temp file
 | 
						|
	            // OpenCMIS does this for us ....
 | 
						|
	            tempFile = copyToTempFile(contentStream);
 | 
						|
	            final Charset encoding = (tempFile == null ? null : getEncoding(tempFile, contentStream.getMimeType()));
 | 
						|
	                
 | 
						|
	            ContentWriter writer = connector.getFileFolderService().getWriter(nodeRef);
 | 
						|
	            writer.setMimetype(mimeType);
 | 
						|
	            writer.setEncoding(encoding.name());
 | 
						|
	            writer.putContent(tempFile);
 | 
						|
	        }
 | 
						|
        }
 | 
						|
        finally
 | 
						|
        {
 | 
						|
        	if(tempFile != null)
 | 
						|
        	{
 | 
						|
        		removeTempFile(tempFile);
 | 
						|
        	}
 | 
						|
        }
 | 
						|
 | 
						|
        connector.extractMetadata(nodeRef);
 | 
						|
 | 
						|
        // generate "doclib" thumbnail asynchronously
 | 
						|
        connector.createThumbnails(nodeRef, Collections.singleton("doclib"));
 | 
						|
 | 
						|
        connector.applyVersioningState(nodeRef, versioningState);
 | 
						|
 | 
						|
        removeTempFile(tempFile);
 | 
						|
 | 
						|
        String objectId = connector.createObjectId(nodeRef);
 | 
						|
 | 
						|
        connector.getActivityPoster().postFileFolderAdded(nodeRef);
 | 
						|
 | 
						|
        return objectId;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createDocumentFromSource(
 | 
						|
            String repositoryId, String sourceId, final Properties properties,
 | 
						|
            String folderId, final VersioningState versioningState, final List<String> policies, final Acl addAces,
 | 
						|
            final Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get the parent folder node ref
 | 
						|
        final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Parent folder");
 | 
						|
 | 
						|
        // get source
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(sourceId, "Source");
 | 
						|
 | 
						|
        // check source
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Source object is not a document!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef sourceNodeRef = info.getNodeRef();
 | 
						|
        if (!info.isDocument())
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Source object is not a document!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get name and type
 | 
						|
        final String name = connector.getNameProperty(properties, info.getName());
 | 
						|
 | 
						|
        final TypeDefinitionWrapper type = info.getType();
 | 
						|
        connector.checkChildObjectType(parentInfo, type.getTypeId());
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
            FileInfo fileInfo = connector.getFileFolderService().copy(
 | 
						|
                    sourceNodeRef, parentInfo.getNodeRef(), name);
 | 
						|
            NodeRef nodeRef = fileInfo.getNodeRef();
 | 
						|
            connector.setProperties(nodeRef, type, properties, new String[] {
 | 
						|
                    PropertyIds.NAME, PropertyIds.OBJECT_TYPE_ID });
 | 
						|
            connector.applyPolicies(nodeRef, type, policies);
 | 
						|
            connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
            
 | 
						|
            connector.extractMetadata(nodeRef);
 | 
						|
            connector.createThumbnails(nodeRef, Collections.singleton("doclib"));
 | 
						|
 | 
						|
            connector.applyVersioningState(nodeRef, versioningState);
 | 
						|
            
 | 
						|
            connector.getActivityPoster().postFileFolderAdded(nodeRef);
 | 
						|
            
 | 
						|
            return connector.createObjectId(nodeRef);
 | 
						|
        }
 | 
						|
        catch (FileNotFoundException e)
 | 
						|
        {
 | 
						|
            throw new CmisContentAlreadyExistsException("An object with this name already exists!", e);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createPolicy(
 | 
						|
            String repositoryId, Properties properties, String folderId, List<String> policies,
 | 
						|
            Acl addAces, Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get the parent folder
 | 
						|
        getOrCreateFolderInfo(folderId, "Parent Folder");
 | 
						|
 | 
						|
        String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
        connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_POLICY);
 | 
						|
 | 
						|
        // we should never get here - policies are not creatable!
 | 
						|
        throw new CmisRuntimeException("Polcies cannot be created!");
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public String createRelationship(
 | 
						|
            String repositoryId, Properties properties, List<String> policies, Acl addAces,
 | 
						|
            Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get type
 | 
						|
        String objectTypeId = connector.getObjectTypeIdProperty(properties);
 | 
						|
        final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_RELATIONSHIP);
 | 
						|
 | 
						|
        // get source object
 | 
						|
        String sourceId = connector.getSourceIdProperty(properties);
 | 
						|
        CMISNodeInfo sourceInfo = getOrCreateNodeInfo(sourceId, "Source");
 | 
						|
 | 
						|
        if (!sourceInfo.isVariant(CMISObjectVariant.CURRENT_VERSION) && !sourceInfo.isVariant(CMISObjectVariant.FOLDER) && !sourceInfo.isVariant(CMISObjectVariant.ITEM))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Source is not the latest version of a document, a folder or an item object!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef sourceNodeRef = sourceInfo.getNodeRef();
 | 
						|
 | 
						|
        // get target object
 | 
						|
        String targetId = connector.getTargetIdProperty(properties);
 | 
						|
        CMISNodeInfo targetInfo = getOrCreateNodeInfo(targetId, "Target");
 | 
						|
 | 
						|
        if (!targetInfo.isVariant(CMISObjectVariant.CURRENT_VERSION) && !targetInfo.isVariant(CMISObjectVariant.FOLDER) && !targetInfo.isVariant(CMISObjectVariant.ITEM))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException(
 | 
						|
                    "Target is not the latest version of a document, a folder or an item object!!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef targetNodeRef = targetInfo.getNodeRef();
 | 
						|
 | 
						|
        // check policies and ACLs
 | 
						|
        if ((policies != null) && (!policies.isEmpty()))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not policy controllable!");
 | 
						|
        }
 | 
						|
 | 
						|
        if ((addAces != null) && (addAces.getAces() != null) && (!addAces.getAces().isEmpty()))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not ACL controllable!");
 | 
						|
        }
 | 
						|
 | 
						|
        if ((removeAces != null) && (removeAces.getAces() != null) && (!removeAces.getAces().isEmpty()))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not ACL controllable!");
 | 
						|
        }
 | 
						|
 | 
						|
        // create relationship
 | 
						|
        // ALF-10085 : disable auditing behaviour for this use case
 | 
						|
        boolean wasEnabled = connector.disableBehaviour(ContentModel.ASPECT_AUDITABLE, sourceNodeRef);        // Lasts for txn
 | 
						|
        try
 | 
						|
        {
 | 
						|
            AssociationRef assocRef = connector.getNodeService().createAssociation(
 | 
						|
                    sourceNodeRef, targetNodeRef, type.getAlfrescoClass());
 | 
						|
 | 
						|
            return CMISConnector.ASSOC_ID_PREFIX + assocRef.getId();
 | 
						|
        }
 | 
						|
        finally
 | 
						|
        {
 | 
						|
            if(wasEnabled)
 | 
						|
            {
 | 
						|
                connector.enableBehaviour(ContentModel.ASPECT_AUDITABLE, sourceNodeRef);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void appendContentStream(String repositoryId, Holder<String> objectId, Holder<String> changeToken,
 | 
						|
            ContentStream contentStream, boolean isLastChunk, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        if ((contentStream == null) || (contentStream.getStream() == null))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("No content!");
 | 
						|
        }
 | 
						|
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
        NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        if (((DocumentTypeDefinition) info.getType().getTypeDefinition(false)).getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED)
 | 
						|
        {
 | 
						|
            throw new CmisStreamNotSupportedException("Document type doesn't allow content!");
 | 
						|
        }
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
        	connector.appendContent(info, contentStream, isLastChunk);
 | 
						|
            objectId.setValue(connector.createObjectId(nodeRef));
 | 
						|
        }
 | 
						|
    	catch(IOException e)
 | 
						|
    	{
 | 
						|
    		throw new ContentIOException("", e);
 | 
						|
    	}
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void setContentStream(
 | 
						|
            String repositoryId, Holder<String> objectId, Boolean overwriteFlag,
 | 
						|
            Holder<String> changeToken, final ContentStream contentStream, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        if (!info.isVariant(CMISObjectVariant.CURRENT_VERSION) && !info.isVariant(CMISObjectVariant.PWC))
 | 
						|
        {
 | 
						|
            throw new CmisStreamNotSupportedException("Content can only be set ondocuments!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        if (((DocumentTypeDefinition) info.getType().getTypeDefinition(false)).getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED)
 | 
						|
        {
 | 
						|
            throw new CmisStreamNotSupportedException("Document type doesn't allow content!");
 | 
						|
        }
 | 
						|
 | 
						|
        boolean existed = connector.getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT) != null;
 | 
						|
        if (existed && !overwriteFlag)
 | 
						|
        {
 | 
						|
            throw new CmisContentAlreadyExistsException("Content already exists!");
 | 
						|
        }
 | 
						|
 | 
						|
        if ((contentStream == null) || (contentStream.getStream() == null))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("No content!");
 | 
						|
        }
 | 
						|
 | 
						|
        // copy stream to temp file
 | 
						|
        final File tempFile = copyToTempFile(contentStream);
 | 
						|
        final Charset encoding = getEncoding(tempFile, contentStream.getMimeType());
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
            ContentWriter writer = connector.getFileFolderService().getWriter(nodeRef);
 | 
						|
            String mimeType = parseMimeType(contentStream);
 | 
						|
            writer.setMimetype(mimeType);
 | 
						|
            writer.setEncoding(encoding.name());
 | 
						|
            writer.putContent(tempFile);
 | 
						|
        }
 | 
						|
        finally
 | 
						|
        {
 | 
						|
            removeTempFile(tempFile);
 | 
						|
        }
 | 
						|
 | 
						|
        objectId.setValue(connector.createObjectId(nodeRef));
 | 
						|
 | 
						|
        connector.getActivityPoster().postFileFolderUpdated(info.isFolder(), nodeRef);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void deleteContentStream(
 | 
						|
            String repositoryId, Holder<String> objectId, Holder<String> changeToken,
 | 
						|
            ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        if (!info.isVariant(CMISObjectVariant.CURRENT_VERSION) && !info.isVariant(CMISObjectVariant.PWC))
 | 
						|
        {
 | 
						|
            throw new CmisStreamNotSupportedException("Content can only be deleted from ondocuments!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        if (((DocumentTypeDefinition) info.getType().getTypeDefinition(false)).getContentStreamAllowed() == ContentStreamAllowed.REQUIRED)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Document type requires content!");
 | 
						|
        }
 | 
						|
 | 
						|
        connector.getNodeService().setProperty(nodeRef, ContentModel.PROP_CONTENT, null);
 | 
						|
        
 | 
						|
//        connector.createVersion(nodeRef, VersionType.MINOR, "Delete content");
 | 
						|
 | 
						|
        connector.getActivityPoster().postFileFolderUpdated(info.isFolder(), nodeRef);
 | 
						|
 | 
						|
        objectId.setValue(connector.createObjectId(nodeRef));
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void moveObject(
 | 
						|
            String repositoryId, Holder<String> objectId, String targetFolderId, String sourceFolderId,
 | 
						|
            ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get object and source and target parent
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getCurrentNodeNodeRef();
 | 
						|
        final CMISNodeInfo sourceInfo = getOrCreateFolderInfo(sourceFolderId, "Source Folder");
 | 
						|
        final CMISNodeInfo targetInfo = getOrCreateFolderInfo(targetFolderId, "Target Folder");
 | 
						|
 | 
						|
        connector.checkChildObjectType(targetInfo, info.getType().getTypeId());
 | 
						|
 | 
						|
        ChildAssociationRef primaryParentRef = connector.getNodeService().getPrimaryParent(nodeRef);
 | 
						|
        // if this is a primary child node, move it
 | 
						|
        if (primaryParentRef.getParentRef().equals(sourceInfo.getNodeRef()))
 | 
						|
        {
 | 
						|
            connector.getNodeService().moveNode(
 | 
						|
                    nodeRef, targetInfo.getNodeRef(),
 | 
						|
                    primaryParentRef.getTypeQName(), primaryParentRef.getQName());
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            boolean found = false;
 | 
						|
            // otherwise, reparent it
 | 
						|
            for (ChildAssociationRef parent : connector.getNodeService().getParentAssocs(
 | 
						|
                    nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL))
 | 
						|
            {
 | 
						|
                if (parent.getParentRef().equals(sourceInfo.getNodeRef()))
 | 
						|
                {
 | 
						|
                    connector.getNodeService().removeChildAssociation(parent);
 | 
						|
                    connector.getNodeService().addChild(
 | 
						|
                            targetInfo.getNodeRef(), nodeRef,
 | 
						|
                            ContentModel.ASSOC_CONTAINS, parent.getQName());
 | 
						|
                    found = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (!found)
 | 
						|
            {
 | 
						|
                throw new IllegalArgumentException(
 | 
						|
                        new CmisInvalidArgumentException(
 | 
						|
                                "Document is not a child of the source folder that was specified!"));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void updateProperties(
 | 
						|
            String repositoryId, Holder<String> objectId, Holder<String> changeToken,
 | 
						|
            final Properties properties, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        final CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Relationship properties cannot be updated!");
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
            {
 | 
						|
                throw new CmisInvalidArgumentException("Document is not the latest version!");
 | 
						|
            }
 | 
						|
 | 
						|
            final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
            connector.setProperties(nodeRef, info.getType(), properties, new String[0]);
 | 
						|
            
 | 
						|
            objectId.setValue(connector.createObjectId(nodeRef));
 | 
						|
 | 
						|
        	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
            if (isObjectInfoRequired)
 | 
						|
            {
 | 
						|
                getObjectInfo(repositoryId, objectId.getValue(), "*", IncludeRelationships.NONE);
 | 
						|
            }
 | 
						|
 | 
						|
            connector.getActivityPoster().postFileFolderUpdated(info.isFolder(), nodeRef);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void deleteObject(String repositoryId, String objectId, Boolean allVersions, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        deleteObjectOrCancelCheckOut(repositoryId, objectId, allVersions, extension);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void deleteObjectOrCancelCheckOut(
 | 
						|
            String repositoryId, final String objectId, final Boolean allVersions,
 | 
						|
            ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        final CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        do
 | 
						|
        {
 | 
						|
            // handle relationships
 | 
						|
            if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
            {
 | 
						|
                AssociationRef assocRef = info.getAssociationRef();
 | 
						|
                connector.getNodeService().removeAssociation(
 | 
						|
                        assocRef.getSourceRef(),
 | 
						|
                        assocRef.getTargetRef(),
 | 
						|
                        assocRef.getTypeQName());
 | 
						|
                break;      // Reason for do-while
 | 
						|
            }
 | 
						|
 | 
						|
            NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
            // handle PWC
 | 
						|
            if (info.isVariant(CMISObjectVariant.PWC))
 | 
						|
            {
 | 
						|
                connector.getCheckOutCheckInService().cancelCheckout(nodeRef);
 | 
						|
                break;      // Reason for do-while
 | 
						|
            }
 | 
						|
 | 
						|
            // handle folders
 | 
						|
            if (info.isFolder())
 | 
						|
            {
 | 
						|
                // Check if there is at least one child
 | 
						|
                if (connector.getNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL, 1, false).size() > 0)
 | 
						|
                {
 | 
						|
                    throw new CmisConstraintException(
 | 
						|
                            "Could not delete folder with at least one child!");
 | 
						|
                }
 | 
						|
 | 
						|
                connector.deleteNode(nodeRef, true);
 | 
						|
                break;      // Reason for do-while
 | 
						|
            }
 | 
						|
 | 
						|
            if(info.hasPWC())
 | 
						|
            {
 | 
						|
                // is a checked out document. If a delete, don't allow unless checkout is canceled. If a cancel
 | 
						|
                // checkout, not allowed.
 | 
						|
                throw new CmisConstraintException(
 | 
						|
                "Could not delete/cancel checkout on the original checked out document");
 | 
						|
            }
 | 
						|
 | 
						|
            // handle versions
 | 
						|
            if (allVersions)
 | 
						|
            {
 | 
						|
                NodeRef workingCopy = connector.getCheckOutCheckInService().getWorkingCopy(nodeRef);
 | 
						|
                if (workingCopy != null)
 | 
						|
                {
 | 
						|
                    connector.getCheckOutCheckInService().cancelCheckout(workingCopy);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
            {
 | 
						|
                Version version = ((CMISNodeInfoImpl) info).getVersion();
 | 
						|
                connector.getVersionService().deleteVersion(nodeRef, version);
 | 
						|
                break;      // Reason for do-while
 | 
						|
            }
 | 
						|
 | 
						|
            if (info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
            {
 | 
						|
                nodeRef = info.getCurrentNodeNodeRef();
 | 
						|
            }
 | 
						|
 | 
						|
            // attempt to delete the node
 | 
						|
            if (allVersions)
 | 
						|
            {
 | 
						|
                connector.deleteNode(nodeRef, true);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CMISNodeInfoImpl infoImpl = ((CMISNodeInfoImpl) info);
 | 
						|
                Version version = infoImpl.getVersion();
 | 
						|
 | 
						|
                if (infoImpl.getVersionHistory().getPredecessor(version) == null)
 | 
						|
                {
 | 
						|
                    connector.deleteNode(nodeRef, true);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    connector.getVersionService().deleteVersion(nodeRef, version);
 | 
						|
                    // MNT-10032 revert node version to predecessor
 | 
						|
                    connector.getVersionService().revert(nodeRef);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        while (false);      // Dodgey, but avoided having to play with too much code during refactor
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public FailedToDeleteData deleteTree(
 | 
						|
            String repositoryId, String folderId, Boolean allVersions,
 | 
						|
            UnfileObject unfileObjects, final Boolean continueOnFailure, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (!allVersions)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Only allVersions=true supported!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (unfileObjects == UnfileObject.UNFILE)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Unfiling not supported!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef folderNodeRef = getOrCreateFolderInfo(folderId, "Folder").getNodeRef();
 | 
						|
        final FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
            connector.deleteNode(folderNodeRef, true);
 | 
						|
        }
 | 
						|
        catch (Exception e)
 | 
						|
        {
 | 
						|
            List<String> ids = new ArrayList<String>();
 | 
						|
            ids.add(folderId);
 | 
						|
            result.setIds(ids);
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectData getObject(
 | 
						|
            String repositoryId, String objectId, String filter, Boolean includeAllowableActions,
 | 
						|
            IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds,
 | 
						|
            Boolean includeAcl, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // create a CMIS object
 | 
						|
        ObjectData object = connector.createCMISObject(
 | 
						|
                info, filter, includeAllowableActions, includeRelationships,
 | 
						|
                renditionFilter, includePolicyIds, includeAcl);
 | 
						|
 | 
						|
    	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
        if (isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            getObjectInfo(repositoryId, info.getObjectId(), includeRelationships);
 | 
						|
        }
 | 
						|
 | 
						|
        return object;
 | 
						|
    }
 | 
						|
    
 | 
						|
    @Override
 | 
						|
    public List<BulkUpdateObjectIdAndChangeToken> bulkUpdateProperties(final String repositoryId,
 | 
						|
            List<BulkUpdateObjectIdAndChangeToken> objectIdAndChangeTokens, final Properties properties,
 | 
						|
            final List<String> addSecondaryTypeIds, final List<String> removeSecondaryTypeIds, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
        
 | 
						|
        if(objectIdAndChangeTokens.size() > connector.getBulkMaxItems())
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Bulk update not supported for more than " + connector.getBulkMaxItems() + " objects.");
 | 
						|
        }
 | 
						|
 | 
						|
        // WorkProvider
 | 
						|
        class WorkProvider implements BatchProcessWorkProvider<BulkEntry>
 | 
						|
        {
 | 
						|
            private final Iterator<BulkUpdateObjectIdAndChangeToken> iterator;
 | 
						|
            private final int size;
 | 
						|
            private final int batchSize;
 | 
						|
            private BulkUpdateContext context;
 | 
						|
 | 
						|
            public WorkProvider(List<BulkUpdateObjectIdAndChangeToken> objectIdAndChangeTokens, BulkUpdateContext context, int batchSize)
 | 
						|
            {
 | 
						|
                this.iterator = objectIdAndChangeTokens.iterator();
 | 
						|
                this.size = objectIdAndChangeTokens.size();
 | 
						|
                this.context = context;
 | 
						|
                this.batchSize = batchSize;
 | 
						|
            }
 | 
						|
 | 
						|
            @Override
 | 
						|
            public synchronized int getTotalEstimatedWorkSize()
 | 
						|
            {
 | 
						|
                return size;
 | 
						|
            }
 | 
						|
 | 
						|
            @Override
 | 
						|
            public synchronized Collection<BulkEntry> getNextWork()
 | 
						|
            {
 | 
						|
                Collection<BulkEntry> results = new ArrayList<BulkEntry>(batchSize);
 | 
						|
                while (results.size() < batchSize && iterator.hasNext())
 | 
						|
                {
 | 
						|
                    results.add(new BulkEntry(context, iterator.next(), properties, addSecondaryTypeIds, removeSecondaryTypeIds, getContext().isObjectInfoRequired()));
 | 
						|
                }
 | 
						|
                return results;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        
 | 
						|
        BulkUpdateContext context = new BulkUpdateContext(objectIdAndChangeTokens.size());
 | 
						|
        RetryingTransactionHelper helper = connector.getRetryingTransactionHelper();
 | 
						|
        final String runAsUser = AuthenticationUtil.getRunAsUser();
 | 
						|
 | 
						|
        // Worker
 | 
						|
        BatchProcessWorker<BulkEntry> worker = new BatchProcessWorker<BulkEntry>()
 | 
						|
        {
 | 
						|
            @Override
 | 
						|
            public void process(final BulkEntry entry) throws Throwable
 | 
						|
            {
 | 
						|
                entry.update();
 | 
						|
            }
 | 
						|
 | 
						|
            public String getIdentifier(BulkEntry entry)
 | 
						|
            {
 | 
						|
                return entry.getObjectIdAndChangeToken().getId();
 | 
						|
            }
 | 
						|
 | 
						|
            @Override
 | 
						|
            public void beforeProcess() throws Throwable
 | 
						|
            {
 | 
						|
                // Authentication
 | 
						|
                AuthenticationUtil.pushAuthentication();
 | 
						|
                AuthenticationUtil.setFullyAuthenticatedUser(runAsUser);
 | 
						|
            }
 | 
						|
 | 
						|
            @Override
 | 
						|
            public void afterProcess() throws Throwable
 | 
						|
            {
 | 
						|
                // Clear authentication
 | 
						|
                AuthenticationUtil.popAuthentication();
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        // Processor
 | 
						|
        BatchProcessor<BulkEntry> processor = new BatchProcessor<BulkEntry>(
 | 
						|
                "CMISbulkUpdateProperties",
 | 
						|
                helper,
 | 
						|
                new WorkProvider(objectIdAndChangeTokens, context, connector.getBulkBatchSize()),
 | 
						|
                connector.getBulkWorkerThreads(), connector.getBulkBatchSize(),
 | 
						|
                null,
 | 
						|
                logger, 100);
 | 
						|
        processor.process(worker, true);
 | 
						|
        
 | 
						|
        for(CMISNodeInfo info : context.getSuccesses())
 | 
						|
        {
 | 
						|
            NodeRef nodeRef = info.getNodeRef();
 | 
						|
            connector.getActivityPoster().postFileFolderUpdated(info.isFolder(), nodeRef);
 | 
						|
        }
 | 
						|
 | 
						|
        return context.getChanges();
 | 
						|
    }
 | 
						|
    
 | 
						|
    private class BulkEntry
 | 
						|
    {
 | 
						|
        private String repositoryId;
 | 
						|
        private BulkUpdateContext bulkUpdateContext;
 | 
						|
 | 
						|
        private BulkUpdateObjectIdAndChangeToken objectIdAndChangeToken;
 | 
						|
        private Properties properties;
 | 
						|
        private List<String> addSecondaryTypeIds;
 | 
						|
        private List<String> removeSecondaryTypeIds;
 | 
						|
        private boolean isObjectInfoRequired;
 | 
						|
 | 
						|
        BulkEntry(BulkUpdateContext bulkUpdateContext, BulkUpdateObjectIdAndChangeToken objectIdAndChangeToken, Properties properties, List<String> addSecondaryTypeIds,
 | 
						|
                List<String> removeSecondaryTypeIds, boolean isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            this.bulkUpdateContext = bulkUpdateContext;
 | 
						|
            this.objectIdAndChangeToken = objectIdAndChangeToken;
 | 
						|
            this.properties = properties;
 | 
						|
            this.addSecondaryTypeIds = addSecondaryTypeIds;
 | 
						|
            this.removeSecondaryTypeIds = removeSecondaryTypeIds;
 | 
						|
            this.isObjectInfoRequired = isObjectInfoRequired;
 | 
						|
        }
 | 
						|
 | 
						|
        public void update()
 | 
						|
        {
 | 
						|
            String objectId = objectIdAndChangeToken.getId();
 | 
						|
            final CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
            if (!info.isVariant(CMISObjectVariant.ASSOC) && !info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
            {
 | 
						|
                final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
                connector.setProperties(nodeRef, info.getType(), properties, new String[0]);
 | 
						|
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, objectId, "*", IncludeRelationships.NONE);
 | 
						|
                }
 | 
						|
 | 
						|
                connector.addSecondaryTypes(nodeRef, addSecondaryTypeIds);
 | 
						|
                connector.removeSecondaryTypes(nodeRef, removeSecondaryTypeIds);
 | 
						|
 | 
						|
                if (properties.getProperties().size() > 0 || addSecondaryTypeIds.size() > 0 || removeSecondaryTypeIds.size() > 0)
 | 
						|
                {
 | 
						|
                    bulkUpdateContext.success(info);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        };
 | 
						|
        
 | 
						|
        public BulkUpdateObjectIdAndChangeToken getObjectIdAndChangeToken()
 | 
						|
        {
 | 
						|
            return objectIdAndChangeToken;
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    private static class BulkUpdateContext
 | 
						|
    {
 | 
						|
        private Set<CMISNodeInfo> successes;
 | 
						|
        
 | 
						|
        BulkUpdateContext(int size)
 | 
						|
        {
 | 
						|
            this.successes = Collections.newSetFromMap(new ConcurrentHashMap<CMISNodeInfo, Boolean>());
 | 
						|
        }
 | 
						|
        
 | 
						|
        void success(CMISNodeInfo info)
 | 
						|
        {
 | 
						|
            successes.add(info);
 | 
						|
        }
 | 
						|
        
 | 
						|
        Set<CMISNodeInfo> getSuccesses()
 | 
						|
        {
 | 
						|
            return successes;
 | 
						|
        }
 | 
						|
 | 
						|
        List<BulkUpdateObjectIdAndChangeToken> getChanges()
 | 
						|
        {
 | 
						|
            List<BulkUpdateObjectIdAndChangeToken> changes = new ArrayList<BulkUpdateObjectIdAndChangeToken>(successes.size());
 | 
						|
            for(CMISNodeInfo info : successes)
 | 
						|
            {
 | 
						|
                BulkUpdateObjectIdAndChangeTokenImpl a = new BulkUpdateObjectIdAndChangeTokenImpl();
 | 
						|
                a.setId(info.getObjectId());
 | 
						|
//              a.setNewId(info.getObjectId());
 | 
						|
                changes.add(a);
 | 
						|
            }
 | 
						|
 | 
						|
            return changes;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectData getObjectByPath(
 | 
						|
            String repositoryId, String path, String filter, Boolean includeAllowableActions,
 | 
						|
            IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds,
 | 
						|
            Boolean includeAcl, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // start at the root node
 | 
						|
        NodeRef rootNodeRef = connector.getRootNodeRef();
 | 
						|
 | 
						|
        if (path.equals("/"))
 | 
						|
        {
 | 
						|
            return connector.createCMISObject(createNodeInfo(rootNodeRef), filter, includeAllowableActions,
 | 
						|
                    includeRelationships, renditionFilter, includePolicyIds, includeAcl);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            try
 | 
						|
            {
 | 
						|
                // resolve path and get the node ref
 | 
						|
                FileInfo fileInfo = connector.getFileFolderService().resolveNamePath(
 | 
						|
                        rootNodeRef,
 | 
						|
                        Arrays.asList(path.substring(1).split("/")));
 | 
						|
 | 
						|
                if(connector.filter(fileInfo.getNodeRef()))
 | 
						|
                {
 | 
						|
                    throw new CmisObjectNotFoundException("Object not found: " + path);
 | 
						|
                }
 | 
						|
 | 
						|
                CMISNodeInfo info = createNodeInfo(fileInfo.getNodeRef());
 | 
						|
 | 
						|
                ObjectData object = connector.createCMISObject(
 | 
						|
                        info, fileInfo, filter, includeAllowableActions,
 | 
						|
                        includeRelationships, renditionFilter, includePolicyIds, includeAcl);
 | 
						|
 | 
						|
            	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, info.getObjectId(), includeRelationships);
 | 
						|
                }
 | 
						|
 | 
						|
                return object;
 | 
						|
            }
 | 
						|
            catch (FileNotFoundException e)
 | 
						|
            {
 | 
						|
                throw new CmisObjectNotFoundException("Object not found: " + path);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public Properties getProperties(String repositoryId, String objectId, String filter, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
    	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
        if (isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            getObjectInfo(repositoryId, info.getObjectId(), IncludeRelationships.NONE);
 | 
						|
        }
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            return connector.getAssocProperties(info, filter);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            return connector.getNodeProperties(info, filter);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public AllowableActions getAllowableActions(String repositoryId, String objectId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        return connector.getAllowableActions(info);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ContentStream getContentStream(
 | 
						|
            String repositoryId, String objectId, String streamId, BigInteger offset,
 | 
						|
            BigInteger length, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // relationships cannot have content
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object is a relationship and cannot have content!");
 | 
						|
        }
 | 
						|
 | 
						|
        // now get it
 | 
						|
        return connector.getContentStream(info, streamId, offset, length);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<RenditionData> getRenditions(String repositoryId, String objectId, String renditionFilter,
 | 
						|
            BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            return Collections.emptyList();
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            return connector.getRenditions(info.getNodeRef(), renditionFilter, maxItems, skipCount);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // --- versioning service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void checkOut(
 | 
						|
            String repositoryId, final Holder<String> objectId, ExtensionsData extension,
 | 
						|
            final Holder<Boolean> contentCopied)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        // Check for current version
 | 
						|
        if (info.isVariant(CMISObjectVariant.CURRENT_VERSION))
 | 
						|
        {
 | 
						|
            // Good
 | 
						|
        }
 | 
						|
        else if (info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Can't check out an old version of a document");
 | 
						|
        }
 | 
						|
        else {   
 | 
						|
            throw new CmisInvalidArgumentException("Only documents can be checked out! Object was a " + info.getObjectVariant().toString());
 | 
						|
        }
 | 
						|
 | 
						|
        // get object
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        if (!((DocumentTypeDefinition) info.getType().getTypeDefinition(false)).isVersionable())
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Document is not versionable!");
 | 
						|
        }
 | 
						|
        
 | 
						|
        // check out
 | 
						|
        NodeRef pwcNodeRef = connector.getCheckOutCheckInService().checkout(nodeRef);
 | 
						|
        CMISNodeInfo pwcNodeInfo = createNodeInfo(pwcNodeRef);
 | 
						|
        objectId.setValue(pwcNodeInfo.getObjectId());
 | 
						|
 | 
						|
        if (contentCopied != null)
 | 
						|
        {
 | 
						|
            contentCopied.setValue(connector.getFileFolderService().getReader(pwcNodeRef) != null);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void cancelCheckOut(String repositoryId, String objectId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
        
 | 
						|
        // only accept a PWC
 | 
						|
        if (!info.isVariant(CMISObjectVariant.PWC))
 | 
						|
        {
 | 
						|
            NodeRef nodeRef = info.getNodeRef();
 | 
						|
            NodeRef workingCopyNodeRef = connector.getCheckOutCheckInService().getWorkingCopy(nodeRef);
 | 
						|
            info = getOrCreateNodeInfo(workingCopyNodeRef.getId());
 | 
						|
            if (!info.isVariant(CMISObjectVariant.PWC))
 | 
						|
            {
 | 
						|
                throw new CmisVersioningException("Object is not a PWC!");
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // get object
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        // cancel check out
 | 
						|
        connector.getCheckOutCheckInService().cancelCheckout(nodeRef);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void checkIn(
 | 
						|
            String repositoryId, final Holder<String> objectId, final Boolean major,
 | 
						|
            final Properties properties, final ContentStream contentStream, final String checkinComment,
 | 
						|
            final List<String> policies, final Acl addAces, final Acl removeAces, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
 | 
						|
 | 
						|
        // only accept a PWC
 | 
						|
        if (!info.isVariant(CMISObjectVariant.PWC))
 | 
						|
        {
 | 
						|
            throw new CmisVersioningException("Object is not a PWC!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get object
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
        final TypeDefinitionWrapper type = info.getType();
 | 
						|
 | 
						|
        // copy stream to temp file
 | 
						|
        final File tempFile = copyToTempFile(contentStream);
 | 
						|
        final Charset encoding = (tempFile == null ? null : getEncoding(tempFile, contentStream.getMimeType()));
 | 
						|
 | 
						|
        // check in
 | 
						|
        // update PWC
 | 
						|
        connector.setProperties(nodeRef, type, properties,
 | 
						|
                new String[] { PropertyIds.OBJECT_TYPE_ID });
 | 
						|
        connector.applyPolicies(nodeRef, type, policies);
 | 
						|
        connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
 | 
						|
        // handle content
 | 
						|
        if (contentStream != null)
 | 
						|
        {
 | 
						|
            // write content
 | 
						|
            ContentWriter writer = connector.getFileFolderService().getWriter(nodeRef);
 | 
						|
            writer.setMimetype(parseMimeType(contentStream));
 | 
						|
            writer.setEncoding(encoding.name());
 | 
						|
            writer.putContent(tempFile);
 | 
						|
        }
 | 
						|
 | 
						|
        // create version properties
 | 
						|
        Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(5);
 | 
						|
        versionProperties.put(VersionModel.PROP_VERSION_TYPE, major ? VersionType.MAJOR
 | 
						|
                : VersionType.MINOR);
 | 
						|
        if (checkinComment != null)
 | 
						|
        {
 | 
						|
            versionProperties.put(VersionModel.PROP_DESCRIPTION, checkinComment);
 | 
						|
        }
 | 
						|
 | 
						|
        // check in
 | 
						|
        NodeRef newNodeRef = connector.getCheckOutCheckInService().checkin(nodeRef, versionProperties);
 | 
						|
 | 
						|
        connector.getActivityPoster().postFileFolderUpdated(info.isFolder(), newNodeRef);
 | 
						|
 | 
						|
        objectId.setValue(connector.createObjectId(newNodeRef));
 | 
						|
        
 | 
						|
        removeTempFile(tempFile);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<ObjectData> getAllVersions(
 | 
						|
            String repositoryId, String objectId, String versionSeriesId, String filter,
 | 
						|
            Boolean includeAllowableActions, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (versionSeriesId == null && objectId != null)
 | 
						|
        {
 | 
						|
            // it's a browser binding call
 | 
						|
            versionSeriesId = connector.getCurrentVersionId(objectId);
 | 
						|
        }
 | 
						|
 | 
						|
        if (versionSeriesId == null)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object Id or Object Series Id must be set!");
 | 
						|
        }
 | 
						|
 | 
						|
        List<ObjectData> result = new ArrayList<ObjectData>();
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId);
 | 
						|
 | 
						|
        // when webservices binding is used, objectId points to null and versionSeriesId points to original node instead of PWC
 | 
						|
        // see MNT-13839
 | 
						|
        if (objectId == null)
 | 
						|
        {
 | 
						|
            info = getOrCreateNodeInfo(versionSeriesId);
 | 
						|
            if (info.hasPWC())
 | 
						|
            {
 | 
						|
                NodeRef nodeRef = info.getNodeRef();
 | 
						|
                info = getOrCreateNodeInfo(connector.getCheckOutCheckInService().getWorkingCopy(nodeRef).toString());
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (!EnumSet.of(CMISObjectVariant.CURRENT_VERSION, CMISObjectVariant.PWC, CMISObjectVariant.VERSION).contains(info.getObjectVariant()))
 | 
						|
        {
 | 
						|
            // the version series id is the id of current version, which is a
 | 
						|
            // document
 | 
						|
            throw new CmisInvalidArgumentException("Version Series does not exist!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get current version and it's history
 | 
						|
        NodeRef nodeRef = info.getNodeRef();
 | 
						|
        VersionHistory versionHistory = ((CMISNodeInfoImpl) info).getVersionHistory();
 | 
						|
 | 
						|
        if (versionHistory == null || info.isPWC())
 | 
						|
        {
 | 
						|
            // add current version
 | 
						|
            result.add(connector.createCMISObject(info, filter, includeAllowableActions, IncludeRelationships.NONE,
 | 
						|
                    CMISConnector.RENDITION_NONE, false, false));
 | 
						|
 | 
						|
        	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
            if (isObjectInfoRequired)
 | 
						|
            {
 | 
						|
                getObjectInfo(repositoryId, info.getObjectId(), IncludeRelationships.NONE);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (info.hasPWC())
 | 
						|
            {
 | 
						|
                CMISNodeInfo pwcInfo = createNodeInfo(connector.getCheckOutCheckInService().getWorkingCopy(nodeRef));
 | 
						|
 | 
						|
                result.add(
 | 
						|
                        connector.createCMISObject(
 | 
						|
                                pwcInfo, filter, includeAllowableActions,
 | 
						|
                                IncludeRelationships.NONE, CMISConnector.RENDITION_NONE, false, false));
 | 
						|
 | 
						|
                boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, pwcInfo.getObjectId(), IncludeRelationships.NONE);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            // convert the version history
 | 
						|
            for (Version version : versionHistory.getAllVersions())
 | 
						|
            {
 | 
						|
                CMISNodeInfo versionInfo = createNodeInfo(version.getFrozenStateNodeRef(), versionHistory);
 | 
						|
                // MNT-9557 fix. Replace head version with current node info
 | 
						|
                if (versionHistory.getHeadVersion().equals(version))
 | 
						|
                {
 | 
						|
                    versionInfo = createNodeInfo(info.getCurrentNodeNodeRef());
 | 
						|
                }
 | 
						|
 | 
						|
                result.add(
 | 
						|
                        connector.createCMISObject(
 | 
						|
                                versionInfo, filter, includeAllowableActions,
 | 
						|
                                IncludeRelationships.NONE, CMISConnector.RENDITION_NONE, false, false));
 | 
						|
 | 
						|
            	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
                if (isObjectInfoRequired)
 | 
						|
                {
 | 
						|
                    getObjectInfo(repositoryId, versionInfo.getObjectId(), IncludeRelationships.NONE);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectData getObjectOfLatestVersion(
 | 
						|
            String repositoryId, String objectId, String versionSeriesId,
 | 
						|
            Boolean major, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
 | 
						|
            String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (objectId != null)
 | 
						|
        {
 | 
						|
            // it's an AtomPub call
 | 
						|
            versionSeriesId = connector.getCurrentVersionId(objectId);
 | 
						|
        }
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(versionSeriesId, "Version Series");
 | 
						|
        CMISNodeInfo versionInfo = createNodeInfo(((CMISNodeInfoImpl) info).getLatestVersionNodeRef(major));
 | 
						|
 | 
						|
        ObjectData object = connector.createCMISObject(
 | 
						|
                versionInfo, filter, includeAllowableActions,
 | 
						|
                includeRelationships, renditionFilter, includePolicyIds, includeAcl);
 | 
						|
 | 
						|
    	boolean isObjectInfoRequired = getContext().isObjectInfoRequired();
 | 
						|
        if (isObjectInfoRequired)
 | 
						|
        {
 | 
						|
            getObjectInfo(repositoryId, info.getObjectId(), includeRelationships);
 | 
						|
        }
 | 
						|
 | 
						|
        return object;
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public Properties getPropertiesOfLatestVersion(
 | 
						|
            String repositoryId, String objectId, String versionSeriesId,
 | 
						|
            Boolean major, String filter, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (objectId != null)
 | 
						|
        {
 | 
						|
            // it's an AtomPub call
 | 
						|
            versionSeriesId = connector.getCurrentVersionId(objectId);
 | 
						|
        }
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(versionSeriesId, "Version Series");
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            return connector.getAssocProperties(info, filter);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            CMISNodeInfo versionInfo = createNodeInfo(((CMISNodeInfoImpl) info).getLatestVersionNodeRef(major));
 | 
						|
            addNodeInfo(versionInfo);
 | 
						|
            return connector.getNodeProperties(versionInfo, filter);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // --- multifiling service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void addObjectToFolder(
 | 
						|
            String repositoryId, String objectId, String folderId, Boolean allVersions,
 | 
						|
            ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (!allVersions)
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Only allVersions=true supported!");
 | 
						|
        }
 | 
						|
 | 
						|
        // get node ref
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        if (!info.isDocument())
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object is not a document!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        // get the folder node ref
 | 
						|
        final CMISNodeInfo folderInfo = getOrCreateFolderInfo(folderId, "Folder");
 | 
						|
 | 
						|
        connector.checkChildObjectType(folderInfo, info.getType().getTypeId());
 | 
						|
 | 
						|
        final QName name = QName.createQName(
 | 
						|
                NamespaceService.CONTENT_MODEL_1_0_URI,
 | 
						|
                QName.createValidLocalName((String) connector.getNodeService().getProperty(nodeRef,
 | 
						|
                        ContentModel.PROP_NAME)));
 | 
						|
 | 
						|
        connector.getNodeService().addChild(
 | 
						|
                folderInfo.getNodeRef(), nodeRef, ContentModel.ASSOC_CONTAINS, name);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // get node ref
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        if (!info.isDocument())
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object is not a document!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getNodeRef();
 | 
						|
 | 
						|
        // get the folder node ref
 | 
						|
        final NodeRef folderNodeRef = getOrCreateFolderInfo(folderId, "Folder").getNodeRef();
 | 
						|
 | 
						|
        // check primary parent
 | 
						|
        if (connector.getNodeService().getPrimaryParent(nodeRef).getParentRef().equals(folderNodeRef))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException(
 | 
						|
                    "Unfiling from primary parent folder is not supported! Use deleteObject() instead.");
 | 
						|
        }
 | 
						|
 | 
						|
        connector.getNodeService().removeChild(folderNodeRef, nodeRef);
 | 
						|
    }
 | 
						|
 | 
						|
    // --- discovery service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectList getContentChanges(
 | 
						|
            String repositoryId, Holder<String> changeLogToken, Boolean includeProperties,
 | 
						|
            String filter, Boolean includePolicyIds, Boolean includeAcl, BigInteger maxItems, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        return connector.getContentChanges(changeLogToken, maxItems);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectList query(String repositoryId, String statement, Boolean searchAllVersions,
 | 
						|
            Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
 | 
						|
            BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        if (searchAllVersions.booleanValue())
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Search all version is not supported!");
 | 
						|
        }
 | 
						|
 | 
						|
        return connector.query(
 | 
						|
                statement, includeAllowableActions, includeRelationships, renditionFilter,
 | 
						|
                maxItems, skipCount);
 | 
						|
    }
 | 
						|
 | 
						|
    // --- relationship service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public ObjectList getObjectRelationships(
 | 
						|
            String repositoryId, String objectId, Boolean includeSubRelationshipTypes,
 | 
						|
            RelationshipDirection relationshipDirection, String typeId, String filter, Boolean includeAllowableActions,
 | 
						|
            BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object is a relationship!");
 | 
						|
        }
 | 
						|
 | 
						|
        if (info.isVariant(CMISObjectVariant.VERSION))
 | 
						|
        {
 | 
						|
            throw new CmisInvalidArgumentException("Object is a document version!");
 | 
						|
        }
 | 
						|
 | 
						|
        // check if the relationship base type is requested
 | 
						|
        if (BaseTypeId.CMIS_RELATIONSHIP.value().equals(typeId))
 | 
						|
        {
 | 
						|
            boolean isrt = (includeSubRelationshipTypes == null ? false : includeSubRelationshipTypes.booleanValue());
 | 
						|
            if (isrt)
 | 
						|
            {
 | 
						|
                // all relationships are a direct subtype of the base type in
 | 
						|
                // Alfresco -> remove filter
 | 
						|
                typeId = null;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                // there are no relationships of the base type in Alfresco ->
 | 
						|
                // return empty list
 | 
						|
                ObjectListImpl result = new ObjectListImpl();
 | 
						|
                result.setHasMoreItems(false);
 | 
						|
                result.setNumItems(BigInteger.ZERO);
 | 
						|
                result.setObjects(new ArrayList<ObjectData>());
 | 
						|
                return result;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return connector.getObjectRelationships(
 | 
						|
                info.getNodeRef(), relationshipDirection, typeId, filter, includeAllowableActions,
 | 
						|
                maxItems, skipCount);
 | 
						|
    }
 | 
						|
 | 
						|
    // --- policy service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void applyPolicy(String repositoryId, String policyId, String objectId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        TypeDefinitionWrapper type = info.getType();
 | 
						|
        if (type == null)
 | 
						|
        {
 | 
						|
            throw new CmisObjectNotFoundException("No corresponding type found! Not a CMIS object?");
 | 
						|
        }
 | 
						|
 | 
						|
        connector.applyPolicies(info.getNodeRef(), type, Collections.singletonList(policyId));
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void removePolicy(String repositoryId, String policyId, String objectId, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        TypeDefinitionWrapper type = info.getType();
 | 
						|
        if (type == null)
 | 
						|
        {
 | 
						|
            throw new CmisObjectNotFoundException("No corresponding type found! Not a CMIS object?");
 | 
						|
        }
 | 
						|
 | 
						|
        throw new CmisConstraintException("Object is not policy controllable!");
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public List<ObjectData> getAppliedPolicies(
 | 
						|
            String repositoryId, String objectId, String filter, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // what kind of object is it?
 | 
						|
        getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // policies are not supported -> return empty list
 | 
						|
        return Collections.emptyList();
 | 
						|
    }
 | 
						|
 | 
						|
    // --- ACL service ---
 | 
						|
 | 
						|
    @Override
 | 
						|
    public Acl applyAcl(
 | 
						|
            String repositoryId, String objectId, final Acl addAces, final Acl removeAces,
 | 
						|
            AclPropagation aclPropagation, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // We are spec compliant if we just let it through and the tck will not fail
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // relationships don't have ACLs
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not ACL controllable!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getCurrentNodeNodeRef();
 | 
						|
        final TypeDefinitionWrapper type = info.getType();
 | 
						|
 | 
						|
        connector.applyACL(nodeRef, type, addAces, removeAces);
 | 
						|
 | 
						|
        return connector.getACL(nodeRef, false);
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public Acl applyAcl(String repositoryId, String objectId, final Acl aces, AclPropagation aclPropagation)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        // We are spec compliant if we just let it through and the tck will not fail
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // relationships don't have ACLs
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            throw new CmisConstraintException("Relationships are not ACL controllable!");
 | 
						|
        }
 | 
						|
 | 
						|
        final NodeRef nodeRef = info.getCurrentNodeNodeRef();
 | 
						|
        final TypeDefinitionWrapper type = info.getType();
 | 
						|
 | 
						|
        connector.applyACL(nodeRef, type, aces);
 | 
						|
 | 
						|
        return connector.getACL(nodeRef, false);
 | 
						|
    }
 | 
						|
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
    @Override
 | 
						|
    public Acl getAcl(String repositoryId, String objectId, Boolean onlyBasicPermissions, ExtensionsData extension)
 | 
						|
    {
 | 
						|
        checkRepositoryId(repositoryId);
 | 
						|
 | 
						|
        CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
 | 
						|
 | 
						|
        // relationships don't have ACLs
 | 
						|
        if (info.isVariant(CMISObjectVariant.ASSOC))
 | 
						|
        {
 | 
						|
            return new AccessControlListImpl(Collections.EMPTY_LIST);
 | 
						|
        }
 | 
						|
 | 
						|
        // get the ACL
 | 
						|
        return connector.getACL(info.getCurrentNodeNodeRef(), onlyBasicPermissions);
 | 
						|
    }
 | 
						|
 | 
						|
    // --------------------------------------------------------
 | 
						|
 | 
						|
    /**
 | 
						|
     * Collects the {@link ObjectInfo} about an object.
 | 
						|
     * 
 | 
						|
     * (Provided by OpenCMIS, but optimized for Alfresco.)
 | 
						|
     */
 | 
						|
    @Override
 | 
						|
    public ObjectInfo getObjectInfo(String repositoryId, String objectId)
 | 
						|
    {
 | 
						|
        return getObjectInfo(repositoryId, objectId, null, IncludeRelationships.BOTH);
 | 
						|
    }
 | 
						|
 | 
						|
    protected ObjectInfo getObjectInfo(String repositoryId, String objectId, IncludeRelationships includeRelationships)
 | 
						|
    {
 | 
						|
        return getObjectInfo(repositoryId, objectId, null, includeRelationships);
 | 
						|
    }
 | 
						|
 | 
						|
    protected ObjectInfo getObjectInfo(
 | 
						|
            String repositoryId, String objectId, String filter,
 | 
						|
            IncludeRelationships includeRelationships)
 | 
						|
    {
 | 
						|
        ObjectInfo info = objectInfoMap.get(objectId);
 | 
						|
        if (info == null)
 | 
						|
        {
 | 
						|
            CMISNodeInfo nodeInfo = getOrCreateNodeInfo(objectId);
 | 
						|
 | 
						|
            if (nodeInfo.getObjectVariant() == CMISObjectVariant.INVALID_ID
 | 
						|
                    || nodeInfo.getObjectVariant() == CMISObjectVariant.NOT_EXISTING
 | 
						|
                    || nodeInfo.getObjectVariant() == CMISObjectVariant.NOT_A_CMIS_OBJECT
 | 
						|
                    || nodeInfo.getObjectVariant() == CMISObjectVariant.PERMISSION_DENIED)
 | 
						|
            {
 | 
						|
                info = null;
 | 
						|
            } else
 | 
						|
            {
 | 
						|
                // object info has not been found -> create one
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    if (filter == null)
 | 
						|
                    {
 | 
						|
                        filter = MIN_FILTER;
 | 
						|
                    }
 | 
						|
                    else if (!filter.equals("*"))
 | 
						|
                    {
 | 
						|
                        filter = filter + "," + MIN_FILTER;
 | 
						|
                    }
 | 
						|
 | 
						|
                    // get the object and its info
 | 
						|
                    ObjectData object = connector.createCMISObject(
 | 
						|
                            nodeInfo, filter, false, includeRelationships, null, false, false);
 | 
						|
 | 
						|
                    info = getObjectInfoIntern(repositoryId, object);
 | 
						|
 | 
						|
                    // add object info
 | 
						|
                    objectInfoMap.put(objectId, info);
 | 
						|
                }
 | 
						|
                catch (Exception e)
 | 
						|
                {
 | 
						|
                    e.printStackTrace();
 | 
						|
                    info = null;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return info;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Collects the {@link ObjectInfo} about an object.
 | 
						|
     * 
 | 
						|
     * (Provided by OpenCMIS, but optimized for Alfresco.)
 | 
						|
     */
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
	@Override
 | 
						|
    protected ObjectInfo getObjectInfoIntern(String repositoryId, ObjectData object)
 | 
						|
    {
 | 
						|
        // if the object has no properties, stop here
 | 
						|
        if (object.getProperties() == null || object.getProperties().getProperties() == null)
 | 
						|
        {
 | 
						|
            throw new CmisRuntimeException("No properties!");
 | 
						|
        }
 | 
						|
 | 
						|
        CMISNodeInfo ni = getOrCreateNodeInfo(object.getId());
 | 
						|
 | 
						|
        ObjectInfoImpl info = new ObjectInfoImpl();
 | 
						|
 | 
						|
        // general properties
 | 
						|
        info.setObject(object);
 | 
						|
        info.setId(object.getId());
 | 
						|
        info.setName(ni.getName());
 | 
						|
        info.setCreatedBy(getStringProperty(object, PropertyIds.CREATED_BY));
 | 
						|
        info.setCreationDate(getDateTimeProperty(object, PropertyIds.CREATION_DATE));
 | 
						|
        info.setLastModificationDate(getDateTimeProperty(object, PropertyIds.LAST_MODIFICATION_DATE));
 | 
						|
        info.setTypeId(getIdProperty(object, PropertyIds.OBJECT_TYPE_ID));
 | 
						|
        info.setBaseType(object.getBaseTypeId());
 | 
						|
 | 
						|
        if (ni.isRelationship())
 | 
						|
        {
 | 
						|
            // versioning
 | 
						|
            info.setWorkingCopyId(null);
 | 
						|
            info.setWorkingCopyOriginalId(null);
 | 
						|
 | 
						|
            info.setVersionSeriesId(null);
 | 
						|
            info.setIsCurrentVersion(true);
 | 
						|
            info.setWorkingCopyId(null);
 | 
						|
            info.setWorkingCopyOriginalId(null);
 | 
						|
 | 
						|
            // content
 | 
						|
            info.setHasContent(false);
 | 
						|
            info.setContentType(null);
 | 
						|
            info.setFileName(null);
 | 
						|
 | 
						|
            // parent
 | 
						|
            info.setHasParent(false);
 | 
						|
 | 
						|
            // policies and relationships
 | 
						|
            info.setSupportsRelationships(false);
 | 
						|
            info.setSupportsPolicies(false);
 | 
						|
 | 
						|
            // renditions
 | 
						|
            info.setRenditionInfos(null);
 | 
						|
 | 
						|
            // relationships
 | 
						|
            info.setRelationshipSourceIds(null);
 | 
						|
            info.setRelationshipTargetIds(null);
 | 
						|
 | 
						|
            // global settings
 | 
						|
            info.setHasAcl(false);
 | 
						|
            info.setSupportsDescendants(false);
 | 
						|
            info.setSupportsFolderTree(false);
 | 
						|
        }
 | 
						|
        else if (ni.isFolder())
 | 
						|
        {
 | 
						|
            // versioning
 | 
						|
            info.setWorkingCopyId(null);
 | 
						|
            info.setWorkingCopyOriginalId(null);
 | 
						|
 | 
						|
            info.setVersionSeriesId(null);
 | 
						|
            info.setIsCurrentVersion(true);
 | 
						|
            info.setWorkingCopyId(null);
 | 
						|
            info.setWorkingCopyOriginalId(null);
 | 
						|
 | 
						|
            // content
 | 
						|
            info.setHasContent(false);
 | 
						|
            info.setContentType(null);
 | 
						|
            info.setFileName(null);
 | 
						|
 | 
						|
            // parent
 | 
						|
            info.setHasParent(!ni.isRootFolder());
 | 
						|
 | 
						|
            // policies and relationships
 | 
						|
            info.setSupportsRelationships(true);
 | 
						|
            info.setSupportsPolicies(true);
 | 
						|
 | 
						|
            // renditions
 | 
						|
            info.setRenditionInfos(null);
 | 
						|
 | 
						|
            // relationships
 | 
						|
            setRelaionshipsToObjectInfo(object, info);
 | 
						|
 | 
						|
            // global settings
 | 
						|
            info.setHasAcl(true);
 | 
						|
            info.setSupportsDescendants(true);
 | 
						|
            info.setSupportsFolderTree(true);
 | 
						|
        }
 | 
						|
        else if (ni.isDocument())
 | 
						|
        {
 | 
						|
            // versioning
 | 
						|
            info.setWorkingCopyId(null);
 | 
						|
            info.setWorkingCopyOriginalId(null);
 | 
						|
 | 
						|
            info.setVersionSeriesId(ni.getCurrentNodeId());
 | 
						|
 | 
						|
            if (ni.isPWC())
 | 
						|
            {
 | 
						|
                info.setIsCurrentVersion(false);
 | 
						|
                info.setWorkingCopyId(ni.getObjectId());
 | 
						|
                info.setWorkingCopyOriginalId(ni.getCurrentObjectId());
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                info.setIsCurrentVersion(ni.isCurrentVersion());
 | 
						|
 | 
						|
                if (ni.hasPWC())
 | 
						|
                {
 | 
						|
                    info.setWorkingCopyId(ni.getCurrentNodeId() + CMISConnector.ID_SEPERATOR
 | 
						|
                            + CMISConnector.PWC_VERSION_LABEL);
 | 
						|
                    info.setWorkingCopyOriginalId(ni.getCurrentObjectId());
 | 
						|
                } else
 | 
						|
                {
 | 
						|
                    info.setWorkingCopyId(null);
 | 
						|
                    info.setWorkingCopyOriginalId(null);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            // content
 | 
						|
            String fileName = getStringProperty(object, PropertyIds.CONTENT_STREAM_FILE_NAME);
 | 
						|
            String mimeType = getStringProperty(object, PropertyIds.CONTENT_STREAM_MIME_TYPE);
 | 
						|
            String streamId = getIdProperty(object, PropertyIds.CONTENT_STREAM_ID);
 | 
						|
            BigInteger length = getIntegerProperty(object, PropertyIds.CONTENT_STREAM_LENGTH);
 | 
						|
            boolean hasContent = fileName != null || mimeType != null || streamId != null || length != null;
 | 
						|
            if (hasContent)
 | 
						|
            {
 | 
						|
                info.setHasContent(hasContent);
 | 
						|
                info.setContentType(mimeType);
 | 
						|
                info.setFileName(fileName);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                info.setHasContent(false);
 | 
						|
                info.setContentType(null);
 | 
						|
                info.setFileName(null);
 | 
						|
            }
 | 
						|
 | 
						|
            // parent
 | 
						|
            info.setHasParent(ni.isCurrentVersion() || ni.isPWC());
 | 
						|
 | 
						|
            // policies and relationships
 | 
						|
            info.setSupportsRelationships(true);
 | 
						|
            info.setSupportsPolicies(true);
 | 
						|
 | 
						|
            // renditions
 | 
						|
            info.setRenditionInfos(null);
 | 
						|
            List<RenditionData> renditions = object.getRenditions();
 | 
						|
            if (renditions != null && renditions.size() > 0)
 | 
						|
            {
 | 
						|
                List<RenditionInfo> renditionInfos = new ArrayList<RenditionInfo>();
 | 
						|
                for (RenditionData rendition : renditions)
 | 
						|
                {
 | 
						|
                    RenditionInfoImpl renditionInfo = new RenditionInfoImpl();
 | 
						|
                    renditionInfo.setId(rendition.getStreamId());
 | 
						|
                    renditionInfo.setKind(rendition.getKind());
 | 
						|
                    renditionInfo.setContentType(rendition.getMimeType());
 | 
						|
                    renditionInfo.setTitle(rendition.getTitle());
 | 
						|
                    renditionInfo.setLength(rendition.getBigLength());
 | 
						|
                    renditionInfos.add(renditionInfo);
 | 
						|
                }
 | 
						|
                info.setRenditionInfos(renditionInfos);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
            	info.setRenditionInfos(Collections.EMPTY_LIST);
 | 
						|
            }
 | 
						|
 | 
						|
            // relationships
 | 
						|
            setRelaionshipsToObjectInfo(object, info);
 | 
						|
 | 
						|
            // global settings
 | 
						|
            info.setHasAcl(true);
 | 
						|
            info.setSupportsDescendants(true);
 | 
						|
            info.setSupportsFolderTree(true);
 | 
						|
        }
 | 
						|
        else if (ni.isItem())
 | 
						|
        {
 | 
						|
        	info.setHasAcl(true);
 | 
						|
        	info.setHasContent(false);        	
 | 
						|
        }
 | 
						|
 | 
						|
        return info;
 | 
						|
    }
 | 
						|
 | 
						|
    private void setRelaionshipsToObjectInfo(ObjectData object, ObjectInfoImpl info)
 | 
						|
    {
 | 
						|
        info.setRelationshipSourceIds(null);
 | 
						|
        info.setRelationshipTargetIds(null);
 | 
						|
 | 
						|
        List<ObjectData> relationships = object.getRelationships();
 | 
						|
        if (relationships != null && relationships.size() > 0)
 | 
						|
        {
 | 
						|
            List<String> sourceIds = new ArrayList<String>();
 | 
						|
            List<String> targetIds = new ArrayList<String>();
 | 
						|
            for (ObjectData relationship : relationships)
 | 
						|
            {
 | 
						|
                String sourceId = getIdProperty(relationship, PropertyIds.SOURCE_ID);
 | 
						|
                String targetId = getIdProperty(relationship, PropertyIds.TARGET_ID);
 | 
						|
                if (object.getId().equals(sourceId))
 | 
						|
                {
 | 
						|
                    sourceIds.add(relationship.getId());
 | 
						|
                }
 | 
						|
                if (object.getId().equals(targetId))
 | 
						|
                {
 | 
						|
                    targetIds.add(relationship.getId());
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (sourceIds.size() > 0)
 | 
						|
            {
 | 
						|
                info.setRelationshipSourceIds(sourceIds);
 | 
						|
            }
 | 
						|
            if (targetIds.size() > 0)
 | 
						|
            {
 | 
						|
                info.setRelationshipTargetIds(targetIds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // --------------------------------------------------------
 | 
						|
 | 
						|
    protected void checkRepositoryId(String repositoryId)
 | 
						|
    {
 | 
						|
        if (!connector.getRepositoryId().equals(repositoryId))
 | 
						|
        {
 | 
						|
            throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private Charset getEncoding(File tempFile, String mimeType)
 | 
						|
    {
 | 
						|
        Charset encoding = null;
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
            InputStream tfis = new BufferedInputStream(new FileInputStream(tempFile));
 | 
						|
            ContentCharsetFinder charsetFinder = connector.getMimetypeService().getContentCharsetFinder();
 | 
						|
            encoding = charsetFinder.getCharset(tfis, mimeType);
 | 
						|
            tfis.close();
 | 
						|
        } catch (Exception e)
 | 
						|
        {
 | 
						|
            throw new CmisStorageException("Unable to read content: " + e.getMessage(), e);
 | 
						|
        }
 | 
						|
 | 
						|
        return encoding;
 | 
						|
    }
 | 
						|
 | 
						|
    private File copyToTempFile(ContentStream contentStream)
 | 
						|
    {
 | 
						|
        if (contentStream == null)
 | 
						|
        {
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
 | 
						|
        File result = null;
 | 
						|
        try
 | 
						|
        {
 | 
						|
            result = TempFileProvider.createTempFile(contentStream.getStream(), "cmis", "content");
 | 
						|
        }
 | 
						|
        catch (Exception e)
 | 
						|
        {
 | 
						|
            throw new CmisStorageException("Unable to store content: " + e.getMessage(), e);
 | 
						|
        }
 | 
						|
 | 
						|
        if ((contentStream.getLength() > -1) && (result == null || contentStream.getLength() != result.length()))
 | 
						|
        {
 | 
						|
            removeTempFile(result);
 | 
						|
            throw new CmisStorageException("Expected " + contentStream.getLength() + " bytes but retrieved " +
 | 
						|
                    (result == null ? -1 :result.length()) + " bytes!");
 | 
						|
        }
 | 
						|
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    private void removeTempFile(File tempFile)
 | 
						|
    {
 | 
						|
        if (tempFile == null)
 | 
						|
        {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        try
 | 
						|
        {
 | 
						|
            tempFile.delete();
 | 
						|
        }
 | 
						|
        catch (Exception e)
 | 
						|
        {
 | 
						|
            // ignore - file will be removed by TempFileProvider
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void beforeCall()
 | 
						|
    {
 | 
						|
        AuthenticationUtil.pushAuthentication();
 | 
						|
        if (authentication != null)
 | 
						|
        {
 | 
						|
            // Use the previously-obtained authentication
 | 
						|
            AuthenticationUtil.setFullAuthentication(authentication);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
        	CallContext context = getContext();
 | 
						|
            if (context == null)
 | 
						|
            {
 | 
						|
                // Service not opened, yet
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            // Sticky sessions?
 | 
						|
            if (connector.openHttpSession())
 | 
						|
            {
 | 
						|
                // create a session -> set a cookie
 | 
						|
                // if the CMIS client supports cookies that might help in clustered environments
 | 
						|
                ((HttpServletRequest)context.get(CallContext.HTTP_SERVLET_REQUEST)).getSession();
 | 
						|
            }
 | 
						|
            
 | 
						|
            // Authenticate
 | 
						|
            if (authentication != null)
 | 
						|
            {
 | 
						|
                // We have already authenticated; just reuse the authentication
 | 
						|
                AuthenticationUtil.setFullAuthentication(authentication);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                // First check if we already are authenticated
 | 
						|
                if (AuthenticationUtil.getFullyAuthenticatedUser() == null)
 | 
						|
                {
 | 
						|
                    // We have to go to the repo and authenticate
 | 
						|
                    String user = context.getUsername();
 | 
						|
                    String password = context.getPassword();
 | 
						|
                    Authorization auth = new Authorization(user, password);
 | 
						|
                    if (auth.isTicket())
 | 
						|
                    {
 | 
						|
                        connector.getAuthenticationService().validate(auth.getTicket());
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        connector.getAuthenticationService().authenticate(auth.getUserName(), auth.getPasswordCharArray());
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                this.authentication = AuthenticationUtil.getFullAuthentication();
 | 
						|
            }
 | 
						|
            
 | 
						|
//            // TODO: How is the proxy user working.
 | 
						|
//            //       Until we know what it is meant to do, it's not available
 | 
						|
//            String currentUser = connector.getAuthenticationService().getCurrentUserName();
 | 
						|
//            String user = getContext().getUsername();
 | 
						|
//            String password = getContext().getPassword();
 | 
						|
//            if (currentUser != null && currentUser.equals(connector.getProxyUser()))
 | 
						|
//            {
 | 
						|
//                if (user != null && user.length() > 0)
 | 
						|
//                {
 | 
						|
//                    AuthenticationUtil.setFullyAuthenticatedUser(user);
 | 
						|
//                }
 | 
						|
//            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @Override
 | 
						|
    public void afterCall()
 | 
						|
    {
 | 
						|
        AuthenticationUtil.popAuthentication();
 | 
						|
    }
 | 
						|
}
 |