Package org.apache.jackrabbit.core.nodetype.xml

Source Code of org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter

/*
* Copyright 2004-2005 The Apache Software Foundation or its licensors,
*                     as applicable.
*
* Licensed 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.xml;

import org.apache.jackrabbit.core.nodetype.NodeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
import org.apache.jackrabbit.core.nodetype.PropDef;
import org.apache.jackrabbit.core.nodetype.ValueConstraint;
import org.apache.jackrabbit.core.util.DOMBuilder;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.NoPrefixDeclaredException;
import org.apache.jackrabbit.name.QName;

import javax.jcr.NamespaceRegistry;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.version.OnParentVersionAction;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.OutputStream;

/**
* Node type definition writer. This class is used to write the
* persistent node type definition files used by Jackrabbit.
*/
public final class NodeTypeWriter {

    /**
     * Writes a node type definition file. The file contents are written
     * to the given output stream and will contain the given node type
     * definitions. The given namespace registry is used for namespace
     * mappings.
     *
     * @param xml XML output stream
     * @param registry namespace registry
     * @param types node types
     * @throws IOException         if the node type definitions cannot
     *                             be written
     * @throws RepositoryException on repository errors
     */
    public static void write(
            OutputStream xml, NodeTypeDef[] types, NamespaceRegistry registry)
            throws IOException, RepositoryException {
        try {
            NodeTypeWriter writer = new NodeTypeWriter(registry);
            for (int i = 0; i < types.length; i++) {
                writer.addNodeTypeDef(types[i]);
            }
            writer.write(xml);
        } catch (ParserConfigurationException e) {
            throw new IOException(e.getMessage());
        } catch (NoPrefixDeclaredException e) {
            throw new RepositoryException(
                    "Invalid namespace reference in a node type definition", e);
        }
    }

    /** The node type document builder. */
    private final DOMBuilder builder;

    /** The namespace resolver. */
    private final NamespaceResolver resolver;

    /**
     * Creates a node type definition file writer. The given namespace
     * registry is used for the XML namespace bindings.
     *
     * @param registry namespace registry
     * @throws ParserConfigurationException if the node type definition
     *                                      document cannot be created
     * @throws RepositoryException          if the namespace mappings cannot
     *                                      be retrieved from the registry
     */
    private NodeTypeWriter(NamespaceRegistry registry)
            throws ParserConfigurationException, RepositoryException {
        builder = new DOMBuilder(Constants.NODETYPES_ELEMENT);

        String[] prefixes = registry.getPrefixes();
        for (int i = 0; i < prefixes.length; i++) {
            if (!"".equals(prefixes[i])) {
                String uri = registry.getURI(prefixes[i]);
                builder.setAttribute("xmlns:" + prefixes[i], uri);
            }
        }

        resolver = new AdditionalNamespaceResolver(registry);
    }

    /**
     * Builds a node type definition element under the current element.
     *
     * @param def node type definition
     * @throws RepositoryException       if the default property values
     *                                   cannot be serialized
     * @throws NoPrefixDeclaredException if the node type definition contains
     *                                   invalid namespace references
     */
    private void addNodeTypeDef(NodeTypeDef def)
            throws RepositoryException, NoPrefixDeclaredException {
        builder.startElement(Constants.NODETYPE_ELEMENT);

        // simple attributes
        builder.setAttribute(
                Constants.NAME_ATTRIBUTE, def.getName().toJCRName(resolver));
        builder.setAttribute(
                Constants.ISMIXIN_ATTRIBUTE, def.isMixin());
        builder.setAttribute(
                Constants.HASORDERABLECHILDNODES_ATTRIBUTE,
                def.hasOrderableChildNodes());

        // primary item name
        QName item = def.getPrimaryItemName();
        if (item != null) {
            builder.setAttribute(
                    Constants.PRIMARYITEMNAME_ATTRIBUTE,
                    item.toJCRName(resolver));
        } else {
            builder.setAttribute(Constants.PRIMARYITEMNAME_ATTRIBUTE, "");
        }

        // supertype declarations
        QName[] supertypes = def.getSupertypes();
        if (supertypes != null && supertypes.length > 0) {
            builder.startElement(Constants.SUPERTYPES_ELEMENT);
            for (int i = 0; i < supertypes.length; i++) {
                builder.addContentElement(
                        Constants.SUPERTYPE_ELEMENT,
                        supertypes[i].toJCRName(resolver));
            }
            builder.endElement();
        }

        // property definitions
        PropDef[] properties = def.getPropertyDefs();
        for (int i = 0; i < properties.length; i++) {
            addPropDef(properties[i]);
        }

        // child node definitions
        NodeDef[] nodes = def.getChildNodeDefs();
        for (int i = 0; i < nodes.length; i++) {
            addChildNodeDef(nodes[i]);
        }

        builder.endElement();
    }

    /**
     * Builds a property definition element under the current element.
     *
     * @param def property definition
     * @throws RepositoryException       if the default values cannot
     *                                   be serialized
     * @throws NoPrefixDeclaredException if the property definition contains
     *                                   invalid namespace references
     */
    private void addPropDef(PropDef def)
            throws RepositoryException, NoPrefixDeclaredException {
        builder.startElement(Constants.PROPERTYDEFINITION_ELEMENT);

        // simple attributes
        builder.setAttribute(
                Constants.NAME_ATTRIBUTE, def.getName().toJCRName(resolver));
        builder.setAttribute(
                Constants.AUTOCREATED_ATTRIBUTE, def.isAutoCreated());
        builder.setAttribute(
                Constants.MANDATORY_ATTRIBUTE, def.isMandatory());
        builder.setAttribute(
                Constants.PROTECTED_ATTRIBUTE, def.isProtected());
        builder.setAttribute(
                Constants.ONPARENTVERSION_ATTRIBUTE,
                OnParentVersionAction.nameFromValue(def.getOnParentVersion()));
        builder.setAttribute(
                Constants.MULTIPLE_ATTRIBUTE, def.isMultiple());
        builder.setAttribute(
                Constants.REQUIREDTYPE_ATTRIBUTE,
                PropertyType.nameFromValue(def.getRequiredType()));

        // value constraints
        ValueConstraint[] constraints = def.getValueConstraints();
        if (constraints != null && constraints.length > 0) {
            builder.startElement(Constants.VALUECONSTRAINTS_ELEMENT);
            for (int i = 0; i < constraints.length; i++) {
                builder.addContentElement(
                        Constants.VALUECONSTRAINT_ELEMENT,
                        constraints[i].getDefinition(resolver));
            }
            builder.endElement();
        }

        // default values
        InternalValue[] defaults = def.getDefaultValues();
        if (defaults != null && defaults.length > 0) {
            builder.startElement(Constants.DEFAULTVALUES_ELEMENT);
            for (int i = 0; i < defaults.length; i++) {
                builder.addContentElement(
                        Constants.DEFAULTVALUE_ELEMENT,
                        defaults[i].toJCRValue(resolver).getString());
            }
            builder.endElement();
        }

        builder.endElement();
    }

    /**
     * Builds a child node definition element under the current element.
     *
     * @param def child node definition
     * @throws NoPrefixDeclaredException if the child node definition contains
     *                                   invalid namespace references
     */
    private void addChildNodeDef(NodeDef def)
            throws NoPrefixDeclaredException {
        builder.startElement(Constants.CHILDNODEDEFINITION_ELEMENT);

        // simple attributes
        builder.setAttribute(
                Constants.NAME_ATTRIBUTE, def.getName().toJCRName(resolver));
        builder.setAttribute(
                Constants.AUTOCREATED_ATTRIBUTE, def.isAutoCreated());
        builder.setAttribute(
                Constants.MANDATORY_ATTRIBUTE, def.isMandatory());
        builder.setAttribute(
                Constants.PROTECTED_ATTRIBUTE, def.isProtected());
        builder.setAttribute(
                Constants.ONPARENTVERSION_ATTRIBUTE,
                OnParentVersionAction.nameFromValue(def.getOnParentVersion()));
        builder.setAttribute(
                Constants.SAMENAMESIBLINGS_ATTRIBUTE, def.allowsSameNameSiblings());

        // default primary type
        QName type = def.getDefaultPrimaryType();
        if (type != null) {
            builder.setAttribute(
                    Constants.DEFAULTPRIMARYTYPE_ATTRIBUTE,
                    type.toJCRName(resolver));
        } else {
            builder.setAttribute(Constants.DEFAULTPRIMARYTYPE_ATTRIBUTE, "");
        }

        // required primary types
        QName[] requiredTypes = def.getRequiredPrimaryTypes();
        builder.startElement(Constants.REQUIREDPRIMARYTYPES_ELEMENT);
        for (int i = 0; i < requiredTypes.length; i++) {
            builder.addContentElement(
                    Constants.REQUIREDPRIMARYTYPE_ELEMENT,
                    requiredTypes[i].toJCRName(resolver));
        }
        builder.endElement();

        builder.endElement();
    }

    /**
     * Writes the node type definition document to the given output stream.
     *
     * @param xml XML output stream
     * @throws IOException if the node type document could not be written
     */
    private void write(OutputStream xml) throws IOException {
        builder.write(xml);
    }

}
TOP

Related Classes of org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter

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.