Package org.apache.jackrabbit.test.api.nodetype

Source Code of org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  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.test.api.nodetype;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Comparator;

import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.nodetype.ItemDefinition;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.OnParentVersionAction;

import org.apache.jackrabbit.test.AbstractJCRTest;
import org.apache.jackrabbit.test.NotExecutableException;

/**
* <code>PredefinedNodeTypeTest</code> tests if the predefined node types are
* implemented correctly.
*
* @test
* @sources PredefinedNodeTypeTest.java
* @executeClass org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest
* @keywords level1
*/
public class PredefinedNodeTypeTest extends AbstractJCRTest {

    /**
     * The NodeTypeManager of the session
     */
    private NodeTypeManager manager;

    /**
     * The read-only session for the test
     */
    private Session session;

    /**
     * Sets up the fixture for this test.
     */
    protected void setUp() throws Exception {
        isReadOnly = true;
        super.setUp();

        session = helper.getReadOnlySession();
        manager = session.getWorkspace().getNodeTypeManager();
    }

    /**
     * Releases the session aquired in {@link #setUp()}.
     */
    protected void tearDown() throws Exception {
        if (session != null) {
            session.logout();
        }
        super.tearDown();
    }

    /**
     * Tests if all primary node types are subtypes of node type <code>nt:base</code>
     */
    public void testIfPrimaryNodeTypesAreSubtypesOfNTBase()
            throws RepositoryException {
        NodeTypeIterator types = manager.getPrimaryNodeTypes();
        while (types.hasNext()) {
            NodeType type = types.nextNodeType();
            assertTrue("Primary node type " + type.getName() +
                    " must inherit nt:base",
                    type.isNodeType("nt:base"));
        }
    }

    /** Test for the predefined mix:lockable node type. */
    public void testLockable() throws NotExecutableException {
        testPredefinedNodeType("mix:lockable");
    }

    /** Test for the predefined mix:referenceable node type. */
    public void testReferenceable() throws NotExecutableException {
        testPredefinedNodeType("mix:referenceable");
    }

    /** Test for the predefined mix:versionable node type. */
    public void testVersionable() throws NotExecutableException {
        testPredefinedNodeType("mix:versionable");
    }

    /** Test for the predefined nt:base node type. */
    public void testBase() throws NotExecutableException {
        testPredefinedNodeType("nt:base");
    }

    /** Test for the predefined nt:unstructured node type. */
    public void testUnstructured() throws NotExecutableException {
        testPredefinedNodeType("nt:unstructured");
    }

    /** Test for the predefined nt:hierarchyNode node type. */
    public void testHierarchyNode() throws NotExecutableException {
        testPredefinedNodeType("nt:hierarchyNode");
    }

    /** Test for the predefined nt:file node type. */
    public void testFile() throws NotExecutableException {
        testPredefinedNodeType("nt:file");
    }

    /** Test for the predefined nt:linkedFile node type. */
    public void testLinkedFile() throws NotExecutableException {
        testPredefinedNodeType("nt:linkedFile");
    }

    /** Test for the predefined nt:folder node type. */
    public void testFolder() throws NotExecutableException {
        testPredefinedNodeType("nt:folder");
    }

    /** Test for the predefined nt:nodeType node type. */
    public void testNodeType() throws NotExecutableException {
        testPredefinedNodeType("nt:nodeType");
    }

    /** Test for the predefined nt:propertyDef node type. */
    public void testPropertyDef() throws NotExecutableException {
        testPredefinedNodeType("nt:propertyDefinition");
    }

    /** Test for the predefined nt:childNodeDef node type. */
    public void testChildNodeDef() throws NotExecutableException {
        testPredefinedNodeType("nt:childNodeDefinition");
    }

    /** Test for the predefined nt:versionHistory node type. */
    public void testVersionHistory() throws NotExecutableException {
        testPredefinedNodeType("nt:versionHistory");
    }

    /** Test for the predefined nt:versionLabels node type. */
    public void testVersionLabels() throws NotExecutableException {
        testPredefinedNodeType("nt:versionLabels");
    }

    /** Test for the predefined nt:version node type. */
    public void testVersion() throws NotExecutableException {
        testPredefinedNodeType("nt:version");
    }

    /** Test for the predefined nt:frozenNode node type. */
    public void testFrozenNode() throws NotExecutableException {
        testPredefinedNodeType("nt:frozenNode");
    }

    /** Test for the predefined nt:versionedChild node type. */
    public void testVersionedChild() throws NotExecutableException {
        testPredefinedNodeType("nt:versionedChild");
    }

    /** Test for the predefined nt:query node type. */
    public void testQuery() throws NotExecutableException {
        testPredefinedNodeType("nt:query");
    }

    /** Test for the predefined nt:resource node type. */
    public void testResource() throws NotExecutableException {
        testPredefinedNodeType("nt:resource");
    }

    /**
     * Tests that the named node type matches the JSR 170 specification.
     * The test is performed by genererating a node type definition spec
     * string in the format used by the JSR 170 specification, and comparing
     * the result with a static spec file extracted from the specification
     * itself.
     * <p>
     * Note that the extracted spec files are not exact copies of the node
     * type specification in the JSR 170 document. Some formatting and
     * ordering changes have been made to simplify the test code, but the
     * semantics remain the same.
     *
     * @param name node type name
     * @throws NotExecutableException if the node type is not supported by
     *   this repository implementation.
     */
    private void testPredefinedNodeType(String name)
            throws NotExecutableException {
        try {
            StringBuffer spec = new StringBuffer();
            String resource =
                "org/apache/jackrabbit/test/api/nodetype/spec/"
                + name.replace(':', '-') + ".txt";
            Reader reader = new InputStreamReader(
                    getClass().getClassLoader().getResourceAsStream(resource));
            for (int ch = reader.read(); ch != -1; ch = reader.read()) {
                spec.append((char) ch);
            }

            NodeType type = manager.getNodeType(name);
            String current = getNodeTypeSpec(type);
            if (!System.getProperty("line.separator").equals("\n")) {
                current = normalizeLineSeparators(current);
            }
            String expected = normalizeLineSeparators(spec.toString());

            assertEquals("Predefined node type " + name, expected, current);
        } catch (IOException e) {
            fail(e.getMessage());
        } catch (NoSuchNodeTypeException e) {
            // only nt:base is strictly required
            if ("nt:base".equals(name)) {
                fail(e.getMessage());
            } else {
                throw new NotExecutableException("NodeType " + name +
                        " not supported by this repository implementation.");
            }
        } catch (RepositoryException e) {
            fail(e.getMessage());
        }
    }

    /**
     * Creates and returns a spec string for the given node type definition.
     * The returned spec string follows the node type definition format
     * used in the JSR 170 specification.
     *
     * @param type node type definition
     * @return spec string
     * @throws RepositoryException on repository errors
     */
    private static String getNodeTypeSpec(NodeType type)
            throws RepositoryException {
        StringWriter buffer = new StringWriter();

        PrintWriter writer = new PrintWriter(buffer);
        writer.println("NodeTypeName");
        writer.println("  " + type.getName());
        writer.println("Supertypes");
        NodeType[] supertypes = type.getDeclaredSupertypes();
        if (supertypes.length > 0) {
            Arrays.sort(supertypes, NODE_TYPE_COMPARATOR);
            for (int i = 0; i < supertypes.length; i++) {
                writer.println("  " + supertypes[i].getName());
            }
        } else {
            writer.println("  []");
        }
        writer.println("IsMixin");
        writer.println("  " + type.isMixin());
        writer.println("HasOrderableChildNodes");
        writer.println("  " + type.hasOrderableChildNodes());
        writer.println("PrimaryItemName");
        writer.println("  " + type.getPrimaryItemName());
        NodeDefinition[] nodes = type.getDeclaredChildNodeDefinitions();
        Arrays.sort(nodes, NODE_DEF_COMPARATOR);
        for (int i = 0; i < nodes.length; i++) {
            writer.print(getChildNodeDefSpec(nodes[i]));
        }
        PropertyDefinition[] properties = type.getDeclaredPropertyDefinitions();
        Arrays.sort(properties, PROPERTY_DEF_COMPARATOR);
        for (int i = 0; i < properties.length; i++) {
            writer.print(getPropertyDefSpec(properties[i]));
        }

        return buffer.toString();
    }

    /**
     * Creates and returns a spec string for the given node definition.
     * The returned spec string follows the child node definition format
     * used in the JSR 170 specification.
     *
     * @param node child node definition
     * @return spec string
     */
    private static String getChildNodeDefSpec(NodeDefinition node) {
        StringWriter buffer = new StringWriter();

        PrintWriter writer = new PrintWriter(buffer);
        writer.println("ChildNodeDefinition");
        if (node.getName().equals("*")) {
            writer.println("  Name \"*\"");
        } else {
            writer.println("  Name " + node.getName());
        }
        writer.print("  RequiredPrimaryTypes [");
        NodeType[] types = node.getRequiredPrimaryTypes();
        Arrays.sort(types, NODE_TYPE_COMPARATOR);
        for (int j = 0; j < types.length; j++) {
            if (j > 0) {
                writer.print(',');
            }
            writer.print(types[j].getName());
        }
        writer.println("]");
        if (node.getDefaultPrimaryType() != null) {
            writer.println("  DefaultPrimaryType "
                    + node.getDefaultPrimaryType().getName());
        } else {
            writer.println("  DefaultPrimaryType null");
        }
        writer.println("  AutoCreated " + node.isAutoCreated());
        writer.println("  Mandatory " + node.isMandatory());
        writer.println("  OnParentVersion "
                + OnParentVersionAction.nameFromValue(node.getOnParentVersion()));
        writer.println("  Protected " + node.isProtected());
        writer.println("  SameNameSiblings " + node.allowsSameNameSiblings());

        return buffer.toString();
    }

    /**
     * Creates and returns a spec string for the given property definition.
     * The returned spec string follows the property definition format
     * used in the JSR 170 specification.
     *
     * @param property property definition
     * @return spec string
     * @throws RepositoryException on repository errors
     */
    private static String getPropertyDefSpec(PropertyDefinition property)
            throws RepositoryException {
        StringWriter buffer = new StringWriter();

        PrintWriter writer = new PrintWriter(buffer);
        writer.println("PropertyDefinition");
        if (property.getName().equals("*")) {
            writer.println("  Name \"*\"");
        } else {
            writer.println("  Name " + property.getName());
        }
        String type = PropertyType.nameFromValue(property.getRequiredType());
        writer.println("  RequiredType " + type.toUpperCase());
        writer.print("  ValueConstraints [");
        String[] constraints = property.getValueConstraints();
        for (int i = 0; i < constraints.length; i++) {
            if (i > 0) {
                writer.print(',');
            }
            writer.print(constraints[i]);
        }
        writer.println("]");
        Value[] values = property.getDefaultValues();
        if (values != null && values.length > 0) {
            writer.print("  DefaultValues [");
            for (int j = 0; j < values.length; j++) {
                if (j > 0) {
                    writer.print(',');
                }
                writer.print(values[j].getString());
            }
            writer.println("]");
        } else {
            writer.println("  DefaultValues null");
        }
        writer.println("  AutoCreated " + property.isAutoCreated());
        writer.println("  Mandatory " + property.isMandatory());
        String action = OnParentVersionAction.nameFromValue(
                property.getOnParentVersion());
        writer.println("  OnParentVersion " + action);
        writer.println("  Protected " + property.isProtected());
        writer.println("  Multiple " + property.isMultiple());

        return buffer.toString();
    }

    /**
     * Replaces platform-dependant line-separators in <code>stringValue</code>
     * with "\n".
     *
     * @param stringValue string to normalize
     * @return the normalized string
     */
    private String normalizeLineSeparators(String stringValue) {
        // Replace "\r\n" (Windows format) with "\n" (Unix format)
        stringValue = stringValue.replaceAll("\r\n", "\n");
        // Replace "\r" (Mac format) with "\n" (Unix format)
        stringValue = stringValue.replaceAll("\r", "\n");

        return stringValue;
    }

    /**
     * Comparator for ordering node definition arrays. Node definitions are
     * ordered by name, with the wildcard item definition ("*") ordered last.
     */
    private static final Comparator NODE_DEF_COMPARATOR = new Comparator() {
        public int compare(Object a, Object b) {
            NodeDefinition nda = (NodeDefinition) a;
            NodeDefinition ndb = (NodeDefinition) b;
            if (nda.getName().equals("*") && !ndb.getName().equals("*")) {
                return 1;
            } else if (!nda.getName().equals("*") && ndb.getName().equals("*")) {
                return -1;
            } else {
                return nda.getName().compareTo(ndb.getName());
            }
        }
    };

    /**
     * Comparator for ordering property definition arrays. Property definitions
     * are ordered by name, with the wildcard item definition ("*") ordered
     * last, and isMultiple flag, with <code>isMultiple==true</code> ordered last.
     */
    private static final Comparator PROPERTY_DEF_COMPARATOR = new Comparator() {
        public int compare(Object a, Object b) {
            PropertyDefinition pda = (PropertyDefinition) a;
            PropertyDefinition pdb = (PropertyDefinition) b;
            if (pda.getName().equals("*") && !pdb.getName().equals("*")) {
                return 1;
            } else if (!pda.getName().equals("*") && pdb.getName().equals("*")) {
                return -1;
            }
            int result = pda.getName().compareTo(pdb.getName());
            if (result != 0) {
                return result;
            }
            if (pda.isMultiple() && !pdb.isMultiple()) {
                return 1;
            } else if (!pda.isMultiple() && pdb.isMultiple()) {
                return -1;
            } else {
                return 0;
            }
        }
    };

    /**
     * Comparator for ordering node type arrays. Node types are ordered by
     * name, with all primary node types ordered before mixin node types.
     */
    private static final Comparator NODE_TYPE_COMPARATOR = new Comparator() {
        public int compare(Object a, Object b) {
            NodeType nta = (NodeType) a;
            NodeType ntb = (NodeType) b;
            if (nta.isMixin() && !ntb.isMixin()) {
                return 1;
            } else if (!nta.isMixin() && ntb.isMixin()) {
                return -1;
            } else {
                return nta.getName().compareTo(ntb.getName());
            }
        }
    };

}
TOP

Related Classes of org.apache.jackrabbit.test.api.nodetype.PredefinedNodeTypeTest

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.