Package org.apache.jackrabbit.spi.commons

Source Code of org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl

/*
* 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.spi.commons;

import org.apache.jackrabbit.spi.QNodeTypeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.NameFactory;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.QValueFactory;
import org.apache.jackrabbit.spi.QValueConstraint;
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
import org.apache.jackrabbit.spi.commons.value.ValueFormat;
import org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint;

import javax.jcr.PropertyType;
import javax.jcr.NamespaceException;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.NodeDefinition;
import java.util.Collection;
import java.util.HashSet;
import java.util.Collections;
import java.util.Arrays;
import java.io.Serializable;

/**
* <code>QNodeTypeDefinitionImpl</code> implements a serializable SPI node
* type definition.
*/
public class QNodeTypeDefinitionImpl implements QNodeTypeDefinition, Serializable {

    /**
     * The name of the node definition.
     */
    private final Name name;

    /**
     * The names of the declared super types of this node type definition.
     */
    private final Name[] supertypes;

    /**
     * The names of the supported mixins on this node type (or <code>null</code>)
     */
    private final Name[] supportedMixins;

    /**
     * Indicates whether this is a mixin node type definition.
     */
    private final boolean isMixin;

    /**
     * Indicates whether this is an abstract node type definition.
     */
    private final boolean isAbstract;

    /**
     * Indicates whether this is a queryable node type definition.
     */
    private final boolean isQueryable;

    /**
     * Indicates whether this node type definition has orderable child nodes.
     */
    private final boolean hasOrderableChildNodes;

    /**
     * The name of the primary item or <code>null</code> if none is defined.
     */
    private final Name primaryItemName;

    /**
     * The list of property definitions.
     */
    private final QPropertyDefinition[] propertyDefs;

    /**
     * The list of child node definitions.
     */
    private final QNodeDefinition[] childNodeDefs;

    /**
     * Unmodifiable collection of dependent node type <code>Name</code>s.
     * @see #getDependencies()
     */
    private transient Collection<Name> dependencies;

    /**
     * Copy constructor.
     *
     * @param nt the node type definition.
     */
    public QNodeTypeDefinitionImpl(QNodeTypeDefinition nt) {
        this(nt.getName(), nt.getSupertypes(), nt.getSupportedMixinTypes(),
                nt.isMixin(), nt.isAbstract(), nt.isQueryable(),
                nt.hasOrderableChildNodes(), nt.getPrimaryItemName(),
                nt.getPropertyDefs(), nt.getChildNodeDefs());
    }

    /**
     * Creates a new serializable SPI node type definition.
     *
     * @param name                   the name of the node type
     * @param supertypes             the names of the supertypes
     * @param supportedMixins        the names of supported mixins (or <code>null</code>)
     * @param isMixin                if this is a mixin node type
     * @param isAbstract             if this is an abstract node type definition.
     * @param isQueryable            if this is a queryable node type definition.
     * @param hasOrderableChildNodes if this node type has orderable child
     *                               nodes.
     * @param primaryItemName        the name of the primary item, or
     *                               <code>null</code>.
     * @param declaredPropDefs       the declared property definitions.
     * @param declaredNodeDefs       the declared child node definitions.
     */
    public QNodeTypeDefinitionImpl(Name name,
                                   Name[] supertypes,
                                   Name[] supportedMixins,
                                   boolean isMixin,
                                   boolean isAbstract,
                                   boolean isQueryable,
                                   boolean hasOrderableChildNodes,
                                   Name primaryItemName,
                                   QPropertyDefinition[] declaredPropDefs,
                                   QNodeDefinition[] declaredNodeDefs) {
        this.name = name;
        this.supertypes = supertypes;
        this.supportedMixins = supportedMixins;
        this.isMixin = isMixin;
        this.isAbstract = isAbstract;
        this.isQueryable = isQueryable;
        this.hasOrderableChildNodes = hasOrderableChildNodes;
        this.primaryItemName = primaryItemName;
        this.propertyDefs = getSerializablePropertyDefs(declaredPropDefs);
        this.childNodeDefs = getSerializableNodeDefs(declaredNodeDefs);
    }

    /**
     * Createa a new <code>QNodeTypeDefinitionImpl</code> from a JCR
     * NodeType definition.
     *
     * @param def node type definition
     * @param resolver resolver
     * @param qValueFactory value factory
     * @throws RepositoryException if an error occurs
     */
    public QNodeTypeDefinitionImpl(NodeTypeDefinition def,
                                   NamePathResolver resolver,
                                   QValueFactory qValueFactory)
            throws RepositoryException {
        this(resolver.getQName(def.getName()),
                getNames(def.getDeclaredSupertypeNames(), resolver), null, def.isMixin(),
                def.isAbstract(), def.isQueryable(), def.hasOrderableChildNodes(),
                def.getPrimaryItemName() == null ? null : resolver.getQName(def.getPrimaryItemName()),
                createQPropertyDefinitions(def.getDeclaredPropertyDefinitions(), resolver, qValueFactory),
                createQNodeDefinitions(def.getDeclaredChildNodeDefinitions(), resolver));
    }

    //------------------------------------------------< QNodeTypeDefinition >---
    /**
     * {@inheritDoc}
     */
    public Name getName() {
        return name;
    }

    /**
     * {@inheritDoc}
     */
    public Name[] getSupertypes() {
        Name[] sTypes = new Name[supertypes.length];
        System.arraycopy(supertypes, 0, sTypes, 0, supertypes.length);
        return sTypes;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isMixin() {
        return isMixin;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isAbstract() {
        return isAbstract;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isQueryable() {
        return isQueryable;
    }

    /**
     * {@inheritDoc}
     */
    public boolean hasOrderableChildNodes() {
        return hasOrderableChildNodes;
    }

    /**
     * {@inheritDoc}
     */
    public Name getPrimaryItemName() {
        return primaryItemName;
    }

    /**
     * {@inheritDoc}
     */
    public QPropertyDefinition[] getPropertyDefs() {
        QPropertyDefinition[] pDefs = new QPropertyDefinition[propertyDefs.length];
        System.arraycopy(propertyDefs, 0, pDefs, 0, propertyDefs.length);
        return pDefs;
    }

    /**
     * {@inheritDoc}
     */
    public QNodeDefinition[] getChildNodeDefs() {
        QNodeDefinition[] cnDefs = new QNodeDefinition[childNodeDefs.length];
        System.arraycopy(childNodeDefs, 0, cnDefs, 0, childNodeDefs.length);
        return cnDefs;
    }

    /**
     * {@inheritDoc}
     */
    public Collection getDependencies() {
        if (dependencies == null) {
            Collection<Name> deps = new HashSet<Name>();
            // supertypes
            deps.addAll(Arrays.asList(supertypes));
            // child node definitions
            for (QNodeDefinition childNodeDef : childNodeDefs) {
                // default primary type
                Name ntName = childNodeDef.getDefaultPrimaryType();
                if (ntName != null && !name.equals(ntName)) {
                    deps.add(ntName);
                }
                // required primary type
                Name[] ntNames = childNodeDef.getRequiredPrimaryTypes();
                for (Name ntName1 : ntNames) {
                    if (ntName1 != null && !name.equals(ntName1)) {
                        deps.add(ntName1);
                    }
                }
            }
            // property definitions
            for (QPropertyDefinition propertyDef : propertyDefs) {
                // [WEAK]REFERENCE value constraints
                if (propertyDef.getRequiredType() == PropertyType.REFERENCE
                        || propertyDef.getRequiredType() == PropertyType.WEAKREFERENCE) {
                    QValueConstraint[] ca = propertyDef.getValueConstraints();
                    if (ca != null) {
                        for (QValueConstraint aCa : ca) {
                            NameFactory factory = NameFactoryImpl.getInstance();
                            Name ntName = factory.create(aCa.getString());
                            if (!name.equals(ntName)) {
                                deps.add(ntName);
                            }
                        }
                    }
                }
            }
            dependencies = Collections.unmodifiableCollection(deps);
        }
        return dependencies;
    }
   
    public Name[] getSupportedMixinTypes() {
        if (supportedMixins == null) {
            return null;
        }
        else {
            Name[] mixins = new Name[supportedMixins.length];
            System.arraycopy(supportedMixins, 0, mixins, 0, supportedMixins.length);
            return mixins;
        }
    }
   
    //-------------------------------< internal >-------------------------------

    /**
     * Returns an array of serializable property definitions for
     * <code>propDefs</code>.
     *
     * @param propDefs the SPI property definitions.
     * @return an array of serializable property definitions.
     */
    private static QPropertyDefinition[] getSerializablePropertyDefs(
            QPropertyDefinition[] propDefs) {
        QPropertyDefinition[] serDefs = new QPropertyDefinition[propDefs.length];
        for (int i = 0; i < propDefs.length; i++) {
            if (propDefs[i] instanceof Serializable) {
                serDefs[i] = propDefs[i];
            } else {
                serDefs[i] = new QPropertyDefinitionImpl(propDefs[i]);
            }
        }
        return serDefs;
    }

    /**
     * Returns an array of serializable node definitions for
     * <code>nodeDefs</code>.
     *
     * @param nodeDefs the node definitions.
     * @return an array of serializable node definitions.
     */
    private static QNodeDefinition[] getSerializableNodeDefs(
            QNodeDefinition[] nodeDefs) {
        QNodeDefinition[] serDefs = new QNodeDefinition[nodeDefs.length];
        for (int i = 0; i < nodeDefs.length; i++) {
            if (nodeDefs[i] instanceof Serializable) {
                serDefs[i] = nodeDefs[i];
            } else {
                serDefs[i] = new QNodeDefinitionImpl(nodeDefs[i]);
            }
        }
        return serDefs;
    }

    private static Name[] getNames(String[] jcrNames, NamePathResolver resolver) throws NamespaceException, IllegalNameException {
        Name[] names = new Name[jcrNames.length];
        for (int i = 0; i < jcrNames.length; i++) {
            names[i] = resolver.getQName(jcrNames[i]);
        }
        return names;
    }

    private static QPropertyDefinition[] createQPropertyDefinitions(PropertyDefinition[] pds,
                                                                    NamePathResolver resolver,
                                                                    QValueFactory qValueFactory)
            throws RepositoryException {
        QPropertyDefinition[] declaredPropDefs = new QPropertyDefinition[pds.length];
        for (int i = 0; i < pds.length; i++) {
            PropertyDefinition propDef = pds[i];
            Name name = propDef.getName().equals(QItemDefinitionImpl.ANY_NAME.getLocalName())
                    ? QItemDefinitionImpl.ANY_NAME
                    : resolver.getQName(propDef.getName());
            Name declName = resolver.getQName(propDef.getDeclaringNodeType().getName());
            QValue[] defVls = ValueFormat.getQValues(propDef.getDefaultValues(), resolver, qValueFactory);
            String[] jcrConstraints = propDef.getValueConstraints();
            QValueConstraint[] constraints = new QValueConstraint[jcrConstraints.length];
            for (int j=0; j<constraints.length; j++) {
                constraints[j] = ValueConstraint.create(propDef.getRequiredType(), jcrConstraints[j], resolver);
            }
            declaredPropDefs[i] = new QPropertyDefinitionImpl(
                    name, declName,
                    propDef.isAutoCreated(),
                    propDef.isMandatory(),
                    propDef.getOnParentVersion(),
                    propDef.isProtected(),
                    defVls,
                    propDef.isMultiple(),
                    propDef.getRequiredType(),
                    constraints,
                    propDef.getAvailableQueryOperators(),
                    propDef.isFullTextSearchable(),
                    propDef.isQueryOrderable());
        }
        return declaredPropDefs;
    }

    private static QNodeDefinition[] createQNodeDefinitions(NodeDefinition[] nds, NamePathResolver resolver) throws RepositoryException {
        QNodeDefinition[] declaredNodeDefs = new QNodeDefinition[nds.length];
        for (int i = 0; i < nds.length; i++) {
            NodeDefinition nodeDef = nds[i];
            Name name = nodeDef.getName().equals(QItemDefinitionImpl.ANY_NAME.getLocalName())
                    ? QItemDefinitionImpl.ANY_NAME
                    : resolver.getQName(nodeDef.getName());
            Name declName = resolver.getQName(nodeDef.getDeclaringNodeType().getName());
            Name defaultPrimaryType = nodeDef.getDefaultPrimaryTypeName() == null
                    ? null
                    : resolver.getQName(nodeDef.getDefaultPrimaryTypeName());
            Name[] requiredPrimaryTypes = getNames(nodeDef.getRequiredPrimaryTypeNames(), resolver);

            declaredNodeDefs[i] = new QNodeDefinitionImpl(
                    name,
                    declName,
                    nodeDef.isAutoCreated(),
                    nodeDef.isMandatory(),
                    nodeDef.getOnParentVersion(),
                    nodeDef.isProtected(),
                    defaultPrimaryType,
                    requiredPrimaryTypes,
                    nodeDef.allowsSameNameSiblings());
        }
        return declaredNodeDefs;
    }
}
TOP

Related Classes of org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl

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.