in jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java [984:1146]
private synchronized void internalMerge(EffectiveNodeType other, boolean supertype)
throws NodeTypeConflictException {
Name[] nta = other.getAllNodeTypes();
int includedCount = 0;
for (Name aNta : nta) {
if (includesNodeType(aNta)) {
// redundant node type
log.debug("node type '" + aNta + "' is already contained.");
includedCount++;
}
}
if (includedCount == nta.length) {
// total overlap, ignore
return;
}
// named item definitions
QItemDefinition[] defs = other.getNamedItemDefs();
for (QItemDefinition def : defs) {
if (includesNodeType(def.getDeclaringNodeType())) {
// ignore redundant definitions
continue;
}
Name name = def.getName();
List<QItemDefinition> existingDefs = namedItemDefs.get(name);
if (existingDefs != null) {
if (existingDefs.size() > 0) {
// there already exists at least one definition with that name
for (QItemDefinition existingDef : existingDefs) {
// make sure none of them is auto-create
if (def.isAutoCreated() || existingDef.isAutoCreated()) {
// conflict
String msg = "The item definition for '" + name
+ "' in node type '"
+ def.getDeclaringNodeType()
+ "' conflicts with node type '"
+ existingDef.getDeclaringNodeType()
+ "': name collision with auto-create definition";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
// check ambiguous definitions
if (def.definesNode() == existingDef.definesNode()) {
if (!def.definesNode()) {
// property definition
QPropertyDefinition pd = (QPropertyDefinition) def;
QPropertyDefinition epd = (QPropertyDefinition) existingDef;
// compare type & multiValued flag
if (pd.getRequiredType() == epd.getRequiredType()
&& pd.isMultiple() == epd.isMultiple()) {
// conflict
String msg = "The property definition for '"
+ name + "' in node type '"
+ def.getDeclaringNodeType()
+ "' conflicts with node type '"
+ existingDef.getDeclaringNodeType()
+ "': ambiguous property definition";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
} else {
// child node definition
// conflict
String msg = "The child node definition for '"
+ name + "' in node type '"
+ def.getDeclaringNodeType()
+ "' conflicts with node type '"
+ existingDef.getDeclaringNodeType()
+ "': ambiguous child node definition";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
}
}
}
} else {
existingDefs = new ArrayList<QItemDefinition>();
namedItemDefs.put(name, existingDefs);
}
existingDefs.add(def);
}
// residual item definitions
defs = other.getUnnamedItemDefs();
for (QItemDefinition def : defs) {
if (includesNodeType(def.getDeclaringNodeType())) {
// ignore redundant definitions
continue;
}
for (QItemDefinition existing : unnamedItemDefs) {
// compare with existing definition
if (def.definesNode() == existing.definesNode()) {
if (!def.definesNode()) {
// property definition
QPropertyDefinition pd = (QPropertyDefinition) def;
QPropertyDefinition epd = (QPropertyDefinition) existing;
// compare type & multiValued flag
if (pd.getRequiredType() == epd.getRequiredType()
&& pd.isMultiple() == epd.isMultiple()) {
// conflict
String msg = "A property definition in node type '"
+ def.getDeclaringNodeType()
+ "' conflicts with node type '"
+ existing.getDeclaringNodeType()
+ "': ambiguous residual property definition";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
} else {
// child node definition
QNodeDefinition nd = (QNodeDefinition) def;
QNodeDefinition end = (QNodeDefinition) existing;
// compare required & default primary types
if (Arrays.equals(nd.getRequiredPrimaryTypes(), end.getRequiredPrimaryTypes())
&& (nd.getDefaultPrimaryType() == null
? end.getDefaultPrimaryType() == null
: nd.getDefaultPrimaryType().equals(end.getDefaultPrimaryType()))) {
// conflict
String msg = "A child node definition in node type '"
+ def.getDeclaringNodeType()
+ "' conflicts with node type '"
+ existing.getDeclaringNodeType()
+ "': ambiguous residual child node definition";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
}
}
}
unnamedItemDefs.add(def);
}
allNodeTypes.addAll(Arrays.asList(nta));
if (supertype) {
// implicit merge as result of inheritance
// add other merged node types as supertypes
nta = other.getMergedNodeTypes();
inheritedNodeTypes.addAll(Arrays.asList(nta));
// add supertypes of other merged node types as supertypes
nta = other.getInheritedNodeTypes();
inheritedNodeTypes.addAll(Arrays.asList(nta));
} else {
// explicit merge
// merge with other merged node types
nta = other.getMergedNodeTypes();
mergedNodeTypes.addAll(Arrays.asList(nta));
// add supertypes of other merged node types as supertypes
nta = other.getInheritedNodeTypes();
inheritedNodeTypes.addAll(Arrays.asList(nta));
}
// update 'orderable child nodes' attribute value (JCR-1947)
if (other.hasOrderableChildNodes()) {
orderableChildNodes = true;
}
// update 'primary item' attribute value (JCR-1947)
if (primaryItemName == null && other.getPrimaryItemName() != null) {
primaryItemName = other.getPrimaryItemName();
}
}