assert system != null;
assert nodeTypes != null;
Name name = nodeType.getInternalName();
final NodeKey key = nodeType.key();
MutableCachedNode nodeTypeNode = null;
Set<NodeKey> existingChildKeys = null;
if (nodeTypes.getChildReferences(system).hasChild(key)) {
// The node already exists ...
if (!updateExisting) return;
nodeTypeNode = system.mutable(key);
// We'll need to delete any existing child that isn't there anymore ...
existingChildKeys = new HashSet<NodeKey>();
for (ChildReference childRef : nodeTypeNode.getChildReferences(system)) {
existingChildKeys.add(childRef.getKey());
}
}
// Define the properties for this node type ...
NodeType[] supertypes = nodeType.getDeclaredSupertypes();
List<Name> supertypeNames = new ArrayList<Name>(supertypes.length);
for (int i = 0; i < supertypes.length; i++) {
supertypeNames.add(((JcrNodeType)supertypes[i]).getInternalName());
}
List<Property> properties = new ArrayList<Property>();
properties.add(propertyFactory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.NODE_TYPE));
properties.add(propertyFactory.create(JcrLexicon.IS_MIXIN, nodeType.isMixin()));
properties.add(propertyFactory.create(JcrLexicon.IS_ABSTRACT, nodeType.isAbstract()));
properties.add(propertyFactory.create(JcrLexicon.IS_QUERYABLE, nodeType.isQueryable()));
if (nodeType.getPrimaryItemName() != null) {
properties.add(propertyFactory.create(JcrLexicon.PRIMARY_ITEM_NAME, nodeType.getPrimaryItemName()));
}
properties.add(propertyFactory.create(JcrLexicon.NODE_TYPE_NAME, nodeType.getName()));
properties.add(propertyFactory.create(JcrLexicon.HAS_ORDERABLE_CHILD_NODES, nodeType.hasOrderableChildNodes()));
properties.add(propertyFactory.create(JcrLexicon.SUPERTYPES, supertypeNames));
// Now make or adjust the node for the node type ...
if (nodeTypeNode != null) {
// Update the properties ...
nodeTypeNode.setProperties(system, properties);
// make sure each new supertype of the existing node is present *before* the existing node in the parent nodeTypes
// this because node type validation is a top-down process, expecting the parents before the children
for (NodeType superType : supertypes) {
CachedNode superTypeNode = system.getNode(((JcrNodeType)superType).key());
if (superTypeNode instanceof MutableCachedNode && ((MutableCachedNode)superTypeNode).isNew()) {
nodeTypes.reorderChild(system, superTypeNode.getKey(), nodeTypeNode.getKey());
}
}
} else {
// We have to create the node type node ...
nodeTypeNode = nodeTypes.createChild(system, key, name, properties);
}
// And the property definitions ...
for (JcrPropertyDefinition defn : nodeType.getDeclaredPropertyDefinitions()) {
store(nodeTypeNode, defn);
if (existingChildKeys != null) existingChildKeys.remove(defn.key());
}
// And the child node definitions ...
for (JcrNodeDefinition defn : nodeType.getDeclaredChildNodeDefinitions()) {
store(nodeTypeNode, defn);
if (existingChildKeys != null) existingChildKeys.remove(defn.key());
}
// Remove any children that weren't represented by a property definition or child node definition ...
if (existingChildKeys != null && !existingChildKeys.isEmpty()) {
for (NodeKey childKey : existingChildKeys) {
// Remove the child from the parent, then destrot it ...
nodeTypeNode.removeChild(system, childKey);
system.destroy(childKey);
}
}
}