jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r157940 - in incubator/jackrabbit/trunk/src: java/org/apache/jackrabbit/core/nodetype/ java/org/apache/jackrabbit/core/nodetype/xml/ test/org/apache/jackrabbit/core/nodetype/ test/org/apache/jackrabbit/core/nodetype/xml/
Date Thu, 17 Mar 2005 16:12:06 GMT
Author: jukka
Date: Thu Mar 17 08:12:03 2005
New Revision: 157940

URL: http://svn.apache.org/viewcvs?view=rev&rev=157940
Log:
Removed JDOM dependency from nodetype XML handling (JCR-54)
 - converted all JDOM references to the equivalent standard DOM code
 - Moved the rest of XML references out of the NodeTypeDefStore class
 - Added the NodeTypeFormatter facade class
 - Made a number of small changes and restructurings to better match the DOM API
 - Added a mostly complete test case in src/test/o.a.j/core/nodetype/xml
   (the tests in .../test/api/nodetype are more concerned with the nodetype
   API than the XML handling)
 - Added a simple ValueConstraint.equals() method to simplify the test cases
   (fixes a problem in NodeTypeDef.equals())

Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormatter.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/template.xml
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/TestAll.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml
Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ValueConstraint.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java Thu Mar 17 08:12:03 2005
@@ -24,68 +24,43 @@
 import java.util.HashMap;
 import java.util.Iterator;
 
+import javax.jcr.NamespaceRegistry;
 import javax.jcr.RepositoryException;
 
-import org.apache.jackrabbit.core.NamespaceRegistryImpl;
-import org.apache.jackrabbit.core.NamespaceResolver;
 import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeFormat;
-import org.apache.jackrabbit.core.nodetype.xml.AdditionalNamespaceResolver;
-import org.apache.log4j.Logger;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-import org.jdom.output.Format;
-import org.jdom.output.XMLOutputter;
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeFormatter;
 
 /**
  * <code>NodeTypeDefStore</code> ...
  */
 class NodeTypeDefStore {
-    private static Logger log = Logger.getLogger(NodeTypeDefStore.class);
 
-    private static final String ROOT_ELEMENT = "nodeTypes";
+    /** Map of node type names to node type definitions. */
+    private final HashMap ntDefs;
 
-    // map of node type names and node type definitions
-    private HashMap ntDefs;
+    /** The node type definition file formatter. */
+    private final NodeTypeFormatter formatter;
 
     /**
      * Empty default constructor.
      */
-    NodeTypeDefStore() {
+    NodeTypeDefStore() throws RepositoryException {
         ntDefs = new HashMap();
+        formatter = new NodeTypeFormatter();
     }
 
     /**
      * @param in
      * @throws IOException
      * @throws InvalidNodeTypeDefException
-     * @throws RepositoryException
      */
     void load(InputStream in)
-            throws IOException, InvalidNodeTypeDefException, RepositoryException {
-        SAXBuilder builder = new SAXBuilder();
-        Element root;
-        try {
-            Document doc = builder.build(in);
-            root = doc.getRootElement();
-        } catch (JDOMException jde) {
-            String msg = "internal error: failed to parse persistent node type definitions";
-            log.debug(msg);
-            throw new RepositoryException(msg, jde);
-        }
-
-        // read definitions
-        NamespaceResolver resolver = new AdditionalNamespaceResolver(root);
-        Iterator iter =
-            root.getChildren(NodeTypeFormat.NODETYPE_ELEMENT).iterator();
-        while (iter.hasNext()) {
-            NodeTypeFormat format =
-                new NodeTypeFormat(resolver, (Element) iter.next());
-            format.read();
-            add(format.getNodeType());
+            throws IOException, InvalidNodeTypeDefException,
+            RepositoryException {
+        Collection types = formatter.read(in);
+        Iterator iterator = types.iterator();
+        while (iterator.hasNext()) {
+            add((NodeTypeDef) iterator.next());
         }
     }
 
@@ -95,32 +70,9 @@
      * @throws IOException
      * @throws RepositoryException
      */
-    void store(OutputStream out, NamespaceRegistryImpl nsReg)
+    void store(OutputStream out, NamespaceRegistry registry)
             throws IOException, RepositoryException {
-        Element root = new Element(ROOT_ELEMENT);
-
-        // namespace declarations
-        String[] prefixes = nsReg.getPrefixes();
-        for (int i = 0; i < prefixes.length; i++) {
-            String prefix = prefixes[i];
-            if ("".equals(prefix)) {
-                continue;
-            }
-            String uri = nsReg.getURI(prefix);
-            root.addNamespaceDeclaration(Namespace.getNamespace(prefix, uri));
-        }
-
-        // node type definitions
-        Iterator iter = all().iterator();
-        while (iter.hasNext()) {
-            NodeTypeFormat format =
-                new NodeTypeFormat(nsReg, (NodeTypeDef) iter.next());
-            format.write();
-            root.addContent(format.getElement());
-        }
-
-        XMLOutputter serializer = new XMLOutputter(Format.getPrettyFormat());
-        serializer.output(new Document(root), out);
+        formatter.write(out, registry, ntDefs.values());
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ValueConstraint.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ValueConstraint.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ValueConstraint.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ValueConstraint.java Thu Mar 17 08:12:03 2005
@@ -51,6 +51,16 @@
         this.definition = definition;
     }
 
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        } else if (other instanceof ValueConstraint) {
+            return definition.equals(((ValueConstraint) other).definition);
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Returns the original (raw) definition of this constraint.
      *

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java Thu Mar 17 08:12:03 2005
@@ -16,15 +16,17 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
-import java.util.Iterator;
 import java.util.Properties;
 
 import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.Constants;
 import org.apache.jackrabbit.core.NamespaceResolver;
-import org.jdom.Element;
-import org.jdom.Namespace;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 
 /**
  * A simple namespace resolver implementation, that uses the additional
@@ -39,19 +41,35 @@
     private final Properties uriToPrefix = new Properties();
 
     /**
-     * Creates a namespace resolver using the additional namespaces declared
+     * Creates a namespace resolver using the namespaces declared
      * in the given XML element.
      *
      * @param element XML element
      */
     public AdditionalNamespaceResolver(Element element) {
-        Iterator namespaces = element.getAdditionalNamespaces().iterator();
-        while (namespaces.hasNext()) {
-            Namespace namespace = (Namespace) namespaces.next();
-            addNamespace(namespace.getPrefix(), namespace.getURI());
+        NamedNodeMap attributes = element.getAttributes();
+        for (int i = 0; i < attributes.getLength(); i++) {
+            Attr attribute = (Attr) attributes.item(i);
+            if (Constants.NS_XMLNS_PREFIX.equals(attribute.getPrefix())) {
+                addNamespace(attribute.getLocalName(), attribute.getValue());
+            }
         }
-
         addNamespace(Constants.NS_EMPTY_PREFIX, Constants.NS_DEFAULT_URI);
+    }
+
+    /**
+     * Creates a namespace resolver using the namespaces declared
+     * in the given namespace registry.
+     *
+     * @param registry namespace registry
+     * @throws RepositoryException on repository errors
+     */
+    public AdditionalNamespaceResolver(NamespaceRegistry registry)
+            throws RepositoryException {
+        String[] prefixes = registry.getPrefixes();
+        for (int i = 0; i < prefixes.length; i++) {
+            addNamespace(prefixes[i], registry.getURI(prefixes[i]));
+        }
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java Thu Mar 17 08:12:03 2005
@@ -16,7 +16,9 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
+import java.util.Collection;
 import java.util.Iterator;
+import java.util.Vector;
 
 import org.apache.jackrabbit.core.Constants;
 import org.apache.jackrabbit.core.IllegalNameException;
@@ -25,7 +27,11 @@
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.UnknownPrefixException;
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
-import org.jdom.Element;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
 
 /**
  * Common functionality shared by the format classes.
@@ -38,6 +44,10 @@
     /** The wildcard name */
     private static final String WILDCARD = "*";
 
+    /** The wildcard qualified name. */
+    private static final QName WILDCARD_NAME =
+        new QName(Constants.NS_DEFAULT_URI, WILDCARD);
+
     /** The namespace resolver. */
     private final NamespaceResolver resolver;
 
@@ -65,17 +75,9 @@
     }
 
     /**
-     * Returns the formatted XML element.
-     *
-     * @return XML element
-     */
-    public Element getElement() {
-        return element;
-    }
-
-    /**
      * Converts the given JCR name to a qualified name using the associated
-     * namespace resolver.
+     * namespace resolver. The wildcard name are converted to the special
+     * wildcard qualified name.
      *
      * @param name JCR name
      * @return qualified name
@@ -85,7 +87,7 @@
             throws InvalidNodeTypeDefException {
         try {
             if (WILDCARD.equals(name)) {
-                return new QName(Constants.NS_DEFAULT_URI, WILDCARD);
+                return WILDCARD_NAME;
             } else {
                 return QName.fromJCRName(name, resolver);
             }
@@ -129,13 +131,13 @@
      * @throws InvalidNodeTypeDefException if the attribute does not exist
      */
     protected String getAttribute(String name) throws InvalidNodeTypeDefException {
-        String value = element.getAttributeValue(name);
+        String value = element.getAttribute(name);
         if (value != null) {
             return value;
         } else {
             throw new InvalidNodeTypeDefException(
                     "Missing attribute " + name
-                    + " in element " + element.getName());
+                    + " in element " + element.getNodeName());
         }
     }
 
@@ -150,23 +152,124 @@
     }
 
     /**
-     * Returns the named child element of the XML element.
+     * Returns an iterator of all the named child elements of the XML element.
      *
-     * @param name child element name
-     * @return child element
+     * @param childName child element name
+     * @return child element iterator
      */
-    protected Element getChild(String name) {
-        return element.getChild(name);
+    protected Iterator getChildElements(String childName) {
+        Vector children = new Vector();
+
+        NodeList nodes = element.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType() == Node.ELEMENT_NODE
+                    && childName.equals(node.getNodeName())) {
+                children.add(node);
+            }
+        }
+
+        return children.iterator();
     }
 
     /**
-     * Returns an iterator of all the named child elements of the XML element.
+     * Returns the text contents of all the named grand child elements
+     * of the XML element. Returns <code>null</code> if the named child
+     * element does not exist.
      *
-     * @param name child element name
-     * @return child element iterator
+     * @param childName child element name
+     * @param grandChildName grand child element name
+     * @return grand child contents, or <code>null</code>
      */
-    protected Iterator getChildIterator(String name) {
-        return element.getChildren(name).iterator();
+    protected Collection getGrandChildContents(
+            String childName, String grandChildName) {
+        NodeList children = element.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++ ) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE
+                    && childName.equals(child.getNodeName())) {
+                Vector contents = new Vector();
+
+                NodeList nodes = child.getChildNodes();
+                for (int j = 0; j < nodes.getLength(); j++) {
+                    Node node = nodes.item(j);
+                    if (node.getNodeType() == Node.ELEMENT_NODE
+                            && grandChildName.equals(node.getNodeName())) {
+                        contents.add(getContents(node));
+                    }
+                }
+
+                return contents;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Utility method to get the text contents of an XML element.
+     *
+     * @param element XML element
+     * @return trimmed text contents of the element
+     */
+    private static String getContents(Node element) {
+        StringBuffer text = new StringBuffer();
+
+        NodeList nodes = element.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType() == Node.TEXT_NODE) {
+                text.append(((CharacterData) node).getData());
+            }
+        }
+
+        return text.toString().trim();
+    }
+
+    /**
+     * Adds the given collection of string values as a grand child
+     * element structure. Each value in the collection is added as
+     * a separate grand child element below the created child element.
+     *
+     * @param childName child element name
+     * @param grandChildName grand child element name
+     * @param contents string value collection
+     */
+    protected void setGrandChildContents(
+            String childName, String grandChildName, Collection contents) {
+        Element child = newElement(childName);
+
+        Iterator iterator = contents.iterator();
+        while (iterator.hasNext()) {
+            String value = (String) iterator.next();
+            child.appendChild(newElement(grandChildName, value));
+        }
+
+        addChild(child);
+    }
+
+    /**
+     * Creates a new XML element.
+     *
+     * @param name element name
+     * @return XML element
+     */
+    protected Element newElement(String name) {
+        return element.getOwnerDocument().createElement(name);
+    }
+
+    /**
+     * Creates a new XML element with the given text content.
+     *
+     * @param name element name
+     * @param content element content
+     * @return XML element
+     */
+    protected Element newElement(String name, String content) {
+        Element element = newElement(name);
+        Text text = element.getOwnerDocument().createTextNode(content);
+        element.appendChild(text);
+        return element;
     }
 
     /**
@@ -175,7 +278,7 @@
      * @param child child element
      */
     protected void addChild(Element child) {
-        element.addContent(child);
+        element.appendChild(child);
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java Thu Mar 17 08:12:03 2005
@@ -21,7 +21,7 @@
 import org.apache.jackrabbit.core.NamespaceResolver;
 import org.apache.jackrabbit.core.nodetype.ChildItemDef;
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
-import org.jdom.Element;
+import org.w3c.dom.Element;
 
 /**
  * Common functionality shared by the property and node definition format

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java Thu Mar 17 08:12:03 2005
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.Vector;
 
@@ -23,16 +24,13 @@
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
-import org.jdom.Element;
+import org.w3c.dom.Element;
 
 /**
  * Utility class for reading and writing node definition XML elements.
  */
 class NodeDefFormat extends ItemDefFormat {
 
-    /** Name of the child node definition element. */
-    public static final String CHILDNODEDEF_ELEMENT = "childNodeDef";
-
     /** Name of the required primary types element. */
     private static final String REQUIREDPRIMARYTYPES_ELEMENT =
         "requiredPrimaryTypes";
@@ -52,60 +50,26 @@
     private final ChildNodeDef def;
 
     /**
-     * Creates a node definition format object. This constructor
-     * is used internally by the public reader and writer constructors.
+     * Creates a node definition format object.
      *
      * @param resolver namespace resolver
      * @param element node definition element
      * @param def node definition
      */
-    private NodeDefFormat(
+    protected NodeDefFormat(
             NamespaceResolver resolver, Element element, ChildNodeDef def) {
         super(resolver, element, def);
         this.def = def;
     }
 
     /**
-     * Creates a node definition reader. An empty node definition instance
-     * is created. The instance properties are filled in by the
-     * {@link #read(QName) read} method.
-     *
-     * @param resolver namespace resolver
-     * @param element node definition element
-     */
-    public NodeDefFormat(NamespaceResolver resolver, Element element) {
-        this(resolver, element, new ChildNodeDef());
-    }
-
-    /**
-     * Creates a node definition writer. The node definition element is
-     * instantiated as an empty <code>childNodeDef</code> element.
-     * The element is filled in by the {@link #write() write} method.
-     *
-     * @param resolver namespace resolver
-     * @param def node definition
-     */
-    public NodeDefFormat(NamespaceResolver resolver, ChildNodeDef def) {
-        this(resolver, new Element(CHILDNODEDEF_ELEMENT), def);
-    }
-
-    /**
-     * Returns the node definition object.
-     *
-     * @return node definition
-     */
-    public ChildNodeDef getNodeDef() {
-        return def;
-    }
-
-    /**
      * Reads the node definition from the XML element.
      *
      * @param type name of the declaring node type
      * @throws InvalidNodeTypeDefException if the format of the node
      *                                    definition element is invalid
      */
-    public void read(QName type) throws InvalidNodeTypeDefException {
+    protected void read(QName type) throws InvalidNodeTypeDefException {
         def.setDeclaringNodeType(type);
         super.read();
         readRequiredPrimaryTypes();
@@ -116,7 +80,7 @@
     /**
      * Writes the node definition to the XML element.
      */
-    public void write() {
+    protected void write() {
         super.write();
         writeRequiredPrimaryTypes();
         writeDefaultPrimaryType();
@@ -130,35 +94,40 @@
      *                                    definition element is invalid
      */
     private void readRequiredPrimaryTypes() throws InvalidNodeTypeDefException {
-        Vector vector = new Vector();
-
-        Element types = getChild(REQUIREDPRIMARYTYPES_ELEMENT);
+        Collection types = getGrandChildContents(
+                REQUIREDPRIMARYTYPES_ELEMENT, REQUIREDPRIMARYTYPE_ELEMENT);
         if (types != null) {
-            Iterator iterator =
-                types.getChildren(REQUIREDPRIMARYTYPE_ELEMENT).iterator();
+            Vector vector = new Vector();
+
+            Iterator iterator = types.iterator();
             while (iterator.hasNext()) {
-                Element type = (Element) iterator.next();
-                vector.add(fromJCRName(type.getTextTrim()));
+                String type = (String) iterator.next();
+                vector.add(fromJCRName(type));
             }
-        }
 
-        def.setRequiredPrimaryTypes((QName[]) vector.toArray(new QName[0]));
+            def.setRequiredPrimaryTypes((QName[]) vector.toArray(new QName[0]));
+        } else {
+            /* Default to nt:base?
+            throw new InvalidNodeTypeDefException(
+                    "Required primary type(s) not defined for child node "
+                    + def.getName() + " of node type "
+                    + def.getDeclaringNodeType());
+            */
+        }
     }
 
     /**
      * Writes the required primary types of the node definition.
      */
     private void writeRequiredPrimaryTypes() {
-        Element types = new Element(REQUIREDPRIMARYTYPES_ELEMENT);
-
         QName[] values = def.getRequiredPrimaryTypes();
+        Vector types = new Vector();
         for (int i = 0; i < values.length; i++) {
-            Element type = new Element(REQUIREDPRIMARYTYPE_ELEMENT);
-            type.setText(toJCRName(values[i]));
-            types.addContent(type);
+            types.add(toJCRName(values[i]));
         }
-
-        addChild(types);
+        setGrandChildContents(
+                REQUIREDPRIMARYTYPES_ELEMENT, REQUIREDPRIMARYTYPE_ELEMENT,
+                types);
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java Thu Mar 17 08:12:03 2005
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.Vector;
 
@@ -25,15 +26,18 @@
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
 import org.apache.jackrabbit.core.nodetype.PropDef;
-import org.jdom.Element;
+import org.w3c.dom.Element;
 
 /**
  * Utility class for reading and writing node type definition XML elements.
  */
-public class NodeTypeFormat extends CommonFormat {
+class NodeTypeFormat extends CommonFormat {
 
-    /** Name of the node type definition element. */
-    public static final String NODETYPE_ELEMENT = "nodeType";
+    /** Name of the child node definition element. */
+    private static final String CHILDNODEDEF_ELEMENT = "childNodeDef";
+
+    /** Name of the property definition element. */
+    private static final String PROPERTYDEF_ELEMENT = "propertyDef";
 
     /** Name of the <code>isMixin</code> attribute. */
     private static final String ISMIXIN_ATTRIBUTE = "isMixin";
@@ -56,59 +60,25 @@
     private final NodeTypeDef def;
 
     /**
-     * Creates a node type definition format object. This constructor
-     * is used internally by the public reader and writer constructors.
+     * Creates a node type definition format object.
      *
      * @param resolver namespace resolver
      * @param element node type definition element
      * @param def node type definition
      */
-    private NodeTypeFormat(
+    protected NodeTypeFormat(
             NamespaceResolver resolver, Element element, NodeTypeDef def) {
         super(resolver, element);
         this.def = def;
     }
 
     /**
-     * Creates a node type definition reader. An empty node type definition
-     * instance is created. The instance properties are filled in by the
-     * {@link #read() read} method.
-     *
-     * @param resolver namespace resolver
-     * @param element node type definition element
-     */
-    public NodeTypeFormat(NamespaceResolver resolver, Element element) {
-        this(resolver, element, new NodeTypeDef());
-    }
-
-    /**
-     * Creates a node type definition writer. The node type definition
-     * element is instantiated as an empty <code>nodeType</code> element.
-     * The element is filled in by the {@link #write() write} method.
-     *
-     * @param resolver namespace resolver
-     * @param def node type definition
-     */
-    public NodeTypeFormat(NamespaceResolver resolver, NodeTypeDef def) {
-        this(resolver, new Element(NODETYPE_ELEMENT), def);
-    }
-
-    /**
-     * Returns the node type definition object.
-     *
-     * @return node type definition
-     */
-    public NodeTypeDef getNodeType() {
-        return def;
-    }
-
-    /**
      * Reads the node type definition from the XML element.
      *
      * @throws InvalidNodeTypeDefException if the format of the node type
      *                                    definition element is invalid
      */
-    public void read() throws InvalidNodeTypeDefException {
+    protected void read() throws InvalidNodeTypeDefException {
         readName();
         readSupertypes();
         readIsMixin();
@@ -121,7 +91,7 @@
     /**
      * Writes the node type definition to the XML element.
      */
-    public void write() {
+    protected void write() {
         writeName();
         writeSupertypes();
         writeIsMixin();
@@ -155,18 +125,18 @@
      *                                    definition element is invalid
      */
     private void readSupertypes() throws InvalidNodeTypeDefException {
-        Vector vector = new Vector();
-
-        Element types = getChild(SUPERTYPES_ELEMENT);
+        Collection types =
+            getGrandChildContents(SUPERTYPES_ELEMENT, SUPERTYPE_ELEMENT);
         if (types != null) {
-            Iterator iterator = types.getChildren(SUPERTYPE_ELEMENT).iterator();
+            Vector vector = new Vector();
+
+            Iterator iterator = types.iterator();
             while (iterator.hasNext()) {
-                Element type = (Element) iterator.next();
-                vector.add(fromJCRName(type.getTextTrim()));
+                vector.add(fromJCRName((String) iterator.next()));
             }
-        }
 
-        def.setSupertypes((QName[]) vector.toArray(new QName[0]));
+            def.setSupertypes((QName[]) vector.toArray(new QName[0]));
+        }
     }
 
     /**
@@ -174,14 +144,13 @@
      */
     private void writeSupertypes() {
         QName[] values = def.getSupertypes();
-        if (values.length > 0) {
-            Element types = new Element(SUPERTYPES_ELEMENT);
+        if (values != null && values.length > 0) {
+            Vector types = new Vector();
             for (int i = 0; i < values.length; i++) {
-                Element type = new Element(SUPERTYPE_ELEMENT);
-                type.setText(toJCRName(values[i]));
-                types.addContent(type);
+                types.add(toJCRName(values[i]));
             }
-            addChild(types);
+            setGrandChildContents(
+                    SUPERTYPES_ELEMENT, SUPERTYPE_ELEMENT, types);
         }
     }
 
@@ -263,12 +232,14 @@
     private void readPropertyDefinitions() throws InvalidNodeTypeDefException {
         Vector vector = new Vector();
 
-        Iterator iterator = getChildIterator(PropDefFormat.PROPERTYDEF_ELEMENT);
+        Iterator iterator = getChildElements(PROPERTYDEF_ELEMENT);
         while (iterator.hasNext()) {
-            PropDefFormat format = new PropDefFormat(
-                    getNamespaceResolver(), (Element) iterator.next());
+            PropDef property = new PropDef();
+            Element element = (Element) iterator.next();
+            PropDefFormat format =
+                new PropDefFormat(getNamespaceResolver(), element, property);
             format.read(def.getName());
-            vector.add(format.getPropDef());
+            vector.add(property);
         }
 
         def.setPropertyDefs((PropDef[]) vector.toArray(new PropDef[0]));
@@ -280,10 +251,12 @@
     private void writePropertyDefinitions() {
         PropDef[] defs = def.getPropertyDefs();
         for (int i = 0; i < defs.length; i++) {
+            PropDef property = defs[i];
+            Element element = newElement(PROPERTYDEF_ELEMENT);
             PropDefFormat format =
-                new PropDefFormat(getNamespaceResolver(), defs[i]);
+                new PropDefFormat(getNamespaceResolver(), element, property);
             format.write();
-            addChild(format.getElement());
+            addChild(element);
         }
     }
 
@@ -299,13 +272,14 @@
     private void readChildNodeDefinitions() throws InvalidNodeTypeDefException {
         Vector vector = new Vector();
 
-        Iterator iterator =
-            getChildIterator(NodeDefFormat.CHILDNODEDEF_ELEMENT);
+        Iterator iterator = getChildElements(CHILDNODEDEF_ELEMENT);
         while (iterator.hasNext()) {
-            NodeDefFormat format = new NodeDefFormat(
-                    getNamespaceResolver(), (Element) iterator.next());
+            ChildNodeDef node = new ChildNodeDef();
+            Element element = (Element) iterator.next();
+            NodeDefFormat format =
+                new NodeDefFormat(getNamespaceResolver(), element, node);
             format.read(def.getName());
-            vector.add(format.getNodeDef());
+            vector.add(node);
         }
 
         def.setChildNodeDefs(
@@ -318,10 +292,12 @@
     private void writeChildNodeDefinitions() {
         ChildNodeDef[] defs = def.getChildNodeDefs();
         for (int i = 0; i < defs.length; i++) {
+            ChildNodeDef node = defs[i];
+            Element element = newElement(CHILDNODEDEF_ELEMENT);
             NodeDefFormat format =
-                new NodeDefFormat(getNamespaceResolver(), defs[i]);
+                new NodeDefFormat(getNamespaceResolver(), element, node);
             format.write();
-            addChild(format.getElement());
+            addChild(element);
         }
     }
 

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormatter.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormatter.java?view=auto&rev=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormatter.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormatter.java Thu Mar 17 08:12:03 2005
@@ -0,0 +1,203 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * TODO
+ */
+public class NodeTypeFormatter {
+
+    /** Path of the node type definition template file. */
+    private static final String TEMPLATE =
+        "org/apache/jackrabbit/core/nodetype/xml/template.xml";
+
+    /** Name of the node type definition root element. */
+    private static final String NODETYPES_ELEMENT = "nodeTypes";
+
+    /** Name of the node type definition element. */
+    private static final String NODETYPE_ELEMENT = "nodeType";
+
+    /** The transformer used to serialize and deserialise DOM objects. */
+    private Transformer transformer;
+
+    /**
+     * Creates a node type formatter object.
+     *
+     * @throws RepositoryException if the formatter initialization fails
+     */
+    public NodeTypeFormatter() throws RepositoryException {
+        try {
+            TransformerFactory factory = TransformerFactory.newInstance();
+            transformer = factory.newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        } catch (TransformerConfigurationException e) {
+            throw new RepositoryException(
+                    "Unable to create a node type formatter", e);
+        }
+    }
+
+    /**
+     * Reads a set of node type definitions from the given input stream.
+     *
+     * @param xml XML input stream
+     * @return node type definitions
+     * @throws IOException on IO errors
+     * @throws InvalidNodeTypeDefException if the node type definition
+     *                                     format is invalid
+     * @throws RepositoryException on repository errors
+     */
+    public Collection read(InputStream xml)
+            throws IOException, InvalidNodeTypeDefException,
+            RepositoryException {
+        Vector types = new Vector();
+
+        Document document = readDocument(xml);
+        Element root = document.getDocumentElement();
+        NamespaceResolver resolver = new AdditionalNamespaceResolver(root);
+        if (!NODETYPES_ELEMENT.equals(root.getNodeName())) {
+            throw new InvalidNodeTypeDefException(
+                    "Invalid node type definition root "
+                    + root.getNodeName());
+        }
+
+        NodeList nodes = root.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType() == Node.ELEMENT_NODE
+                    && NODETYPE_ELEMENT.equals(node.getNodeName())) {
+                NodeTypeDef def = new NodeTypeDef();
+                NodeTypeFormat format =
+                    new NodeTypeFormat(resolver, (Element) node, def);
+                format.read();
+                types.add(def);
+            }
+        }
+
+        return types;
+    }
+
+    /**
+     * Writes the given set of node type definitions to the given output
+     * stream.
+     *
+     * @param xml XML output stream
+     * @param registry namespace registry
+     * @param types node types
+     * @throws IOException on IO errors
+     * @throws RepositoryException on repository errors
+     */
+    public void write(
+            OutputStream xml, NamespaceRegistry registry, Collection types)
+            throws IOException, RepositoryException {
+        InputStream template =
+            getClass().getClassLoader().getResourceAsStream(TEMPLATE);
+        Document document =  readDocument(template);
+        Element root = document.getDocumentElement();
+
+        String[] prefixes = registry.getPrefixes();
+        for (int i = 0; i < prefixes.length; i++) {
+            if (!Constants.NS_EMPTY_PREFIX.equals(prefixes[i])) {
+                String uri = registry.getURI(prefixes[i]);
+                root.setAttribute(
+                        Constants.NS_XMLNS_PREFIX + ":" + prefixes[i], uri);
+            }
+        }
+
+        NamespaceResolver resolver =
+            new AdditionalNamespaceResolver(registry);
+        Iterator iterator = types.iterator();
+        while (iterator.hasNext()) {
+            Element element =
+                root.getOwnerDocument().createElement(NODETYPE_ELEMENT);
+            NodeTypeDef type = (NodeTypeDef) iterator.next();
+            NodeTypeFormat format =
+                new NodeTypeFormat(resolver, element, type);
+            format.write();
+            root.appendChild(element);
+        }
+
+        writeDocument(xml, document);
+    }
+
+    /**
+     * Reads a DOM document from the given XML stream.
+     *
+     * @param xml XML stream
+     * @return DOM document
+     * @throws RepositoryException if the document could not be read
+     */
+    private Document readDocument(InputStream xml) throws RepositoryException {
+        try {
+            StreamSource source = new StreamSource(xml);
+            DOMResult result = new DOMResult();
+            transformer.transform(source, result);
+            return (Document) result.getNode();
+        } catch (TransformerException e) {
+            throw new RepositoryException(
+                    "Unable to read a node type definition file", e);
+        }
+    }
+
+    /**
+     * Writes a DOM document to the given XML stream.
+     *
+     * @param xml XML stream
+     * @param document DOM document
+     * @throws RepositoryException if the document could not be written
+     */
+    private void writeDocument(OutputStream xml, Document document)
+            throws RepositoryException {
+        try {
+            DOMSource source = new DOMSource(document);
+            StreamResult result = new StreamResult(xml);
+            transformer.transform(source, result);
+        } catch (TransformerException e) {
+            throw new RepositoryException(
+                    "Unable to write a node type definition file", e);
+        }
+    }
+}

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java?view=diff&r1=157939&r2=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java Thu Mar 17 08:12:03 2005
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.Vector;
 
@@ -28,16 +29,13 @@
 import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
 import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.nodetype.ValueConstraint;
-import org.jdom.Element;
+import org.w3c.dom.Element;
 
 /**
  * Utility class for reading and writing property definition XML elements.
  */
 class PropDefFormat extends ItemDefFormat {
 
-    /** Name of the property definition element. */
-    public static final String PROPERTYDEF_ELEMENT = "propertyDef";
-
     /** Name of the required type attribute. */
     private static final String REQUIREDTYPE_ATTRIBUTE = "requiredType";
 
@@ -67,53 +65,20 @@
      * @param element property definition element
      * @param def property definition
      */
-    private PropDefFormat(
+    protected PropDefFormat(
             NamespaceResolver resolver, Element element, PropDef def) {
         super(resolver, element, def);
         this.def = def;
     }
 
     /**
-     * Creates a property definition reader. The internal property
-     * definition instance is created using the given node type name
-     * as the name of the declaring node type.
-     *
-     * @param resolver namespace resolver
-     * @param element property definition element
-     */
-    public PropDefFormat(NamespaceResolver resolver, Element element) {
-        this(resolver, element, new PropDef());
-    }
-
-    /**
-     * Creates a property definition writer. The internal property
-     * definition element is instantiated as an empty <code>propertyDef</code>
-     * element.
-     *
-     * @param resolver namespace resolver
-     * @param def property definition
-     */
-    public PropDefFormat(NamespaceResolver resolver, PropDef def) {
-        this(resolver, new Element(PROPERTYDEF_ELEMENT), def);
-    }
-
-    /**
-     * Returns the property definition instance.
-     *
-     * @return property definition
-     */
-    public PropDef getPropDef() {
-        return def;
-    }
-
-    /**
      * Reads the property definition from the XML element.
      *
      * @param type name of the declaring node type
      * @throws InvalidNodeTypeDefException if the format of the property
-     *                                    definition element is invalid
+     *                                     definition element is invalid
      */
-    public void read(QName type) throws InvalidNodeTypeDefException {
+    protected void read(QName type) throws InvalidNodeTypeDefException {
         def.setDeclaringNodeType(type);
         super.read();
         readRequiredType();
@@ -125,7 +90,7 @@
     /**
      * Writes the property definition to the XML element.
      */
-    public void write() {
+    protected void write() {
         super.write();
         writeRequiredType();
         writeValueConstraints();
@@ -137,7 +102,7 @@
      * Reads and sets the required type of the property definition.
      *
      * @throws InvalidNodeTypeDefException if the format of the property
-     *                                    definition element is invalid
+     *                                     definition element is invalid
      */
     private void readRequiredType() throws InvalidNodeTypeDefException {
         String value = getAttribute(REQUIREDTYPE_ATTRIBUTE);
@@ -156,89 +121,84 @@
      * Reads and sets the value constraints of the property definition.
      *
      * @throws InvalidNodeTypeDefException if the format of the property
-     *                                    definition element is invalid
+     *                                      definition element is invalid
      */
     private void readValueConstraints() throws InvalidNodeTypeDefException {
-        Vector vector = new Vector();
-
-        Element constraints = getChild(VALUECONSTRAINTS_ELEMENT);
+        Collection constraints = getGrandChildContents(
+                VALUECONSTRAINTS_ELEMENT, VALUECONSTRAINT_ELEMENT);
         if (constraints != null) {
-            int type = def.getRequiredType();
+            Vector vector = new Vector();
 
-            Iterator iterator =
-                constraints.getChildren(VALUECONSTRAINT_ELEMENT).iterator();
+            int type = def.getRequiredType();
+            Iterator iterator = constraints.iterator();
             while (iterator.hasNext()) {
-                Element constraint = (Element) iterator.next();
-                String value = constraint.getTextTrim();
+                String constraint = (String) iterator.next();
                 try {
                     vector.add(ValueConstraint.create(
-                            type, value, getNamespaceResolver()));
+                            type, constraint, getNamespaceResolver()));
                 } catch (InvalidConstraintException e) {
                     throw new InvalidNodeTypeDefException(
-                            "Invalid property value constraint " + value, e);
+                            "Invalid value constraint " + constraint, e);
                 }
             }
-        }
 
-        def.setValueConstraints(
-                (ValueConstraint[]) vector.toArray(new ValueConstraint[0]));
+            def.setValueConstraints(
+                    (ValueConstraint[]) vector.toArray(new ValueConstraint[0]));
+        }
     }
 
     /**
      * Writes the value constraints of the property definition.
      */
     private void writeValueConstraints() {
-        Element values = new Element(VALUECONSTRAINTS_ELEMENT);
-
         ValueConstraint[] constraints = def.getValueConstraints();
-        for (int i = 0; i < constraints.length; i++) {
-            Element value = new Element(VALUECONSTRAINT_ELEMENT);
-            value.setText(constraints[i].getDefinition());
-            values.addContent(value);
+        if (constraints != null && constraints.length > 0) {
+            Vector values = new Vector();
+            for (int i = 0; i < constraints.length; i++) {
+                values.add(constraints[i].getDefinition());
+            }
+            setGrandChildContents(
+                    VALUECONSTRAINTS_ELEMENT, VALUECONSTRAINT_ELEMENT, values);
         }
-
-        addChild(values);
     }
 
     /**
      * Reads and sets the default values of the property definition.
      */
     private void readDefaultValues() {
-        Vector vector = new Vector();
+        Collection defaults = getGrandChildContents(
+                DEFAULTVALUES_ELEMENT, DEFAULTVALUE_ELEMENT);
+        if (defaults != null) {
+            Vector vector = new Vector();
 
-        Element values = getChild(DEFAULTVALUES_ELEMENT);
-        if (values != null) {
             int type = def.getRequiredType();
             if (type == PropertyType.UNDEFINED) {
                 type = PropertyType.STRING;
             }
-
-            Iterator iterator =
-                values.getChildren(DEFAULTVALUE_ELEMENT).iterator();
+            Iterator iterator = defaults.iterator();
             while (iterator.hasNext()) {
-                Element value = (Element) iterator.next();
-                vector.add(InternalValue.valueOf(value.getTextTrim(), type));
+                String value = (String) iterator.next();
+                vector.add(InternalValue.valueOf(value, type));
             }
-        }
 
-        def.setDefaultValues(
-                (InternalValue[]) vector.toArray(new InternalValue[0]));
+            def.setDefaultValues(
+                    (InternalValue[]) vector.toArray(new InternalValue[0]));
+        }
     }
 
     /**
      * Writes the default values of the property definition.
      */
     private void writeDefaultValues() {
-        Element values = new Element(DEFAULTVALUES_ELEMENT);
-
         InternalValue[] defaults = def.getDefaultValues();
-        for (int i = 0; i < defaults.length; i++) {
-            Element value = new Element(DEFAULTVALUE_ELEMENT);
-            value.setText(defaults[i].toString());
-            values.addContent(value);
+        if (defaults != null && defaults.length > 0) {
+            Vector values = new Vector();
+            for (int i = 0; i < defaults.length; i++) {
+                values.add(defaults[i].toString());
+            }
+            setGrandChildContents(
+                    DEFAULTVALUES_ELEMENT, DEFAULTVALUE_ELEMENT, values);
         }
-
-        addChild(values);
     }
 
     /**
@@ -246,7 +206,7 @@
      * property definition.
      *
      * @throws InvalidNodeTypeDefException if the format of the property
-     *                                    definition element is invalid
+     *                                     definition element is invalid
      */
     private void readMultiple() throws InvalidNodeTypeDefException {
         String value = getAttribute(MULTIPLE_ATTRIBUTE);

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/template.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/template.xml?view=auto&rev=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/template.xml (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/template.xml Thu Mar 17 08:12:03 2005
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nodeTypes/>

Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java?view=auto&rev=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java Thu Mar 17 08:12:03 2005
@@ -0,0 +1,82 @@
+/*
+ * 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 java.util.Properties;
+
+import javax.jcr.NamespaceRegistry;
+
+import org.apache.jackrabbit.core.Constants;
+
+/**
+ * Simple utility implementation of the NamespaceRegistry interface.
+ * Used by the node type formatter test cases.
+ */
+class SimpleNamespaceRegistry implements NamespaceRegistry {
+
+    /** Map from namespace prefixes to namespace URIs. */
+    private final Properties prefixToURI = new Properties();
+
+    /** Map from namespace URIs to namespace prefixes. */
+    private final Properties uriToPrefix = new Properties();
+
+    /**
+     * Creates a simple namespace registry.
+     */
+    public SimpleNamespaceRegistry() {
+        registerNamespace(Constants.NS_JCR_PREFIX, Constants.NS_JCR_URI);
+        registerNamespace(Constants.NS_MIX_PREFIX, Constants.NS_MIX_URI);
+        registerNamespace(Constants.NS_NT_PREFIX, Constants.NS_NT_URI);
+        registerNamespace(Constants.NS_REP_PREFIX, Constants.NS_REP_URI);
+        registerNamespace(Constants.NS_EMPTY_PREFIX, Constants.NS_EMPTY_PREFIX);
+    }
+
+    /** {@inheritDoc} */
+    public void registerNamespace(String prefix, String uri) {
+        prefixToURI.put(prefix, uri);
+        uriToPrefix.put(uri, prefix);
+    }
+
+    /** {@inheritDoc} */
+    public void unregisterNamespace(String prefix) {
+        if (prefixToURI.contains(prefix)) {
+            uriToPrefix.remove(prefixToURI.get(prefix));
+            prefixToURI.remove(prefix);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public String[] getPrefixes() {
+        return (String[]) prefixToURI.keySet().toArray(new String[0]);
+    }
+
+    /** {@inheritDoc} */
+    public String[] getURIs() {
+        return (String[]) uriToPrefix.keySet().toArray(new String[0]);
+    }
+
+    /** {@inheritDoc} */
+    public String getURI(String prefix) {
+        return prefixToURI.getProperty(prefix);
+    }
+
+    /** {@inheritDoc} */
+    public String getPrefix(String uri) {
+        return uriToPrefix.getProperty(uri);
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/TestAll.java?view=auto&rev=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/TestAll.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/TestAll.java Thu Mar 17 08:12:03 2005
@@ -0,0 +1,524 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.OnParentVersionAction;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.InternalValue;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+
+/**
+ * Test cases for reading and writing node type definition files.
+ */
+public class TestAll extends TestCase {
+
+    /** The dummy test namespace. */
+    private static final String TEST_NAMESPACE = "test-namespace";
+
+    /** Name of the include test node type definition file. */
+    private static final String TEST_NODETYPES =
+        "org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml";
+
+    /** Node type formatter object being tested. */
+    private NodeTypeFormatter formatter;
+
+    /** Test node types definitions. */
+    private Collection types;
+
+    /** Registry for the test namespaces. */
+    private NamespaceRegistry registry;
+
+    /**
+     * Initializes the node type formatter tests.
+     *
+     * @throws Exception on initialization errors
+     */
+    protected void setUp() throws Exception {
+        InputStream xml =
+            getClass().getClassLoader().getResourceAsStream(TEST_NODETYPES);
+
+        formatter = new NodeTypeFormatter();
+        types = formatter.read(xml);
+
+        registry = new SimpleNamespaceRegistry();
+        registry.registerNamespace("test", TEST_NAMESPACE);
+    }
+
+    /**
+     * Returns the named node type definition. If the node type does not
+     * exist, an assertion failure is generated.
+     *
+     * @param name node type name
+     * @return node type definition
+     */
+    private NodeTypeDef getNodeType(String name) {
+        QName qname = new QName(TEST_NAMESPACE, name);
+        Iterator iterator = types.iterator();
+        while (iterator.hasNext()) {
+            NodeTypeDef def = (NodeTypeDef) iterator.next();
+            if (qname.equals(def.getName())) {
+                return def;
+            }
+        }
+        throw new AssertionFailedError("Node type " + name + " does not exist");
+    }
+
+    /**
+     * Returns the named property definition from the named node type
+     * definition. If either of the definitions do not exist, an assertion
+     * failure is generated.
+     *
+     * @param typeName node type name
+     * @param propertyName property name
+     * @return property definition
+     */
+    private PropDef getProperty(String typeName, String propertyName) {
+        QName name = new QName(TEST_NAMESPACE, propertyName);
+
+        NodeTypeDef def = getNodeType(typeName);
+        PropDef[] defs = def.getPropertyDefs();
+        for (int i = 0; i < defs.length; i++) {
+            if (name.equals(defs[i].getName())) {
+                return defs[i];
+            }
+        }
+
+        throw new AssertionFailedError(
+                "Property " + propertyName + " does not exist");
+    }
+
+    /**
+     * Returns the string value of the identified property default value.
+     *
+     * @param def property definition
+     * @param index default value index
+     * @return default value
+     */
+    private String getDefaultValue(PropDef def, int index) {
+        try {
+            InternalValue[] values = def.getDefaultValues();
+            NamespaceResolver resolver = new AdditionalNamespaceResolver(registry);
+            return values[index].toJCRValue(resolver).getString();
+        } catch (RepositoryException e) {
+            throw new AssertionFailedError(e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the named child node definition from the named node type
+     * definition. If either of the definitions do not exist, an assertion
+     * failure is generated.
+     *
+     * @param typeName node type name
+     * @param nodeName child node name
+     * @return child node definition
+     */
+    private ChildNodeDef getChildNode(String typeName, String nodeName) {
+        QName name = new QName(TEST_NAMESPACE, nodeName);
+
+        NodeTypeDef def = getNodeType(typeName);
+        ChildNodeDef[] defs = def.getChildNodeDefs();
+        for (int i = 0; i < defs.length; i++) {
+            if (name.equals(defs[i].getName())) {
+                return defs[i];
+            }
+        }
+
+        throw new AssertionFailedError(
+                "Child node " + nodeName + " does not exist");
+    }
+
+    /**
+     * Test for reading a node type definition file. The test file
+     * has already been read during the test setup, so this method
+     * just verifies the number of node types.
+     */
+    public void testRead() {
+        assertEquals("number of node types", 6, types.size());
+    }
+
+    /** Test for the empty node type. */
+    public void testEmptyNodeType() {
+        NodeTypeDef def = getNodeType("emptyNodeType");
+        assertNotNull("emptyNodeType exists", def);
+        assertEquals("emptyNodeType mixin",
+                false, def.isMixin());
+        assertEquals("emptyNodeType hasOrderableChildNodes",
+                false, def.hasOrderableChildNodes());
+        assertEquals("emptyNodeType primaryItemName",
+                null, def.getPrimaryItemName());
+        assertEquals("emptyNodeType childNodeDefs",
+                0, def.getChildNodeDefs().length);
+        assertEquals("emptyNodeType propertyDefs",
+                0, def.getPropertyDefs().length);
+    }
+
+    /** Test for the <code>mixin</code> node type attribute. */
+    public void testMixinNodeType() {
+        NodeTypeDef def = getNodeType("mixinNodeType");
+        assertEquals("mixinNodeType mixin",
+                true, def.isMixin());
+    }
+
+    /** Test for the <code>hasOrderableChildNodes</code> node type attribute. */
+    public void testOrderedNodeType() {
+        NodeTypeDef def = getNodeType("orderedNodeType");
+        assertEquals("orderedNodeType hasOrderableChildNodes",
+                true, def.hasOrderableChildNodes());
+    }
+
+    /** Test for node type item definitions. */
+    public void testItemNodeType() {
+        NodeTypeDef def = getNodeType("itemNodeType");
+        assertEquals("itemNodeType primaryItemName",
+                new QName(TEST_NAMESPACE, "emptyItem"),
+                def.getPrimaryItemName());
+        assertEquals("itemNodeType propertyDefs",
+                10, def.getPropertyDefs().length);
+        PropDef[] defs = def.getPropertyDefs();
+        assertEquals("itemNodeType wildcard property",
+                new QName(Constants.NS_DEFAULT_URI, "*"),
+                def.getPropertyDefs()[0].getName());
+    }
+
+    /** Test for the empty item definition. */
+    public void testEmptyItem() {
+        PropDef def = getProperty("itemNodeType", "emptyItem");
+        assertEquals("emptyItem autoCreate",
+                false, def.isAutoCreate());
+        assertEquals("emptyItem mandatory",
+                false, def.isMandatory());
+        assertEquals("emptyItem onParentVersion",
+                OnParentVersionAction.IGNORE, def.getOnParentVersion());
+        assertEquals("emptyItem protected",
+                false, def.isProtected());
+    }
+
+    /** Test for the <code>autoCreate</code> item definition attribute. */
+    public void testAutoCreateItem() {
+        PropDef def = getProperty("itemNodeType", "autoCreateItem");
+        assertEquals("autoCreateItem autoCreate",
+                true, def.isAutoCreate());
+    }
+
+    /** Test for the <code>mandatory</code> item definition attribute. */
+    public void testMandatoryItem() {
+        PropDef def = getProperty("itemNodeType", "mandatoryItem");
+        assertEquals("mandatoryItem mandatory",
+                true, def.isMandatory());
+    }
+
+    /** Test for the <code>copy</code> parent version action. */
+    public void testCopyItem() {
+        PropDef def = getProperty("itemNodeType", "copyItem");
+        assertEquals("copyItem onParentVersion",
+                OnParentVersionAction.COPY, def.getOnParentVersion());
+    }
+
+    /** Test for the <code>version</code> parent version action. */
+    public void testVersionItem() {
+        PropDef def = getProperty("itemNodeType", "versionItem");
+        assertEquals("versionItem onParentVersion",
+                OnParentVersionAction.VERSION, def.getOnParentVersion());
+    }
+
+    /** Test for the <code>initialize</code> parent version action. */
+    public void testInitializeItem() {
+        PropDef def = getProperty("itemNodeType", "initializeItem");
+        assertEquals("initializeItem onParentVersion",
+                OnParentVersionAction.INITIALIZE, def.getOnParentVersion());
+    }
+
+    /** Test for the <code>compute</code> parent version action. */
+    public void testComputeItem() {
+        PropDef def = getProperty("itemNodeType", "computeItem");
+        assertEquals("computeItem onParentVersion",
+                OnParentVersionAction.COMPUTE, def.getOnParentVersion());
+    }
+
+    /** Test for the <code>abort</code> parent version action. */
+    public void testAbortItem() {
+        PropDef def = getProperty("itemNodeType", "abortItem");
+        assertEquals("abortItem onParentVersion",
+                OnParentVersionAction.ABORT, def.getOnParentVersion());
+    }
+
+    /** Test for the <code>protected</code> item definition attribute. */
+    public void testProtectedItem() {
+        PropDef def = getProperty("itemNodeType", "protectedItem");
+        assertEquals("protectedItem protected",
+                true, def.isProtected());
+    }
+
+    /** Test for node type property definitions. */
+    public void testPropertyNodeType() {
+        NodeTypeDef def = getNodeType("propertyNodeType");
+        assertEquals("propertyNodeType propertyDefs",
+                11, def.getPropertyDefs().length);
+    }
+
+    /** Test for the empty property definition. */
+    public void testEmptyProperty() {
+        PropDef def = getProperty("propertyNodeType", "emptyProperty");
+        assertEquals("emptyProperty requiredType",
+                PropertyType.UNDEFINED, def.getRequiredType());
+        assertEquals("emptyProperty multiple",
+                false, def.isMultiple());
+        assertEquals("emptyProperty defaultValues",
+                0, def.getDefaultValues().length);
+        assertEquals("emptyProperty valueConstraints",
+                0, def.getValueConstraints().length);
+    }
+
+    /** Test for the <code>binary</code> property definition type. */
+    public void testBinaryProperty() {
+        PropDef def = getProperty("propertyNodeType", "binaryProperty");
+        assertEquals("binaryProperty requiredType",
+                PropertyType.BINARY, def.getRequiredType());
+        assertEquals("binaryProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("binaryProperty valueConstraints[0]",
+                "[0,)", (def.getValueConstraints())[0].getDefinition());
+        assertEquals("binaryProperty defaultValues",
+                0, def.getDefaultValues().length);
+    }
+
+    /** Test for the <code>boolean</code> property definition type. */
+    public void testBooleanProperty() {
+        PropDef def = getProperty("propertyNodeType", "booleanProperty");
+        assertEquals("booleanProperty requiredType",
+                PropertyType.BOOLEAN, def.getRequiredType());
+        assertEquals("booleanProperty valueConstraints",
+                2, def.getValueConstraints().length);
+        assertEquals("booleanProperty valueConstraints[0]",
+                "true", (def.getValueConstraints())[0].getDefinition());
+        assertEquals("booleanProperty valueConstraints[1]",
+                "false", (def.getValueConstraints())[1].getDefinition());
+        assertEquals("booleanProperty defaultValues",
+                1, def.getDefaultValues().length);
+        assertEquals("booleanProperty defaultValues[0]",
+                "true", getDefaultValue(def, 0));
+    }
+
+    /** Test for the <code>date</code> property definition type. */
+    public void testDateProperty() {
+        PropDef def = getProperty("propertyNodeType", "dateProperty");
+        assertEquals("dateProperty requiredType",
+                PropertyType.DATE, def.getRequiredType());
+        assertEquals("dateProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("dateProperty valueConstraints[0]",
+                "[2005-01-01T00:00:00.000Z,2006-01-01T00:00:00.000Z)",
+                (def.getValueConstraints())[0].getDefinition());
+        assertEquals("dateProperty defaultValues",
+                1, def.getDefaultValues().length);
+        assertEquals("dateProperty defaultValues[0]",
+                "2005-01-01T00:00:00.000Z", getDefaultValue(def, 0));
+    }
+
+    /** Test for the <code>double</code> property definition type. */
+    public void testDoubleProperty() {
+        PropDef def = getProperty("propertyNodeType", "doubleProperty");
+        assertEquals("doubleProperty requiredType",
+                PropertyType.DOUBLE, def.getRequiredType());
+        assertEquals("doubleProperty valueConstraints",
+                3, def.getValueConstraints().length);
+        assertEquals("doubleProperty valueConstraints[0]",
+                "[,0.0)", (def.getValueConstraints())[0].getDefinition());
+        assertEquals("doubleProperty valueConstraints[1]",
+                "(1.0,2.0)", (def.getValueConstraints())[1].getDefinition());
+        assertEquals("doubleProperty valueConstraints[2]",
+                "(3.0,]", (def.getValueConstraints())[2].getDefinition());
+        assertEquals("doubleProperty defaultValues",
+                1, def.getDefaultValues().length);
+        assertEquals("doubleProperty defaultValues[0]",
+                "1.5", getDefaultValue(def, 0));
+    }
+
+    /** Test for the <code>long</code> property definition type. */
+    public void testLongProperty() {
+        PropDef def = getProperty("propertyNodeType", "longProperty");
+        assertEquals("longProperty requiredType",
+                PropertyType.LONG, def.getRequiredType());
+        assertEquals("longProperty valueConstraints",
+                3, def.getValueConstraints().length);
+        assertEquals("longProperty valueConstraints[0]",
+                "(-10,0]", (def.getValueConstraints())[0].getDefinition());
+        assertEquals("longProperty valueConstraints[1]",
+                "[1,2]", (def.getValueConstraints())[1].getDefinition());
+        assertEquals("longProperty valueConstraints[2]",
+                "[10,100)", (def.getValueConstraints())[2].getDefinition());
+        assertEquals("longProperty defaultValues",
+                1, def.getDefaultValues().length);
+        assertEquals("longProperty defaultValues[0]",
+                "25", getDefaultValue(def, 0));
+    }
+
+    /** Test for the <code>name</code> property definition type. */
+    public void testNameProperty() {
+        PropDef def = getProperty("propertyNodeType", "nameProperty");
+        assertEquals("nameProperty requiredType",
+                PropertyType.NAME, def.getRequiredType());
+        assertEquals("nameProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("nameProperty valueConstraints[0]",
+                "{test-namespace}testName",
+                (def.getValueConstraints())[0].getDefinition());
+        assertEquals("nameProperty defaultValues",
+                1, def.getDefaultValues().length);
+        assertEquals("nameProperty defaultValues[0]",
+                "test:testName", getDefaultValue(def, 0));
+    }
+
+    /** Test for the <code>path</code> property definition type. */
+    public void testPathProperty() {
+        PropDef def = getProperty("propertyNodeType", "pathProperty");
+        assertEquals("pathProperty requiredType",
+                PropertyType.PATH, def.getRequiredType());
+        assertEquals("pathProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("pathProperty valueConstraints[0]",
+                "/{test-namespace}testPath",
+                (def.getValueConstraints())[0].getDefinition());
+        assertEquals("pathProperty defaultValues",
+                0, def.getDefaultValues().length);
+    }
+
+    /** Test for the <code>reference</code> property definition type. */
+    public void testReferenceProperty() {
+        PropDef def = getProperty("propertyNodeType", "referenceProperty");
+        assertEquals("referenceProperty requiredType",
+                PropertyType.REFERENCE, def.getRequiredType());
+        assertEquals("referenceProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("referenceProperty valueConstraints[0]",
+                "{test-namespace}testType",
+                (def.getValueConstraints())[0].getDefinition());
+        assertEquals("referenceProperty defaultValues",
+                0, def.getDefaultValues().length);
+    }
+
+    /** Test for the <code>string</code> property definition type. */
+    public void testStringProperty() {
+        PropDef def = getProperty("propertyNodeType", "stringProperty");
+        assertEquals("stringProperty requiredType",
+                PropertyType.STRING, def.getRequiredType());
+        assertEquals("stringProperty valueConstraints",
+                1, def.getValueConstraints().length);
+        assertEquals("stringProperty valueConstraints[0]",
+                "bananas?",
+                (def.getValueConstraints())[0].getDefinition());
+        assertEquals("stringProperty defaultValues",
+                2, def.getDefaultValues().length);
+        assertEquals("stringProperty defaultValues[0]",
+                "banana", getDefaultValue(def, 0));
+        assertEquals("stringProperty defaultValues[1]",
+                "bananas", getDefaultValue(def, 1));
+    }
+
+    /** Test for the <code>multiple</code> property definition attribute. */
+    public void testMultipleProperty() {
+        PropDef def = getProperty("propertyNodeType", "multipleProperty");
+        assertEquals("multipleProperty multiple",
+                true, def.isMultiple());
+    }
+
+    /** Test for node type child node definitions. */
+    public void testChildNodeType() {
+        NodeTypeDef def = getNodeType("childNodeType");
+        assertEquals("childNodeType childNodeDefs",
+                4, def.getChildNodeDefs().length);
+    }
+
+    /** Test for the empty child node definition. */
+    public void testEmptyNode() {
+        ChildNodeDef def = getChildNode("childNodeType", "emptyNode");
+        assertEquals("emptyNode allowSameNameSibs",
+                false, def.allowSameNameSibs());
+        assertEquals("emptyNode defaultPrimaryType",
+                null, def.getDefaultPrimaryType());
+    }
+
+    /** Test for the <code>allowSameNameSibs</code> child node attribute. */
+    public void testSiblingNode() {
+        ChildNodeDef def = getChildNode("childNodeType", "siblingNode");
+        assertEquals("siblingNode allowSameNameSibs",
+                true, def.allowSameNameSibs());
+    }
+
+    /** Test for the <code>defaultPrimaryType</code> child node attribute. */
+    public void testDefaultTypeNode() {
+        ChildNodeDef def = getChildNode("childNodeType", "defaultTypeNode");
+        assertEquals("defaultTypeNode defaultPrimaryType",
+                new QName(TEST_NAMESPACE, "testType"),
+                def.getDefaultPrimaryType());
+    }
+
+    /** Test for the <code>requiredPrimaryTypes</code> child node attributes. */
+    public void testRequiredTypeNode() {
+        ChildNodeDef def = getChildNode("childNodeType", "requiredTypeNode");
+        assertEquals("requiredTypeNode requiredPrimaryTypes",
+                2, def.getRequiredPrimaryTypes().length);
+        assertEquals("requiredTypeNode requiredPrimaryTypes[0]",
+                new QName(TEST_NAMESPACE, "baseType"),
+                def.getRequiredPrimaryTypes()[0]);
+        assertEquals("requiredTypeNode requiredPrimaryTypes[1]",
+                new QName(TEST_NAMESPACE, "testType"),
+                def.getRequiredPrimaryTypes()[1]);
+    }
+
+    /**
+     * Test for writing a node type definition file. Writing is tested
+     * by writing and re-reading the test node types using an internal
+     * byte array. The resulting node type map is then compared to the
+     * original test node types.
+     *
+     * @throws IOException on IO errors
+     * @throws RepositoryException on repository errors
+     */
+    public void testWrite() throws IOException, RepositoryException {
+        try {
+            ByteArrayOutputStream xml = new ByteArrayOutputStream();
+            formatter.write(xml, registry, types);
+            byte[] bytes = xml.toByteArray();
+            Collection output = formatter.read(new ByteArrayInputStream(bytes));
+            assertEquals("write output", types, output);
+        } catch (InvalidNodeTypeDefException e) {
+            fail(e.getMessage());
+        }
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml?view=auto&rev=157940
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml Thu Mar 17 08:12:03 2005
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * 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.
+ */
+ -->
+<nodeTypes xmlns:test="test-namespace"
+           xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+
+  <nodeType name="test:emptyNodeType"
+            isMixin="false" hasOrderableChildNodes="false" primaryItemName=""/>
+
+  <nodeType name="test:mixinNodeType"
+            isMixin="true" hasOrderableChildNodes="false" primaryItemName=""/>
+
+  <nodeType name="test:orderedNodeType"
+            isMixin="false" hasOrderableChildNodes="true" primaryItemName=""/>
+
+  <nodeType name="test:itemNodeType"
+            isMixin="false" hasOrderableChildNodes="false"
+            primaryItemName="test:emptyItem">
+    <propertyDef name="*"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false"/>
+    <propertyDef name="test:emptyItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false"/>
+    <propertyDef name="test:autoCreateItem"
+                 requiredType="undefined" autoCreate="true" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false"/>
+    <propertyDef name="test:mandatoryItem"
+                 requiredType="undefined" autoCreate="false" mandatory="true"
+                 onParentVersion="IGNORE" protected="false" multiple="false"/>
+    <propertyDef name="test:copyItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="COPY" protected="false" multiple="false"/>
+    <propertyDef name="test:versionItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="VERSION" protected="false" multiple="false"/>
+    <propertyDef name="test:initializeItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="INITIALIZE" protected="false" multiple="false"/>
+    <propertyDef name="test:computeItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="COMPUTE" protected="false" multiple="false"/>
+    <propertyDef name="test:abortItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="ABORT" protected="false" multiple="false"/>
+    <propertyDef name="test:protectedItem"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="true" multiple="false"/>
+  </nodeType>
+
+  <nodeType name="test:propertyNodeType"
+            isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <propertyDef name="test:emptyProperty"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false"/>
+    <propertyDef name="test:binaryProperty"
+                 requiredType="Binary" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>[0,)</valueConstraint>
+      </valueConstraints>
+    </propertyDef>
+    <propertyDef name="test:booleanProperty"
+                 requiredType="Boolean" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>true</valueConstraint>
+        <valueConstraint>false</valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>true</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:dateProperty"
+                 requiredType="Date" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>
+          [2005-01-01T00:00:00.000Z,2006-01-01T00:00:00.000Z)
+        </valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>2005-01-01T00:00:00.000Z</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:doubleProperty"
+                 requiredType="Double" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>[,0.0)</valueConstraint>
+        <valueConstraint>(1.0,2.0)</valueConstraint>
+        <valueConstraint>(3.0,]</valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>1.5</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:longProperty"
+                 requiredType="Long" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>(-10,0]</valueConstraint>
+        <valueConstraint>[1,2]</valueConstraint>
+        <valueConstraint>[10,100)</valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>25</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:nameProperty"
+                 requiredType="Name" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>{test-namespace}testName</valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>{test-namespace}testName</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:pathProperty"
+                 requiredType="Path" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>/{test-namespace}testPath</valueConstraint>
+      </valueConstraints>
+    </propertyDef>
+    <propertyDef name="test:referenceProperty"
+                 requiredType="Reference" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="false">
+      <valueConstraints>
+        <valueConstraint>{test-namespace}testType</valueConstraint>
+      </valueConstraints>
+    </propertyDef>
+    <propertyDef name="test:stringProperty"
+                 requiredType="String" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="true">
+      <valueConstraints>
+        <valueConstraint>bananas?</valueConstraint>
+      </valueConstraints>
+      <defaultValues>
+        <defaultValue>banana</defaultValue>
+        <defaultValue>bananas</defaultValue>
+      </defaultValues>
+    </propertyDef>
+    <propertyDef name="test:multipleProperty"
+                 requiredType="undefined" autoCreate="false" mandatory="false"
+                 onParentVersion="IGNORE" protected="false" multiple="true"/>
+  </nodeType>
+
+  <nodeType name="test:childNodeType"
+            isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <childNodeDef name="test:emptyNode"
+                  defaultPrimaryType="" sameNameSibs="false"
+                  autoCreate="false" mandatory="false"
+                  onParentVersion="IGNORE" protected="false"/>
+    <childNodeDef name="test:siblingNode"
+                  defaultPrimaryType="" sameNameSibs="true"
+                  autoCreate="false" mandatory="false"
+                  onParentVersion="IGNORE" protected="false"/>
+    <childNodeDef name="test:defaultTypeNode"
+                  defaultPrimaryType="test:testType" sameNameSibs="false"
+                  autoCreate="false" mandatory="false"
+                  onParentVersion="IGNORE" protected="false"/>
+    <childNodeDef name="test:requiredTypeNode"
+                  defaultPrimaryType="" sameNameSibs="false"
+                  autoCreate="false" mandatory="false"
+                  onParentVersion="IGNORE" protected="false">
+      <requiredPrimaryTypes>
+        <requiredPrimaryType>test:baseType</requiredPrimaryType>
+        <requiredPrimaryType>test:testType</requiredPrimaryType>
+      </requiredPrimaryTypes>
+    </childNodeDef>
+  </nodeType>
+
+</nodeTypes>
\ No newline at end of file



Mime
View raw message