EffectiveNodeTypeCache entCache,
Map ntdCache)
throws NodeTypeConflictException, NoSuchNodeTypeException {
// create empty effective node type instance
EffectiveNodeType ent = new EffectiveNodeType();
QName ntName = ntd.getName();
// prepare new instance
ent.mergedNodeTypes.add(ntName);
ent.allNodeTypes.add(ntName);
// map of all item definitions (maps id to definition)
// used to effectively detect ambiguous child definitions where
// ambiguity is defined in terms of definition identity
HashMap itemDefIds = new HashMap();
NodeDef[] cnda = ntd.getChildNodeDefs();
for (int i = 0; i < cnda.length; i++) {
// check if child node definition would be ambiguous within
// this node type definition
if (itemDefIds.containsKey(cnda[i].getId())) {
// conflict
String msg;
if (cnda[i].definesResidual()) {
msg = ntName + " contains ambiguous residual child node definitions";
} else {
msg = ntName + " contains ambiguous definitions for child node named "
+ cnda[i].getName();
}
log.debug(msg);
throw new NodeTypeConflictException(msg);
} else {
itemDefIds.put(cnda[i].getId(), cnda[i]);
}
if (cnda[i].definesResidual()) {
// residual node definition
ent.unnamedItemDefs.add(cnda[i]);
} else {
// named node definition
QName name = cnda[i].getName();
List defs = (List) ent.namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList();
ent.namedItemDefs.put(name, defs);
}
if (defs.size() > 0) {
/**
* there already exists at least one definition with that
* name; make sure none of them is auto-create
*/
for (int j = 0; j < defs.size(); j++) {
ItemDef def = (ItemDef) defs.get(j);
if (cnda[i].isAutoCreated() || def.isAutoCreated()) {
// conflict
String msg = "There are more than one 'auto-create' item definitions for '"
+ name + "' in node type '" + ntName + "'";
log.debug(msg);
throw new NodeTypeConflictException(msg);
}
}
}
defs.add(cnda[i]);
}
}
PropDef[] pda = ntd.getPropertyDefs();
for (int i = 0; i < pda.length; i++) {
// check if property definition would be ambiguous within
// this node type definition
if (itemDefIds.containsKey(pda[i].getId())) {
// conflict
String msg;
if (pda[i].definesResidual()) {
msg = ntName + " contains ambiguous residual property definitions";
} else {
msg = ntName + " contains ambiguous definitions for property named "
+ pda[i].getName();
}
log.debug(msg);
throw new NodeTypeConflictException(msg);
} else {
itemDefIds.put(pda[i].getId(), pda[i]);
}
if (pda[i].definesResidual()) {
// residual property definition
ent.unnamedItemDefs.add(pda[i]);
} else {
// named property definition
QName name = pda[i].getName();
List defs = (List) ent.namedItemDefs.get(name);
if (defs == null) {
defs = new ArrayList();
ent.namedItemDefs.put(name, defs);
}