You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2009/09/14 14:30:37 UTC

svn commit: r814610 [2/2] - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ jackra...

Copied: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefReader.java (from r812902, jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java)
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefReader.java?p2=jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefReader.java&p1=jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java&r1=812902&r2=814610&rev=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefReader.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefReader.java Mon Sep 14 12:30:36 2009
@@ -14,52 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.spi.commons.nodetype.compact;
+package org.apache.jackrabbit.commons.cnd;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.Reader;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
-import javax.jcr.NamespaceException;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.ValueFormatException;
-import javax.jcr.nodetype.NodeTypeDefinition;
 import javax.jcr.query.qom.QueryObjectModelConstants;
 import javax.jcr.version.OnParentVersionAction;
 
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
-import org.apache.jackrabbit.spi.QValue;
-import org.apache.jackrabbit.spi.QValueConstraint;
-import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
-import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
-import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeDefinitionFactory;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QNodeDefinitionBuilder;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QNodeTypeDefinitionBuilder;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.QNodeTypeDefinitionsBuilder.QPropertyDefinitionBuilder;
-import org.apache.jackrabbit.spi.commons.query.qom.Operator;
-import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.commons.cnd.AbstractItemTypeDefinitionsBuilder.AbstractNodeDefinitionBuilder;
+import org.apache.jackrabbit.commons.cnd.AbstractItemTypeDefinitionsBuilder.AbstractNodeTypeDefinitionBuilder;
+import org.apache.jackrabbit.commons.cnd.AbstractItemTypeDefinitionsBuilder.AbstractPropertyDefinitionBuilder;
 
 /**
  * CompactNodeTypeDefReader. Parses node type definitions written in the compact
- * node type definition format and provides a list of QNodeTypeDefinition
+ * node type definition format and provides a list of type definition
  * objects that can then be used to register node types.
  *
+ * The CompactNodeTypeDefReader is parameterizable in the type of the node type
+ * definition <code>T</code> and the type of the namespace mapping <code>N</code>
+ * which the parser should build. For types <code>T</code> and <code>N</code> the
+ * parser's constructor takes a {@link AbstractItemTypeDefinitionsBuilder} for
+ * <code>T</code> and <code>N</code>.
+ *
  * <p/>
  * The EBNF grammar of the compact node type definition:<br>
  * <pre>
@@ -120,41 +100,16 @@
  * UnquotedString ::= XmlChar {XmlChar}
  * XmlChar ::= see 3.2.2 Local Names
  * </pre>
+ *
+ * @param <T>
+ * @param <N>
  */
-public class CompactNodeTypeDefReader {
-
-    /**
-     * Default namespace mappings
-     */
-    public static final NamespaceMapping NS_DEFAULTS;
-    static {
-        try {
-            NS_DEFAULTS = new NamespaceMapping();
-            NS_DEFAULTS.setMapping(Name.NS_EMPTY_PREFIX, Name.NS_DEFAULT_URI);
-            NS_DEFAULTS.setMapping(Name.NS_JCR_PREFIX, Name.NS_JCR_URI);
-            NS_DEFAULTS.setMapping(Name.NS_MIX_PREFIX, Name.NS_MIX_URI);
-            NS_DEFAULTS.setMapping(Name.NS_NT_PREFIX, Name.NS_NT_URI);
-            NS_DEFAULTS.setMapping(Name.NS_REP_PREFIX, Name.NS_REP_URI);
-        } catch (NamespaceException e) {
-            throw new InternalError(e.toString());
-        }
-    }
+public class CompactNodeTypeDefReader<T, N> {
 
     /**
      * the list of parsed QNodeTypeDefinition
      */
-    private final List<QNodeTypeDefinition> nodeTypeDefs
-            = new LinkedList<QNodeTypeDefinition>();
-
-    /**
-     * the current namespace mapping
-     */
-    private final NamespaceMapping nsMapping;
-
-    /**
-     * Name and Path resolver
-     */
-    private final NamePathResolver resolver;
+    private final List<T> nodeTypeDefs = new LinkedList<T>();
 
     /**
      * the underlying lexer
@@ -169,107 +124,42 @@
     /**
      * The builder for QNodeTypeDefinitions
      */
-    private final QNodeTypeDefinitionsBuilder builder;
-
-    /**
-     * Convenience method that creates a new CND reader and parses the given
-     * file directly.
-     *
-     * @param file A CND file
-     * @return a new 'parsed' reader object
-     * @throws ParseException if an error occurs
-     * @throws IOException if an I/O error occurs.
-     */
-    public static CompactNodeTypeDefReader read(File file)
-            throws ParseException, IOException {
-        InputStream in = null;
-        Reader r = null;
-        try {
-            in = new FileInputStream(file);
-            r = new InputStreamReader(in, "utf8");
-            return new CompactNodeTypeDefReader(r, file.getPath());
-        } finally {
-            if (r != null) {
-                try {
-                    r.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Creates a new CND reader and parses the given stream directly.
-     *
-     * @param r a reader to the CND
-     * @param systemId a informative id of the given stream
-     * @throws ParseException if an error occurs
-     */
-    public CompactNodeTypeDefReader(Reader r, String systemId)
-            throws ParseException {
-        this(r, systemId, null, null);
-    }
+    private final AbstractItemTypeDefinitionsBuilder<T, N> builder;
 
     /**
-     * Creates a new CND reader and parses the given stream it directly.
-     * If <code>builder</code> is <code>null</code> the reader uses the
-     * default {@link QNodeTypeDefinitionsBuilderImpl}.
+     * Creates a new CND reader and parses the given stream.
      *
      * @param r a reader to the CND
      * @param systemId a informative id of the given stream
-     * @param builder build for creating new definitions or <code>null</code>
+     * @param builder builder for creating new definitions and handling namespaces
      * @throws ParseException if an error occurs
      */
     public CompactNodeTypeDefReader(Reader r, String systemId,
-                                    QNodeTypeDefinitionsBuilder builder)
-            throws ParseException {
+            AbstractItemTypeDefinitionsBuilder<T, N> builder) throws ParseException {
+
         this(r, systemId, null, builder);
     }
 
     /**
-     * Creates a new CND reader and parses the given stream it directly.
+     * Creates a new CND reader and parses the given stream.
      *
      * @param r a reader to the CND
      * @param systemId a informative id of the given stream
-     * @param mapping default namespace mapping to use
+     * @param nsMapping default namespace mapping to use
+     * @param builder builder for creating new definitions and handling namespaces
      * @throws ParseException if an error occurs
      */
-    public CompactNodeTypeDefReader(Reader r, String systemId, NamespaceMapping mapping)
-            throws ParseException {
-        this(r, systemId, mapping, null);
-    }
+    public CompactNodeTypeDefReader(Reader r, String systemId, N nsMapping,
+            AbstractItemTypeDefinitionsBuilder<T, N> builder) throws ParseException {
 
-    /**
-     * Creates a new CND reader and parses the given stream it directly.
-     * If <code>builder</code> is <code>null</code> the reader uses the
-     * default {@link QNodeTypeDefinitionsBuilderImpl}.
-     *
-     * @param r a reader to the CND
-     * @param systemId a informative id of the given stream
-     * @param mapping default namespace mapping to use
-     * @param builder build for creating new definitions
-     * @throws ParseException if an error occurs
-     */
-    public CompactNodeTypeDefReader(Reader r, String systemId, NamespaceMapping mapping,
-            QNodeTypeDefinitionsBuilder builder) throws ParseException {
+        super();
 
-        this.builder = builder == null
-                ? new QNodeTypeDefinitionsBuilderImpl()
-                : builder;
+        this.builder = builder;
         lexer = new Lexer(r, systemId);
-        this.nsMapping = mapping == null
-                ? new NamespaceMapping(NS_DEFAULTS)
-                : mapping;
-        this.resolver = new DefaultNamePathResolver(nsMapping);
+        if (nsMapping != null) {
+            builder.setNamespaceMapping(nsMapping);
+        }
+
         nextToken();
         parse();
     }
@@ -283,35 +173,21 @@
     }
 
     /**
-     * Returns the list of parsed QNodeTypeDefinition definitions.
+     * Returns the list of parsed node type definitions definitions.
      *
-     * @return a collection of QNodeTypeDefinition objects
+     * @return a collection of node type definition objects
      */
-    public List<QNodeTypeDefinition> getNodeTypeDefinitions() {
+    public List<T> getNodeTypeDefinitions() {
         return nodeTypeDefs;
     }
 
     /**
-     * Convenience method that returns the list of parsed NodeTypeDefinition
-     * definitions, using the {@link NodeTypeDefinitionFactory}.
-     *
-     * @param session repository session used for converting the definitions.
-     * @return a collection of NodeTypeDefinition objects
-     * @throws RepositoryException if an error occurs
-     */
-    public List<NodeTypeDefinition> getNodeTypeDefinitions(Session session)
-            throws RepositoryException {
-        NodeTypeDefinitionFactory fac = new NodeTypeDefinitionFactory(session);
-        return fac.create(nodeTypeDefs);
-    }
-
-    /**
      * Returns the namespace mapping.
      *
-     * @return a NamespaceMapping object.
+     * @return
      */
-    public NamespaceMapping getNamespaceMapping() {
-        return nsMapping;
+    public N getNamespaceMapping() {
+        return builder.getNamespaceMapping();
     }
 
     /**
@@ -325,18 +201,22 @@
                 break;
             }
         }
-        while (!currentTokenEquals(Lexer.EOF)) {
-            QNodeTypeDefinitionBuilder ntd = builder.newQNodeTypeDefinition();
-            ntd.setOrderableChildNodes(false);
-            ntd.setMixin(false);
-            ntd.setAbstract(false);
-            ntd.setQueryable(true);
-            ntd.setPrimaryItemName(null);
-            doNodeTypeName(ntd);
-            doSuperTypes(ntd);
-            doOptions(ntd);
-            doItemDefs(ntd);
-            nodeTypeDefs.add(ntd.build());
+        try {
+            while (!currentTokenEquals(Lexer.EOF)) {
+                AbstractNodeTypeDefinitionBuilder<T> ntd = builder.newNodeTypeDefinitionBuilder();
+                ntd.setOrderableChildNodes(false);
+                ntd.setMixin(false);
+                ntd.setAbstract(false);
+                ntd.setQueryable(true);
+                doNodeTypeName(ntd);
+                doSuperTypes(ntd);
+                doOptions(ntd);
+                doItemDefs(ntd);
+                nodeTypeDefs.add(ntd.build());
+            }
+        }
+        catch (RepositoryException e) {
+            lexer.fail(e);
         }
     }
 
@@ -344,7 +224,6 @@
 
     /**
      * processes the namespace declaration
-     *
      * @return <code>true</code> if a namespace was parsed
      * @throws ParseException if an error during parsing occurs
      */
@@ -365,9 +244,10 @@
             lexer.fail("Missing > in namespace decl.");
         }
         try {
-            nsMapping.setMapping(prefix, uri);
-        } catch (NamespaceException e) {
-            // ignore
+            builder.setNamespace(prefix, uri);
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting namespace mapping " + currentToken, e);
         }
         nextToken();
         return true;
@@ -379,12 +259,17 @@
      * @param ntd nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doNodeTypeName(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+    private void doNodeTypeName(AbstractNodeTypeDefinitionBuilder<T> ntd) throws ParseException {
         if (!currentTokenEquals(Lexer.BEGIN_NODE_TYPE_NAME)) {
             lexer.fail("Missing '" + Lexer.BEGIN_NODE_TYPE_NAME + "' delimiter for beginning of node type name");
         }
         nextToken();
-        ntd.setName(toName(currentToken));
+        try {
+            ntd.setName(currentToken);
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting node type name " + currentToken, e);
+        }
 
         nextToken();
         if (!currentTokenEquals(Lexer.END_NODE_TYPE_NAME)) {
@@ -399,16 +284,19 @@
      * @param ntd nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doSuperTypes(QNodeTypeDefinitionBuilder ntd) throws ParseException {
-        Set<Name> supertypes = new HashSet<Name>();
+    private void doSuperTypes(AbstractNodeTypeDefinitionBuilder<T> ntd) throws ParseException  {
+
         if (currentTokenEquals(Lexer.EXTENDS))
             do {
                 nextToken();
-                supertypes.add(toName(currentToken));
+                try {
+                    ntd.addSupertype(currentToken);
+                }
+                catch (RepositoryException e) {
+                    lexer.fail("Error setting super type of " + ntd.getName() + " to " + currentToken, e);
+                }
                 nextToken();
             } while (currentTokenEquals(Lexer.LIST_DELIMITER));
-
-        ntd.setSupertypes(supertypes.toArray(new Name[supertypes.size()]));
     }
 
     /**
@@ -417,32 +305,38 @@
      * @param ntd nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doOptions(QNodeTypeDefinitionBuilder ntd) throws ParseException {
+    private void doOptions(AbstractNodeTypeDefinitionBuilder<T> ntd) throws ParseException {
+
         boolean hasOption = true;
-        while (hasOption) {
-            if (currentTokenEquals(Lexer.ORDERABLE)) {
-                nextToken();
-                ntd.setOrderableChildNodes(true);
-            } else if (currentTokenEquals(Lexer.MIXIN)) {
-                nextToken();
-                ntd.setMixin(true);
-            } else if (currentTokenEquals(Lexer.ABSTRACT)) {
-                nextToken();
-                ntd.setAbstract(true);
-            } else if (currentTokenEquals(Lexer.NOQUERY)) {
-                nextToken();
-                ntd.setQueryable(false);
-            } else if (currentTokenEquals(Lexer.QUERY)) {
-                nextToken();
-                ntd.setQueryable(true);
-            } else if (currentTokenEquals(Lexer.PRIMARYITEM)) {
-                nextToken();
-                ntd.setPrimaryItemName(toName(currentToken));
-                nextToken();
-            } else {
-                hasOption = false;
+        try {
+            while (hasOption) {
+                if (currentTokenEquals(Lexer.ORDERABLE)) {
+                    nextToken();
+                    ntd.setOrderableChildNodes(true);
+                } else if (currentTokenEquals(Lexer.MIXIN)) {
+                    nextToken();
+                    ntd.setMixin(true);
+                } else if (currentTokenEquals(Lexer.ABSTRACT)) {
+                    nextToken();
+                    ntd.setAbstract(true);
+                } else if (currentTokenEquals(Lexer.NOQUERY)) {
+                    nextToken();
+                    ntd.setQueryable(false);
+                } else if (currentTokenEquals(Lexer.QUERY)) {
+                    nextToken();
+                    ntd.setQueryable(true);
+                } else if (currentTokenEquals(Lexer.PRIMARYITEM)) {
+                    nextToken();
+                    ntd.setPrimaryItemName(currentToken);
+                    nextToken();
+                } else {
+                    hasOption = false;
+                }
             }
         }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting option of " + ntd.getName() + " to " + currentToken, e);
+        }
     }
 
     /**
@@ -451,49 +345,57 @@
      * @param ntd nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doItemDefs(QNodeTypeDefinitionBuilder ntd) throws ParseException {
-        List<QPropertyDefinition> propertyDefinitions = new LinkedList<QPropertyDefinition>();
-        List<QNodeDefinition> nodeDefinitions = new LinkedList<QNodeDefinition>();
+    private void doItemDefs(AbstractNodeTypeDefinitionBuilder<T> ntd) throws ParseException {
         while (currentTokenEquals(Lexer.PROPERTY_DEFINITION) || currentTokenEquals(Lexer.CHILD_NODE_DEFINITION)) {
             if (currentTokenEquals(Lexer.PROPERTY_DEFINITION)) {
-                QPropertyDefinitionBuilder pd = ntd.newQPropertyDefinition();
-
-                pd.setAutoCreated(false);
-                pd.setDeclaringNodeType(ntd.getName());
-                pd.setDefaultValues(null);
-                pd.setMandatory(false);
-                pd.setMultiple(false);
-                pd.setOnParentVersion(OnParentVersionAction.COPY);
-                pd.setProtected(false);
-                pd.setRequiredType(PropertyType.STRING);
-                pd.setValueConstraints(QValueConstraint.EMPTY_ARRAY);
-                pd.setFullTextSearchable(true);
-                pd.setQueryOrderable(true);
-                pd.setAvailableQueryOperators(Operator.getAllQueryOperators());
-
-                nextToken();
-                doPropertyDefinition(pd, ntd);
-                propertyDefinitions.add(pd.build());
+                try {
+                    AbstractPropertyDefinitionBuilder<T> pd = ntd.newPropertyDefinitionBuilder();
+                    try {
+                        pd.setAutoCreated(false);
+                        pd.setDeclaringNodeType(ntd.getName());
+                        pd.setMandatory(false);
+                        pd.setMultiple(false);
+                        pd.setOnParentVersion(OnParentVersionAction.COPY);
+                        pd.setProtected(false);
+                        pd.setRequiredType(PropertyType.STRING);
+                        pd.setFullTextSearchable(true);
+                        pd.setQueryOrderable(true);
+                    }
+                    catch (RepositoryException e) {
+                        lexer.fail("Error setting property definitions of " + pd.getName() + " to " + currentToken, e);
+                    }
+                    nextToken();
+                    doPropertyDefinition(pd, ntd);
+                    pd.build();
+                }
+                catch (RepositoryException e) {
+                    lexer.fail("Error building property definition for " + ntd.getName(), e);
+                }
 
             } else if (currentTokenEquals(Lexer.CHILD_NODE_DEFINITION)) {
-                QNodeDefinitionBuilder nd = ntd.newQNodeDefinitionBuilder();
-
-                nd.setAllowsSameNameSiblings(false);
-                nd.setAutoCreated(false);
-                nd.setDeclaringNodeType(ntd.getName());
-                nd.setMandatory(false);
-                nd.setOnParentVersion(OnParentVersionAction.COPY);
-                nd.setProtected(false);
-                nd.setDefaultPrimaryType(null);
-                nd.setRequiredPrimaryTypes(new Name[]{NameConstants.NT_BASE});
+                try {
+                    AbstractNodeDefinitionBuilder<T> nd = ntd.newNodeDefinitionBuilder();
+                    try {
+                        nd.setAllowsSameNameSiblings(false);
+                        nd.setAutoCreated(false);
+                        nd.setDeclaringNodeType(ntd.getName());
+                        nd.setMandatory(false);
+                        nd.setOnParentVersion(OnParentVersionAction.COPY);
+                        nd.setProtected(false);
+                    }
+                    catch (RepositoryException e) {
+                        lexer.fail("Error setting node definitions of " + nd.getName() + " to " + currentToken, e);
+                    }
 
-                nextToken();
-                doChildNodeDefinition(nd, ntd);
-                nodeDefinitions.add(nd.build());
+                    nextToken();
+                    doChildNodeDefinition(nd, ntd);
+                    nd.build();
+                }
+                catch (RepositoryException e) {
+                    lexer.fail("Error building node definition for " + ntd.getName(), e);
+                }
             }
         }
-        ntd.setPropertyDefs(propertyDefinitions.toArray(new QPropertyDefinition[propertyDefinitions.size()]));
-        ntd.setChildNodeDefs(nodeDefinitions.toArray(new QNodeDefinition[nodeDefinitions.size()]));
     }
 
     /**
@@ -501,14 +403,16 @@
      *
      * @param pd property definition builder
      * @param ntd declaring nodetype definition builder
-     * @throws ParseException if an error during parsing occurs
+     * @throws ParseException if an error during parsing occur
      */
-    private void doPropertyDefinition(QPropertyDefinitionBuilder pd, QNodeTypeDefinitionBuilder ntd)
+    private void doPropertyDefinition(AbstractPropertyDefinitionBuilder<T> pd, AbstractNodeTypeDefinitionBuilder<T> ntd)
             throws ParseException {
-        if (currentToken.equals("*")) {
-            pd.setName(NameConstants.ANY_NAME);
-        } else {
-            pd.setName(toName(currentToken));
+
+        try {
+            pd.setName(currentToken);
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting name of " + pd.getName() + " to " + currentToken);
         }
         nextToken();
         doPropertyType(pd);
@@ -523,39 +427,45 @@
      * @param pd property definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doPropertyType(QPropertyDefinitionBuilder pd) throws ParseException {
+    private void doPropertyType(AbstractPropertyDefinitionBuilder<T> pd) throws ParseException {
+
         if (!currentTokenEquals(Lexer.BEGIN_TYPE)) {
             return;
         }
         nextToken();
-        if (currentTokenEquals(Lexer.STRING)) {
-            pd.setRequiredType(PropertyType.STRING);
-        } else if (currentTokenEquals(Lexer.BINARY)) {
-            pd.setRequiredType(PropertyType.BINARY);
-        } else if (currentTokenEquals(Lexer.LONG)) {
-            pd.setRequiredType(PropertyType.LONG);
-        } else if (currentTokenEquals(Lexer.DECIMAL)) {
-            pd.setRequiredType(PropertyType.DECIMAL);
-        } else if (currentTokenEquals(Lexer.DOUBLE)) {
-            pd.setRequiredType(PropertyType.DOUBLE);
-        } else if (currentTokenEquals(Lexer.BOOLEAN)) {
-            pd.setRequiredType(PropertyType.BOOLEAN);
-        } else if (currentTokenEquals(Lexer.DATE)) {
-            pd.setRequiredType(PropertyType.DATE);
-        } else if (currentTokenEquals(Lexer.NAME)) {
-            pd.setRequiredType(PropertyType.NAME);
-        } else if (currentTokenEquals(Lexer.PATH)) {
-            pd.setRequiredType(PropertyType.PATH);
-        } else if (currentTokenEquals(Lexer.URI)) {
-            pd.setRequiredType(PropertyType.URI);
-        } else if (currentTokenEquals(Lexer.REFERENCE)) {
-            pd.setRequiredType(PropertyType.REFERENCE);
-        } else if (currentTokenEquals(Lexer.WEAKREFERENCE)) {
-            pd.setRequiredType(PropertyType.WEAKREFERENCE);
-        } else if (currentTokenEquals(Lexer.UNDEFINED)) {
-            pd.setRequiredType(PropertyType.UNDEFINED);
-        } else {
-            lexer.fail("Unkown property type '" + currentToken + "' specified");
+        try {
+            if (currentTokenEquals(Lexer.STRING)) {
+                pd.setRequiredType(PropertyType.STRING);
+            } else if (currentTokenEquals(Lexer.BINARY)) {
+                pd.setRequiredType(PropertyType.BINARY);
+            } else if (currentTokenEquals(Lexer.LONG)) {
+                pd.setRequiredType(PropertyType.LONG);
+            } else if (currentTokenEquals(Lexer.DECIMAL)) {
+                pd.setRequiredType(PropertyType.DECIMAL);
+            } else if (currentTokenEquals(Lexer.DOUBLE)) {
+                pd.setRequiredType(PropertyType.DOUBLE);
+            } else if (currentTokenEquals(Lexer.BOOLEAN)) {
+                pd.setRequiredType(PropertyType.BOOLEAN);
+            } else if (currentTokenEquals(Lexer.DATE)) {
+                pd.setRequiredType(PropertyType.DATE);
+            } else if (currentTokenEquals(Lexer.NAME)) {
+                pd.setRequiredType(PropertyType.NAME);
+            } else if (currentTokenEquals(Lexer.PATH)) {
+                pd.setRequiredType(PropertyType.PATH);
+            } else if (currentTokenEquals(Lexer.URI)) {
+                pd.setRequiredType(PropertyType.URI);
+            } else if (currentTokenEquals(Lexer.REFERENCE)) {
+                pd.setRequiredType(PropertyType.REFERENCE);
+            } else if (currentTokenEquals(Lexer.WEAKREFERENCE)) {
+                pd.setRequiredType(PropertyType.WEAKREFERENCE);
+            } else if (currentTokenEquals(Lexer.UNDEFINED)) {
+                pd.setRequiredType(PropertyType.UNDEFINED);
+            } else {
+                lexer.fail("Unkown property type '" + currentToken + "' specified");
+            }
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting property type of " + pd.getName() + " to " + currentToken);
         }
         nextToken();
         if (!currentTokenEquals(Lexer.END_TYPE)) {
@@ -571,49 +481,45 @@
      * @param ntd declaring nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doPropertyAttributes(QPropertyDefinitionBuilder pd,
-                                      QNodeTypeDefinitionBuilder ntd)
-            throws ParseException {
-        while (currentTokenEquals(Lexer.PROP_ATTRIBUTE)) {
-            if (currentTokenEquals(Lexer.PRIMARY)) {
-                if (ntd.getPrimaryItemName() != null) {
-                    String name = null;
-                    try {
-                        name = resolver.getJCRName(ntd.getName());
-                    } catch (NamespaceException e) {
-                        // Should never happen, checked earlier
-                    }
-                    lexer.fail("More than one primary item specified in node type '" + name + "'");
+    private void doPropertyAttributes(AbstractPropertyDefinitionBuilder<T> pd,
+            AbstractNodeTypeDefinitionBuilder<T> ntd) throws ParseException {
+
+        try {
+            while (currentTokenEquals(Lexer.PROP_ATTRIBUTE)) {
+                if (currentTokenEquals(Lexer.PRIMARY)) {
+                    ntd.setPrimaryItemName(pd.getName());
+                } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
+                    pd.setAutoCreated(true);
+                } else if (currentTokenEquals(Lexer.MANDATORY)) {
+                    pd.setMandatory(true);
+                } else if (currentTokenEquals(Lexer.PROTECTED)) {
+                    pd.setProtected(true);
+                } else if (currentTokenEquals(Lexer.MULTIPLE)) {
+                    pd.setMultiple(true);
+                } else if (currentTokenEquals(Lexer.COPY)) {
+                    pd.setOnParentVersion(OnParentVersionAction.COPY);
+                } else if (currentTokenEquals(Lexer.VERSION)) {
+                    pd.setOnParentVersion(OnParentVersionAction.VERSION);
+                } else if (currentTokenEquals(Lexer.INITIALIZE)) {
+                    pd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
+                } else if (currentTokenEquals(Lexer.COMPUTE)) {
+                    pd.setOnParentVersion(OnParentVersionAction.COMPUTE);
+                } else if (currentTokenEquals(Lexer.IGNORE)) {
+                    pd.setOnParentVersion(OnParentVersionAction.IGNORE);
+                } else if (currentTokenEquals(Lexer.ABORT)) {
+                    pd.setOnParentVersion(OnParentVersionAction.ABORT);
+                } else if (currentTokenEquals(Lexer.NOFULLTEXT)) {
+                    pd.setFullTextSearchable(false);
+                } else if (currentTokenEquals(Lexer.NOQUERYORDER)) {
+                    pd.setQueryOrderable(false);
+                } else if (currentTokenEquals(Lexer.QUERYOPS)) {
+                    doPropertyQueryOperators(pd);
                 }
-                ntd.setPrimaryItemName(pd.getName());
-            } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
-                pd.setAutoCreated(true);
-            } else if (currentTokenEquals(Lexer.MANDATORY)) {
-                pd.setMandatory(true);
-            } else if (currentTokenEquals(Lexer.PROTECTED)) {
-                pd.setProtected(true);
-            } else if (currentTokenEquals(Lexer.MULTIPLE)) {
-                pd.setMultiple(true);
-            } else if (currentTokenEquals(Lexer.COPY)) {
-                pd.setOnParentVersion(OnParentVersionAction.COPY);
-            } else if (currentTokenEquals(Lexer.VERSION)) {
-                pd.setOnParentVersion(OnParentVersionAction.VERSION);
-            } else if (currentTokenEquals(Lexer.INITIALIZE)) {
-                pd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
-            } else if (currentTokenEquals(Lexer.COMPUTE)) {
-                pd.setOnParentVersion(OnParentVersionAction.COMPUTE);
-            } else if (currentTokenEquals(Lexer.IGNORE)) {
-                pd.setOnParentVersion(OnParentVersionAction.IGNORE);
-            } else if (currentTokenEquals(Lexer.ABORT)) {
-                pd.setOnParentVersion(OnParentVersionAction.ABORT);
-            } else if (currentTokenEquals(Lexer.NOFULLTEXT)) {
-                pd.setFullTextSearchable(false);
-            } else if (currentTokenEquals(Lexer.NOQUERYORDER)) {
-                pd.setQueryOrderable(false);
-            } else if (currentTokenEquals(Lexer.QUERYOPS)) {
-                doPropertyQueryOperators(pd);
+                nextToken();
             }
-            nextToken();
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting property attribute of " + pd.getName() + " to " + currentToken);
         }
     }
 
@@ -623,7 +529,7 @@
      * @param pd the property definition builder
      * @throws ParseException if an error occurs
      */
-    private void doPropertyQueryOperators(QPropertyDefinitionBuilder pd)
+    private void doPropertyQueryOperators(AbstractPropertyDefinitionBuilder<T> pd)
             throws ParseException {
         if (!currentTokenEquals(Lexer.QUERYOPS)) {
             return;
@@ -652,7 +558,12 @@
                 lexer.fail("'" + s + "' is not a valid query operator");
             }
         }
-        pd.setAvailableQueryOperators(queryOps.toArray(new String[queryOps.size()]));
+        try {
+            pd.setAvailableQueryOperators(queryOps.toArray(new String[queryOps.size()]));
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error query operators for " + pd.getName() + " to " + currentToken);
+        }
     }
 
     /**
@@ -661,24 +572,23 @@
      * @param pd property definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doPropertyDefaultValue(QPropertyDefinitionBuilder pd)
+    private void doPropertyDefaultValue(AbstractPropertyDefinitionBuilder<T> pd)
             throws ParseException {
+
         if (!currentTokenEquals(Lexer.DEFAULT)) {
             return;
         }
-        List<QValue> defaultValues = new LinkedList<QValue>();
+
         do {
             nextToken();
             try {
-                defaultValues.add(pd.createValue(currentToken, resolver));
-            } catch (ValueFormatException e) {
-                lexer.fail("'" + currentToken + "' is not a valid string representation of a value of type " + pd.getRequiredType());
-            } catch (RepositoryException e) {
-                lexer.fail("An error occured during value conversion of '" + currentToken + "'");
+                pd.addDefaultValues(currentToken);
+            }
+            catch (RepositoryException e) {
+                lexer.fail("Error adding default value for " + pd.getName() + " to " + currentToken);
             }
             nextToken();
         } while (currentTokenEquals(Lexer.LIST_DELIMITER));
-        pd.setDefaultValues(defaultValues.toArray(new QValue[defaultValues.size()]));
     }
 
     /**
@@ -687,22 +597,23 @@
      * @param pd property definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doPropertyValueConstraints(QPropertyDefinitionBuilder pd)
+    private void doPropertyValueConstraints(AbstractPropertyDefinitionBuilder<T> pd)
             throws ParseException {
+
         if (!currentTokenEquals(Lexer.CONSTRAINT)) {
             return;
         }
-        List<QValueConstraint> constraints = new LinkedList<QValueConstraint>();
+
         do {
             nextToken();
             try {
-                constraints.add(pd.createValueConstraint(currentToken, resolver));
-            } catch (InvalidConstraintException e) {
-                lexer.fail("'" + currentToken + "' is not a valid constraint expression for a value of type " + pd.getRequiredType());
+                pd.addValueConstraint(currentToken);
+            }
+            catch (RepositoryException e) {
+                lexer.fail("Error adding value constraint for " + pd.getName() + " to " + currentToken);
             }
             nextToken();
         } while (currentTokenEquals(Lexer.LIST_DELIMITER));
-        pd.setValueConstraints(constraints.toArray(new QValueConstraint[constraints.size()]));
     }
 
     /**
@@ -712,13 +623,15 @@
      * @param ntd declaring nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doChildNodeDefinition(QNodeDefinitionBuilder nd,
-                                       QNodeTypeDefinitionBuilder ntd)
+    private void doChildNodeDefinition(AbstractNodeDefinitionBuilder<T> nd,
+                                       AbstractNodeTypeDefinitionBuilder<T> ntd)
             throws ParseException {
-        if (currentTokenEquals('*')) {
-            nd.setName(NameConstants.ANY_NAME);
-        } else {
-            nd.setName(toName(currentToken));
+
+        try {
+            nd.setName(currentToken);
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting child name of " + nd.getName() + " to " + currentToken);
         }
         nextToken();
         doChildNodeRequiredTypes(nd);
@@ -732,18 +645,23 @@
      * @param nd node definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doChildNodeRequiredTypes(QNodeDefinitionBuilder nd)
+    private void doChildNodeRequiredTypes(AbstractNodeDefinitionBuilder<T> nd)
             throws ParseException {
+
         if (!currentTokenEquals(Lexer.BEGIN_TYPE)) {
             return;
         }
-        List<Name> types = new LinkedList<Name>();
+
         do {
             nextToken();
-            types.add(toName(currentToken));
+            try {
+                nd.addRequiredPrimaryType(currentToken);
+            }
+            catch (RepositoryException e) {
+                lexer.fail("Error setting required primary type of " + nd.getName() + " to " + currentToken);
+            }
             nextToken();
         } while (currentTokenEquals(Lexer.LIST_DELIMITER));
-        nd.setRequiredPrimaryTypes(types.toArray(new Name[types.size()]));
         nextToken();
     }
 
@@ -753,13 +671,19 @@
      * @param nd node definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doChildNodeDefaultType(QNodeDefinitionBuilder nd)
+    private void doChildNodeDefaultType(AbstractNodeDefinitionBuilder<T> nd)
             throws ParseException {
+
         if (!currentTokenEquals(Lexer.DEFAULT)) {
             return;
         }
         nextToken();
-        nd.setDefaultPrimaryType(toName(currentToken));
+        try {
+            nd.setDefaultPrimaryType(currentToken);
+        }
+        catch (RepositoryException e) {
+            lexer.fail("Error setting default primary type of " + nd.getName() + " to " + currentToken);
+        }
         nextToken();
     }
 
@@ -770,65 +694,40 @@
      * @param ntd declaring nodetype definition builder
      * @throws ParseException if an error during parsing occurs
      */
-    private void doChildNodeAttributes(QNodeDefinitionBuilder nd,
-                                       QNodeTypeDefinitionBuilder ntd)
+    private void doChildNodeAttributes(AbstractNodeDefinitionBuilder<T> nd,
+                                       AbstractNodeTypeDefinitionBuilder<T> ntd)
             throws ParseException {
-        while (currentTokenEquals(Lexer.NODE_ATTRIBUTE)) {
-            if (currentTokenEquals(Lexer.PRIMARY)) {
-                if (ntd.getPrimaryItemName() != null) {
-                    String name = null;
-                    try {
-                        name = resolver.getJCRName(ntd.getName());
-                    } catch (NamespaceException e) {
-                        // Should never happen, checked earlier
-                    }
-                    lexer.fail("More than one primary item specified in node type '" + name + "'");
+
+        try {
+            while (currentTokenEquals(Lexer.NODE_ATTRIBUTE)) {
+                if (currentTokenEquals(Lexer.PRIMARY)) {
+                    ntd.setPrimaryItemName(nd.getName());
+                } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
+                    nd.setAutoCreated(true);
+                } else if (currentTokenEquals(Lexer.MANDATORY)) {
+                    nd.setMandatory(true);
+                } else if (currentTokenEquals(Lexer.PROTECTED)) {
+                    nd.setProtected(true);
+                } else if (currentTokenEquals(Lexer.SNS)) {
+                    nd.setAllowsSameNameSiblings(true);
+                } else if (currentTokenEquals(Lexer.COPY)) {
+                    nd.setOnParentVersion(OnParentVersionAction.COPY);
+                } else if (currentTokenEquals(Lexer.VERSION)) {
+                    nd.setOnParentVersion(OnParentVersionAction.VERSION);
+                } else if (currentTokenEquals(Lexer.INITIALIZE)) {
+                    nd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
+                } else if (currentTokenEquals(Lexer.COMPUTE)) {
+                    nd.setOnParentVersion(OnParentVersionAction.COMPUTE);
+                } else if (currentTokenEquals(Lexer.IGNORE)) {
+                    nd.setOnParentVersion(OnParentVersionAction.IGNORE);
+                } else if (currentTokenEquals(Lexer.ABORT)) {
+                    nd.setOnParentVersion(OnParentVersionAction.ABORT);
                 }
-                ntd.setPrimaryItemName(nd.getName());
-            } else if (currentTokenEquals(Lexer.AUTOCREATED)) {
-                nd.setAutoCreated(true);
-            } else if (currentTokenEquals(Lexer.MANDATORY)) {
-                nd.setMandatory(true);
-            } else if (currentTokenEquals(Lexer.PROTECTED)) {
-                nd.setProtected(true);
-            } else if (currentTokenEquals(Lexer.SNS)) {
-                nd.setAllowsSameNameSiblings(true);
-            } else if (currentTokenEquals(Lexer.COPY)) {
-                nd.setOnParentVersion(OnParentVersionAction.COPY);
-            } else if (currentTokenEquals(Lexer.VERSION)) {
-                nd.setOnParentVersion(OnParentVersionAction.VERSION);
-            } else if (currentTokenEquals(Lexer.INITIALIZE)) {
-                nd.setOnParentVersion(OnParentVersionAction.INITIALIZE);
-            } else if (currentTokenEquals(Lexer.COMPUTE)) {
-                nd.setOnParentVersion(OnParentVersionAction.COMPUTE);
-            } else if (currentTokenEquals(Lexer.IGNORE)) {
-                nd.setOnParentVersion(OnParentVersionAction.IGNORE);
-            } else if (currentTokenEquals(Lexer.ABORT)) {
-                nd.setOnParentVersion(OnParentVersionAction.ABORT);
+                nextToken();
             }
-            nextToken();
         }
-    }
-
-    /**
-     * Converts the given string into a <code>Name</code> using the current
-     * namespace mapping.
-     *
-     * @param stringName jcr name
-     * @return A <code>Name</code> object.
-     * @throws ParseException if the conversion fails
-     */
-    private Name toName(String stringName) throws ParseException {
-        try {
-            Name n = resolver.getQName(stringName);
-            String decodedLocalName = ISO9075.decode(n.getLocalName());
-            return builder.createName(n.getNamespaceURI(), decodedLocalName);
-        } catch (NameException e) {
-            lexer.fail("Error while parsing '" + stringName + "'", e);
-            return null;
-        } catch (NamespaceException e) {
-            lexer.fail("Error while parsing '" + stringName + "'", e);
-            return null;
+        catch (RepositoryException e) {
+            lexer.fail("Error setting child node attribute of " + nd.getName() + " to " + currentToken);
         }
     }
 

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ItemTemplatesBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ItemTemplatesBuilder.java?rev=814610&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ItemTemplatesBuilder.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ItemTemplatesBuilder.java Mon Sep 14 12:30:36 2009
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.commons.cnd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NodeDefinitionTemplate;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.nodetype.PropertyDefinitionTemplate;
+
+
+/**
+ * This implementation of {@link AbstractItemTypeDefinitionsBuilder} can be used with
+ * the {@link CompactNodeTypeDefReader} to produce node type definitions of type
+ * {@link NodeTypeTemplate} and a namespace map of type {@link NamespaceRegistry}.
+ * It uses {@link NodeTypeTemplateBuilder} for building node type definitions,
+ * {@link PropertyDefinitionTemplateBuilder} for building property definitions, and
+ * {@link NodeDefinitionTemplateBuilder} for building node definitions.
+ */
+public class ItemTemplatesBuilder extends
+        AbstractItemTypeDefinitionsBuilder<NodeTypeTemplate, NamespaceRegistry> {
+
+    private final NodeTypeManager nodeTypeManager;
+    private final ValueFactory valueFactory;
+    private NamespaceRegistry namespaceRegistry;
+
+    public ItemTemplatesBuilder(NodeTypeManager nodeTypeManager, ValueFactory valueFactory,
+            NamespaceRegistry namespaceRegistry) {
+
+        this.nodeTypeManager = nodeTypeManager;
+        this.valueFactory = valueFactory;
+        this.namespaceRegistry = namespaceRegistry;
+    }
+
+    @Override
+    public AbstractNodeTypeDefinitionBuilder<NodeTypeTemplate> newNodeTypeDefinitionBuilder()
+            throws UnsupportedRepositoryOperationException, RepositoryException {
+
+        return new NodeTypeTemplateBuilder();
+    }
+
+    @Override
+    public void setNamespaceMapping(NamespaceRegistry namespaceRegistry) {
+        this.namespaceRegistry = namespaceRegistry;
+    }
+
+    @Override
+    public NamespaceRegistry getNamespaceMapping() {
+        return namespaceRegistry;
+    }
+
+    @Override
+    public void setNamespace(String prefix, String uri) {
+        try {
+            namespaceRegistry.registerNamespace(prefix, uri);
+        }
+        catch (RepositoryException e) {
+            // ignore
+        }
+    }
+
+    public class NodeTypeTemplateBuilder extends AbstractNodeTypeDefinitionBuilder<NodeTypeTemplate> {
+        private final NodeTypeTemplate template;
+        private final List<String> supertypes = new ArrayList<String>();
+
+        public NodeTypeTemplateBuilder() throws UnsupportedRepositoryOperationException, RepositoryException {
+            super();
+            template = nodeTypeManager.createNodeTypeTemplate();
+        }
+
+        @Override
+        public AbstractNodeDefinitionBuilder<NodeTypeTemplate> newNodeDefinitionBuilder()
+                throws UnsupportedRepositoryOperationException, RepositoryException {
+
+            return new NodeDefinitionTemplateBuilder(this);
+        }
+
+        @Override
+        public AbstractPropertyDefinitionBuilder<NodeTypeTemplate> newPropertyDefinitionBuilder()
+                throws UnsupportedRepositoryOperationException, RepositoryException {
+
+            return new PropertyDefinitionTemplateBuilder(this);
+        }
+
+        @Override
+        public NodeTypeTemplate build() throws ConstraintViolationException {
+            template.setMixin(super.isMixin);
+            template.setOrderableChildNodes(super.isOrderable);
+            template.setAbstract(super.isAbstract);
+            template.setQueryable(super.queryable);
+            template.setDeclaredSuperTypeNames(supertypes.toArray(new String[supertypes.size()]));
+            return template;
+        }
+
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            template.setName(name);
+        }
+
+        @Override
+        public void addSupertype(String name) {
+            supertypes.add(name);
+        }
+
+        @Override
+        public void setPrimaryItemName(String name) throws ConstraintViolationException {
+            template.setPrimaryItemName(name);
+        }
+
+    }
+
+    public class PropertyDefinitionTemplateBuilder extends
+            AbstractPropertyDefinitionBuilder<NodeTypeTemplate> {
+
+        private final NodeTypeTemplateBuilder ntd;
+        private final PropertyDefinitionTemplate template;
+        private final List<Value> values = new ArrayList<Value>();
+        private final List<String> constraints = new ArrayList<String>();
+
+        public PropertyDefinitionTemplateBuilder(NodeTypeTemplateBuilder ntd)
+                throws UnsupportedRepositoryOperationException, RepositoryException {
+
+            super();
+            this.ntd = ntd;
+            template = nodeTypeManager.createPropertyDefinitionTemplate();
+        }
+
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            template.setName(name);
+        }
+
+        @Override
+        public void addDefaultValues(String value) throws ValueFormatException {
+            values.add(valueFactory.createValue(value, getRequiredType()));
+        }
+
+        @Override
+        public void addValueConstraint(String constraint) {
+            constraints.add(constraint);
+        }
+
+        @Override
+        public void setDeclaringNodeType(String name) {
+            // empty
+        }
+
+        @Override
+        public void build() throws IllegalStateException {
+            template.setAutoCreated(super.autocreate);
+            template.setMandatory(super.isMandatory);
+            template.setOnParentVersion(super.onParent);
+            template.setProtected(super.isProtected);
+            template.setRequiredType(super.requiredType);
+            template.setValueConstraints(constraints.toArray(new String[constraints.size()]));
+            template.setDefaultValues(values.toArray(new Value[values.size()]));
+            template.setMultiple(super.isMultiple);
+            template.setAvailableQueryOperators(super.queryOperators);
+            template.setFullTextSearchable(super.fullTextSearchable);
+            template.setQueryOrderable(super.queryOrderable);
+
+            @SuppressWarnings("unchecked")
+            List<PropertyDefinitionTemplate> templates = ntd.template.getPropertyDefinitionTemplates();
+            templates.add(template);
+        }
+
+    }
+
+    public class NodeDefinitionTemplateBuilder extends AbstractNodeDefinitionBuilder<NodeTypeTemplate> {
+        private final NodeTypeTemplateBuilder ntd;
+        private final NodeDefinitionTemplate template;
+        private final List<String> requiredPrimaryTypes = new ArrayList<String>();
+
+        public NodeDefinitionTemplateBuilder(NodeTypeTemplateBuilder ntd)
+                throws UnsupportedRepositoryOperationException, RepositoryException {
+
+            super();
+            this.ntd = ntd;
+            template = nodeTypeManager.createNodeDefinitionTemplate();
+        }
+
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            template.setName(name);
+        }
+
+        @Override
+        public void addRequiredPrimaryType(String name) {
+            requiredPrimaryTypes.add(name);
+        }
+
+        @Override
+        public void setDefaultPrimaryType(String name) throws ConstraintViolationException {
+            template.setDefaultPrimaryTypeName(name);
+        }
+
+        @Override
+        public void setDeclaringNodeType(String name) {
+            // empty
+        }
+
+        @Override
+        public void build() throws ConstraintViolationException {
+            template.setAutoCreated(super.autocreate);
+            template.setMandatory(super.isMandatory);
+            template.setOnParentVersion(super.onParent);
+            template.setProtected(super.isProtected);
+            template.setRequiredPrimaryTypeNames(requiredPrimaryTypes
+                    .toArray(new String[requiredPrimaryTypes.size()]));
+            template.setSameNameSiblings(super.allowSns);
+
+            @SuppressWarnings("unchecked")
+            List<NodeDefinitionTemplate> templates = ntd.template.getNodeDefinitionTemplates();
+            templates.add(template);
+        }
+
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ItemTemplatesBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/Lexer.java (from r808006, jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java)
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/Lexer.java?p2=jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/Lexer.java&p1=jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java&r1=808006&r2=814610&rev=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/Lexer.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/Lexer.java Mon Sep 14 12:30:36 2009
@@ -14,11 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.spi.commons.nodetype.compact;
+package org.apache.jackrabbit.commons.cnd;
 
-import java.io.StreamTokenizer;
-import java.io.Reader;
 import java.io.IOException;
+import java.io.Reader;
+import java.io.StreamTokenizer;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -196,13 +196,17 @@
         return systemId;
     }
 
+    public int getLineNumber() {
+        return st.lineno();
+    }
+
     /**
      * Creates a failure exception including the current line number and systemid.
      * @param message message
      * @throws ParseException the created exception
      */
     public void fail(String message) throws ParseException {
-        throw new ParseException(message, st.lineno(), -1, systemId);
+        throw new ParseException(message, getLineNumber(), -1, systemId);
     }
 
     /**
@@ -212,7 +216,7 @@
      * @throws ParseException the created exception
      */
     public void fail(String message, Throwable e) throws ParseException {
-        throw new ParseException(message, e, st.lineno(), -1, systemId);
+        throw new ParseException(message, e, getLineNumber(), -1, systemId);
     }
 
     /**
@@ -221,6 +225,6 @@
      * @throws ParseException the created exception
      */
     public void fail(Throwable e) throws ParseException {
-        throw new ParseException(e, st.lineno(), -1, systemId);
+        throw new ParseException(e, getLineNumber(), -1, systemId);
     }
 }

Copied: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ParseException.java (from r808006, jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java)
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ParseException.java?p2=jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ParseException.java&p1=jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java&r1=808006&r2=814610&rev=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/ParseException.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ParseException.java Mon Sep 14 12:30:36 2009
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.spi.commons.nodetype.compact;
+package org.apache.jackrabbit.commons.cnd;
 
 /**
  * ParseException
@@ -36,7 +36,6 @@
      */
     private final String systemId;
 
-
     /**
      * Constructs a new instance of this class with <code>null</code> as its
      * detail message.
@@ -105,7 +104,8 @@
      * {@inheritDoc}
      */
     public String getMessage() {
-        StringBuffer b = new StringBuffer(super.getMessage());
+        String message = super.getMessage();
+        StringBuffer b = new StringBuffer(message == null ? "" : message);
         String delim = " (";
         if (systemId != null && !systemId.equals("")) {
             b.append(delim);

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java?rev=814610&r1=814609&r2=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AbstractJCR2SPITest.java Mon Sep 14 12:30:36 2009
@@ -37,6 +37,7 @@
 
 import junit.framework.TestCase;
 
+import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
 import org.apache.jackrabbit.spi.Batch;
 import org.apache.jackrabbit.spi.ChildInfo;
@@ -64,7 +65,6 @@
 import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.Subscription;
 import org.apache.jackrabbit.spi.commons.AbstractReadableRepositoryService;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
 import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
 
 /**

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractReadableRepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractReadableRepositoryService.java?rev=814610&r1=814609&r2=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractReadableRepositoryService.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractReadableRepositoryService.java Mon Sep 14 12:30:36 2009
@@ -32,13 +32,13 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 
+import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.ItemInfo;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.NodeInfo;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.SessionInfo;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
 
 /**
  * <code>AbstractReadableRepositoryService</code> provides an abstract base

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractRepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractRepositoryService.java?rev=814610&r1=814609&r2=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractRepositoryService.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/AbstractRepositoryService.java Mon Sep 14 12:30:36 2009
@@ -48,6 +48,8 @@
 import javax.jcr.query.InvalidQueryException;
 import javax.jcr.version.VersionException;
 
+import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader;
+import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.spi.Batch;
 import org.apache.jackrabbit.spi.EventBundle;
 import org.apache.jackrabbit.spi.EventFilter;
@@ -75,8 +77,7 @@
 import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
 import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeStorage;
 import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeStorageImpl;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.CompactNodeTypeDefReader;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
+import org.apache.jackrabbit.spi.commons.nodetype.QItemDefinitionsBuilder;
 import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
 
 /**
@@ -205,9 +206,11 @@
             this.namespaces.setMapping(entry.getKey(), entry.getValue());
         }
 
-        CompactNodeTypeDefReader reader;
+        CompactNodeTypeDefReader<QNodeTypeDefinition, NamespaceMapping> reader;
         try {
-            reader = new CompactNodeTypeDefReader(cnd, "", this.namespaces);
+            reader = new CompactNodeTypeDefReader<QNodeTypeDefinition, NamespaceMapping>(cnd, "",
+                    this.namespaces, new QItemDefinitionsBuilder());
+
             List<QNodeTypeDefinition> ntds = reader.getNodeTypeDefinitions();
             nodeTypeDefs.registerNodeTypes(ntds.toArray(new QNodeTypeDefinition[ntds.size()]), true);
         }

Copied: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/QItemDefinitionsBuilder.java (from r808006, jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java)
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/QItemDefinitionsBuilder.java?p2=jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/QItemDefinitionsBuilder.java&p1=jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java&r1=808006&r2=814610&rev=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/QNodeTypeDefinitionsBuilderImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/QItemDefinitionsBuilder.java Mon Sep 14 12:30:36 2009
@@ -14,11 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.spi.commons.nodetype.compact;
+package org.apache.jackrabbit.spi.commons.nodetype;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.NamespaceException;
 import javax.jcr.RepositoryException;
-import javax.jcr.ValueFormatException;
 
+import org.apache.jackrabbit.commons.cnd.AbstractItemTypeDefinitionsBuilder;
+import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NameFactory;
 import org.apache.jackrabbit.spi.QNodeDefinition;
@@ -29,117 +34,254 @@
 import org.apache.jackrabbit.spi.commons.QNodeDefinitionImpl;
 import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl;
 import org.apache.jackrabbit.spi.commons.QPropertyDefinitionImpl;
+import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
+import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
-import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
+import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
 import org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint;
+import org.apache.jackrabbit.spi.commons.query.qom.Operator;
 import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
 import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+import org.apache.jackrabbit.util.ISO9075;
 
 /**
- * Default implementations of a {@link QNodeTypeDefinitionsBuilder}. This implementations uses
- * {@link QNodeTypeDefinitionBuilderImpl} for building node type definitions,
- * {@link QPropertyDefinitionBuilderImpl} for building property definitions, and
- * {@link QNodeDefinitionBuilderImpl} for building node definitions. It further uses
+ * This implementation of {@link AbstractItemTypeDefinitionsBuilder} can be used with
+ * the {@link CompactNodeTypeDefReader} to produce node type definitions of type
+ * {@link QNodeTypeDefinition} and a namespace map of type {@link NamespaceMapping}.
+ * It uses {@link QNodeTypeDefinitionBuilder} for building node type definitions,
+ * {@link QPropertyDefinitionBuilder} for building property definitions, and
+ * {@link QNodeDefinitionBuilder} for building node definitions. It further uses
  * {@link NameFactoryImpl} for creating <code>Name</code>s and {@link QValueFactoryImpl} for
  * creating <code>QValue</code>s.
  */
-public class QNodeTypeDefinitionsBuilderImpl extends QNodeTypeDefinitionsBuilder {
+public class QItemDefinitionsBuilder extends
+        AbstractItemTypeDefinitionsBuilder<QNodeTypeDefinition, NamespaceMapping> {
 
     private static final NameFactory NAME_FACTORY = NameFactoryImpl.getInstance();
 
-    public QNodeTypeDefinitionBuilder newQNodeTypeDefinition() {
-        return new QNodeTypeDefinitionBuilderImpl();
+    /**
+     * Default namespace mappings
+     */
+    public static final NamespaceMapping NS_DEFAULTS;
+    static {
+        try {
+            NS_DEFAULTS = new NamespaceMapping();
+            NS_DEFAULTS.setMapping(Name.NS_EMPTY_PREFIX, Name.NS_DEFAULT_URI);
+            NS_DEFAULTS.setMapping(Name.NS_JCR_PREFIX, Name.NS_JCR_URI);
+            NS_DEFAULTS.setMapping(Name.NS_MIX_PREFIX, Name.NS_MIX_URI);
+            NS_DEFAULTS.setMapping(Name.NS_NT_PREFIX, Name.NS_NT_URI);
+            NS_DEFAULTS.setMapping(Name.NS_REP_PREFIX, Name.NS_REP_URI);
+        } catch (NamespaceException e) {
+            throw new InternalError(e.toString());
+        }
     }
 
-    public Name createName(String namespaceURI, String localName) {
-        return NAME_FACTORY.create(namespaceURI, localName);
+    private NamespaceMapping nsMappings = new NamespaceMapping(NS_DEFAULTS);
+    private NamePathResolver resolver = new DefaultNamePathResolver(nsMappings);
+
+    @Override
+    public AbstractNodeTypeDefinitionBuilder<QNodeTypeDefinition> newNodeTypeDefinitionBuilder() {
+        return new QNodeTypeDefinitionBuilder();
     }
 
-    /**
-     * Default implementation of a {@link QNodeTypeDefinitionBuilder}.
-     */
-    public class QNodeTypeDefinitionBuilderImpl extends QNodeTypeDefinitionBuilder {
+    @Override
+    public void setNamespaceMapping(NamespaceMapping nsMapping) {
+        this.nsMappings = nsMapping;
+        this.resolver = new DefaultNamePathResolver(nsMapping);
+    }
 
-        public QNodeDefinitionBuilder newQNodeDefinitionBuilder() {
-            return new QNodeDefinitionBuilderImpl();
+    @Override
+    public NamespaceMapping getNamespaceMapping() {
+        return nsMappings;
+    }
+
+    @Override
+    public void setNamespace(String prefix, String uri) {
+        try {
+            nsMappings.setMapping(prefix, uri);
+        }
+        catch (NamespaceException e) {
+            // ignore
+        }
+    }
+
+    public class QNodeTypeDefinitionBuilder extends AbstractNodeTypeDefinitionBuilder<QNodeTypeDefinition> {
+        private Name name;
+        private final List<Name> supertypes = new ArrayList<Name>();
+        private Name primaryItem;
+        private final List<QPropertyDefinition> propertyDefs = new ArrayList<QPropertyDefinition>();
+        private final List<QNodeDefinition> childNodeDefs = new ArrayList<QNodeDefinition>();
+
+        @Override
+        public AbstractNodeDefinitionBuilder<QNodeTypeDefinition> newNodeDefinitionBuilder() {
+            return new QNodeDefinitionBuilder(this);
         }
 
-        public QPropertyDefinitionBuilder newQPropertyDefinition() {
-            return new QPropertyDefinitionBuilderImpl();
+        @Override
+        public AbstractPropertyDefinitionBuilder<QNodeTypeDefinition> newPropertyDefinitionBuilder() {
+            return new QPropertyDefinitionBuilder(this);
         }
 
+        @Override
         public QNodeTypeDefinition build() {
             return new QNodeTypeDefinitionImpl(
-                    this.getName(),
-                    this.getSuperTypes(),
+                    name,
+                    supertypes.toArray(new Name[supertypes.size()]),
                     null,
-                    this.getMixin(),
-                    this.getAbstract(),
-                    this.getQueryable(),
-                    this.getOrderableChildNodes(),
-                    this.getPrimaryItemName(),
-                    this.getPropertyDefs(),
-                    this.getChildNodeDefs());
+                    super.isMixin,
+                    super.isAbstract,
+                    super.queryable,
+                    super.isOrderable,
+                    primaryItem,
+                    propertyDefs.toArray(new QPropertyDefinition[propertyDefs.size()]),
+                    childNodeDefs.toArray(new QNodeDefinition[childNodeDefs.size()]));
+        }
+
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            this.name = toName(name);
+        }
+
+        @Override
+        public void addSupertype(String name) throws IllegalNameException, NamespaceException {
+            supertypes.add(toName(name));
+        }
+
+        @Override
+        public void setPrimaryItemName(String name) throws IllegalNameException, NamespaceException {
+            primaryItem = toName(name);
         }
 
     }
 
-    /**
-     * Default implementation of a {@link QPropertyDefinitionBuilder}.
-     */
-    public class QPropertyDefinitionBuilderImpl extends QPropertyDefinitionBuilder {
+    public class QPropertyDefinitionBuilder extends AbstractPropertyDefinitionBuilder<QNodeTypeDefinition> {
+        private Name name;
+        private final QNodeTypeDefinitionBuilder ntd;
+        private final List<QValue> values = new ArrayList<QValue>();
+        private final List<QValueConstraint> constraints = new ArrayList<QValueConstraint>();
+        private Name declaringType;
+
+        public QPropertyDefinitionBuilder(QNodeTypeDefinitionBuilder ntd) {
+            super();
+            this.ntd = ntd;
+        }
+
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            if ("*".equals(name)) {
+                this.name = NameConstants.ANY_NAME;
+            }
+            else {
+                this.name = toName(name);
+            }
+        }
 
-        public QValue createValue(String value, NamePathResolver resolver)
-                throws ValueFormatException, RepositoryException {
+        @Override
+        public void addDefaultValues(String value) throws RepositoryException {
+            values.add(ValueFormat.getQValue(value, getRequiredType(), resolver, QValueFactoryImpl.getInstance()));
+        }
 
-            return ValueFormat.getQValue(value, getRequiredType(), resolver, QValueFactoryImpl
-                    .getInstance());
+        @Override
+        public void addValueConstraint(String constraint) throws InvalidConstraintException {
+            constraints.add(ValueConstraint.create(getRequiredType(), constraint, resolver));
         }
 
-        public QValueConstraint createValueConstraint(String constraint, NamePathResolver resolver)
-                throws InvalidConstraintException {
-
-            return ValueConstraint.create(getRequiredType(), constraint, resolver);
-        }
-
-        public QPropertyDefinition build() {
-            return new QPropertyDefinitionImpl(
-                    this.getName(),
-                    this.getDeclaringNodeType(),
-                    this.getAutoCreated(),
-                    this.getMandatory(),
-                    this.getOnParentVersion(),
-                    this.getProtected(),
-                    this.getDefaultValues(),
-                    this.getMultiple(),
-                    this.getRequiredType(),
-                    this.getValueConstraints(),
-                    this.getAvailableQueryOperators(),
-                    this.getFullTextSearchable(),
-                    this.getQueryOrderable());
+        @Override
+        public void setDeclaringNodeType(String name) throws IllegalNameException, NamespaceException {
+            this.declaringType = toName(name);
+        }
+
+        @Override
+        public void build() throws IllegalStateException {
+            if (queryOperators == null) {
+                queryOperators = Operator.getAllQueryOperators();
+            }
+
+            ntd.propertyDefs.add(new QPropertyDefinitionImpl(
+                    name,
+                    declaringType,
+                    super.autocreate,
+                    super.isMandatory,
+                    super.onParent,
+                    super.isProtected,
+                    values.toArray(new QValue[values.size()]),
+                    super.isMultiple,
+                    super.requiredType,
+                    constraints.toArray(new QValueConstraint[constraints.size()]),
+                    super.queryOperators,
+                    super.fullTextSearchable,
+                    super.queryOrderable));
         }
 
     }
 
-    /**
-     * Default implementation of a {@link QNodeDefinitionBuilder}.
-     */
-    public class QNodeDefinitionBuilderImpl extends QNodeDefinitionBuilder {
+    public class QNodeDefinitionBuilder extends AbstractNodeDefinitionBuilder<QNodeTypeDefinition> {
+        private final QNodeTypeDefinitionBuilder ntd;
+        private Name name;
+        private final List<Name> requiredPrimaryTypes = new ArrayList<Name>();
+        private Name defaultPrimaryType;
+        private Name declaringNodeType;
+
+        public QNodeDefinitionBuilder(QNodeTypeDefinitionBuilder ntd) {
+            super();
+            this.ntd = ntd;
+        }
 
-        public QNodeDefinition build() {
-            return new QNodeDefinitionImpl(
-                    this.getName(),
-                    this.getDeclaringNodeType(),
-                    this.getAutoCreated(),
-                    this.getMandatory(),
-                    this.getOnParentVersion(),
-                    this.getProtected(),
-                    this.getDefaultPrimaryType(),
-                    this.getRequiredPrimaryTypes(),
-                    this.getAllowsSameNameSiblings());
+        @Override
+        public void setName(String name) throws RepositoryException {
+            super.setName(name);
+            if ("*".equals(name)) {
+                this.name = NameConstants.ANY_NAME;
+            }
+            else {
+                this.name = toName(name);
+            }
         }
 
+        @Override
+        public void addRequiredPrimaryType(String name) throws IllegalNameException, NamespaceException {
+            requiredPrimaryTypes.add(toName(name));
+        }
+
+        @Override
+        public void setDefaultPrimaryType(String name) throws IllegalNameException, NamespaceException {
+            defaultPrimaryType = toName(name);
+        }
+
+        @Override
+        public void setDeclaringNodeType(String name) throws IllegalNameException, NamespaceException {
+            declaringNodeType = toName(name);
+        }
+
+        @Override
+        public void build() {
+            if (requiredPrimaryTypes.isEmpty()) {
+                requiredPrimaryTypes.add(NameConstants.NT_BASE);
+            }
+
+            ntd.childNodeDefs.add(new QNodeDefinitionImpl(
+                    name,
+                    declaringNodeType,
+                    super.autocreate,
+                    super.isMandatory,
+                    super.onParent,
+                    super.isProtected,
+                    defaultPrimaryType,
+                    requiredPrimaryTypes.toArray(new Name[requiredPrimaryTypes.size()]),
+                    super.allowSns));
+        }
+
+    }
+
+
+    private Name toName(String name) throws IllegalNameException, NamespaceException {
+        Name n = resolver.getQName(name);
+        String decodedLocalName = ISO9075.decode(n.getLocalName());
+        return NAME_FACTORY.create(n.getNamespaceURI(), decodedLocalName);
     }
 
 }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java?rev=814610&r1=814609&r2=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java Mon Sep 14 12:30:36 2009
@@ -36,6 +36,7 @@
 import javax.jcr.query.qom.QueryObjectModelConstants;
 import javax.jcr.version.OnParentVersionAction;
 
+import org.apache.jackrabbit.commons.cnd.Lexer;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefTest.java?rev=814610&r1=814609&r2=814610&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefTest.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefTest.java Mon Sep 14 12:30:36 2009
@@ -23,13 +23,15 @@
 import java.io.StringWriter;
 import java.util.List;
 
+import junit.framework.TestCase;
+
+import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
 import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
 import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeDefDiff;
-
-import junit.framework.TestCase;
+import org.apache.jackrabbit.spi.commons.nodetype.QItemDefinitionsBuilder;
 
 public class CompactNodeTypeDefTest extends TestCase {
 
@@ -39,7 +41,9 @@
 
         // Read in node type def from test file
         Reader reader = new InputStreamReader(getClass().getClassLoader().getResourceAsStream(TEST_FILE));
-        CompactNodeTypeDefReader cndReader = new CompactNodeTypeDefReader(reader, TEST_FILE);
+        CompactNodeTypeDefReader<QNodeTypeDefinition, NamespaceMapping> cndReader =
+            new CompactNodeTypeDefReader<QNodeTypeDefinition, NamespaceMapping>(
+                reader, TEST_FILE, new QItemDefinitionsBuilder());
 
         List<QNodeTypeDefinition> ntdList1 = cndReader.getNodeTypeDefinitions();
         NamespaceMapping nsm = cndReader.getNamespaceMapping();
@@ -50,7 +54,8 @@
         CompactNodeTypeDefWriter.write(ntdList1, nsm, resolver, sw);
 
         // Rerun the reader on the product of the writer
-        cndReader = new CompactNodeTypeDefReader(new StringReader(sw.toString()), TEST_FILE);
+        cndReader = new CompactNodeTypeDefReader<QNodeTypeDefinition, NamespaceMapping>(
+                new StringReader(sw.toString()), TEST_FILE, new QItemDefinitionsBuilder());
 
         List<QNodeTypeDefinition> ntdList2 = cndReader.getNodeTypeDefinitions();