Package org.apache.jackrabbit.jcr2spi.nodetype

Source Code of org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl

/*
* 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.jcr2spi.nodetype;

import org.apache.commons.collections.map.ReferenceMap;
import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
import org.apache.jackrabbit.spi.commons.conversion.NameException;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.nodetype.AbstractNodeTypeManager;
import org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl;
import org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl;
import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.jcr2spi.util.Dumpable;
import org.apache.jackrabbit.jcr2spi.ManagerProvider;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.QNodeTypeDefinition;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;

import javax.jcr.RepositoryException;
import javax.jcr.PropertyType;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.NamespaceException;
import javax.jcr.version.OnParentVersionAction;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeTypeExistsException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.HashSet;
import java.util.List;
import java.io.PrintStream;

/**
* A <code>NodeTypeManagerImpl</code> implements a session dependant
* NodeTypeManager.
*/
public class NodeTypeManagerImpl extends AbstractNodeTypeManager implements NodeTypeDefinitionProvider, NodeTypeRegistryListener, Dumpable {

    /**
     * Logger instance for this class
     */
    private static Logger log = LoggerFactory.getLogger(NodeTypeManagerImpl.class);

    /**
     * The ManagerProvider
     */
    private final ManagerProvider mgrProvider;

    /**
     * The wrapped node type registry.
     */
    private final NodeTypeRegistry ntReg;

    /**
     * The ValueFactory used to build property definitions.
     */
    private final ValueFactory valueFactory;

    /**
     * A cache for <code>NodeType</code> instances created by this
     * <code>NodeTypeManager</code>
     */
    private final Map ntCache;

    /**
     * A cache for <code>PropertyDefinition</code> instances created by this
     * <code>NodeTypeManager</code>
     */
    private final Map pdCache;

    /**
     * A cache for <code>NodeDefinition</code> instances created by this
     * <code>NodeTypeManager</code>
     */
    private final Map ndCache;

    /**
     * Creates a new <code>NodeTypeManagerImpl</code> instance.
     *
     * @param ntReg        node type registry
     * @param mgrProvider  the manager provider
     * @throws RepositoryException If an error occurs.
     */
    public NodeTypeManagerImpl(NodeTypeRegistry ntReg,
                               ManagerProvider mgrProvider) throws RepositoryException {
        this.mgrProvider = mgrProvider;
        this.ntReg = ntReg;
        this.ntReg.addListener(this);
        this.valueFactory = mgrProvider.getJcrValueFactory();

        // setup caches with soft references to node type
        ntCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
        pdCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
        ndCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
    }

    private NamespaceResolver nsResolver() {
        return mgrProvider.getNamespaceResolver();
    }

    private NamePathResolver resolver() {
        return mgrProvider.getNamePathResolver();
    }

    private EffectiveNodeTypeProvider entProvider() {
        return mgrProvider.getEffectiveNodeTypeProvider();
    }

    //--------------------------------------------------------------------------
    /**
     * @param name
     * @return
     * @throws NoSuchNodeTypeException
     */
    public NodeTypeImpl getNodeType(Name name) throws NoSuchNodeTypeException {
        synchronized (ntCache) {
            NodeTypeImpl nt = (NodeTypeImpl) ntCache.get(name);
            if (nt == null) {
                EffectiveNodeType ent = entProvider().getEffectiveNodeType(name);
                QNodeTypeDefinition def = ntReg.getNodeTypeDefinition(name);
                nt = new NodeTypeImpl(ent, def, this, mgrProvider);
                ntCache.put(name, nt);
            }
            return nt;
        }
    }

    /**
     *
     * @param nodeTypeName
     * @return
     */
    public boolean hasNodeType(Name nodeTypeName) {
        boolean isRegistered = ntCache.containsKey(nodeTypeName);
        if (!isRegistered) {
            isRegistered = ntReg.isRegistered(nodeTypeName);
        }
        return isRegistered;
    }

    /**
     * Retrieve the <code>NodeDefinition</code> for the given
     * <code>QNodeDefinition</code>.
     *
     * @param def
     * @return
     */
    public NodeDefinition getNodeDefinition(QNodeDefinition def) {
        synchronized (ndCache) {
            NodeDefinition ndi = (NodeDefinition) ndCache.get(def);
            if (ndi == null) {
                ndi = new NodeDefinitionImpl(def, this, resolver());
                ndCache.put(def, ndi);
            }
            return ndi;
        }
    }

    /**
     * Retrieve the <code>PropertyDefinition</code> for the given
     * <code>QPropertyDefinition</code>.
     *
     * @param def
     * @return
     */
    public PropertyDefinition getPropertyDefinition(QPropertyDefinition def) {
        synchronized (pdCache) {
            PropertyDefinition pdi = (PropertyDefinition) pdCache.get(def);
            if (pdi == null) {
                pdi = new PropertyDefinitionImpl(def, this, resolver(), valueFactory);
                pdCache.put(def, pdi);
            }
            return pdi;
        }
    }

    /**
     * @return the NodeTypeRegistry
     */
    NodeTypeRegistry getNodeTypeRegistry() {
        return ntReg;
    }

    //-----------------------------------------< NodeTypeDefinitionProvider >---
    /**
     * @see NodeTypeDefinitionProvider#getNodeTypeDefinition(org.apache.jackrabbit.spi.Name)
     */
    public QNodeTypeDefinition getNodeTypeDefinition(Name ntName) throws NoSuchNodeTypeException, RepositoryException {
        NodeTypeImpl nt = getNodeType(ntName);
        return nt.getDefinition();
    }

    //-------------------------------------------< NodeTypeRegistryListener >---
    /**
     * {@inheritDoc}
     */
    public void nodeTypeRegistered(Name ntName) {
        // not interested, ignore
    }

    /**
     * {@inheritDoc}
     */
    public void nodeTypeReRegistered(Name ntName) {
        // flush all affected cache entries
        ntCache.remove(ntName);
        try {
            String name = resolver().getJCRName(ntName);
            synchronized (pdCache) {
                Iterator iter = pdCache.values().iterator();
                while (iter.hasNext()) {
                    PropertyDefinition pd = (PropertyDefinition) iter.next();
                    if (name.equals(pd.getDeclaringNodeType().getName())) {
                        iter.remove();
                    }
                }
            }
            synchronized (ndCache) {
                Iterator iter = ndCache.values().iterator();
                while (iter.hasNext()) {
                    NodeDefinition nd = (NodeDefinition) iter.next();
                    if (name.equals(nd.getDeclaringNodeType().getName())) {
                        iter.remove();
                    }
                }
            }
        } catch (NamespaceException e) {
            log.warn(e.getMessage() + " -> clear definition cache." );
            synchronized (pdCache) {
                pdCache.clear();
            }
            synchronized (ndCache) {
                ndCache.clear();
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void nodeTypeUnregistered(Name ntName) {
        // flush all affected cache entries
        ntCache.remove(ntName);
        try {
            String name = resolver().getJCRName(ntName);
            synchronized (pdCache) {
                Iterator iter = pdCache.values().iterator();
                while (iter.hasNext()) {
                    PropertyDefinition pd = (PropertyDefinition) iter.next();
                    if (name.equals(pd.getDeclaringNodeType().getName())) {
                        iter.remove();
                    }
                }
            }
            synchronized (ndCache) {
                Iterator iter = ndCache.values().iterator();
                while (iter.hasNext()) {
                    NodeDefinition nd = (NodeDefinition) iter.next();
                    if (name.equals(nd.getDeclaringNodeType().getName())) {
                        iter.remove();
                    }
                }
            }
        } catch (NamespaceException e) {
            log.warn(e.getMessage() + " -> clear definition cache." );
            synchronized (pdCache) {
                pdCache.clear();
            }
            synchronized (ndCache) {
                ndCache.clear();
            }
        }
    }

    //----------------------------------------------------< NodeTypeManager >---
    /**
     * {@inheritDoc}
     */
    public NodeTypeIterator getAllNodeTypes() throws RepositoryException {
        Name[] ntNames = ntReg.getRegisteredNodeTypes();
        ArrayList list = new ArrayList(ntNames.length);
        for (int i = 0; i < ntNames.length; i++) {
            list.add(getNodeType(ntNames[i]));
        }
        return new NodeTypeIteratorAdapter(list);
    }

    /**
     * {@inheritDoc}
     */
    public NodeTypeIterator getPrimaryNodeTypes() throws RepositoryException {
        Name[] ntNames = ntReg.getRegisteredNodeTypes();
        ArrayList list = new ArrayList(ntNames.length);
        for (int i = 0; i < ntNames.length; i++) {
            NodeType nt = getNodeType(ntNames[i]);
            if (!nt.isMixin()) {
                list.add(nt);
            }
        }
        return new NodeTypeIteratorAdapter(list);
    }

    /**
     * {@inheritDoc}
     */
    public NodeTypeIterator getMixinNodeTypes() throws RepositoryException {
        Name[] ntNames = ntReg.getRegisteredNodeTypes();
        ArrayList list = new ArrayList(ntNames.length);
        for (int i = 0; i < ntNames.length; i++) {
            NodeType nt = getNodeType(ntNames[i]);
            if (nt.isMixin()) {
                list.add(nt);
            }
        }
        return new NodeTypeIteratorAdapter(list);
    }

    /**
     * {@inheritDoc}
     */
    public NodeType getNodeType(String nodeTypeName)
            throws NoSuchNodeTypeException {
        try {
            Name qName = resolver().getQName(nodeTypeName);
            return getNodeType(qName);
        } catch (NamespaceException e) {
            throw new NoSuchNodeTypeException(nodeTypeName, e);
        } catch (NameException e) {
            throw new NoSuchNodeTypeException(nodeTypeName, e);
        }
    }

    /**
     * @see NodeTypeManager#hasNodeType(String)
     */
    public boolean hasNodeType(String name) throws RepositoryException {
        try {
            Name qName = resolver().getQName(name);
            return hasNodeType(qName);
        } catch (NamespaceException e) {
            return false;
        } catch (NameException e) {
            return false;
        }
    }

    /**
     * @see NodeTypeManager#registerNodeTypes(javax.jcr.nodetype.NodeTypeDefinition[], boolean)
     */
    public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate)
            throws RepositoryException {
        List<QNodeTypeDefinition> defs = new ArrayList<QNodeTypeDefinition>(ntds.length);
        for (NodeTypeDefinition definition : ntds) {
            QNodeTypeDefinition qdef = new QNodeTypeDefinitionImpl(definition, resolver(), mgrProvider.getQValueFactory());
            if (!allowUpdate && hasNodeType(qdef.getName())) {
                throw new NodeTypeExistsException("NodeType " + definition.getName() + " already exists.");
            }
            defs.add(qdef);
        }

        getNodeTypeRegistry().registerNodeTypes(defs, allowUpdate);

        List<NodeType> nts = new ArrayList<NodeType>();
        for (Iterator<QNodeTypeDefinition> it = defs.iterator(); it.hasNext();) {
            nts.add(getNodeType(it.next().getName()));
        }
        return new NodeTypeIteratorAdapter(nts);

    }

    /**
     * @see NodeTypeManager#unregisterNodeTypes(String[])
     */
    public void unregisterNodeTypes(String[] names) throws RepositoryException {
        HashSet ntNames = new HashSet();
        for (String name : names) {
            ntNames.add(resolver().getQName(name));
        }
        getNodeTypeRegistry().unregisterNodeTypes(ntNames);
    }

    //-----------------------------------------------------------< Dumpable >---
    /**
     * {@inheritDoc}
     */
    public void dump(PrintStream ps) {
        ps.println("NodeTypeManager (" + this + ")");
        ps.println();
        ps.println("All NodeTypes:");
        ps.println();
        try {
            NodeTypeIterator iter = this.getAllNodeTypes();
            while (iter.hasNext()) {
                NodeType nt = iter.nextNodeType();
                ps.println(nt.getName());
                NodeType[] supertypes = nt.getSupertypes();
                ps.println("\tSupertypes");
                for (int i = 0; i < supertypes.length; i++) {
                    ps.println("\t\t" + supertypes[i].getName());
                }
                ps.println("\tMixin\t" + nt.isMixin());
                ps.println("\tOrderableChildNodes\t" + nt.hasOrderableChildNodes());
                ps.println("\tPrimaryItemName\t" + (nt.getPrimaryItemName() == null ? "<null>" : nt.getPrimaryItemName()));
                PropertyDefinition[] pd = nt.getPropertyDefinitions();
                for (int i = 0; i < pd.length; i++) {
                    ps.print("\tPropertyDefinition");
                    ps.println(" (declared in " + pd[i].getDeclaringNodeType().getName() + ") ");
                    ps.println("\t\tName\t\t" + (pd[i].getName()));
                    String type = pd[i].getRequiredType() == 0 ? "null" : PropertyType.nameFromValue(pd[i].getRequiredType());
                    ps.println("\t\tRequiredType\t" + type);
                    String[] vca = pd[i].getValueConstraints();
                    StringBuffer constraints = new StringBuffer();
                    if (vca == null) {
                        constraints.append("<null>");
                    } else {
                        for (int n = 0; n < vca.length; n++) {
                            if (constraints.length() > 0) {
                                constraints.append(", ");
                            }
                            constraints.append(vca[n]);
                        }
                    }
                    ps.println("\t\tValueConstraints\t" + constraints.toString());
                    Value[] defVals = pd[i].getDefaultValues();
                    StringBuffer defaultValues = new StringBuffer();
                    if (defVals == null) {
                        defaultValues.append("<null>");
                    } else {
                        for (int n = 0; n < defVals.length; n++) {
                            if (defaultValues.length() > 0) {
                                defaultValues.append(", ");
                            }
                            defaultValues.append(defVals[n].getString());
                        }
                    }
                    ps.println("\t\tDefaultValue\t" + defaultValues.toString());
                    ps.println("\t\tAutoCreated\t" + pd[i].isAutoCreated());
                    ps.println("\t\tMandatory\t" + pd[i].isMandatory());
                    ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(pd[i].getOnParentVersion()));
                    ps.println("\t\tProtected\t" + pd[i].isProtected());
                    ps.println("\t\tMultiple\t" + pd[i].isMultiple());
                }
                NodeDefinition[] nd = nt.getChildNodeDefinitions();
                for (int i = 0; i < nd.length; i++) {
                    ps.print("\tNodeDefinition");
                    ps.println(" (declared in " + nd[i].getDeclaringNodeType() + ") ");
                    ps.println("\t\tName\t\t" + nd[i].getName());
                    NodeType[] reqPrimaryTypes = nd[i].getRequiredPrimaryTypes();
                    if (reqPrimaryTypes != null && reqPrimaryTypes.length > 0) {
                        for (int n = 0; n < reqPrimaryTypes.length; n++) {
                            ps.print("\t\tRequiredPrimaryType\t" + reqPrimaryTypes[n].getName());
                        }
                    }
                    NodeType defPrimaryType = nd[i].getDefaultPrimaryType();
                    if (defPrimaryType != null) {
                        ps.print("\n\t\tDefaultPrimaryType\t" + defPrimaryType.getName());
                    }
                    ps.println("\n\t\tAutoCreated\t" + nd[i].isAutoCreated());
                    ps.println("\t\tMandatory\t" + nd[i].isMandatory());
                    ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(nd[i].getOnParentVersion()));
                    ps.println("\t\tProtected\t" + nd[i].isProtected());
                    ps.println("\t\tAllowsSameNameSiblings\t" + nd[i].allowsSameNameSiblings());
                }
            }
            ps.println();
        } catch (RepositoryException e) {
            e.printStackTrace(ps);
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.