if (isRoot()) {
throw new ConstraintViolationException(JcrI18n.setPrimaryTypeOnRootNodeIsNotSupported.text());
}
Name newPrimaryTypeName = nameFrom(nodeTypeName);
NodeTypes nodeTypes = session.nodeTypes();
if (newPrimaryTypeName.equals(getPrimaryTypeName())) return;
final JcrNodeType newPrimaryType = nodeTypes.getNodeType(newPrimaryTypeName);
// validate the new primary type
if (newPrimaryType == null) {
throw new NoSuchNodeTypeException(JcrI18n.typeNotFound.text(newPrimaryType));
}
if (newPrimaryType.isMixin()) {
throw new ConstraintViolationException(JcrI18n.cannotUseMixinTypeAsPrimaryType.text(nodeTypeName));
}
if (newPrimaryType.isAbstract()) {
throw new ConstraintViolationException(JcrI18n.primaryTypeCannotBeAbstract.text(newPrimaryType));
}
// Make sure that all existing properties will have a valid property definition with the new primary type ...
SessionCache cache = sessionCache();
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);