propertytyperegistry.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 183 行

JAVA
183
字号
/* * 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.query;import org.apache.jackrabbit.core.nodetype.NodeTypeDef;import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;import org.apache.jackrabbit.core.nodetype.NodeTypeRegistryListener;import org.apache.jackrabbit.core.nodetype.PropDef;import org.apache.jackrabbit.name.QName;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.PropertyType;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;/** * The <code>PropertyTypeRegistry</code> keeps track of registered node type * definitions and its property types. It provides a fast type lookup for a * given property name. */public class PropertyTypeRegistry implements NodeTypeRegistryListener {    /** The logger instance for this class */    private static final Logger log = LoggerFactory.getLogger(PropertyTypeRegistry.class);    /**     * Empty <code>TypeMapping</code> array as return value if no type is     * found     */    private static final TypeMapping[] EMPTY = new TypeMapping[0];    /** The NodeTypeRegistry */    private final NodeTypeRegistry registry;    /** Property QName to TypeMapping[] mapping */    private final Map typeMapping = new HashMap();    /**     * Creates a new <code>PropertyTypeRegistry</code> instance. This instance     * is *not* registered as listener to the NodeTypeRegistry in the constructor!     * @param reg the <code>NodeTypeRegistry</code> where to read the property     * type information.     */    public PropertyTypeRegistry(NodeTypeRegistry reg) {        this.registry = reg;        fillCache();    }    /**     * Returns an array of type mappings for a given property name     * <code>propName</code>. If <code>propName</code> is not defined as a property     * in any registered node type an empty array is returned.     * @param propName the name of the property.     * @return an array of <code>TypeMapping</code> instances.     */    public TypeMapping[] getPropertyTypes(QName propName) {        synchronized (typeMapping) {            TypeMapping[] types = (TypeMapping[]) typeMapping.get(propName);            if (types != null) {                return types;            } else {                return EMPTY;            }        }    }    public void nodeTypeRegistered(QName ntName) {        try {            NodeTypeDef def = registry.getNodeTypeDef(ntName);            PropDef[] propDefs = def.getPropertyDefs();            synchronized (typeMapping) {                for (int i = 0; i < propDefs.length; i++) {                    int type = propDefs[i].getRequiredType();                    if (!propDefs[i].definesResidual() && type != PropertyType.UNDEFINED) {                        QName name = propDefs[i].getName();                        // only remember defined property types                        TypeMapping[] types = (TypeMapping[]) typeMapping.get(name);                        if (types == null) {                            types = new TypeMapping[1];                        } else {                            TypeMapping[] tmp = new TypeMapping[types.length + 1];                            System.arraycopy(types, 0, tmp, 0, types.length);                            types = tmp;                        }                        types[types.length - 1] = new TypeMapping(ntName, type, propDefs[i].isMultiple());                        typeMapping.put(name, types);                    }                }            }        } catch (NoSuchNodeTypeException e) {            log.error("Unable to get newly registered node type definition for name: " + ntName);        }    }    public void nodeTypeReRegistered(QName ntName) {        nodeTypeUnregistered(ntName);        nodeTypeRegistered(ntName);    }    public void nodeTypeUnregistered(QName ntName) {        // remove all TypeMapping instances refering to this ntName        synchronized (typeMapping) {            Map modified = new HashMap();            for (Iterator it = typeMapping.keySet().iterator(); it.hasNext();) {                QName propName = (QName) it.next();                TypeMapping[] mapping = (TypeMapping[]) typeMapping.get(propName);                List remove = null;                for (int i = 0; i < mapping.length; i++) {                    if (mapping[i].ntName.equals(ntName)) {                        if (remove == null) {                            // not yet created                            remove = new ArrayList(mapping.length);                        }                        remove.add(mapping[i]);                    }                }                if (remove != null) {                    it.remove();                    if (mapping.length == remove.size()) {                        // all removed -> done                    } else {                        // only some removed                        List remaining = new ArrayList(Arrays.asList(mapping));                        remaining.removeAll(remove);                        modified.put(propName, remaining.toArray(new TypeMapping[remaining.size()]));                    }                }            }            // finally re-add the modified mappings            typeMapping.putAll(modified);        }    }    /**     * Initially fills the cache of this registry with property type definitions     * from the {@link org.apache.jackrabbit.core.nodetype.NodeTypeRegistry}.     */    private void fillCache() {        QName[] ntNames = registry.getRegisteredNodeTypes();        for (int i = 0; i < ntNames.length; i++) {            nodeTypeRegistered(ntNames[i]);        }    }    public static class TypeMapping {        /** The property type as an integer */        public final int type;        /** The QName of the node type where this type mapping originated */        final QName ntName;        /** True if the property type is multi-valued */        public final boolean isMultiValued;        private TypeMapping(QName ntName, int type, boolean isMultiValued) {            this.type = type;            this.ntName = ntName;            this.isMultiValued = isMultiValued;        }    }}

⌨️ 快捷键说明

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