AtomicReference<MutableCachedNode> frozenNodeOutput ) {
assert versionHistoryPath != null;
assert versionHistoryPath.size() == 6;
// Get the information from this node ...
NodeKey versionableNodeKey = versionableNode.getKey();
Name primaryTypeName = versionableNode.getPrimaryType(cacheForVersionableNode);
Set<Name> mixinTypeNames = versionableNode.getMixinTypes(cacheForVersionableNode);
NodeKey versionHistoryKey = versionHistoryNodeKeyFor(versionableNodeKey);
// Find the existing version history for this node (if it exists) ...
Name versionName = null;
MutableCachedNode historyNode = system.mutable(versionHistoryKey);
Property predecessors = null;
NodeKey versionKey = versionHistoryKey.withRandomId();
if (historyNode == null) {
// Initialize the version history ...
historyNode = initializeVersionStorage(versionableNodeKey, versionHistoryKey, null, primaryTypeName, mixinTypeNames,
versionHistoryPath, originalVersionKey, now);
// Overwrite the predecessor's property ...
NodeKey rootVersionKey = historyNode.getChildReferences(system).getChild(JcrLexicon.ROOT_VERSION).getKey();
Reference rootVersionRef = referenceFactory.create(rootVersionKey, true);
predecessors = propertyFactory.create(JcrLexicon.PREDECESSORS, new Object[] {rootVersionRef});
versionName = names.create("1.0");
} else {
ChildReferences historyChildren = historyNode.getChildReferences(system);
predecessors = versionableNode.getProperty(JcrLexicon.PREDECESSORS, cacheForVersionableNode);
versionName = nextNameForVersionNode(predecessors, historyChildren);
}
// Create a 'nt:version' node under the version history node ...
List<Property> props = new ArrayList<Property>();
props.add(propertyFactory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.VERSION));
props.add(predecessors);
props.add(propertyFactory.create(JcrLexicon.CREATED, now));
props.add(propertyFactory.create(JcrLexicon.UUID, versionKey.getIdentifier()));
MutableCachedNode versionNode = historyNode.createChild(system, versionKey, versionName, props);
// Create a 'nt:frozenNode' node under the 'nt:version' node ...
NodeKey frozenNodeKey = systemKey().withRandomId();
props = new ArrayList<Property>();
props.add(propertyFactory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FROZEN_NODE));
props.add(propertyFactory.create(JcrLexicon.FROZEN_UUID, versionableNodeKey.getIdentifier()));
props.add(propertyFactory.create(JcrLexicon.FROZEN_PRIMARY_TYPE, primaryTypeName));
props.add(propertyFactory.create(JcrLexicon.FROZEN_MIXIN_TYPES, mixinTypeNames));
props.add(propertyFactory.create(JcrLexicon.UUID, frozenNodeKey));
if (versionableProperties != null) props.addAll(versionableProperties);
MutableCachedNode frozenNode = versionNode.createChild(system, frozenNodeKey, JcrLexicon.FROZEN_NODE, props);
assert frozenNode != null;
frozenNodeOutput.set(frozenNode);
// Now update the predecessor nodes to have the new version node be included as one of their successors ...
Property successors = null;
final Set<Reference> successorReferences = new HashSet<Reference>();
for (Object value : predecessors) {
NodeKey predecessorKey = ((NodeKeyReference)value).getNodeKey();
CachedNode predecessor = system.getNode(predecessorKey);
// Look up the 'jcr:successors' property on the predecessor ...
successors = predecessor.getProperty(JcrLexicon.SUCCESSORS, system);
if (successors != null) {
// There were already successors, so we need to add our new version node the list ...
successorReferences.clear();
for (Object successorValue : successors) {
NodeKey successorKey = ((NodeKeyReference)successorValue).getNodeKey();
successorReferences.add(referenceFactory.create(successorKey, true));
}
}
// Now add the uuid of the versionable node ...