/** * Helper method to transactionally record <code>NodeRef</code> properties so that they can later * be fixed up to point to the relative, after-copy locations. * * <p>When the copy has been completed, the second stage of the process can be applied. * * @param sourceNodeRef the node that is being copied * @param properties the node properties being copied * @param propertyQName the qualified name of the property to check * @see #repointNodeRefs(NodeRef, QName, Map, NodeService) */ public void recordNodeRefsForRepointing( NodeRef sourceNodeRef, Map<QName, Serializable> properties, QName propertyQName) { Serializable parameterValue = properties.get(propertyQName); if (parameterValue != null && (parameterValue instanceof Collection<?> || parameterValue instanceof NodeRef)) { String key = KEY_NODEREF_REPOINTING_PREFIX + propertyQName.toString(); // Store it for later Map<NodeRef, Serializable> map = TransactionalResourceHelper.getMap(key); map.put(sourceNodeRef, parameterValue); } }
/** * The second stage of the <code>NodeRef</code> repointing. Call this method to have any <code> * NodeRef</code> properties readjusted to reflect the copied node hierarchy. Only use this method * if it a requirement for the particular type or aspect that you are coding for. * * @param sourceNodeRef the source node * @param propertyQName the target node i.e. the copy of the source node * @param copyMap the full hierarchy copy map of source to copies * @see #recordNodeRefsForRepointing(NodeRef, Map, QName) */ @SuppressWarnings("unchecked") public void repointNodeRefs( NodeRef sourceNodeRef, NodeRef targetNodeRef, QName propertyQName, Map<NodeRef, NodeRef> copyMap, NodeService nodeService) { String key = KEY_NODEREF_REPOINTING_PREFIX + propertyQName.toString(); Map<NodeRef, Serializable> map = TransactionalResourceHelper.getMap(key); Serializable value = map.get(sourceNodeRef); if (value == null) { // Don't bother. The source node did not have a NodeRef property return; } Serializable newValue = null; if (value instanceof Collection) { Collection<Serializable> oldList = (Collection<Serializable>) value; List<Serializable> newList = new ArrayList<Serializable>(oldList.size()); for (Serializable oldListValue : oldList) { Serializable newListValue = oldListValue; if (oldListValue instanceof NodeRef) { newListValue = repointNodeRef(copyMap, (NodeRef) oldListValue); } // Put the value in the new list even though the new list might be discarded newList.add(newListValue); // Check if the value changed if (!newListValue.equals(oldListValue)) { // The value changed, so the new list will have to be set onto the target node newValue = (Serializable) newList; } } } else if (value instanceof NodeRef) { NodeRef newNodeRef = repointNodeRef(copyMap, (NodeRef) value); if (!newNodeRef.equals(value)) { // The value changed, so the new list will have to be set onto the target node newValue = newNodeRef; } } else { throw new IllegalStateException("Should only have Collections and NodeRef values"); } // Fix the node property on the target, if necessary if (newValue != null) { nodeService.setProperty(targetNodeRef, propertyQName, newValue); } }