effectivenodetype.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,125 行 · 第 1/3 页

JAVA
1,125
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.nodetype;import org.apache.jackrabbit.core.value.InternalValue;import org.apache.jackrabbit.name.QName;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.PropertyType;import javax.jcr.RepositoryException;import javax.jcr.nodetype.ConstraintViolationException;import javax.jcr.nodetype.NoSuchNodeTypeException;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.TreeSet;/** * An <code>EffectiveNodeType</code> represents one or more * <code>NodeType</code>s as one 'effective' node type where inheritance * is resolved. * <p/> * Instances of <code>EffectiveNodeType</code> are immutable. */public class EffectiveNodeType implements Cloneable {    private static Logger log = LoggerFactory.getLogger(EffectiveNodeType.class);    // list of explicitly aggregated {i.e. merged) node types    private final TreeSet mergedNodeTypes;    // list of implicitly aggregated {through inheritance) node types    private final TreeSet inheritedNodeTypes;    // list of all either explicitly (through aggregation) or implicitly    // (through inheritance) included node types.    private final TreeSet allNodeTypes;    // map of named item definitions (maps name to list of definitions)    private final HashMap namedItemDefs;    // list of unnamed item definitions (i.e. residual definitions)    private final ArrayList unnamedItemDefs;    /**     * private constructor.     */    private EffectiveNodeType() {        mergedNodeTypes = new TreeSet();        inheritedNodeTypes = new TreeSet();        allNodeTypes = new TreeSet();        namedItemDefs = new HashMap();        unnamedItemDefs = new ArrayList();    }    /**     * Package private factory method.     * <p/>     * Creates an effective node type representation of a node type definition.     * Note that the definitions of all referenced node types must be contained     * in <code>ntdCache</code>.     *     * @param ntd      node type definition     * @param entCache cache of already-built effective node types     * @param ntdCache cache of node type definitions, used to resolve dependencies     * @return an effective node type representation of the given node type definition.     * @throws NodeTypeConflictException if the node type definition is invalid,     *                                   e.g. due to ambiguous child definitions.     * @throws NoSuchNodeTypeException if a node type reference (e.g. a supertype)     *                                 could not be resolved.     */    static EffectiveNodeType create(NodeTypeDef ntd,                                    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);                }                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 (pda[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(pda[i]);            }        }        // resolve supertypes recursively        QName[] supertypes = ntd.getSupertypes();        if (supertypes.length > 0) {            EffectiveNodeType base =                    NodeTypeRegistry.getEffectiveNodeType(supertypes, entCache, ntdCache);            ent.internalMerge(base, true);        }        // we're done        return ent;    }    /**     * Package private factory method for creating a new 'empty' effective     * node type instance.     *     * @return an 'empty' effective node type instance.     */    static EffectiveNodeType create() {        return new EffectiveNodeType();    }    public QName[] getMergedNodeTypes() {        return (QName[]) mergedNodeTypes.toArray(new QName[mergedNodeTypes.size()]);    }    public QName[] getInheritedNodeTypes() {        return (QName[]) inheritedNodeTypes.toArray(new QName[inheritedNodeTypes.size()]);    }    public QName[] getAllNodeTypes() {        return (QName[]) allNodeTypes.toArray(new QName[allNodeTypes.size()]);    }    public ItemDef[] getAllItemDefs() {        if (namedItemDefs.size() == 0 && unnamedItemDefs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size());        Iterator iter = namedItemDefs.values().iterator();        while (iter.hasNext()) {            defs.addAll((List) iter.next());        }        defs.addAll(unnamedItemDefs);        if (defs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]);    }    public ItemDef[] getNamedItemDefs() {        if (namedItemDefs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(namedItemDefs.size());        Iterator iter = namedItemDefs.values().iterator();        while (iter.hasNext()) {            defs.addAll((List) iter.next());        }        if (defs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]);    }    public ItemDef[] getUnnamedItemDefs() {        if (unnamedItemDefs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        return (ItemDef[]) unnamedItemDefs.toArray(new ItemDef[unnamedItemDefs.size()]);    }    public boolean hasNamedItemDef(QName name) {        return namedItemDefs.containsKey(name);    }    public ItemDef[] getNamedItemDefs(QName name) {        List defs = (List) namedItemDefs.get(name);        if (defs == null || defs.size() == 0) {            return ItemDef.EMPTY_ARRAY;        }        return (ItemDef[]) defs.toArray(new ItemDef[defs.size()]);    }    public NodeDef[] getAllNodeDefs() {        if (namedItemDefs.size() == 0 && unnamedItemDefs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size());        Iterator iter = unnamedItemDefs.iterator();        while (iter.hasNext()) {            ItemDef def = (ItemDef) iter.next();            if (def.definesNode()) {                defs.add(def);            }        }        iter = namedItemDefs.values().iterator();        while (iter.hasNext()) {            List list = (List) iter.next();            Iterator iter1 = list.iterator();            while (iter1.hasNext()) {                ItemDef def = (ItemDef) iter1.next();                if (def.definesNode()) {                    defs.add(def);                }            }        }        if (defs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]);    }    public NodeDef[] getNamedNodeDefs() {        if (namedItemDefs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(namedItemDefs.size());        Iterator iter = namedItemDefs.values().iterator();        while (iter.hasNext()) {            List list = (List) iter.next();            Iterator iter1 = list.iterator();            while (iter1.hasNext()) {                ItemDef def = (ItemDef) iter1.next();                if (def.definesNode()) {                    defs.add(def);                }            }        }        if (defs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]);    }    public NodeDef[] getNamedNodeDefs(QName name) {        List list = (List) namedItemDefs.get(name);        if (list == null || list.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(list.size());        Iterator iter = list.iterator();        while (iter.hasNext()) {            ItemDef def = (ItemDef) iter.next();            if (def.definesNode()) {                defs.add(def);            }        }        if (defs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]);    }    public NodeDef[] getUnnamedNodeDefs() {        if (unnamedItemDefs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        ArrayList defs = new ArrayList(unnamedItemDefs.size());        Iterator iter = unnamedItemDefs.iterator();        while (iter.hasNext()) {            ItemDef def = (ItemDef) iter.next();            if (def.definesNode()) {                defs.add(def);            }        }        if (defs.size() == 0) {            return NodeDef.EMPTY_ARRAY;        }        return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]);    }    public NodeDef[] getAutoCreateNodeDefs() {        // since auto-create items must have a name,        // we're only searching the named item definitions        if (namedItemDefs.size() == 0) {            return NodeDef.EMPTY_ARRAY;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?