try {
Set<Name> names = thisState.getPropertyNames();
for (Name propName : names) {
PropertyId propId = new PropertyId(thisState.getNodeId(), propName);
PropertyState propState = (PropertyState) stateMgr.getItemState(propId);
PropertyDefinition oldDef = itemMgr.getDefinition(propState);
// check if property has been defined by mixin type (or one of its supertypes)
NodeTypeImpl declaringNT = (NodeTypeImpl) oldDef.getDeclaringNodeType();
if (!entResulting.includesNodeType(declaringNT.getQName())) {
// the resulting effective node type doesn't include the
// node type that declared this property
affectedProps.put(propId, oldDef);
}
}
List<ChildNodeEntry> entries = thisState.getChildNodeEntries();
for (ChildNodeEntry entry : entries) {
NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
NodeDefinition oldDef = itemMgr.getDefinition(nodeState);
// check if node has been defined by mixin type (or one of its supertypes)
NodeTypeImpl declaringNT = (NodeTypeImpl) oldDef.getDeclaringNodeType();
if (!entResulting.includesNodeType(declaringNT.getQName())) {
// the resulting effective node type doesn't include the
// node type that declared this child node
affectedNodes.put(entry, oldDef);
}
}
} catch (ItemStateException e) {
throw new RepositoryException("Internal Error: Failed to determine effect of removing mixin " + session.getJCRName(mixinName), e);
}
// modify the state of this node
thisState.setMixinTypeNames(remainingMixins);
// set jcr:mixinTypes property
setMixinTypesProperty(remainingMixins);
// process affected nodes & properties:
// 1. try to redefine item based on the resulting
// new effective node type (see JCR-2130)
// 2. remove item if 1. fails
boolean success = false;
try {
for (PropertyId id : affectedProps.keySet()) {
PropertyImpl prop = (PropertyImpl) itemMgr.getItem(id);
PropertyDefinition oldDef = affectedProps.get(id);
if (oldDef.isProtected()) {
// remove 'orphaned' protected properties immediately
removeChildProperty(id.getName());
continue;
}
// try to find new applicable definition first and
// redefine property if possible (JCR-2130)
try {
PropertyDefinitionImpl newDef = getApplicablePropertyDefinition(
id.getName(), prop.getType(),
oldDef.isMultiple(), false);
if (newDef.getRequiredType() != PropertyType.UNDEFINED
&& newDef.getRequiredType() != prop.getType()) {
// value conversion required
if (oldDef.isMultiple()) {
// convert value
Value[] values =
ValueHelper.convert(
prop.getValues(),
newDef.getRequiredType(),
session.getValueFactory());
// redefine property
prop.onRedefine(newDef.unwrap());
// set converted values
prop.setValue(values);
} else {
// convert value
Value value =
ValueHelper.convert(
prop.getValue(),
newDef.getRequiredType(),
session.getValueFactory());
// redefine property
prop.onRedefine(newDef.unwrap());
// set converted values
prop.setValue(value);
}
} else {
// redefine property
prop.onRedefine(newDef.unwrap());
}
} catch (ValueFormatException vfe) {
// value conversion failed, remove it
removeChildProperty(id.getName());
} catch (ConstraintViolationException cve) {
// no suitable definition found for this property,
// remove it
removeChildProperty(id.getName());
}
}
for (ChildNodeEntry entry : affectedNodes.keySet()) {
NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
NodeImpl node = (NodeImpl) itemMgr.getItem(entry.getId());
NodeDefinition oldDef = affectedNodes.get(entry);
if (oldDef.isProtected()) {
// remove 'orphaned' protected child node immediately
removeChildNode(entry.getName(), entry.getIndex());
continue;
}