effectivenodetype.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,125 行 · 第 1/3 页
JAVA
1,125 行
* @return * @throws ConstraintViolationException if no applicable property definition * could be found */ public PropDef getApplicablePropertyDef(QName name, int type, boolean multiValued) throws ConstraintViolationException { // try named property definitions first PropDef match = getMatchingPropDef(getNamedPropDefs(name), type, multiValued); if (match != null) { return match; } // no item with that name defined; // try residual property definitions match = getMatchingPropDef(getUnnamedPropDefs(), type, multiValued); if (match != null) { return match; } // no applicable definition found throw new ConstraintViolationException("no matching property definition found for " + name); } /** * Returns the applicable property definition for a property with the * specified name and type. The multiValued flag is not taken into account * in the selection algorithm. Other than * <code>{@link #getApplicablePropertyDef(QName, int, boolean)}</code> * this method does not take the multiValued flag into account in the * selection algorithm. If there more than one applicable definitions then * the following rules are applied: * <ul> * <li>named definitions are preferred to residual definitions</li> * <li>definitions with specific required type are preferred to definitions * with required type UNDEFINED</li> * <li>single-value definitions are preferred to multiple-value definitions</li> * </ul> * * @param name * @param type * @return * @throws ConstraintViolationException if no applicable property definition * could be found */ public PropDef getApplicablePropertyDef(QName name, int type) throws ConstraintViolationException { // try named property definitions first PropDef match = getMatchingPropDef(getNamedPropDefs(name), type); if (match != null) { return match; } // no item with that name defined; // try residual property definitions match = getMatchingPropDef(getUnnamedPropDefs(), type); if (match != null) { return match; } // no applicable definition found throw new ConstraintViolationException("no matching property definition found for " + name); } private PropDef getMatchingPropDef(PropDef[] defs, int type) { PropDef match = null; for (int i = 0; i < defs.length; i++) { ItemDef def = defs[i]; if (!def.definesNode()) { PropDef pd = (PropDef) def; int reqType = pd.getRequiredType(); // match type if (reqType == PropertyType.UNDEFINED || type == PropertyType.UNDEFINED || reqType == type) { if (match == null) { match = pd; } else { // check if this definition is a better match than // the one we've already got if (match.getRequiredType() != pd.getRequiredType()) { if (match.getRequiredType() == PropertyType.UNDEFINED) { // found better match match = pd; } } else { if (match.isMultiple() && !pd.isMultiple()) { // found better match match = pd; } } } if (match.getRequiredType() != PropertyType.UNDEFINED && !match.isMultiple()) { // found best possible match, get outta here return match; } } } } return match; } private PropDef getMatchingPropDef(PropDef[] defs, int type, boolean multiValued) { PropDef match = null; for (int i = 0; i < defs.length; i++) { ItemDef def = defs[i]; if (!def.definesNode()) { PropDef pd = (PropDef) def; int reqType = pd.getRequiredType(); // match type if (reqType == PropertyType.UNDEFINED || type == PropertyType.UNDEFINED || reqType == type) { // match multiValued flag if (multiValued == pd.isMultiple()) { // found match if (pd.getRequiredType() != PropertyType.UNDEFINED) { // found best possible match, get outta here return pd; } else { if (match == null) { match = pd; } } } } } } return match; } /** * @param name * @throws ConstraintViolationException */ public void checkRemoveItemConstraints(QName name) throws ConstraintViolationException { /** * as there might be multiple definitions with the same name and we * don't know which one is applicable, we check all of them */ ItemDef[] defs = getNamedItemDefs(name); if (defs != null) { for (int i = 0; i < defs.length; i++) { if (defs[i].isMandatory()) { throw new ConstraintViolationException("can't remove mandatory item"); } if (defs[i].isProtected()) { throw new ConstraintViolationException("can't remove protected item"); } } } } /** * Merges another <code>EffectiveNodeType</code> with this one. * Checks for merge conflicts. * * @param other * @return * @throws NodeTypeConflictException */ EffectiveNodeType merge(EffectiveNodeType other) throws NodeTypeConflictException { // create a clone of this instance and perform the merge on // the 'clone' to avoid a potentially inconsistant state // of this instance if an exception is thrown during // the merge. EffectiveNodeType copy = (EffectiveNodeType) clone(); copy.internalMerge(other, false); return copy; } /** * Internal helper method which merges another <code>EffectiveNodeType</code> * instance with <i>this</i> instance. * <p/> * Warning: This instance might be in an inconsistent state if an exception * is thrown. * * @param other * @param supertype true if the merge is a result of inheritance, i.e. <code>other</code> * represents one or more supertypes of this instance; otherwise false, i.e. * the merge is the result of an explicit aggregation * @throws NodeTypeConflictException */ private synchronized void internalMerge(EffectiveNodeType other, boolean supertype) throws NodeTypeConflictException { QName[] nta = other.getAllNodeTypes(); int includedCount = 0; for (int i = 0; i < nta.length; i++) { if (includesNodeType(nta[i])) { // redundant node type log.debug("node type '" + nta[i] + "' is already contained."); includedCount++; } } if (includedCount == nta.length) { // total overlap, ignore return; } // named item definitions ItemDef[] defs = other.getNamedItemDefs(); for (int i = 0; i < defs.length; i++) { ItemDef def = defs[i]; if (includesNodeType(def.getDeclaringNodeType())) { // ignore redundant definitions continue; } QName name = def.getName(); List existingDefs = (List) namedItemDefs.get(name); if (existingDefs != null) { if (existingDefs.size() > 0) { // there already exists at least one definition with that name for (int j = 0; j < existingDefs.size(); j++) { ItemDef existingDef = (ItemDef) existingDefs.get(j); // 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 PropDef pd = (PropDef) def; PropDef epd = (PropDef) 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(); namedItemDefs.put(name, existingDefs); } existingDefs.add(def); } // residual item definitions defs = other.getUnnamedItemDefs(); for (int i = 0; i < defs.length; i++) { ItemDef def = defs[i]; if (includesNodeType(def.getDeclaringNodeType())) { // ignore redundant definitions continue; } Iterator iter = unnamedItemDefs.iterator(); while (iter.hasNext()) { ItemDef existing = (ItemDef) iter.next(); // compare with existing definition if (def.definesNode() == existing.definesNode()) { if (!def.definesNode()) { // property definition PropDef pd = (PropDef) def; PropDef epd = (PropDef) 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 NodeDef nd = (NodeDef) def; NodeDef end = (NodeDef) 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); } for (int i = 0; i < nta.length; i++) { allNodeTypes.add(nta[i]); } if (supertype) { // implicit merge as result of inheritance // add other merged node types as supertypes nta = other.getMergedNodeTypes(); for (int i = 0; i < nta.length; i++) { inheritedNodeTypes.add(nta[i]); } // add supertypes of other merged node types as supertypes nta = other.getInheritedNodeTypes(); for (int i = 0; i < nta.length; i++) { inheritedNodeTypes.add(nta[i]); } } else { // explicit merge // merge with other merged node types nta = other.getMergedNodeTypes(); for (int i = 0; i < nta.length; i++) { mergedNodeTypes.add(nta[i]); } // add supertypes of other merged node types as supertypes nta = other.getInheritedNodeTypes(); for (int i = 0; i < nta.length; i++) { inheritedNodeTypes.add(nta[i]); } } } protected Object clone() { EffectiveNodeType clone = new EffectiveNodeType(); clone.mergedNodeTypes.addAll(mergedNodeTypes); clone.inheritedNodeTypes.addAll(inheritedNodeTypes); clone.allNodeTypes.addAll(allNodeTypes); Iterator iter = namedItemDefs.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); List list = (List) namedItemDefs.get(key); clone.namedItemDefs.put(key, new ArrayList(list)); } clone.unnamedItemDefs.addAll(unnamedItemDefs); return clone; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?