Java Code Examples for org.alfresco.service.cmr.repository.ChildAssociationRef#getTypeQName()

The following examples show how to use org.alfresco.service.cmr.repository.ChildAssociationRef#getTypeQName() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MultiTServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Override
public ChildAssociationRef getName(ChildAssociationRef childAssocRef)
{
    if (childAssocRef == null)
    {
        return null;
    }

    return new ChildAssociationRef(
            childAssocRef.getTypeQName(),
            getName(childAssocRef.getParentRef()),
            childAssocRef.getQName(),
            getName(childAssocRef.getChildRef()),
            childAssocRef.isPrimary(),
            childAssocRef.getNthSibling());
}
 
Example 2
Source File: MultiTServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Override
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef, boolean forceForNonTenant)
{
    if (childAssocRef == null)
    {
        return null;
    }

    return new ChildAssociationRef(
            childAssocRef.getTypeQName(),
            getBaseName(childAssocRef.getParentRef(), forceForNonTenant),
            childAssocRef.getQName(),
            getBaseName(childAssocRef.getChildRef(), forceForNonTenant),
            childAssocRef.isPrimary(),
            childAssocRef.getNthSibling());
}
 
Example 3
Source File: IntegrityChecker.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
/**
 * @see AssocSourceMultiplicityIntegrityEvent
 * @see AssocTargetMultiplicityIntegrityEvent
 */
public void onDeleteChildAssociation(ChildAssociationRef childAssocRef)
{
    if (! storesToIgnore.contains(tenantService.getBaseName(childAssocRef.getChildRef().getStoreRef()).toString()))
    {
        IntegrityEvent event = null;
        // check source multiplicity
        event = new AssocSourceMultiplicityIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getChildRef(),
                childAssocRef.getTypeQName(),
                true);
        save(event);
        // check target multiplicity
        event = new AssocTargetMultiplicityIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getParentRef(),
                childAssocRef.getTypeQName(),
                true);
        save(event);
    }
}
 
Example 4
Source File: AbstractNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
/**
 * @see NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(ChildAssociationRef, boolean)
 */
protected void invokeOnCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
{
    // Get the parent reference and the assoc type qName
    NodeRef parentNodeRef = childAssocRef.getParentRef();
    
    if (ignorePolicy(parentNodeRef))
    {
        return;
    }
    
    QName assocTypeQName = childAssocRef.getTypeQName();
    // get qnames to invoke against
    Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
    // execute policy for node type and aspects
    NodeServicePolicies.OnCreateChildAssociationPolicy policy = onCreateChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName);
    policy.onCreateChildAssociation(childAssocRef, isNewNode);
}
 
Example 5
Source File: AbstractNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
/**
 * @see NodeServicePolicies.BeforeDeleteChildAssociationPolicy#beforeDeleteChildAssociation(ChildAssociationRef)
 */
protected void invokeBeforeDeleteChildAssociation(ChildAssociationRef childAssocRef)
{
    NodeRef parentNodeRef = childAssocRef.getParentRef();
    
    if (ignorePolicy(parentNodeRef))
    {
        return;
    }
    
    QName assocTypeQName = childAssocRef.getTypeQName();
    // get qnames to invoke against
    Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
    // execute policy for node type and aspects
    NodeServicePolicies.BeforeDeleteChildAssociationPolicy policy = beforeDeleteChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName);
    policy.beforeDeleteChildAssociation(childAssocRef);
}
 
Example 6
Source File: AbstractNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
/**
 * @see NodeServicePolicies.OnDeleteChildAssociationPolicy#onDeleteChildAssociation(ChildAssociationRef)
 */
protected void invokeOnDeleteChildAssociation(ChildAssociationRef childAssocRef)
{
    NodeRef parentNodeRef = childAssocRef.getParentRef();
    
    if (ignorePolicy(parentNodeRef))
    {
        return;
    }
    
    QName assocTypeQName = childAssocRef.getTypeQName();
    // get qnames to invoke against
    Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
    // execute policy for node type and aspects
    NodeServicePolicies.OnDeleteChildAssociationPolicy policy = onDeleteChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName);
    policy.onDeleteChildAssociation(childAssocRef);
}
 
Example 7
Source File: DbNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Extend(traitAPI=NodeServiceTrait.class,extensionAPI=NodeServiceExtension.class)
public void setChildAssociationIndex(ChildAssociationRef childAssocRef, int index)
{
    // get nodes
    Pair<Long, NodeRef> parentNodePair = getNodePairNotNull(childAssocRef.getParentRef());
    Pair<Long, NodeRef> childNodePair = getNodePairNotNull(childAssocRef.getChildRef());
    
    Long parentNodeId = parentNodePair.getFirst();
    Long childNodeId = childNodePair.getFirst();
    QName assocTypeQName = childAssocRef.getTypeQName();
    QName assocQName = childAssocRef.getQName();
    
    // set the index
    int updated = nodeDAO.setChildAssocIndex(
            parentNodeId, childNodeId, assocTypeQName, assocQName, index);
    if (updated < 1)
    {
        throw new InvalidChildAssociationRefException(
                "Unable to set child association index: \n" +
                "   assoc: " + childAssocRef + "\n" +
                "   index: " + index,
                childAssocRef);
    }
}
 
Example 8
Source File: AbstractNodeRelation.java    From alfresco-remote-api with GNU Lesser General Public License v3.0 5 votes vote down vote up
protected CollectionWithPagingInfo<Node> listNodeChildAssocs(List<ChildAssociationRef> childAssocRefs, Parameters parameters, Boolean isPrimary, boolean returnChild)
{
    Map<QName, String> qnameMap = new HashMap<>(3);

    Map<String, UserInfo> mapUserInfo = new HashMap<>(10);

    List<String> includeParam = parameters.getInclude();

    List<Node> collection = new ArrayList<Node>(childAssocRefs.size());
    for (ChildAssociationRef childAssocRef : childAssocRefs)
    {
        if (isPrimary == null || (isPrimary == childAssocRef.isPrimary()))
        {
            // minimal info by default (unless "include"d otherwise)
            NodeRef nodeRef = (returnChild ? childAssocRef.getChildRef() : childAssocRef.getParentRef());

            Node node = nodes.getFolderOrDocument(nodeRef, null, null, includeParam, mapUserInfo);

            QName assocTypeQName = childAssocRef.getTypeQName();

            if (!EXCLUDED_NS.contains(assocTypeQName.getNamespaceURI()))
            {
                String assocType = qnameMap.get(assocTypeQName);
                if (assocType == null)
                {
                    assocType = assocTypeQName.toPrefixString(namespaceService);
                    qnameMap.put(assocTypeQName, assocType);
                }

                node.setAssociation(new AssocChild(assocType, childAssocRef.isPrimary()));
                
                collection.add(node);
            }
        }
    }
    
    return listPage(collection, parameters.getPaging());
}
 
Example 9
Source File: Node2ServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 5 votes vote down vote up
/**
 * Child Assocs translation for version store
 */
public List<ChildAssociationRef> getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern) throws InvalidNodeRefException
{
    // Get the child assoc references from the version store
    List<ChildAssociationRef> childAssocRefs = this.dbNodeService.getChildAssocs(
            VersionUtil.convertNodeRef(nodeRef),
            typeQNamePattern, qnamePattern);
    
    List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>(childAssocRefs.size());
    
    for (ChildAssociationRef childAssocRef : childAssocRefs)
    {
        if (! childAssocRef.getTypeQName().equals(Version2Model.CHILD_QNAME_VERSIONED_ASSOCS))
        {
            // Get the child reference
            NodeRef childRef = childAssocRef.getChildRef();
            NodeRef referencedNode = (NodeRef)this.dbNodeService.getProperty(childRef, ContentModel.PROP_REFERENCE);
            
            if (this.dbNodeService.exists(referencedNode))
            {
                // Build a child assoc ref to add to the returned list
                ChildAssociationRef newChildAssocRef = new ChildAssociationRef(
                        childAssocRef.getTypeQName(),
                        childAssocRef.getParentRef(),
                        childAssocRef.getQName(),
                        referencedNode,
                        childAssocRef.isPrimary(),
                        childAssocRef.getNthSibling());
                
                result.add(newChildAssocRef);
            }
        }
    }
    
    // sort the results so that the order appears to be exactly as it was originally
    Collections.sort(result);
    
    return result;
}
 
Example 10
Source File: NodeBrowserPost.java    From alfresco-remote-api with GNU Lesser General Public License v3.0 5 votes vote down vote up
public ChildAssociation(ChildAssociationRef ref)
{
    super(ref.getQName() != null ? ref.getQName() : null,
            ref.getTypeQName() != null ? ref.getTypeQName() : null);
    
    this.childRef = ref.getChildRef();
    this.parentRef = ref.getParentRef(); // could be null
    if (childRef != null)
        this.childType = new QNameBean(getNodeType(childRef));
    if (parentRef != null)
        this.parentType = new QNameBean(getNodeType(parentRef));
    this.primary = ref.isPrimary();
}
 
Example 11
Source File: DbNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
@Extend(traitAPI=NodeServiceTrait.class,extensionAPI=NodeServiceExtension.class)
public boolean removeSecondaryChildAssociation(ChildAssociationRef childAssocRef)
{
    // The node(s) involved may not be pending deletion
    checkPendingDelete(childAssocRef.getParentRef());
    checkPendingDelete(childAssocRef.getChildRef());
    
    Long parentNodeId = getNodePairNotNull(childAssocRef.getParentRef()).getFirst();
    Long childNodeId = getNodePairNotNull(childAssocRef.getChildRef()).getFirst();
    QName assocTypeQName = childAssocRef.getTypeQName();
    QName assocQName = childAssocRef.getQName();
    Pair<Long, ChildAssociationRef> assocPair = nodeDAO.getChildAssoc(
            parentNodeId, childNodeId, assocTypeQName, assocQName);
    if (assocPair == null)
    {
        // No association exists
        return false;
    }
    Long assocId = assocPair.getFirst();
    ChildAssociationRef assocRef = assocPair.getSecond();
    if (assocRef.isPrimary())
    {
        throw new IllegalArgumentException(
                "removeSeconaryChildAssociation can not be applied to a primary association: \n" +
                "   Child Assoc: " + assocRef);
    }
    // Delete the secondary association
    invokeBeforeDeleteChildAssociation(childAssocRef);
    nodeDAO.deleteChildAssoc(assocId);
    invokeOnDeleteChildAssociation(childAssocRef);
    // Done
    return true;
}
 
Example 12
Source File: DbNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Extend(traitAPI=NodeServiceTrait.class,extensionAPI=NodeServiceExtension.class)
public boolean removeChildAssociation(ChildAssociationRef childAssocRef)
{
    // The node(s) involved may not be pending deletion
    checkPendingDelete(childAssocRef.getParentRef());
    checkPendingDelete(childAssocRef.getChildRef());
    
    Long parentNodeId = getNodePairNotNull(childAssocRef.getParentRef()).getFirst();
    Long childNodeId = getNodePairNotNull(childAssocRef.getChildRef()).getFirst();
    QName assocTypeQName = childAssocRef.getTypeQName();
    QName assocQName = childAssocRef.getQName();
    Pair<Long, ChildAssociationRef> assocPair = nodeDAO.getChildAssoc(
            parentNodeId, childNodeId, assocTypeQName, assocQName);
    if (assocPair == null)
    {
        // No association exists
        return false;
    }
    Long assocId = assocPair.getFirst();
    ChildAssociationRef assocRef = assocPair.getSecond();
    if (assocRef.isPrimary())
    {
        NodeRef childNodeRef = assocRef.getChildRef();
        // Delete the child node
        this.deleteNode(childNodeRef);
        // Done
        return true;
    }
    else
    {
        // Delete the association
        invokeBeforeDeleteChildAssociation(childAssocRef);
        nodeDAO.deleteChildAssoc(assocId);
        invokeOnDeleteChildAssociation(childAssocRef);
        // Done
        return true;
    }
}
 
Example 13
Source File: GetChildAssocsMethod.java    From alfresco-repository with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
public List<ChildAssociationRef> execute(NodeProtocol protocol, Reference reference) throws ProtocolMethodException
{
    NodeRef actualNodeRef = reference.execute(new GetActualNodeRefMethod(null));
    NodeRef nodeRefReference = reference.toNodeRef();
    List<ChildAssociationRef> referenceAssociations = new LinkedList<>();
    if (!environment.isSubClass(environment.getType(nodeRefReference), ContentModel.TYPE_FOLDER))
    {
        List<ChildAssociationRef> actualAssociations = environment.getChildAssocs(actualNodeRef,
                                                                                  typeQNamePattern,
                                                                                  qnamePattern,
                                                                                  maxResults,
                                                                                  preload);

        for (ChildAssociationRef actualAssoc : actualAssociations)
        {
            ChildAssociationRef referenceChildAssocRef = new ChildAssociationRef(actualAssoc.getTypeQName(),
                                                                                 nodeRefReference,
                                                                                 actualAssoc.getQName(),
                                                                                 actualAssoc.getChildRef(),
                                                                                 actualAssoc.isPrimary(),
                                                                                 actualAssoc.getNthSibling());

            referenceAssociations.add(referenceChildAssocRef);
        }
    }
    return referenceAssociations;
}
 
Example 14
Source File: WorkflowServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 5 votes vote down vote up
/**
 * @param workflowPackage NodeRef
 */
private List<NodeRef> getRepositoryPackageContents(NodeRef workflowPackage)
{
    List<NodeRef> contents = new ArrayList<NodeRef>();
    // get existing workflow package items
    List<ChildAssociationRef> packageAssocs = protectedNodeService.getChildAssocs(workflowPackage);
    for (ChildAssociationRef assoc : packageAssocs)
    {
        // create our Node representation from the NodeRef
        NodeRef nodeRef = assoc.getChildRef();
        QName assocType = assoc.getTypeQName();
        if (!protectedNodeService.exists(nodeRef))
        {
            if (logger.isDebugEnabled())
                logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
        }
        else if (!ContentModel.ASSOC_CONTAINS.equals(assocType) && !WorkflowModel.ASSOC_PACKAGE_CONTAINS.equals(assocType))
        {
            if (logger.isDebugEnabled())
                logger.debug("Ignoring " + nodeRef + " as it has an invalid association type: "+assocType);
        }
        else
        {
            if (checkTypeIsInDataDictionary(nodeRef))
            {
                contents.add(nodeRef);
            }
        }
    }
    return contents;
}
 
Example 15
Source File: DbNodeServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 4 votes vote down vote up
private NodeRef restoreNodeImpl(NodeRef archivedNodeRef, NodeRef destinationParentNodeRef, QName assocTypeQName, QName assocQName)
{
    Pair<Long, NodeRef> archivedNodePair = getNodePairNotNull(archivedNodeRef);
    Long archivedNodeId = archivedNodePair.getFirst();
    Set<QName> existingAspects = nodeDAO.getNodeAspects(archivedNodeId);
    Set<QName> newAspects = new HashSet<QName>(5);
    Map<QName, Serializable> existingProperties = nodeDAO.getNodeProperties(archivedNodeId);
    Map<QName, Serializable> newProperties = new HashMap<QName, Serializable>(11);
    
    // the node must be a top-level archive node
    if (!existingAspects.contains(ContentModel.ASPECT_ARCHIVED))
    {
        throw new AlfrescoRuntimeException("The node to restore is not an archive node");
    }
    
    // Remove the secondary link to the user that deleted the node
    List<ChildAssociationRef> parentAssocsToRemove = getParentAssocs(
            archivedNodeRef,
            ContentModel.ASSOC_ARCHIVED_LINK,
            RegexQNamePattern.MATCH_ALL);
    for (ChildAssociationRef parentAssocToRemove : parentAssocsToRemove)
    {
        this.removeSecondaryChildAssociation(parentAssocToRemove);
    }
    
    ChildAssociationRef originalPrimaryParentAssocRef = (ChildAssociationRef) existingProperties.get(
            ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
    Serializable originalOwner = existingProperties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER);
    // remove the archived aspect
    Set<QName> removePropertyQNames = new HashSet<QName>(11);
    Set<QName> removeAspectQNames = new HashSet<QName>(3);
    removePropertyQNames.add(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
    removePropertyQNames.add(ContentModel.PROP_ARCHIVED_BY);
    removePropertyQNames.add(ContentModel.PROP_ARCHIVED_DATE);
    removePropertyQNames.add(ContentModel.PROP_ARCHIVED_ORIGINAL_OWNER);
    removeAspectQNames.add(ContentModel.ASPECT_ARCHIVED);
    
    // restore the original ownership
    if (originalOwner == null || originalOwner.equals(OwnableService.NO_OWNER))
    {
        // The ownable aspect was not present before
        removeAspectQNames.add(ContentModel.ASPECT_OWNABLE);
        removePropertyQNames.add(ContentModel.PROP_OWNER);
    }
    else
    {
        newAspects.add(ContentModel.ASPECT_OWNABLE);
        newProperties.put(ContentModel.PROP_OWNER, originalOwner);
    }
    
    // Prepare the node for restoration: remove old aspects and properties; add new aspects and properties
    nodeDAO.removeNodeProperties(archivedNodeId, removePropertyQNames);
    nodeDAO.removeNodeAspects(archivedNodeId, removeAspectQNames);
    nodeDAO.addNodeProperties(archivedNodeId, newProperties);
    nodeDAO.addNodeAspects(archivedNodeId, newAspects);

    if (destinationParentNodeRef == null)
    {
        // we must restore to the original location
        destinationParentNodeRef = originalPrimaryParentAssocRef.getParentRef();
    }
    // check the associations
    if (assocTypeQName == null)
    {
        assocTypeQName = originalPrimaryParentAssocRef.getTypeQName();
    }
    if (assocQName == null)
    {
        assocQName = originalPrimaryParentAssocRef.getQName();
    }

    // move the node to the target parent, which may or may not be the original parent
    ChildAssociationRef newChildAssocRef = moveNode(
            archivedNodeRef,
            destinationParentNodeRef,
            assocTypeQName,
            assocQName);

    // the node reference has changed due to the store move
    NodeRef restoredNodeRef = newChildAssocRef.getChildRef();
    invokeOnRestoreNode(newChildAssocRef);
    // done
    if (logger.isDebugEnabled())
    {
        logger.debug("Restored node: \n" +
                "   original noderef: " + archivedNodeRef + "\n" +
                "   restored noderef: " + restoredNodeRef + "\n" +
                "   new parent: " + destinationParentNodeRef);
    }
    return restoredNodeRef;
}
 
Example 16
Source File: IntegrityChecker.java    From alfresco-repository with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * This handles the creation of secondary child associations.
 * 
 * @see AssocSourceTypeIntegrityEvent
 * @see AssocTargetTypeIntegrityEvent
 * @see AssocSourceMultiplicityIntegrityEvent
 * @see AssocTargetMultiplicityIntegrityEvent
 * @see AssocTargetRoleIntegrityEvent
 */
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNew)
{
    if (isNew)
    {
        return;
    }
    
    if (! storesToIgnore.contains(tenantService.getBaseName(childAssocRef.getChildRef().getStoreRef()).toString()))
    {
        IntegrityEvent event = null;
        // check source type
        event = new AssocSourceTypeIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getParentRef(),
                childAssocRef.getTypeQName());
        save(event);
        // check target type
        event = new AssocTargetTypeIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getChildRef(),
                childAssocRef.getTypeQName());
        save(event);
        // check source multiplicity
        event = new AssocSourceMultiplicityIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getChildRef(),
                childAssocRef.getTypeQName(),
                false);
        save(event);
        // check target multiplicity
        event = new AssocTargetMultiplicityIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getParentRef(),
                childAssocRef.getTypeQName(),
                false);
        save(event);
        // check target role
        event = new AssocTargetRoleIntegrityEvent(
                nodeService,
                dictionaryService,
                childAssocRef.getParentRef(),
                childAssocRef.getTypeQName(),
                childAssocRef.getQName());
        save(event);
    }
}
 
Example 17
Source File: CopyServiceImpl.java    From alfresco-repository with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * {@inheritDoc}
 * 
 * Defer to the standard implementation with copyChildren set to false
 */
public void copy(NodeRef sourceNodeRef, NodeRef targetNodeRef)
{
    QName sourceNodeTypeQName = nodeService.getType(sourceNodeRef);
    QName targetNodeTypeQName = nodeService.getType(targetNodeRef);
    // Check that the source and destination node are the same type
    if (!sourceNodeTypeQName.equals(targetNodeTypeQName))
    {
        // Error - can not copy objects that are of different types
        throw new CopyServiceException("The source and destination node must be the same type.");
    }
    
    // Get the destinations node's details
    ChildAssociationRef destinationPrimaryAssocRef = nodeService.getPrimaryParent(targetNodeRef);
    NodeRef destinationParentNodeRef = destinationPrimaryAssocRef.getParentRef();
    QName assocTypeQName = destinationPrimaryAssocRef.getTypeQName();
    QName assocQName = destinationPrimaryAssocRef.getQName();
    
    // Get the copy details
    CopyDetails copyDetails = getCopyDetails(
            sourceNodeRef, destinationParentNodeRef, targetNodeRef,
            assocTypeQName, assocQName);
    
    // Get callbacks
    Map<QName, CopyBehaviourCallback> callbacks = getCallbacks(copyDetails);
    
    // invoke the before copy policy
    invokeBeforeCopy(sourceNodeRef, targetNodeRef);
    
    // Clear out any record of copied associations
    TransactionalResourceHelper.getList(KEY_POST_COPY_ASSOCS).clear();
    
    // Copy 
    copyProperties(copyDetails, targetNodeRef, sourceNodeTypeQName, callbacks);
    copyAspects(copyDetails, targetNodeRef, Collections.<QName>emptySet(), callbacks);
    copyResidualProperties(copyDetails, targetNodeRef);
    
    Map<NodeRef, NodeRef> copiedNodeRefs = new HashMap<NodeRef, NodeRef>(1);
    copiedNodeRefs.put(sourceNodeRef, targetNodeRef);

    Set<NodeRef> copies = new HashSet<NodeRef>(5);
    copyChildren(
            copyDetails,
            targetNodeRef,
            false,                              // We know that the node has been created
            true,
            copiedNodeRefs,
            copies,
            callbacks);
    
    // Copy an associations that were left until now
    copyPendingAssociations(copiedNodeRefs);
    // invoke the copy complete policy
    invokeCopyComplete(sourceNodeRef, targetNodeRef, false, copiedNodeRefs);         
}