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