CachedNode node = node();
Name oldPrimaryType = node.getPrimaryType(cache);
Set<Name> mixinTypeNames = node.getMixinTypes(cache);
Iterator<Property> iter = node.getProperties(cache);
while (iter.hasNext()) {
Property prop = iter.next();
try {
createJcrProperty(prop, newPrimaryTypeName, mixinTypeNames);
} catch (ConstraintViolationException e) {
// Change the message ...
String propName = readable(prop.getName());
I18n msg = JcrI18n.unableToChangePrimaryTypeDueToPropertyDefinition;
throw new ConstraintViolationException(msg.text(location(), oldPrimaryType, newPrimaryTypeName, propName), e);
}
}
// Check that this would not violate the parent's child node type definitions ...
Name nodeName = node.getName(cache);
CachedNode parent = getParent().node();
Name primaryType = parent.getPrimaryType(cache);
Set<Name> mixins = parent.getMixinTypes(cache);
// The node is already a child, so create a counter that returns the count as if it were not a child ...
SiblingCounter siblingCounter = SiblingCounter.alter(SiblingCounter.create(parent, cache), -1);
boolean skipProtected = true;
NodeDefinitionSet childDefns = nodeTypes.findChildNodeDefinitions(primaryType, mixins);
JcrNodeDefinition childDefn = childDefns.findBestDefinitionForChild(nodeName, newPrimaryTypeName, skipProtected,
siblingCounter);
if (childDefn == null) {
String ptype = readable(primaryType);
String mtypes = readable(parent.getMixinTypes(cache));
I18n msg = JcrI18n.unableToChangePrimaryTypeDueToParentsChildDefinition;
throw new ConstraintViolationException(msg.text(location(), oldPrimaryType, newPrimaryTypeName, ptype, mtypes));
}
setNodeDefinitionId(childDefn.getId(), nodeTypes.getVersion());
// Change the primary type property ...
boolean wasReferenceable = isReferenceable();
MutableCachedNode mutable = mutable();
mutable.setProperty(cache, session.propertyFactory().create(JcrLexicon.PRIMARY_TYPE, newPrimaryTypeName));
if (wasReferenceable && !isReferenceable()) {
// Need to remove the 'jcr:uuid' reference ...
mutable.removeProperty(cache, JcrLexicon.UUID);
} else if (isReferenceable() && !mutable.hasProperty(JcrLexicon.UUID, cache)) {
mutable.setProperty(cache, session.propertyFactory().create(JcrLexicon.UUID, getIdentifier()));
}
// And auto-create any properties that are defined by the new primary type ...
autoCreateItemsFor(newPrimaryType);
// Since we've changed the primary type, release the cached property definition IDs for the node's properties ...
for (AbstractJcrProperty prop : this.jcrProperties.values()) {
prop.releasePropertyDefinitionId();
}
}