This service provides methods to copy nodes within and across folders. It also provides support to update the state of a node, with that of another node, within and across folders.
The service is very useful for managing the copy of nodes. When copying container nodes (folders) you also have the option to copy child nodes. Operations provided by the service include:
- Copy a node, along with (optionally) its children.
- Copy and rename a node.
- Get the copies of a specified node (with paged results).
- Check if the name of a top-level node will be changed during copy, due to policies in place.
- Given the copied node, obtain the original node.
The following code is from the Alfresco source code implementation of the copy action that shows usage of the CopyService service:
public class CopyActionExecuter extends ActionExecuterAbstractBase {
public static final String ERR_OVERWRITE = "Unable to overwrite copy because more than one have been found.";
public static final String NAME = "copy";
public static final String PARAM_DESTINATION_FOLDER = "destination-folder";
public static final String PARAM_DEEP_COPY = "deep-copy";
public static final String PARAM_OVERWRITE_COPY = "overwrite-copy";
private CopyService copyService;
private NodeService nodeService;
private CheckOutCheckInService checkOutCheckInService;
public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; }
public void setCopyService(CopyService copyService) { this.copyService = copyService; }
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService) { this.checkOutCheckInService = checkOutCheckInService; }
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
paramList.add(new ParameterDefinitionImpl(PARAM_DEEP_COPY, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_DEEP_COPY)));
paramList.add(new ParameterDefinitionImpl(PARAM_OVERWRITE_COPY, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_OVERWRITE_COPY)));
}
@Override
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
if (!nodeService.exists(actionedUponNodeRef)) {
return;
}
NodeRef destinationParent = (NodeRef) ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);
Set<QName> destinationAspects = nodeService.getAspects(destinationParent);
if (destinationAspects.contains(ContentModel.ASPECT_PENDING_DELETE)) {
return;
}
boolean deepCopy = false;
Boolean deepCopyValue = (Boolean)ruleAction.getParameterValue(PARAM_DEEP_COPY);
if (deepCopyValue != null) {
deepCopy = deepCopyValue.booleanValue();
}
boolean overwrite = true;
Boolean overwriteValue = (Boolean)ruleAction.getParameterValue(PARAM_OVERWRITE_COPY);
if (overwriteValue != null) {
overwrite = overwriteValue.booleanValue();
}
// Since we are overwriting we need to figure out whether the destination node exists
NodeRef copyNodeRef = null;
if (overwrite == true) {
// Try and find copies of the actioned upon node reference.
// Include the parent folder because that's where the copy will be if this action
// had done the first copy.
PagingResults<CopyInfo> copies = copyService.getCopies(actionedUponNodeRef, destinationParent,
new PagingRequest(1000));
for (CopyInfo copyInfo : copies.getPage()) {
NodeRef copy = copyInfo.getNodeRef();
// We know that it is in the destination parent, but avoid working copies
if (checkOutCheckInService.isWorkingCopy(copy)) {
continue;
}
if (copyNodeRef == null) {
copyNodeRef = copy;
} else {
throw new RuleServiceException(ERR_OVERWRITE);
}
}
}
if (copyNodeRef != null) {
// Overwrite the state of the destination node ref with the actioned upon node state
this.copyService.copy(actionedUponNodeRef, copyNodeRef);
} else {
ChildAssociationRef originalAssoc = nodeService.getPrimaryParent(actionedUponNodeRef);
// Create a new copy of the node
this.copyService.copyAndRename(actionedUponNodeRef, destinationParent, originalAssoc.getTypeQName(),
originalAssoc.getQName(), deepCopy);
}
}
}