You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2012/05/04 15:58:16 UTC

svn commit: r1333966 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype: NodeDefinitionImpl.java NodeTypeImpl.java NodeTypeManagerImpl.java

Author: reschke
Date: Fri May  4 13:58:16 2012
New Revision: 1333966

URL: http://svn.apache.org/viewvc?rev=1333966&view=rev
Log:
OAK-66: switch to CND reader (WIP)

Modified:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerImpl.java

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionImpl.java?rev=1333966&r1=1333965&r2=1333966&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionImpl.java Fri May  4 13:58:16 2012
@@ -33,13 +33,10 @@ class NodeDefinitionImpl extends ItemDef
 
     private final boolean allowsSameNameSiblings;
 
-    protected NodeDefinitionImpl(
-            NodeType type, NameMapper mapper, String name, boolean autoCreated,
-            boolean mandatory, int onParentRevision, boolean isProtected,
-            NodeTypeManager manager, String[] requiredPrimaryTypeNames,
+    protected NodeDefinitionImpl(NodeTypeManager manager, NodeType type, NameMapper mapper, String name, boolean autoCreated,
+            boolean mandatory, int onParentRevision, boolean isProtected, String[] requiredPrimaryTypeNames,
             String defaultPrimaryTypeName, boolean allowsSameNameSiblings) {
-        super(type, mapper, name, autoCreated,
-                mandatory, onParentRevision, isProtected);
+        super(type, mapper, name, autoCreated, mandatory, onParentRevision, isProtected);
         this.manager = manager;
         this.requiredPrimaryTypeNames = requiredPrimaryTypeNames;
         this.defaultPrimaryTypeName = defaultPrimaryTypeName;

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeImpl.java?rev=1333966&r1=1333965&r2=1333966&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeImpl.java Fri May  4 13:58:16 2012
@@ -16,18 +16,6 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
-import org.apache.jackrabbit.oak.namepath.NameMapper;
-
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeIterator;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.jcr.nodetype.PropertyDefinition;
-import javax.jcr.version.OnParentVersionAction;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -36,25 +24,24 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
-class NodeTypeImpl implements NodeType {
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeIterator;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
+import org.apache.jackrabbit.oak.namepath.NameMapper;
 
-    private static final Pattern CND_PATTERN = Pattern.compile(
-            "( > (([\\S, ]+)))?(\n  mixin)?(\n  abstract)?"
-            + "(\n  orderable)?(\n  primaryitem (\\S+))?\n?(.*)",
-            Pattern.DOTALL);
-
-    private static final Pattern DEF_PATTERN = Pattern.compile(
-            "  ([\\+\\-]) (\\S+) \\((\\S+?)\\)( = (\\S+))?"
-            + "(( (mandatory|autocreated|protected|multiple|sns))*)"
-            + "( ([A-Z]+))?(.*)");
+class NodeTypeImpl implements NodeType {
 
     private final NodeTypeManager manager;
 
     private final NameMapper mapper;
-
+    
     private final String name;
 
     private final String[] declaredSuperTypeNames;
@@ -67,104 +54,29 @@ class NodeTypeImpl implements NodeType {
 
     private final String primaryItemName;
 
-    private final List<PropertyDefinition> declaredPropertyDefinitions =
-            new ArrayList<PropertyDefinition>();
+    private final List<PropertyDefinition> declaredPropertyDefinitions = new ArrayList<PropertyDefinition>();
 
     private final List<NodeDefinition> declaredChildNodeDefinitions =
             new ArrayList<NodeDefinition>();
 
-    public NodeTypeImpl(
-            NodeTypeManager manager, NameMapper mapper, String name,
-            String cnd) {
+    public NodeTypeImpl(NodeTypeManager manager, NameMapper mapper, String name, String[] declaredSuperTypeNames,
+            String primaryItemName, boolean mixin, boolean isAbstract, boolean hasOrderableChildNodes) {
         this.manager = manager;
         this.mapper = mapper;
         this.name = name;
-
-        Matcher matcher = CND_PATTERN.matcher(cnd);
-        matcher.matches();
-
-        this.isAbstract = matcher.group(5) != null;
-        this.mixin = matcher.group(4) != null;
-        this.hasOrderableChildNodes = matcher.group(6) != null;
-        this.primaryItemName = matcher.group(7);
-
-        String supertypes = matcher.group(2);
-        if (supertypes != null)  {
-            this.declaredSuperTypeNames = supertypes.split(", ");
-        } else if (mixin) {
-            this.declaredSuperTypeNames = new String[0];
-        } else {
-            this.declaredSuperTypeNames = new String[] { "nt:base" };
-        }
-
-        String defs = matcher.group(9);
-        if (defs != null && !defs.isEmpty()) {
-            for (String line : defs.split("\n")) {
-                matcher = DEF_PATTERN.matcher(line);
-                if (!matcher.matches()) {
-                    continue;
-                }
-
-                String defName = matcher.group(2);
-                String defType = matcher.group(3);
-
-                boolean mandatory = matcher.group(6).contains(" mandatory");
-                boolean autoCreated = matcher.group(6).contains(" autocreated");
-                boolean isProtected = matcher.group(6).contains(" protected");
-                boolean multiple = matcher.group(6).contains(" multiple");
-                boolean allowSNS = matcher.group(6).contains(" sns");
-
-                int onParentVersionAction = OnParentVersionAction.COPY;
-                if (matcher.group(10) != null) {
-                    onParentVersionAction =
-                            OnParentVersionAction.valueFromName(matcher.group(10));
-                }
-
-                if ("+".equals(matcher.group(1))) {
-                    declaredChildNodeDefinitions.add(new NodeDefinitionImpl(
-                            this, mapper, defName, autoCreated, mandatory,
-                            onParentVersionAction, isProtected, manager,
-                            defType.split(", "), matcher.group(5), allowSNS));
-                } else if ("-".equals(matcher.group(1))) {
-                    declaredPropertyDefinitions.add(new PropertyDefinitionImpl(
-                            this, mapper, defName, autoCreated, mandatory,
-                            onParentVersionAction, isProtected,
-                            valueFromName(defType), multiple));
-                }
-            }
-        }
+        this.declaredSuperTypeNames = declaredSuperTypeNames;
+        this.primaryItemName = primaryItemName;
+        this.mixin = mixin;
+        this.isAbstract = isAbstract;
+        this.hasOrderableChildNodes = hasOrderableChildNodes;
+    }
+    
+    public void addPropertyDefinition(PropertyDefinition declaredPropertyDefinition) {
+        this.declaredPropertyDefinitions.add(declaredPropertyDefinition);
     }
 
-    private static int valueFromName(String name) {
-        if (name.equalsIgnoreCase(PropertyType.TYPENAME_STRING)) {
-            return PropertyType.STRING;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_BINARY)) {
-            return PropertyType.BINARY;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_BOOLEAN)) {
-            return PropertyType.BOOLEAN;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_LONG)) {
-            return PropertyType.LONG;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_DOUBLE)) {
-            return PropertyType.DOUBLE;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_DECIMAL)) {
-            return PropertyType.DECIMAL;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_DATE)) {
-            return PropertyType.DATE;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_NAME)) {
-            return PropertyType.NAME;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_PATH)) {
-            return PropertyType.PATH;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_REFERENCE)) {
-            return PropertyType.REFERENCE;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_WEAKREFERENCE)) {
-            return PropertyType.WEAKREFERENCE;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_URI)) {
-            return PropertyType.URI;
-        } else if (name.equalsIgnoreCase(PropertyType.TYPENAME_UNDEFINED)) {
-            return PropertyType.UNDEFINED;
-        } else {
-            throw new IllegalArgumentException("unknown type: " + name);
-        }
+    public void addChildNodeDefinition(NodeDefinition declaredChildNodeDefinition) {
+        this.declaredChildNodeDefinitions.add(declaredChildNodeDefinition);
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerImpl.java?rev=1333966&r1=1333965&r2=1333966&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerImpl.java Fri May  4 13:58:16 2012
@@ -16,69 +16,85 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
-import org.apache.jackrabbit.oak.namepath.NameMapper;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeDefinitionTemplate;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeDefinition;
 import javax.jcr.nodetype.NodeTypeIterator;
 import javax.jcr.nodetype.NodeTypeManager;
 import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.nodetype.PropertyDefinition;
 import javax.jcr.nodetype.PropertyDefinitionTemplate;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
-public class NodeTypeManagerImpl implements NodeTypeManager {
+import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader;
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory;
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractNodeDefinitionBuilder;
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractNodeTypeDefinitionBuilder;
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractPropertyDefinitionBuilder;
+import org.apache.jackrabbit.commons.cnd.ParseException;
+import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
+import org.apache.jackrabbit.oak.namepath.NameMapper;
 
-    private static final Pattern CND_PATTERN =
-            Pattern.compile("\\[(\\S*)?\\](.*?)\n\n", Pattern.DOTALL);
+public class NodeTypeManagerImpl implements NodeTypeManager {
 
     private final NameMapper mapper;
+    private final List<NodeType> types;
 
-    private final Map<String, NodeType> types = new HashMap<String, NodeType>();
+    private final Map<String, NodeType> typemap = new HashMap<String, NodeType>();
 
     public NodeTypeManagerImpl(NameMapper mapper) throws RepositoryException {
         this.mapper = mapper;
 
         try {
-            InputStream stream = NodeTypeManagerImpl.class.getResourceAsStream(
-                    "builtin_nodetypes.cnd");
+            InputStream stream = NodeTypeManagerImpl.class.getResourceAsStream("builtin_nodetypes.cnd");
+            Reader reader = new InputStreamReader(stream, "UTF-8");
             try {
-                String cnd = IOUtils.toString(stream, "UTF-8");
-                Matcher matcher = CND_PATTERN.matcher(cnd.replace("\r\n", "\n"));
-                while (matcher.find()) {
-                    String name = matcher.group(1);
-                    types.put(name, new NodeTypeImpl(
-                            this, mapper, name, matcher.group(2)));
-                }
+                DefinitionBuilderFactory<NodeType, Map<String, String>> dbf = new DefinitionBuilderFactoryImpl(this, mapper);
+                CompactNodeTypeDefReader<NodeType, Map<String, String>> cndr = new CompactNodeTypeDefReader<NodeType, Map<String, String>>(
+                        reader, null, dbf);
+
+                types = cndr.getNodeTypeDefinitions();
+            } catch (ParseException ex) {
+                throw new RepositoryException("Failed to load built-in node types", ex);
             } finally {
                 stream.close();
             }
-        } catch (IOException e) {
-            throw new RepositoryException(
-                    "Failed to load built-in node types", e);
+        } catch (IOException ex) {
+            throw new RepositoryException("Failed to load built-in node types", ex);
+        }
+    }
+
+    private void init() {
+        if (typemap.isEmpty()) {
+            for (NodeType t : types) {
+                typemap.put(t.getName(), t);
+            }
         }
     }
 
     @Override
     public boolean hasNodeType(String name) throws RepositoryException {
-        return types.containsKey(mapper.getOakName(name));
+        init();
+        return typemap.containsKey(mapper.getOakName(name));
     }
 
     @Override
     public NodeType getNodeType(String name) throws RepositoryException {
-        NodeType type = types.get(mapper.getOakName(name));
+        init();
+        NodeType type = typemap.get(mapper.getOakName(name));
         if (type == null) {
             throw new NoSuchNodeTypeException("Unknown node type: " + name);
         }
@@ -87,13 +103,15 @@ public class NodeTypeManagerImpl impleme
 
     @Override
     public NodeTypeIterator getAllNodeTypes() throws RepositoryException {
-        return new NodeTypeIteratorAdapter(types.values());
+        init();
+        return new NodeTypeIteratorAdapter(typemap.values());
     }
 
     @Override
     public NodeTypeIterator getPrimaryNodeTypes() throws RepositoryException {
+        init();
         Collection<NodeType> primary = new ArrayList<NodeType>();
-        for (NodeType type : types.values()) {
+        for (NodeType type : typemap.values()) {
             if (!type.isMixin()) {
                 primary.add(type);
             }
@@ -103,8 +121,9 @@ public class NodeTypeManagerImpl impleme
 
     @Override
     public NodeTypeIterator getMixinNodeTypes() throws RepositoryException {
+        init();
         Collection<NodeType> mixin = new ArrayList<NodeType>();
-        for (NodeType type : types.values()) {
+        for (NodeType type : typemap.values()) {
             if (type.isMixin()) {
                 mixin.add(type);
             }
@@ -118,36 +137,31 @@ public class NodeTypeManagerImpl impleme
     }
 
     @Override
-    public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd)
-            throws RepositoryException {
+    public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd) throws RepositoryException {
 
         throw new UnsupportedRepositoryOperationException();
     }
 
     @Override
-    public NodeDefinitionTemplate createNodeDefinitionTemplate()
-            throws RepositoryException {
+    public NodeDefinitionTemplate createNodeDefinitionTemplate() throws RepositoryException {
 
         throw new UnsupportedRepositoryOperationException();
     }
 
     @Override
-    public PropertyDefinitionTemplate createPropertyDefinitionTemplate()
-            throws RepositoryException {
+    public PropertyDefinitionTemplate createPropertyDefinitionTemplate() throws RepositoryException {
 
         throw new UnsupportedRepositoryOperationException();
     }
 
     @Override
-    public NodeType registerNodeType(NodeTypeDefinition ntd, boolean allowUpdate)
-            throws RepositoryException {
+    public NodeType registerNodeType(NodeTypeDefinition ntd, boolean allowUpdate) throws RepositoryException {
 
         throw new UnsupportedRepositoryOperationException();
     }
 
     @Override
-    public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds,
-            boolean allowUpdate) throws RepositoryException {
+    public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate) throws RepositoryException {
 
         throw new UnsupportedRepositoryOperationException();
     }
@@ -162,4 +176,175 @@ public class NodeTypeManagerImpl impleme
         throw new UnsupportedRepositoryOperationException();
     }
 
+    private class DefinitionBuilderFactoryImpl extends DefinitionBuilderFactory<NodeType, Map<String, String>> {
+
+        private Map<String, String> nsmap = new HashMap<String, String>();
+
+        private final NodeTypeManager ntm;
+        private final NameMapper mapper;
+
+        public DefinitionBuilderFactoryImpl(NodeTypeManager ntm, NameMapper mapper) {
+            this.ntm = ntm;
+            this.mapper = mapper;
+        }
+
+        @Override
+        public Map<String, String> getNamespaceMapping() {
+            return this.nsmap;
+        }
+
+        @Override
+        public org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractNodeTypeDefinitionBuilder<NodeType> newNodeTypeDefinitionBuilder()
+                throws RepositoryException {
+            return new NodeTypeDefinitionBuilderImpl(this.ntm, this.mapper);
+        }
+
+        @Override
+        public void setNamespace(String prefix, String uri) throws RepositoryException {
+            this.nsmap.put(prefix, uri);
+        }
+
+        @Override
+        public void setNamespaceMapping(Map<String, String> nsmap) {
+            this.nsmap = nsmap;
+        }
+    }
+
+    private class NodeTypeDefinitionBuilderImpl extends AbstractNodeTypeDefinitionBuilder<NodeType> {
+
+        private List<PropertyDefinitionBuilderImpl> propertyDefinitions = new ArrayList<PropertyDefinitionBuilderImpl>();
+        private List<NodeDefinitionBuilderImpl> childNodeDefinitions = new ArrayList<NodeDefinitionBuilderImpl>();
+
+        private final NodeTypeManager ntm;
+        private final NameMapper mapper;
+
+        private String primaryItemName;
+        private List<String> declaredSuperTypes = new ArrayList<String>();
+
+        public NodeTypeDefinitionBuilderImpl(NodeTypeManager ntm, NameMapper mapper) {
+            this.ntm = ntm;
+            this.mapper = mapper;
+        }
+
+        @Override
+        public void addSupertype(String superType) throws RepositoryException {
+            this.declaredSuperTypes.add(superType);
+        }
+
+        @Override
+        public void setPrimaryItemName(String primaryItemName) throws RepositoryException {
+            this.primaryItemName = primaryItemName;
+        }
+
+        @Override
+        public AbstractPropertyDefinitionBuilder<NodeType> newPropertyDefinitionBuilder() throws RepositoryException {
+            return new PropertyDefinitionBuilderImpl(this);
+        }
+
+        @Override
+        public AbstractNodeDefinitionBuilder<NodeType> newNodeDefinitionBuilder() throws RepositoryException {
+            return new NodeDefinitionBuilderImpl(this);
+        }
+
+        @Override
+        public NodeType build() throws RepositoryException {
+
+            NodeTypeImpl result = new NodeTypeImpl(ntm, mapper, name, declaredSuperTypes.toArray(new String[declaredSuperTypes
+                    .size()]), primaryItemName, isMixin, isAbstract, isOrderable);
+
+            for (PropertyDefinitionBuilderImpl pdb : propertyDefinitions) {
+                result.addPropertyDefinition(pdb.getPropertyDefinition(result, mapper));
+            }
+
+            for (NodeDefinitionBuilderImpl ndb : childNodeDefinitions) {
+                result.addChildNodeDefinition(ndb.getNodeDefinition(ntm, result, mapper));
+            }
+
+            return result;
+        }
+
+        public void addPropertyDefinition(PropertyDefinitionBuilderImpl pd) {
+            this.propertyDefinitions.add(pd);
+        }
+
+        public void addNodeDefinition(NodeDefinitionBuilderImpl nd) {
+            this.childNodeDefinitions.add(nd);
+        }
+    }
+
+    private class NodeDefinitionBuilderImpl extends AbstractNodeDefinitionBuilder<NodeType> {
+
+        private String declaringNodeType;
+        private String defaultPrimaryType;
+        private List<String> requiredPrimaryTypes = new ArrayList<String>();
+
+        private final NodeTypeDefinitionBuilderImpl ndtb;
+
+        public NodeDefinitionBuilderImpl(NodeTypeDefinitionBuilderImpl ntdb) {
+            this.ndtb = ntdb;
+        }
+
+        public NodeDefinition getNodeDefinition(NodeTypeManager ntm, NodeType nt, NameMapper mapper) {
+            return new NodeDefinitionImpl(ntm, nt, mapper, name, autocreate, isMandatory, onParent, isProtected,
+                    requiredPrimaryTypes.toArray(new String[requiredPrimaryTypes.size()]), defaultPrimaryType, allowSns);
+        };
+
+        @Override
+        public void setDefaultPrimaryType(String defaultPrimaryType) throws RepositoryException {
+            this.defaultPrimaryType = defaultPrimaryType;
+        }
+
+        @Override
+        public void addRequiredPrimaryType(String name) throws RepositoryException {
+            this.requiredPrimaryTypes.add(name);
+        }
+
+        @Override
+        public void setDeclaringNodeType(String declaringNodeType) throws RepositoryException {
+            this.declaringNodeType = declaringNodeType;
+        }
+
+        @Override
+        public void build() throws RepositoryException {
+            this.ndtb.addNodeDefinition(this);
+        }
+    }
+
+    private class PropertyDefinitionBuilderImpl extends AbstractPropertyDefinitionBuilder<NodeType> {
+
+        private String declaringNodeType;
+        private List<String> defaultValues = new ArrayList<String>();
+        private List<String> valueConstraints = new ArrayList<String>();
+
+        private final NodeTypeDefinitionBuilderImpl ndtb;
+
+        public PropertyDefinitionBuilderImpl(NodeTypeDefinitionBuilderImpl ntdb) {
+            this.ndtb = ntdb;
+        }
+
+        public PropertyDefinition getPropertyDefinition(NodeType nt, NameMapper mapper) {
+            return new PropertyDefinitionImpl(nt, mapper, name, autocreate, isMandatory, onParent, isProtected, requiredType,
+                    isMultiple);
+        }
+
+        @Override
+        public void addValueConstraint(String constraint) throws RepositoryException {
+            this.valueConstraints.add(constraint);
+        }
+
+        @Override
+        public void addDefaultValues(String value) throws RepositoryException {
+            this.defaultValues.add(value);
+        }
+
+        @Override
+        public void setDeclaringNodeType(String declaringNodeType) throws RepositoryException {
+            this.declaringNodeType = declaringNodeType;
+        }
+
+        @Override
+        public void build() throws RepositoryException {
+            this.ndtb.addPropertyDefinition(this);
+        }
+    }
 }