mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	.externalToolBuilders
config
source
cpp
java
org
alfresco
email
filesys
jcr
linkvalidation
model
repo
action
admin
attributes
audit
avm
blogIntegration
cache
clt
coci
config
configuration
content
copy
CopyServiceImpl.java
CopyServiceImplTest.java
CopyServicePolicies.java
CrossRepositoryCopyServiceImpl.java
deploy
descriptor
dictionary
domain
exporter
forum
i18n
importer
jscript
lock
model
module
node
ownable
policy
processor
remote
rule
search
security
service
template
tenant
transaction
usage
version
workflow
sandbox
service
tools
util
apache
queryRegister.dtd
meta-inf
test-resources
web
.classpath
.project
build.xml
6636: Temporary hack to fix build. 6637: Better handling of binary string bufs, disable link validation when poll interval is <= 0 6638: Forgotten files for TXT to PDF transformer. 6639: Fix for AWC-1541 6641: Fix for WCM-792. 6642: A little extra PropertyValue support for createNode, too. 6643: Fix for WCM-791 6644: Closure of AR-1528: Check concurrency handling of DuplicateChildNodeNameException 6647: Fix WCM-794 6648: WCM-656 6650: Applied user supplied patch to fix AWC-1546 - Cannot mount AVM using CIFS on new alfresco installation. 6651: Index tidy ups 6654: Various minor updates for passthru authentication debugging and error handling. 6657: Fix for WCM-799 (Some items selected for submission were not present) 6659: Updated installers. 6660: Partial fix to AWC-1524 6661: Fix WCM-803 6664: Including hibernate-3.2.1.jar in $VIRTUAL_TOMCAT_HOME/server/lib/ 6665: adding an automated unit test for output path patterns. 6668: Fixed to add shale-test-1.0.4.jar to Eclipse classpath (PHH oked) 6681: Fixes WCM-811 - Lookup.getIndirectionPath() had a bit of a howler in it. 6684: UncategorizedSQLException with the word 'deadlock' in the message is now cause for retrying a transaction. 6691: Fix for WCM-813 (lock not removed when expiration date set and no workflow on web project) 6696: Imporved SSO filters for SiteMinder etc + test filter 6697: Support for scheduled import 6699: Fix for the compliation target: compile-benchmarkframework 6701: Fix for 1.6 JVMs (1.5 gets by with lucky ordering) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6749 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
			
				
	
	
		
			391 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			391 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
/**
 | 
						|
 * 
 | 
						|
 */
 | 
						|
package org.alfresco.repo.copy;
 | 
						|
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.OutputStream;
 | 
						|
import java.io.Serializable;
 | 
						|
import java.util.HashMap;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
import java.util.Set;
 | 
						|
 | 
						|
import org.alfresco.error.AlfrescoRuntimeException;
 | 
						|
import org.alfresco.model.ContentModel;
 | 
						|
import org.alfresco.repo.avm.AVMNodeConverter;
 | 
						|
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
 | 
						|
import org.alfresco.service.cmr.avm.AVMService;
 | 
						|
import org.alfresco.service.cmr.dictionary.DictionaryService;
 | 
						|
import org.alfresco.service.cmr.model.FileFolderService;
 | 
						|
import org.alfresco.service.cmr.model.FileInfo;
 | 
						|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
 | 
						|
import org.alfresco.service.cmr.repository.ContentData;
 | 
						|
import org.alfresco.service.cmr.repository.ContentReader;
 | 
						|
import org.alfresco.service.cmr.repository.ContentService;
 | 
						|
import org.alfresco.service.cmr.repository.ContentWriter;
 | 
						|
import org.alfresco.service.cmr.repository.CopyService;
 | 
						|
import org.alfresco.service.cmr.repository.CrossRepositoryCopyService;
 | 
						|
import org.alfresco.service.cmr.repository.NodeRef;
 | 
						|
import org.alfresco.service.cmr.repository.NodeService;
 | 
						|
import org.alfresco.service.cmr.repository.StoreRef;
 | 
						|
import org.alfresco.service.namespace.QName;
 | 
						|
import org.alfresco.util.Pair;
 | 
						|
 | 
						|
/**
 | 
						|
 * Cross Repository Copying.
 | 
						|
 * 
 | 
						|
 * @author britt
 | 
						|
 */
 | 
						|
public class CrossRepositoryCopyServiceImpl implements CrossRepositoryCopyService
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * The NodeService reference.
 | 
						|
     */
 | 
						|
    private NodeService fNodeService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The FileFolderService reference.
 | 
						|
     */
 | 
						|
    private FileFolderService fFileFolderService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The regular CopyService reference.
 | 
						|
     */
 | 
						|
    private CopyService fCopyService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The AVMService.
 | 
						|
     */
 | 
						|
    private AVMService fAVMService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The ContentService.
 | 
						|
     */
 | 
						|
    private ContentService fContentService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The DictionaryService.
 | 
						|
     */
 | 
						|
    private DictionaryService fDictionaryService;
 | 
						|
 | 
						|
    /**
 | 
						|
     * A default constructor.
 | 
						|
     */
 | 
						|
    public CrossRepositoryCopyServiceImpl()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    // Setters for Spring.
 | 
						|
 | 
						|
    public void setAvmService(AVMService service)
 | 
						|
    {
 | 
						|
        fAVMService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setContentService(ContentService service)
 | 
						|
    {
 | 
						|
        fContentService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setCopyService(CopyService service)
 | 
						|
    {
 | 
						|
        fCopyService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setDictionaryService(DictionaryService service)
 | 
						|
    {
 | 
						|
        fDictionaryService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setFileFolderService(FileFolderService service)
 | 
						|
    {
 | 
						|
        fFileFolderService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setNodeService(NodeService service)
 | 
						|
    {
 | 
						|
        fNodeService = service;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This copies recursively src, which may be a container or a content type to dst, which must be a container. Copied
 | 
						|
     * nodes will have the copied from aspect applied to them.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            The node to copy.
 | 
						|
     * @param dst
 | 
						|
     *            The container to copy it into.
 | 
						|
     * @param name
 | 
						|
     *            The name to give the copy.
 | 
						|
     */
 | 
						|
    public void copy(NodeRef src, NodeRef dst, String name)
 | 
						|
    {
 | 
						|
        StoreRef srcStoreRef = src.getStoreRef();
 | 
						|
        StoreRef dstStoreRef = dst.getStoreRef();
 | 
						|
        if (srcStoreRef.getProtocol().equals(StoreRef.PROTOCOL_AVM))
 | 
						|
        {
 | 
						|
            if (dstStoreRef.getProtocol().equals(StoreRef.PROTOCOL_AVM))
 | 
						|
            {
 | 
						|
                copyAVMToAVM(src, dst, name);
 | 
						|
            }
 | 
						|
            else if (dstStoreRef.getProtocol().equals(StoreRef.PROTOCOL_WORKSPACE))
 | 
						|
            {
 | 
						|
                copyAVMToRepo(src, dst, name);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else if (srcStoreRef.getProtocol().equals(StoreRef.PROTOCOL_WORKSPACE))
 | 
						|
        {
 | 
						|
            if (dstStoreRef.getProtocol().equals(StoreRef.PROTOCOL_AVM))
 | 
						|
            {
 | 
						|
                copyRepoToAVM(src, dst, name);
 | 
						|
            }
 | 
						|
            else if (dstStoreRef.getProtocol().equals(StoreRef.PROTOCOL_WORKSPACE))
 | 
						|
            {
 | 
						|
                copyRepoToRepo(src, dst, name);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handle copying from AVM to AVM
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            Source node.
 | 
						|
     * @param dst
 | 
						|
     *            Destination directory node.
 | 
						|
     * @param name
 | 
						|
     *            Name to give copy.
 | 
						|
     */
 | 
						|
    private void copyAVMToAVM(NodeRef src, NodeRef dst, String name)
 | 
						|
    {
 | 
						|
        Pair<Integer, String> srcStorePath = AVMNodeConverter.ToAVMVersionPath(src);
 | 
						|
        Pair<Integer, String> dstStorePath = AVMNodeConverter.ToAVMVersionPath(dst);
 | 
						|
        fAVMService.copy(srcStorePath.getFirst(), srcStorePath.getSecond(), dstStorePath.getSecond(), name);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handle copying from AVM to Repo.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            Source node.
 | 
						|
     * @param dst
 | 
						|
     *            Destination Container.
 | 
						|
     * @param name
 | 
						|
     *            The name to give the copy.
 | 
						|
     */
 | 
						|
    private void copyAVMToRepo(NodeRef src, NodeRef dst, String name)
 | 
						|
    {
 | 
						|
        Pair<Integer, String> versionPath = AVMNodeConverter.ToAVMVersionPath(src);
 | 
						|
        AVMNodeDescriptor desc = fAVMService.lookup(versionPath.getFirst(), versionPath.getSecond());
 | 
						|
        NodeRef existing = fFileFolderService.searchSimple(dst, name);
 | 
						|
        if (desc.isFile())
 | 
						|
        {
 | 
						|
            if (existing != null && !fNodeService.getType(existing).equals(ContentModel.TYPE_CONTENT))
 | 
						|
            {
 | 
						|
                fFileFolderService.delete(existing);
 | 
						|
                existing = null;
 | 
						|
            }
 | 
						|
            NodeRef childRef = null;
 | 
						|
            if (existing == null)
 | 
						|
            {
 | 
						|
                childRef = fFileFolderService.create(dst, name, ContentModel.TYPE_CONTENT).getNodeRef();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                childRef = existing;
 | 
						|
            }
 | 
						|
            InputStream in = fAVMService.getFileInputStream(desc);
 | 
						|
            ContentData cd = fAVMService.getContentDataForRead(desc.getVersionID(), desc.getPath());
 | 
						|
            ContentWriter writer = fContentService.getWriter(childRef, ContentModel.PROP_CONTENT, true);
 | 
						|
            writer.setEncoding(cd.getEncoding());
 | 
						|
            writer.setMimetype(cd.getMimetype());
 | 
						|
            OutputStream out = writer.getContentOutputStream();
 | 
						|
            copyData(in, out);
 | 
						|
            copyPropsAndAspectsAVMToRepo(src, childRef);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (existing != null && !fNodeService.getType(existing).equals(ContentModel.TYPE_FOLDER))
 | 
						|
            {
 | 
						|
                fFileFolderService.delete(existing);
 | 
						|
                existing = null;
 | 
						|
            }
 | 
						|
            NodeRef childRef = null;
 | 
						|
            if (existing == null)
 | 
						|
            {
 | 
						|
                childRef = fFileFolderService.create(dst, name, ContentModel.TYPE_FOLDER).getNodeRef();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                childRef = existing;
 | 
						|
            }
 | 
						|
            copyPropsAndAspectsAVMToRepo(src, childRef);
 | 
						|
            Map<String, AVMNodeDescriptor> listing = fAVMService.getDirectoryListing(desc);
 | 
						|
            for (Map.Entry<String, AVMNodeDescriptor> entry : listing.entrySet())
 | 
						|
            {
 | 
						|
                NodeRef srcChild = AVMNodeConverter.ToNodeRef(versionPath.getFirst(), entry.getValue().getPath());
 | 
						|
                copyAVMToRepo(srcChild, childRef, entry.getKey());
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Helper that copies aspects and properties.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            The source AVM node.
 | 
						|
     * @param dst
 | 
						|
     *            The destination Repo node.
 | 
						|
     */
 | 
						|
    private void copyPropsAndAspectsAVMToRepo(NodeRef src, NodeRef dst)
 | 
						|
    {
 | 
						|
        Map<QName, Serializable> props = fNodeService.getProperties(src);
 | 
						|
        fNodeService.setProperties(dst, props);
 | 
						|
        Set<QName> aspects = fNodeService.getAspects(src);
 | 
						|
        Map<QName, Serializable> empty = new HashMap<QName, Serializable>();
 | 
						|
        for (QName aspect : aspects)
 | 
						|
        {
 | 
						|
            fNodeService.addAspect(dst, aspect, empty);
 | 
						|
        }
 | 
						|
        if (!fNodeService.hasAspect(dst, ContentModel.ASPECT_COPIEDFROM))
 | 
						|
        {
 | 
						|
            empty.put(ContentModel.PROP_COPY_REFERENCE, src);
 | 
						|
            fNodeService.addAspect(dst, ContentModel.ASPECT_COPIEDFROM, empty);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            fNodeService.setProperty(dst, ContentModel.PROP_COPY_REFERENCE, src);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handle copying from Repo to AVM.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            The source node.
 | 
						|
     * @param dst
 | 
						|
     *            The destingation directory.
 | 
						|
     * @param name
 | 
						|
     *            The name to give the copy.
 | 
						|
     */
 | 
						|
    private void copyRepoToAVM(NodeRef src, NodeRef dst, String name)
 | 
						|
    {
 | 
						|
        QName srcType = fNodeService.getType(src);
 | 
						|
        Pair<Integer, String> versionPath = AVMNodeConverter.ToAVMVersionPath(dst);
 | 
						|
        String childPath = AVMNodeConverter.ExtendAVMPath(versionPath.getSecond(), name);
 | 
						|
        NodeRef childNodeRef = AVMNodeConverter.ToNodeRef(-1, childPath);
 | 
						|
        if (fDictionaryService.isSubClass(srcType, ContentModel.TYPE_CONTENT))
 | 
						|
        {
 | 
						|
            ContentReader reader = fContentService.getReader(src, ContentModel.PROP_CONTENT);
 | 
						|
            InputStream in = reader.getContentInputStream();
 | 
						|
            AVMNodeDescriptor desc = fAVMService.lookup(-1, childPath);
 | 
						|
            if (desc != null && !desc.isFile())
 | 
						|
            {
 | 
						|
                fAVMService.removeNode(childPath);
 | 
						|
                desc = null;
 | 
						|
            }
 | 
						|
            if (desc == null)
 | 
						|
            {
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    fAVMService.createFile(versionPath.getSecond(), name).close();
 | 
						|
                }
 | 
						|
                catch (IOException e)
 | 
						|
                {
 | 
						|
                    throw new AlfrescoRuntimeException("I/O Error.", e);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            ContentWriter writer = fAVMService.getContentWriter(childPath);
 | 
						|
            writer.setEncoding(reader.getEncoding());
 | 
						|
            writer.setMimetype(reader.getMimetype());
 | 
						|
            OutputStream out = writer.getContentOutputStream();
 | 
						|
            copyData(in, out);
 | 
						|
            copyPropsAndAspectsRepoToAVM(src, childNodeRef, childPath);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if (fDictionaryService.isSubClass(srcType, ContentModel.TYPE_FOLDER))
 | 
						|
        {
 | 
						|
            AVMNodeDescriptor desc = fAVMService.lookup(-1, childPath);
 | 
						|
            if (desc != null && !desc.isDirectory())
 | 
						|
            {
 | 
						|
                fAVMService.removeNode(childPath);
 | 
						|
                desc = null;
 | 
						|
            }
 | 
						|
            if (desc == null)
 | 
						|
            {
 | 
						|
                fAVMService.createDirectory(versionPath.getSecond(), name);
 | 
						|
            }
 | 
						|
            copyPropsAndAspectsRepoToAVM(src, childNodeRef, childPath);
 | 
						|
            List<FileInfo> listing = fFileFolderService.list(src);
 | 
						|
            for (FileInfo info : listing)
 | 
						|
            {
 | 
						|
                copyRepoToAVM(info.getNodeRef(), childNodeRef, info.getName());
 | 
						|
            }
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Helper to copy properties and aspects.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            The source node.
 | 
						|
     * @param dst
 | 
						|
     *            The destination node.
 | 
						|
     * @param dstPath
 | 
						|
     *            The destination AVM path.
 | 
						|
     */
 | 
						|
    private void copyPropsAndAspectsRepoToAVM(NodeRef src, NodeRef dst, String dstPath)
 | 
						|
    {
 | 
						|
        Map<QName, Serializable> props = fNodeService.getProperties(src);
 | 
						|
        fNodeService.setProperties(dst, props);
 | 
						|
        Set<QName> aspects = fNodeService.getAspects(src);
 | 
						|
        for (QName aspect : aspects)
 | 
						|
        {
 | 
						|
            fAVMService.addAspect(dstPath, aspect);
 | 
						|
        }
 | 
						|
        if (!fAVMService.hasAspect(-1, dstPath, ContentModel.ASPECT_COPIEDFROM))
 | 
						|
        {
 | 
						|
            fAVMService.addAspect(dstPath, ContentModel.ASPECT_COPIEDFROM);
 | 
						|
        }
 | 
						|
        fNodeService.setProperty(dst, ContentModel.PROP_COPY_REFERENCE, src);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handle copying from Repo to Repo.
 | 
						|
     * 
 | 
						|
     * @param src
 | 
						|
     *            The source node.
 | 
						|
     * @param dst
 | 
						|
     *            The destination container.
 | 
						|
     * @param name
 | 
						|
     *            The name to give the copy.
 | 
						|
     */
 | 
						|
    private void copyRepoToRepo(NodeRef src, NodeRef dst, String name)
 | 
						|
    {
 | 
						|
        ChildAssociationRef assocRef = fNodeService.getPrimaryParent(src);
 | 
						|
        fCopyService.copyAndRename(src, dst, ContentModel.ASSOC_CONTAINS, assocRef.getQName(), true);
 | 
						|
    }
 | 
						|
 | 
						|
    private void copyData(InputStream in, OutputStream out)
 | 
						|
    {
 | 
						|
        try
 | 
						|
        {
 | 
						|
            byte[] buff = new byte[8192];
 | 
						|
            int read = 0;
 | 
						|
            while ((read = in.read(buff)) != -1)
 | 
						|
            {
 | 
						|
                out.write(buff, 0, read);
 | 
						|
            }
 | 
						|
            in.close();
 | 
						|
            out.close();
 | 
						|
        }
 | 
						|
        catch (IOException e)
 | 
						|
        {
 | 
						|
            throw new AlfrescoRuntimeException("I/O Error.", e);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |