Files
.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
alfresco-community-repo/source/java/org/alfresco/repo/copy/CrossRepositoryCopyServiceImpl.java
Derek Hulley a4b4ca69ec Merged V2.1 to HEAD
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
2007-09-11 04:18:53 +00:00

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);
}
}
}