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 + -
显示快捷键?