Package org.apache.jackrabbit.core.nodetype

Source Code of org.apache.jackrabbit.core.nodetype.NodeTypeDef

/*
* 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.spi.Name;
import org.apache.jackrabbit.spi.commons.name.NameConstants;

import javax.jcr.PropertyType;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

/**
* A <code>NodeTypeDef</code> holds the definition of a node type.
*/
public class NodeTypeDef implements Cloneable {

    private Name name;

    /**
     * Ordered array of supertype names. Empty if no supertypes have been
     * specified. Never <code>null</code>.
     */
    private Name[] supertypes;

    private boolean mixin;
    private boolean orderableChildNodes;
   
    private boolean abstractStatus;
    private Name primaryItemName;

    private HashSet propDefs;
    private HashSet nodeDefs;
    private Set dependencies;

    /**
     * Default constructor.
     */
    public NodeTypeDef() {
        dependencies = null;
        name = null;
        primaryItemName = null;
        nodeDefs = new HashSet();
        propDefs = new HashSet();
        supertypes = Name.EMPTY_ARRAY;
        mixin = false;
        orderableChildNodes = false;
        abstractStatus = false;
    }

    /**
     * Returns a collection of node type <code>Name</code>s that are being
     * referenced by <i>this</i> node type definition (e.g. as supertypes, as
     * required/default primary types in child node definitions, as REFERENCE
     * value constraints in property definitions).
     * <p/>
     * Note that self-references (e.g. a child node definition that specifies
     * the declaring node type as the default primary type) are not considered
     * dependencies.
     *
     * @return a collection of node type <code>Name</code>s
     */
    public Collection getDependencies() {
        if (dependencies == null) {
            dependencies = new HashSet();
            // supertypes
            dependencies.addAll(Arrays.asList(supertypes));
            // child node definitions
            for (Iterator iter = nodeDefs.iterator(); iter.hasNext();) {
                NodeDef nd = (NodeDef) iter.next();
                // default primary type
                Name ntName = nd.getDefaultPrimaryType();
                if (ntName != null && !name.equals(ntName)) {
                    dependencies.add(ntName);
                }
                // required primary type
                Name[] ntNames = nd.getRequiredPrimaryTypes();
                for (int j = 0; j < ntNames.length; j++) {
                    if (ntNames[j] != null && !name.equals(ntNames[j])) {
                        dependencies.add(ntNames[j]);
                    }
                }
            }
            // property definitions
            for (Iterator iter = propDefs.iterator(); iter.hasNext();) {
                PropDef pd = (PropDef) iter.next();
                // REFERENCE value constraints
                if (pd.getRequiredType() == PropertyType.REFERENCE) {
                    ValueConstraint[] ca = pd.getValueConstraints();
                    if (ca != null) {
                        for (int j = 0; j < ca.length; j++) {
                            ReferenceConstraint rc = (ReferenceConstraint) ca[j];
                            if (!name.equals(rc.getNodeTypeName())) {
                                dependencies.add(rc.getNodeTypeName());
                            }
                        }
                    }
                }
            }
        }
        return dependencies;
    }

    private void resetDependencies() {
        dependencies = null;
    }

    //----------------------------------------------------< setters & getters >
    /**
     * Sets the name of the node type being defined.
     *
     * @param name The name of the node type.
     */
    public void setName(Name name) {
        this.name = name;
    }

    /**
     * Sets the supertypes.
     *
     * @param names the names of the supertypes.
     */
    public void setSupertypes(Name[] names) {
        resetDependencies();
        // Optimize common cases (zero or one supertypes)
        if (names.length == 0) {
            supertypes = Name.EMPTY_ARRAY;
        } else if (names.length == 1) {
            supertypes = new Name[] { names[0] };
        } else {
            // Sort and remove duplicates
            SortedSet types = new TreeSet();
            types.addAll(Arrays.asList(names));
            supertypes = (Name[]) types.toArray(new Name[types.size()]);
        }
    }

    /**
     * Sets the mixin flag.
     *
     * @param mixin flag
     */
    public void setMixin(boolean mixin) {
        this.mixin = mixin;
    }

    /**
     * Sets the orderableChildNodes flag.
     *
     * @param orderableChildNodes flag
     */
    public void setOrderableChildNodes(boolean orderableChildNodes) {
        this.orderableChildNodes = orderableChildNodes;
    }

    /**
     * Sets the 'abstract' flag.
     *
     * @param abstractStatus flag
     */
    public void setAbstract(boolean abstractStatus) {
        this.abstractStatus = abstractStatus;
    }

    /**
     * Sets the name of the primary item (one of the child items of the node's
     * of this node type)
     *
     * @param primaryItemName The name of the primary item.
     */
    public void setPrimaryItemName(Name primaryItemName) {
        this.primaryItemName = primaryItemName;
    }

    /**
     * Sets the property definitions.
     *
     * @param defs An array of <code>PropertyDef</code> objects.
     */
    public void setPropertyDefs(PropDef[] defs) {
        resetDependencies();
        propDefs.clear();
        propDefs.addAll(Arrays.asList(defs));
    }

    /**
     * Sets the child node definitions.
     *
     * @param defs An array of <code>NodeDef</code> objects
     */
    public void setChildNodeDefs(NodeDef[] defs) {
        resetDependencies();
        nodeDefs.clear();
        nodeDefs.addAll(Arrays.asList(defs));
    }

    /**
     * Returns the name of the node type being defined or
     * <code>null</code> if not set.
     *
     * @return the name of the node type or <code>null</code> if not set.
     */
    public Name getName() {
        return name;
    }

    /**
     * Returns an array containing the names of the supertypes. If no
     * supertypes have been specified, then an empty array is returned
     * for mixin types and the <code>nt:base</code> primary type and
     * an array containing just <code>nt:base<code> for other primary types.
     * <p>
     * The returned array must not be modified by the application.
     *
     * @return a sorted array of supertype names
     */
    public Name[] getSupertypes() {
        if (supertypes.length > 0
                || isMixin() || NameConstants.NT_BASE.equals(getName())) {
            return supertypes;
        } else {
            return new Name[] { NameConstants.NT_BASE };
        }
    }

    /**
     * Returns the value of the mixin flag.
     *
     * @return true if this is a mixin node type; false otherwise.
     */
    public boolean isMixin() {
        return mixin;
    }

    /**
     * Returns the value of the orderableChildNodes flag.
     *
     * @return true if nodes of this node type can have orderable child nodes; false otherwise.
     */
    public boolean hasOrderableChildNodes() {
        return orderableChildNodes;
    }

    /**
     * Returns the value of the 'abstract' flag.
     *
     * @return true if this node type is abstract; false otherwise.
     */
    public boolean isAbstract() {
        return abstractStatus;
    }

    /**
     * Returns the name of the primary item (one of the child items of the
     * node's of this node type) or <code>null</code> if not set.
     *
     * @return the name of the primary item or <code>null</code> if not set.
     */
    public Name getPrimaryItemName() {
        return primaryItemName;
    }

    /**
     * Returns an array containing the property definitions or
     * <code>null</code> if not set.
     *
     * @return an array containing the property definitions or
     *         <code>null</code> if not set.
     */
    public PropDef[] getPropertyDefs() {
        if (propDefs.isEmpty()) {
            return PropDef.EMPTY_ARRAY;
        }
        return (PropDef[]) propDefs.toArray(new PropDef[propDefs.size()]);
    }

    /**
     * Returns an array containing the child node definitions or
     * <code>null</code> if not set.
     *
     * @return an array containing the child node definitions or
     *         <code>null</code> if not set.
     */
    public NodeDef[] getChildNodeDefs() {
        if (nodeDefs.isEmpty()) {
            return NodeDef.EMPTY_ARRAY;
        }
        return (NodeDef[]) nodeDefs.toArray(new NodeDef[nodeDefs.size()]);
    }

    //-------------------------------------------< java.lang.Object overrides >
    public Object clone() {
        NodeTypeDef clone = new NodeTypeDef();
        clone.name = name;
        clone.primaryItemName = primaryItemName;
        clone.supertypes = supertypes; // immutable, thus ok to share
        clone.mixin = mixin;
        clone.orderableChildNodes = orderableChildNodes;
        clone.nodeDefs = (HashSet) nodeDefs.clone();
        clone.propDefs = (HashSet) propDefs.clone();
        return clone;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof NodeTypeDef) {
            NodeTypeDef other = (NodeTypeDef) obj;
            return (name == null ? other.name == null : name.equals(other.name))
                    && (primaryItemName == null ? other.primaryItemName == null : primaryItemName.equals(other.primaryItemName))
                    && Arrays.equals(getSupertypes(), other.getSupertypes())
                    && mixin == other.mixin
                    && orderableChildNodes == other.orderableChildNodes
                    && propDefs.equals(other.propDefs)
                    && nodeDefs.equals(other.nodeDefs);
        }
        return false;
    }

    /**
     * Returns zero to satisfy the Object equals/hashCode contract.
     * This class is mutable and not meant to be used as a hash key.
     *
     * @return always zero
     * @see Object#hashCode()
     */
    public int hashCode() {
        return 0;
    }
}
TOP

Related Classes of org.apache.jackrabbit.core.nodetype.NodeTypeDef

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.