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 ju...@apache.org on 2012/07/23 22:13:10 UTC

svn commit: r1364781 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr: ./ nodetype/

Author: jukka
Date: Mon Jul 23 20:13:09 2012
New Revision: 1364781

URL: http://svn.apache.org/viewvc?rev=1364781&view=rev
Log:
OAK-66: JCR Node Type Management

Rewrite NodeTypeManagerImpl and related classes in oak-jcr to use in-content type information.

Added:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/DefBuilderFactory.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/TypeNode.java
Removed:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionTemplateImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeManagerDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionDelegate.java
Modified:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionImpl.java
    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/NodeDefinitionTemplateImpl.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
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTemplateImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionTemplateImpl.java

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java Mon Jul 23 20:13:09 2012
@@ -56,7 +56,7 @@ public class NodeDelegate extends ItemDe
      */
     private Tree tree;
 
-    NodeDelegate(SessionDelegate sessionDelegate, Tree tree) {
+    public NodeDelegate(SessionDelegate sessionDelegate, Tree tree) {
         super(sessionDelegate);
         this.tree = tree;
     }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java Mon Jul 23 20:13:09 2012
@@ -29,7 +29,6 @@ import org.apache.jackrabbit.commons.Sim
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.core.ContentRepositoryImpl;
-import org.apache.jackrabbit.oak.jcr.nodetype.NodeTypeManagerDelegate;
 import org.apache.jackrabbit.oak.jcr.util.LazyValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Mon Jul 23 20:13:09 2012
@@ -199,6 +199,25 @@ public class SessionDelegate {
     }
 
     /**
+     * Returns the Oak name for the given JCR name, or throws a
+     * {@link RepositoryException} if the name is invalid or can
+     * otherwise not be mapped.
+     *
+     * @param jcrName JCR name
+     * @return Oak name
+     * @throws RepositoryException if the name is invalid
+     */
+    @Nonnull
+    public String getOakNameOrThrow(String jcrName) throws RepositoryException {
+        String oakName = getNamePathMapper().getOakName(jcrName);
+        if (oakName != null) {
+            return oakName;
+        } else {
+            throw new RepositoryException("Invalid name: " + jcrName);
+        }
+    }
+
+    /**
      * Shortcut for {@code SessionDelegate.getNamePathMapper().getOakPath(jcrPath)}.
      *
      * @param jcrPath JCR path

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/DefBuilderFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/DefBuilderFactory.java?rev=1364781&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/DefBuilderFactory.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/DefBuilderFactory.java Mon Jul 23 20:13:09 2012
@@ -0,0 +1,51 @@
+/*
+ * 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.oak.jcr.nodetype;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.nodetype.NodeTypeTemplate;
+
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory;
+
+class DefBuilderFactory extends
+        DefinitionBuilderFactory<NodeTypeTemplate, Map<String, String>> {
+
+    private Map<String, String> namespaces = new HashMap<String, String>();
+
+    @Override
+    public NodeTypeTemplateImpl newNodeTypeDefinitionBuilder() {
+        return new NodeTypeTemplateImpl();
+    }
+
+    @Override
+    public Map<String, String> getNamespaceMapping() {
+        return namespaces;
+    }
+
+    @Override
+    public void setNamespaceMapping(Map<String, String> namespaces) {
+        this.namespaces = namespaces;
+    }
+
+    @Override
+    public void setNamespace(String prefix, String uri) {
+        namespaces.put(prefix, uri);
+    }
+
+}

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/ItemDefinitionImpl.java Mon Jul 23 20:13:09 2012
@@ -16,52 +16,96 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
+import javax.jcr.Node;
+import javax.jcr.Property;
 import javax.jcr.nodetype.ItemDefinition;
 import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.OnParentVersionAction;
 
-import org.apache.jackrabbit.oak.namepath.NameMapper;
-
-class ItemDefinitionImpl implements ItemDefinition {
-
-    private final ItemDefinitionDelegate dlg;
+/**
+ * Adapter class for turning an in-content property or node definition
+ * node ("nt:propertyDefinition" or "nt:childNodeDefinition") to an
+ * {@link ItemDefinition} instance.
+ */
+class ItemDefinitionImpl extends TypeNode implements ItemDefinition {
 
     private final NodeType type;
 
-    protected final NameMapper mapper;
-
-    protected ItemDefinitionImpl(NodeType type, NameMapper mapper, ItemDefinitionDelegate delegate) {
-        this.dlg = delegate;
+    protected ItemDefinitionImpl(NodeType type, Node node) {
+        super(node);
         this.type = type;
-        this.mapper = mapper;
     }
 
+    protected void appendItemCND(
+            StringBuilder sb, String requiredType, String defaultValue) {
+        sb.append(getName());
+        if (requiredType != null) {
+            sb.append(" (").append(requiredType).append(")");
+        }
+        if (defaultValue != null) {
+            sb.append(" = ").append(defaultValue);
+        }
+        if (isAutoCreated()) {
+            sb.append(" autocreated");
+        }
+        if (isMandatory()) {
+            sb.append(" mandatory");
+        }
+        if (isProtected()) {
+            sb.append(" protected");
+        }
+        int opv = getOnParentVersion();
+        if (opv != OnParentVersionAction.COPY) {
+            sb.append(" ").append(OnParentVersionAction.nameFromValue(opv));
+        }
+    }
+
+    //----------------------------------------------------< ItemDefinition >--
+
     @Override
     public NodeType getDeclaringNodeType() {
         return type;
     }
 
+    /** CND: <pre>- jcr:name (NAME) protected</pre> */
     @Override
     public String getName() {
-        return mapper.getJcrName(dlg.getName());
+        return getString(Property.JCR_NAME, "*");
     }
 
+    /** CND: <pre>- jcr:autoCreated (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isAutoCreated() {
-        return dlg.isAutoCreated();
+        return getBoolean(Property.JCR_AUTOCREATED);
     }
 
+    /** CND: <pre>- jcr:mandatory (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isMandatory() {
-        return dlg.isMandatory();
+        return getBoolean(Property.JCR_MANDATORY);
     }
 
+    /**
+     * CND:
+     * <pre>
+     * - jcr:onParentVersion (STRING) protected mandatory
+     *   &lt; 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE', 'IGNORE', 'ABORT'
+     * </pre>
+     */
     @Override
     public int getOnParentVersion() {
-        return dlg.getOnParentVersion();
+        try {
+            return OnParentVersionAction.valueFromName(
+                    getString(Property.JCR_ON_PARENT_VERSION));
+        } catch (IllegalArgumentException e) {
+            throw illegalState(e);
+        }
     }
 
+    /** CND: <pre>- jcr:protected (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isProtected() {
-        return dlg.isProtected();
+        return getBoolean(Property.JCR_PROTECTED);
     }
-}
+
+}
\ No newline at end of file

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=1364781&r1=1364780&r2=1364781&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 Mon Jul 23 20:13:09 2012
@@ -16,68 +16,82 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import javax.jcr.RepositoryException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.CheckForNull;
+import javax.jcr.Node;
+import javax.jcr.Property;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
 
-import org.apache.jackrabbit.oak.namepath.NameMapper;
+import com.google.common.base.Joiner;
 
+/**
+ * Adapter class for turning an in-content property definition
+ * node ("nt:childNodeDefinition") to a {@link NodeDefinition} instance.
+ */
 class NodeDefinitionImpl extends ItemDefinitionImpl implements NodeDefinition {
 
     private final NodeTypeManager manager;
 
-    private final NodeDefinitionDelegate dlg;
-
-    protected NodeDefinitionImpl(NodeTypeManager manager, NodeType type, NameMapper mapper, NodeDefinitionDelegate delegate) {
-        super(type, mapper, delegate);
+    protected NodeDefinitionImpl(
+            NodeTypeManager manager, NodeType type, Node node) {
+        super(type, node);
         this.manager = manager;
-        this.dlg = delegate;
+    }
+
+    /** CND: <pre>- jcr:requiredPrimaryTypes (NAME) = 'nt:base' protected mandatory multiple</pre> */
+    @Override
+    public String[] getRequiredPrimaryTypeNames() {
+        return getStrings(Property.JCR_REQUIRED_PRIMARY_TYPES);
     }
 
     @Override
     public NodeType[] getRequiredPrimaryTypes() {
         String[] names = getRequiredPrimaryTypeNames();
-        NodeType[] types = new NodeType[names.length];
+        List<NodeType> types = new ArrayList<NodeType>(names.length);
         for (int i = 0; i < names.length; i++) {
-            try {
-                types[i] = manager.getNodeType(names[i]);
-            } catch (RepositoryException e) {
-                throw new IllegalStateException("Inconsistent node definition: " + this, e);
-            }
+            types.add(getType(manager, names[i]));
         }
-        return types;
+        return types.toArray(new NodeType[types.size()]);
     }
 
-    @Override
-    public String[] getRequiredPrimaryTypeNames() {
-        String[] requiredPrimaryTypeNames = dlg.getRequiredPrimaryTypeNames();
-        String[] result = new String[requiredPrimaryTypeNames.length];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = mapper.getJcrName(requiredPrimaryTypeNames[i]);
-        }
-        return result;
+    /** CND: <pre>- jcr:defaultPrimaryType (NAME) protected</pre> */
+    @Override @CheckForNull
+    public String getDefaultPrimaryTypeName() {
+        return getString(Property.JCR_DEFAULT_PRIMARY_TYPE, null);
     }
 
     @Override
     public NodeType getDefaultPrimaryType() {
-        try {
-            String defaultName = getDefaultPrimaryTypeName();
-            return defaultName == null ? null : manager.getNodeType(getDefaultPrimaryTypeName());
-        } catch (RepositoryException e) {
-            throw new IllegalStateException("Inconsistent node definition: " + this, e);
+        String name = getDefaultPrimaryTypeName();
+        if (name != null) {
+            return getType(manager, name);
         }
+        return null;
     }
 
+    /** CND: <pre>- jcr:sameNameSiblings (BOOLEAN) protected mandatory</pre> */
     @Override
-    public String getDefaultPrimaryTypeName() {
-        String defaultPrimaryTypeName = dlg.getDefaultPrimaryTypeName();
-        return defaultPrimaryTypeName == null ? null : mapper.getJcrName(defaultPrimaryTypeName);
+    public boolean allowsSameNameSiblings() {
+        return getBoolean(Property.JCR_SAME_NAME_SIBLINGS);
     }
 
-    @Override
-    public boolean allowsSameNameSiblings() {
-        return dlg.allowsSameNameSiblings();
+    //------------------------------------------------------------< Object >--
+
+    public String toString() {
+        String rt = null;
+        String[] rts = getRequiredPrimaryTypeNames();
+        if (rts != null) {
+            rt = Joiner.on(", ").join(rts);
+        }
+
+        StringBuilder sb = new StringBuilder("+ ");
+        appendItemCND(sb, rt, getDefaultPrimaryTypeName());
+        sb.append(" ..."); // TODO: rest of the info
+        return sb.toString();
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionTemplateImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionTemplateImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionTemplateImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeDefinitionTemplateImpl.java Mon Jul 23 20:13:09 2012
@@ -16,56 +16,178 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.nodetype.NodeDefinitionTemplate;
 import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeTemplate;
+
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractNodeDefinitionBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-class NodeDefinitionTemplateImpl extends ItemDefinitionTemplateImpl
+class NodeDefinitionTemplateImpl
+        extends AbstractNodeDefinitionBuilder<NodeTypeTemplate>
         implements NodeDefinitionTemplate {
 
-    private String defaultPrimaryTypeName = null;
+    private static final Logger log =
+            LoggerFactory.getLogger(NodeDefinitionTemplateImpl.class);
 
-    private String[] requiredPrimaryTypeNames = null;
+    private String defaultPrimaryTypeName;
 
-    private boolean allowSameNameSiblings = false;
+    private String[] requiredPrimaryTypeNames;
+
+    protected NodeType getNodeType(String name) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException();
+    }
 
     @Override
-    public String getDefaultPrimaryTypeName() {
-        return defaultPrimaryTypeName;
+    public void build() {
+        // do nothing by default
     }
 
     @Override
-    public void setDefaultPrimaryTypeName(String name) {
-        this.defaultPrimaryTypeName  = name;
+    public NodeType getDeclaringNodeType() {
+        return null;
+    }
+
+    @Override
+    public void setDeclaringNodeType(String name) {
+        // ignore
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean isAutoCreated() {
+        return autocreate;
+    }
+
+    @Override
+    public void setAutoCreated(boolean autocreate) {
+        this.autocreate = autocreate;
+    }
+
+    @Override
+    public boolean isProtected() {
+        return isProtected;
+    }
+
+    @Override
+    public void setProtected(boolean isProtected) {
+        this.isProtected = isProtected;
+    }
+
+    @Override
+    public boolean isMandatory() {
+        return isMandatory;
+    }
+
+    @Override
+    public void setMandatory(boolean isMandatory) {
+        this.isMandatory = isMandatory;
+    }
+
+    @Override
+    public int getOnParentVersion() {
+        return onParent;
+    }
+
+    @Override
+    public void setOnParentVersion(int onParent) {
+        this.onParent = onParent;
+    }
+
+    @Override
+    public boolean allowsSameNameSiblings() {
+        return allowSns;
+    }
+
+    @Override
+    public void setSameNameSiblings(boolean allowSns) {
+        this.allowSns = allowSns;
+    }
+
+    @Override
+    public void setAllowsSameNameSiblings(boolean allowSns) {
+        setSameNameSiblings(allowSns);
     }
 
     @Override
     public NodeType getDefaultPrimaryType() {
+        if (defaultPrimaryTypeName != null) {
+            try {
+                return getNodeType(defaultPrimaryTypeName);
+            } catch (RepositoryException e) {
+                log.warn("Unable to access default primary type "
+                        + defaultPrimaryTypeName + " of " + name, e);
+            }
+        }
         return null;
     }
 
     @Override
-    public String[] getRequiredPrimaryTypeNames() {
-        return requiredPrimaryTypeNames;
+    public String getDefaultPrimaryTypeName() {
+        return defaultPrimaryTypeName;
     }
 
     @Override
-    public void setRequiredPrimaryTypeNames(String[] names) {
-        this.requiredPrimaryTypeNames = names;
+    public void setDefaultPrimaryTypeName(String name) {
+        this.defaultPrimaryTypeName  = name;
+    }
+
+    @Override
+    public void setDefaultPrimaryType(String name) {
+        setDefaultPrimaryTypeName(name);
     }
 
     @Override
     public NodeType[] getRequiredPrimaryTypes() {
-        return null;
+        if (requiredPrimaryTypeNames == null) {
+            return new NodeType[0];
+        } else {
+            List<NodeType> types =
+                    new ArrayList<NodeType>(requiredPrimaryTypeNames.length);
+            for (String requiredPrimaryTypeName : requiredPrimaryTypeNames) {
+                try {
+                    types.add(getNodeType(requiredPrimaryTypeName));
+                }
+                catch (RepositoryException e) {
+                    log.warn("Unable to required primary primary type "
+                            + requiredPrimaryTypeName + " of " + name, e);
+                }
+            }
+            return types.toArray(new NodeType[types.size()]);
+        }
     }
 
     @Override
-    public boolean allowsSameNameSiblings() {
-        return allowSameNameSiblings;
+    public String[] getRequiredPrimaryTypeNames() {
+        return requiredPrimaryTypeNames;
+    }
+
+    @Override
+    public void setRequiredPrimaryTypeNames(String[] names) {
+        this.requiredPrimaryTypeNames = names;
     }
 
     @Override
-    public void setSameNameSiblings(boolean allowSameNameSiblings) {
-        this.allowSameNameSiblings = allowSameNameSiblings;
+    public void addRequiredPrimaryType(String name) {
+        if (requiredPrimaryTypeNames == null) {
+            requiredPrimaryTypeNames = new String[] { name };
+        } else {
+            String[] names = new String[requiredPrimaryTypeNames.length + 1];
+            System.arraycopy(requiredPrimaryTypeNames, 0, names, 0, requiredPrimaryTypeNames.length);
+            names[requiredPrimaryTypeNames.length] = name;
+            requiredPrimaryTypeNames = names;
+        }
+
     }
 
 }
\ No newline at end of file

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=1364781&r1=1364780&r2=1364781&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 Mon Jul 23 20:13:09 2012
@@ -16,17 +16,19 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
+import static java.util.Arrays.asList;
+
 import java.util.List;
+import java.util.Map;
 import java.util.Queue;
-import java.util.Set;
 
+import javax.annotation.CheckForNull;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeIterator;
@@ -34,252 +36,278 @@ import javax.jcr.nodetype.NodeTypeManage
 import javax.jcr.nodetype.PropertyDefinition;
 
 import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
-import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl;
-import org.apache.jackrabbit.oak.namepath.NameMapper;
 
-class NodeTypeImpl implements NodeType {
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Queues;
+
+/**
+ * Adapter class for turning an in-content node type definition
+ * node ("nt:nodeTYpe") to a {@link NodeType} instance.
+ */
+class NodeTypeImpl extends TypeNode implements NodeType {
 
     private final NodeTypeManager manager;
-    private final NameMapper mapper;
-    private final ValueFactoryImpl valueFactory;
 
-    private final NodeTypeDelegate dlg;
-
-    public NodeTypeImpl(NodeTypeManager manager, ValueFactoryImpl valueFactory, NameMapper mapper, NodeTypeDelegate delegate) {
+    public NodeTypeImpl(NodeTypeManager manager, Node node) {
+        super(node);
         this.manager = manager;
-        this.valueFactory = valueFactory;
-        this.mapper = mapper;
-        this.dlg = delegate;
     }
 
+    /** CND: <pre>- jcr:nodeTypeName (NAME) protected mandatory</pre> */
     @Override
     public String getName() {
-        return mapper.getJcrName(dlg.getName());
+        return getString(Property.JCR_NODE_TYPE_NAME);
     }
 
+    /** CND: <pre>- jcr:supertypes (NAME) protected multiple</pre> */
     @Override
     public String[] getDeclaredSupertypeNames() {
-        List<String> names = new ArrayList<String>();
-        boolean addNtBase = !isMixin();
-        for (String name : dlg.getDeclaredSuperTypeNames()) {
-
-            String jcrName = mapper.getJcrName(name);
-
-            // TODO: figure out a more performant way
-            // check of at least one declared super type being a non-mixin type
-            if (addNtBase) {
-                try {
-                    NodeType nt = manager.getNodeType(jcrName);
-                    if (!nt.isMixin()) {
-                        addNtBase = false;
-                    }
-                } catch (RepositoryException ex) {
-                    // ignored
-                }
-            }
-            names.add(jcrName);
-        }
-
-        if (addNtBase) {
-            names.add(mapper.getJcrName("nt:base"));
-        }
-
-        return names.toArray(new String[names.size()]);
+        return getStrings(Property.JCR_SUPERTYPES, new String[0]);
     }
 
+    /** CND: <pre>- jcr:isAbstract (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isAbstract() {
-        return dlg.isAbstract();
+        return getBoolean(Property.JCR_IS_ABSTRACT);
     }
 
+    /** CND: <pre>- jcr:isMixin (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isMixin() {
-        return dlg.isMixin();
+        return getBoolean(Property.JCR_IS_MIXIN);
     }
 
+    /** CND: <pre>- jcr:hasOrderableChildNodes (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean hasOrderableChildNodes() {
-        return dlg.hasOrderableChildNodes();
+        return getBoolean(Property.JCR_HAS_ORDERABLE_CHILD_NODES);
     }
 
+    /** CND: <pre>- jcr:isQueryable (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isQueryable() {
-        return true;
+        return getBoolean("jcr:isQueryable"); // TODO: constant
     }
 
-    @Override
+    /** CND: <pre>- jcr:primaryItemName (NAME) protected</pre> */
+    @Override @CheckForNull
     public String getPrimaryItemName() {
-        String primaryItemName = dlg.getPrimaryItemName();
-        if (primaryItemName != null) {
-            return mapper.getJcrName(primaryItemName);
-        } else {
-            return null;
-        }
+        return getString(Property.JCR_PRIMARY_ITEM_NAME, null);
     }
 
+    /** CND: <pre>+ jcr:propertyDefinition (nt:propertyDefinition) = nt:propertyDefinition protected sns</pre> */
     @Override
     public PropertyDefinition[] getDeclaredPropertyDefinitions() {
-        List<PropertyDefinitionDelegate> definitionDelegates = dlg.getPropertyDefinitionDelegates();
-        PropertyDefinition[] result = new PropertyDefinition[definitionDelegates.size()];
-
-        for (int i = 0; i < result.length; i++) {
-            result[i] = new PropertyDefinitionImpl(this, mapper, valueFactory, definitionDelegates.get(i));
+        List<PropertyDefinition> list = Lists.newArrayList();
+        NodeIterator iterator = getNodes(Node.JCR_PROPERTY_DEFINITION);
+        while (iterator.hasNext()) {
+            list.add(new PropertyDefinitionImpl(this, iterator.nextNode()));
         }
-
-        return result;
+        return list.toArray(new PropertyDefinition[list.size()]);
     }
 
     @Override
     public NodeDefinition[] getDeclaredChildNodeDefinitions() {
-        List<NodeDefinitionDelegate> definitionDelegates = dlg.getChildNodeDefinitionDelegates();
-        NodeDefinition[] result = new NodeDefinition[definitionDelegates.size()];
-
-        for (int i = 0; i < result.length; i++) {
-            result[i] = new NodeDefinitionImpl(manager, this, mapper, definitionDelegates.get(i));
+        List<NodeDefinition> list = Lists.newArrayList();
+        NodeIterator iterator = getNodes(Node.JCR_CHILD_NODE_DEFINITION);
+        while (iterator.hasNext()) {
+            list.add(new NodeDefinitionImpl(
+                    manager, this, iterator.nextNode()));
         }
-
-        return result;
+        return list.toArray(new NodeDefinition[list.size()]);
     }
 
     @Override
     public NodeType[] getSupertypes() {
-        try {
-            Collection<NodeType> types = new ArrayList<NodeType>();
-            Set<String> added = new HashSet<String>();
-            Queue<String> queue = new LinkedList<String>(Arrays.asList(getDeclaredSupertypeNames()));
-            while (!queue.isEmpty()) {
-                String name = queue.remove();
-                if (added.add(name)) {
-                    NodeType type = manager.getNodeType(name);
-                    types.add(type);
-                    queue.addAll(Arrays.asList(type.getDeclaredSupertypeNames()));
-                }
+        Map<String, NodeType> types = Maps.newHashMap();
+        Queue<String> queue = Queues.newArrayDeque();
+        queue.addAll(asList(getDeclaredSupertypeNames()));
+        while (!queue.isEmpty()) {
+            String name = queue.remove();
+            if (!types.containsKey(name)) {
+                NodeType type = getType(manager, name);
+                types.put(name, type);
+                queue.addAll(asList(type.getDeclaredSupertypeNames()));
             }
-            return types.toArray(new NodeType[types.size()]);
-        } catch (RepositoryException e) {
-            throw new IllegalStateException("Inconsistent node type: " + this, e);
         }
+        return types.values().toArray(new NodeType[types.size()]);
     }
 
     @Override
     public NodeType[] getDeclaredSupertypes() {
-        try {
-            String[] names = getDeclaredSupertypeNames();
-            NodeType[] types = new NodeType[names.length];
-            for (int i = 0; i < types.length; i++) {
-                types[i] = manager.getNodeType(names[i]);
-            }
-            return types;
-        } catch (RepositoryException e) {
-            throw new IllegalStateException("Inconsistent node type: " + this, e);
+        List<NodeType> types = Lists.newArrayList();
+        for (String name : getDeclaredSupertypeNames()) {
+            types.add(getType(manager, name));
         }
+        return types.toArray(new NodeType[types.size()]);
     }
 
     @Override
     public NodeTypeIterator getSubtypes() {
+        List<NodeType> types = Lists.newArrayList();
         try {
-            Collection<NodeType> types = new ArrayList<NodeType>();
+            String name = getName();
             NodeTypeIterator iterator = manager.getAllNodeTypes();
             while (iterator.hasNext()) {
                 NodeType type = iterator.nextNodeType();
-                if (type.isNodeType(getName()) && !isNodeType(type.getName())) {
+                if (!name.equals(type.getName()) && type.isNodeType(name)) {
                     types.add(type);
                 }
             }
-            return new NodeTypeIteratorAdapter(types);
         } catch (RepositoryException e) {
-            throw new IllegalStateException("Inconsistent node type: " + this, e);
+            throw illegalState(e);
         }
+        return new NodeTypeIteratorAdapter(types);
     }
 
     @Override
     public NodeTypeIterator getDeclaredSubtypes() {
+        List<NodeType> types = Lists.newArrayList();
         try {
-            Collection<NodeType> types = new ArrayList<NodeType>();
+            String name = getName();
             NodeTypeIterator iterator = manager.getAllNodeTypes();
             while (iterator.hasNext()) {
                 NodeType type = iterator.nextNodeType();
-                String name = type.getName();
-                if (type.isNodeType(getName()) && !isNodeType(name)) {
-                    List<String> declaredSuperTypeNames = Arrays.asList(type.getDeclaredSupertypeNames());
-                    if (declaredSuperTypeNames.contains(name)) {
-                        types.add(type);
-                    }
+                if (asList(type.getDeclaredSupertypeNames()).contains(name)) {
+                    types.add(type);
                 }
             }
-            return new NodeTypeIteratorAdapter(types);
         } catch (RepositoryException e) {
-            throw new IllegalStateException("Inconsistent node type: " + this, e);
+            throw illegalState(e);
         }
+        return new NodeTypeIteratorAdapter(types);
     }
 
     @Override
     public boolean isNodeType(String nodeTypeName) {
-        String oakName = mapper.getOakName(nodeTypeName);
-        if (dlg.getName().equals(oakName)) {
+        if (nodeTypeName.equals(getName())) {
             return true;
         }
-        for (NodeType type : getSupertypes()) {
-            if (((NodeTypeImpl) type).dlg.getName().equals(oakName)) {
+
+        for (NodeType type : getDeclaredSupertypes()) {
+            if (type.isNodeType(nodeTypeName)) {
                 return true;
             }
         }
+
         return false;
     }
 
     @Override
     public PropertyDefinition[] getPropertyDefinitions() {
-        Collection<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>();
+        List<PropertyDefinition> definitions = Lists.newArrayList();
         for (NodeType type : getSupertypes()) {
-            definitions.addAll(Arrays.asList(type.getDeclaredPropertyDefinitions()));
+            definitions.addAll(asList(type.getDeclaredPropertyDefinitions()));
         }
-        definitions.addAll(Arrays.asList(getDeclaredPropertyDefinitions()));
+        definitions.addAll(asList(getDeclaredPropertyDefinitions()));
         return definitions.toArray(new PropertyDefinition[definitions.size()]);
     }
 
     @Override
     public NodeDefinition[] getChildNodeDefinitions() {
-        Collection<NodeDefinition> definitions = new ArrayList<NodeDefinition>();
+        List<NodeDefinition> definitions = Lists.newArrayList();
         for (NodeType type : getSupertypes()) {
-            definitions.addAll(Arrays.asList(type.getDeclaredChildNodeDefinitions()));
+            definitions.addAll(asList(type.getDeclaredChildNodeDefinitions()));
         }
-        definitions.addAll(Arrays.asList(getDeclaredChildNodeDefinitions()));
+        definitions.addAll(asList(getDeclaredChildNodeDefinitions()));
         return definitions.toArray(new NodeDefinition[definitions.size()]);
     }
 
     @Override
     public boolean canSetProperty(String propertyName, Value value) {
-        return true; // TODO
+        for (PropertyDefinition definition : getPropertyDefinitions()) {
+            String name = definition.getName();
+            if ((propertyName.equals(name) && !definition.isProtected())
+                    || "*".equals(name)) {
+                if (!definition.isMultiple()) {
+                    // TODO: Check value type, constraints, etc.
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     @Override
     public boolean canSetProperty(String propertyName, Value[] values) {
-        return true; // TODO
+        for (PropertyDefinition definition : getPropertyDefinitions()) {
+            String name = definition.getName();
+            if ((propertyName.equals(name) && !definition.isProtected())
+                    || "*".equals(name)) {
+                if (definition.isMultiple()) {
+                    // TODO: Check value type, constraints, etc.
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     @Override
     public boolean canAddChildNode(String childNodeName) {
-        return true; // TODO
+        for (NodeDefinition definition : getChildNodeDefinitions()) {
+            String name = definition.getName();
+            if ((childNodeName.equals(name) && !definition.isProtected())
+                    || "*".equals(name)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
     public boolean canAddChildNode(String childNodeName, String nodeTypeName) {
-        return true; // TODO
+        try {
+            NodeType type = manager.getNodeType(nodeTypeName);
+            for (NodeDefinition definition : getChildNodeDefinitions()) {
+                String name = definition.getName();
+                if ((childNodeName.equals(name) && !definition.isProtected())
+                        || "*".equals(name)) {
+                    for (String required : definition.getRequiredPrimaryTypeNames()) {
+                        if (type.isNodeType(required)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        } catch (NoSuchNodeTypeException e) {
+            return false;
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
     }
 
     @Override
     public boolean canRemoveItem(String itemName) {
-        return true; // TODO
+        return canRemoveNode(itemName) || canRemoveProperty(itemName);
     }
 
     @Override
     public boolean canRemoveNode(String nodeName) {
-        return true; // TODO
+        for (PropertyDefinition definition : getPropertyDefinitions()) {
+            String name = definition.getName();
+            if (nodeName.equals(name)) {
+                if (definition.isMandatory() || definition.isProtected()) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
     @Override
     public boolean canRemoveProperty(String propertyName) {
-        return true; // TODO
+        for (PropertyDefinition definition : getPropertyDefinitions()) {
+            String name = definition.getName();
+            if (propertyName.equals(name)) {
+                if (definition.isMandatory() || definition.isProtected()) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
 }

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=1364781&r1=1364780&r2=1364781&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 Mon Jul 23 20:13:09 2012
@@ -16,116 +16,131 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.ItemDefinition;
 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 javax.jcr.version.OnParentVersionAction;
 
 import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.core.DefaultConflictHandler;
+import org.apache.jackrabbit.oak.jcr.NodeDelegate;
+import org.apache.jackrabbit.oak.jcr.NodeImpl;
 import org.apache.jackrabbit.oak.jcr.SessionDelegate;
-import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl;
-import org.apache.jackrabbit.oak.namepath.NameMapper;
+
+import com.google.common.collect.Lists;
 
 public class NodeTypeManagerImpl implements NodeTypeManager {
 
-    private final ContentSession cs;
-    private final ValueFactoryImpl vf;
-    private final NameMapper mapper;
-    private final NodeTypeManagerDelegate ntmd;
-    private final Map<String, NodeType> typemap = new HashMap<String, NodeType>();
-
-    public NodeTypeManagerImpl(SessionDelegate sd, NodeTypeManagerDelegate ntmd) throws RepositoryException {
-        this.cs = sd.getContentSession();
-        this.vf = sd.getValueFactory();
-        this.mapper = sd.getNamePathMapper();
-        this.ntmd = ntmd;
-    }
-
-    private void init() {
-        if (typemap.isEmpty()) {
-            List<NodeTypeDelegate> alltypes = ntmd.getAllNodeTypeDelegates();
-
-            for (NodeTypeDelegate t : alltypes) {
-                NodeType nt = new NodeTypeImpl(this, vf, mapper, t);
-                typemap.put(t.getName(), nt);
-            }
-        }
+    private static final String PATH = "/jcr:system/jcr:nodeTypes";
+
+    private final SessionDelegate sd;
+
+    public NodeTypeManagerImpl(SessionDelegate sd) {
+        this.sd = sd;
+    }
+
+    /**
+     * Called by the {@link NodeTypeManager} implementation methods to
+     * refresh the state of the session associated with this instance.
+     * That way the session is kept in sync with the latest global state
+     * seen by the node type manager.
+     *
+     * @throws RepositoryException if the session could not be refreshed
+     */
+    protected void refresh() throws RepositoryException {
     }
 
+    private String getTypePath(String name) {
+        // TODO: validate name
+        return PATH + '/' + name;
+    }
+
+    //---------------------------------------------------< NodeTypeManager >--
+
     @Override
     public boolean hasNodeType(String name) throws RepositoryException {
-        init();
-        String oakName = mapper.getOakName(name); // can be null, which is fine
-        return typemap.containsKey(oakName);
+        return sd.getSession().nodeExists(getTypePath(name));
     }
 
     @Override
     public NodeType getNodeType(String name) throws RepositoryException {
-        init();
-        String oakName = mapper.getOakName(name); // can be null, which is fine
-        NodeType type = typemap.get(oakName);
-        if (type == null) {
-            throw new NoSuchNodeTypeException("Unknown node type: " + name);
+        try {
+            return new NodeTypeImpl(
+                    this, sd.getSession().getNode(getTypePath(name)));
+        } catch (PathNotFoundException e) {
+            throw new NoSuchNodeTypeException("Type not found: " + name, e);
         }
-        return type;
     }
 
     @Override
     public NodeTypeIterator getAllNodeTypes() throws RepositoryException {
-        init();
-        return new NodeTypeIteratorAdapter(typemap.values());
+        List<NodeType> types = Lists.newArrayList();
+        Node node = sd.getSession().getNode(PATH);
+        NodeIterator iterator = node.getNodes();
+        while (iterator.hasNext()) {
+            types.add(new NodeTypeImpl(this, iterator.nextNode()));
+        }
+        return new NodeTypeIteratorAdapter(types);
     }
 
     @Override
     public NodeTypeIterator getPrimaryNodeTypes() throws RepositoryException {
-        init();
-        Collection<NodeType> primary = new ArrayList<NodeType>();
-        for (NodeType type : typemap.values()) {
+        List<NodeType> types = Lists.newArrayList();
+        Node node = sd.getSession().getNode(PATH);
+        NodeIterator iterator = node.getNodes();
+        while (iterator.hasNext()) {
+            NodeType type = new NodeTypeImpl(this, iterator.nextNode());
             if (!type.isMixin()) {
-                primary.add(type);
+                types.add(type);
             }
         }
-        return new NodeTypeIteratorAdapter(primary);
+        return new NodeTypeIteratorAdapter(types);
     }
 
     @Override
     public NodeTypeIterator getMixinNodeTypes() throws RepositoryException {
-        init();
-        Collection<NodeType> mixin = new ArrayList<NodeType>();
-        for (NodeType type : typemap.values()) {
+        List<NodeType> types = Lists.newArrayList();
+        Node node = sd.getSession().getNode(PATH);
+        NodeIterator iterator = node.getNodes();
+        while (iterator.hasNext()) {
+            NodeType type = new NodeTypeImpl(this, iterator.nextNode());
             if (type.isMixin()) {
-                mixin.add(type);
+                types.add(type);
             }
         }
-        return new NodeTypeIteratorAdapter(mixin);
+        return new NodeTypeIteratorAdapter(types);
     }
 
     @Override
-    public NodeTypeTemplate createNodeTypeTemplate() throws RepositoryException {
-        return new NodeTypeTemplateImpl();
+    public NodeTypeTemplate createNodeTypeTemplate()
+            throws RepositoryException {
+        return new NodeTypeTemplateImpl(this, sd.getValueFactory());
     }
 
     @Override
-    public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd) throws RepositoryException {
-        return new NodeTypeTemplateImpl(ntd);
+    public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd)
+            throws RepositoryException {
+        return new NodeTypeTemplateImpl(this, sd.getValueFactory(), ntd);
     }
 
     @Override
@@ -139,62 +154,177 @@ public class NodeTypeManagerImpl impleme
     }
 
     @Override
-    public NodeType registerNodeType(NodeTypeDefinition ntd, boolean allowUpdate) throws RepositoryException {
-        // TODO proper node type registration... (OAK-66)
-        try {
-            Root root = cs.getCurrentRoot();
-            NodeType type = internalRegister(ntd, root.getTree("/"));
-            root.commit(DefaultConflictHandler.OURS);
-            return type;
-        } catch (CommitFailedException e) {
-            throw new RepositoryException(e);
+    public NodeType registerNodeType(
+            NodeTypeDefinition ntd, boolean allowUpdate)
+            throws RepositoryException {
+        NodeTypeDefinition[] ntds = new NodeTypeDefinition[] { ntd };
+        return registerNodeTypes(ntds, allowUpdate).nextNodeType();
+    }
+
+    @Override
+    public NodeTypeIterator registerNodeTypes(
+            NodeTypeDefinition[] ntds, boolean allowUpdate)
+            throws RepositoryException {
+        Root root = sd.getContentSession().getCurrentRoot();
+        Node types = getNodeTypes(root);
+
+        for (NodeTypeDefinition ntd : ntds) {
+            internalRegister(types, ntd, allowUpdate);
+        }
+
+        commitChanges(root);
+
+        List<NodeType> list = Lists.newArrayList();
+        for (NodeTypeDefinition ntd : ntds) {
+            list.add(getNodeType(ntd.getName()));
         }
+        return new NodeTypeIteratorAdapter(list);
     }
 
     @Override
-    public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate) throws RepositoryException {
-        // TODO handle inter-type dependencies (OAK-66)
+    public void unregisterNodeType(String name) throws RepositoryException {
+        Root root = sd.getContentSession().getCurrentRoot();
+        Node types = getNodeTypes(root);
+
         try {
-            Root root = cs.getCurrentRoot();
-            NodeType[] types = new NodeType[ntds.length];
-            for (int i = 0; i < ntds.length; i++) {
-                types[i] = internalRegister(ntds[i], root.getTree("/"));
+            types.getNode(name).remove();
+        } catch (PathNotFoundException e) {
+            throw new NoSuchNodeTypeException(
+                    "Node type " + name + " does not exist", e);
+        }
+
+        commitChanges(root);
+    }
+
+    @Override
+    public void unregisterNodeTypes(String[] names) throws RepositoryException {
+        Root root = sd.getContentSession().getCurrentRoot();
+        Node types = getNodeTypes(root);
+
+        for (String name : names) {
+            try {
+                types.getNode(name).remove();
+            } catch (PathNotFoundException e) {
+                throw new NoSuchNodeTypeException(
+                        "Node type " + name + " does not exist", e);
             }
-            root.commit(DefaultConflictHandler.OURS);
-            return new NodeTypeIteratorAdapter(Arrays.asList(types));
-        } catch (CommitFailedException e) {
-            throw new RepositoryException(e);
         }
+
+        commitChanges(root);
     }
 
-    private NodeType internalRegister(NodeTypeDefinition ntd, Tree root) {
-        NodeTypeDelegate delegate = new NodeTypeDelegate(
-                ntd.getName(),
-                ntd.getDeclaredSupertypeNames(), ntd.getPrimaryItemName(),
-                ntd.isMixin(), ntd.isAbstract(), ntd.hasOrderableChildNodes());
-        NodeType type = new NodeTypeImpl(this, vf, mapper, delegate);
-        typemap.put(ntd.getName(), type);
+    //-----------------------------------------------------------< private >--
+
+    private void internalRegister(
+            Node types, NodeTypeDefinition ntd, boolean allowUpdate)
+            throws RepositoryException {
+        String name = ntd.getName();
+        if (types.hasNode(name)) {
+            types.getNode(name).remove();
+        }
+        Node node = types.addNode(ntd.getName());
 
-        Tree system = root.getChild("jcr:system");
-        if (system == null) {
-            system = root.addChild("jcr:system");
+        node.setProperty(Property.JCR_NODE_TYPE_NAME, name, PropertyType.NAME);
+        node.setProperty(Property.JCR_SUPERTYPES, ntd.getDeclaredSupertypeNames(), PropertyType.NAME);
+        node.setProperty(Property.JCR_IS_ABSTRACT, ntd.isAbstract());
+        node.setProperty("jcr:isQueryable", ntd.isQueryable()); // TODO: constant
+        node.setProperty(Property.JCR_IS_MIXIN, ntd.isMixin());
+        node.setProperty(Property.JCR_HAS_ORDERABLE_CHILD_NODES, ntd.hasOrderableChildNodes());
+        String primaryItemName = ntd.getPrimaryItemName();
+        if (primaryItemName != null) {
+            node.setProperty(Property.JCR_PRIMARY_ITEM_NAME, primaryItemName, PropertyType.NAME);
         }
-        Tree nodetypes = system.getChild("jcr:nodeTypes");
-        if (nodetypes == null) {
-            nodetypes = system.addChild("jcr:nodeTypes");
+
+        int pdn = 0;
+        for (PropertyDefinition pd : ntd.getDeclaredPropertyDefinitions()) {
+            internalRegisterPropertyDefinition(
+                    node.addNode("jcr:propertyDefinition[" + (++pdn) + "]"), pd);
         }
-        nodetypes.addChild(ntd.getName());
 
-        return type;
+        int ndn = 0;
+        for (NodeDefinition nd : ntd.getDeclaredChildNodeDefinitions()) {
+            internalRegisterNodeDefinition(
+                    node.addNode("jcr:childNodeDefinition[" + (++ndn) +"]"), nd);
+        }
     }
 
-    @Override
-    public void unregisterNodeType(String name) throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException();
+    private void internalRegisterItemDefinition(Node node, ItemDefinition def)
+            throws RepositoryException {
+        String name = def.getName();
+        if (!"*".equals(name)) {
+            node.setProperty(Property.JCR_NAME, name, PropertyType.NAME);
+        }
+        node.setProperty(Property.JCR_AUTOCREATED, def.isAutoCreated());
+        node.setProperty(Property.JCR_MANDATORY, def.isMandatory());
+        node.setProperty(Property.JCR_PROTECTED, def.isProtected());
+        node.setProperty(
+                Property.JCR_ON_PARENT_VERSION,
+                OnParentVersionAction.nameFromValue(def.getOnParentVersion()));
+    }
+
+    private void internalRegisterPropertyDefinition(
+            Node node, PropertyDefinition def) throws RepositoryException {
+        internalRegisterItemDefinition(node, def);
+
+        node.setProperty(
+                Property.JCR_REQUIRED_TYPE,
+                PropertyType.nameFromValue(def.getRequiredType()));
+        node.setProperty(
+                Property.JCR_MULTIPLE, def.isMultiple());
+        node.setProperty(
+                "jcr:isFullTextSearchable", def.isFullTextSearchable());
+        node.setProperty(
+                "jcr:isQueryOrderable", def.isQueryOrderable());
+        node.setProperty(
+                "jcr:availableQueryOperators",
+                def.getAvailableQueryOperators());
+
+        String[] constraints = def.getValueConstraints();
+        if (constraints != null) {
+            node.setProperty(Property.JCR_VALUE_CONSTRAINTS, constraints);
+        }
+
+        Value[] values = def.getDefaultValues();
+        if (values != null) {
+            node.setProperty(Property.JCR_DEFAULT_VALUES, values);
+        }
     }
 
-    @Override
-    public void unregisterNodeTypes(String[] names) throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException();
+    private void internalRegisterNodeDefinition(
+            Node node, NodeDefinition def) throws RepositoryException {
+        internalRegisterItemDefinition(node, def);
+
+        node.setProperty(
+                Property.JCR_SAME_NAME_SIBLINGS, def.allowsSameNameSiblings());
+        node.setProperty(
+                Property.JCR_REQUIRED_PRIMARY_TYPES,
+                def.getRequiredPrimaryTypeNames(), PropertyType.NAME);
+
+        String defaultPrimaryType = def.getDefaultPrimaryTypeName();
+        if (defaultPrimaryType != null) {
+            node.setProperty(
+                    Property.JCR_DEFAULT_PRIMARY_TYPE,
+                    defaultPrimaryType, PropertyType.NAME);
+        }
+    }
+
+    private Node getNodeTypes(Root root) throws RepositoryException {
+        Tree types = root.getTree(PATH);
+        if (types != null) {
+            return new NodeImpl(new NodeDelegate(sd, types));
+        } else {
+            throw new RepositoryException("Node type registry not found");
+        }
     }
+
+    private void commitChanges(Root root) throws RepositoryException {
+        try {
+            root.commit(DefaultConflictHandler.OURS);
+            refresh();
+        } catch (CommitFailedException e) {
+            throw new RepositoryException(
+                    "Failed to modify the node type registry", e);
+        }
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTemplateImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTemplateImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTemplateImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTemplateImpl.java Mon Jul 23 20:13:09 2012
@@ -19,47 +19,131 @@ package org.apache.jackrabbit.oak.jcr.no
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeDefinitionTemplate;
+import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeDefinition;
+import javax.jcr.nodetype.NodeTypeManager;
 import javax.jcr.nodetype.NodeTypeTemplate;
 import javax.jcr.nodetype.PropertyDefinition;
 import javax.jcr.nodetype.PropertyDefinitionTemplate;
 
-class NodeTypeTemplateImpl implements NodeTypeTemplate {
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractNodeTypeDefinitionBuilder;
+import org.apache.jackrabbit.value.ValueFactoryImpl;
 
-    private String name = null;
+class NodeTypeTemplateImpl
+    extends AbstractNodeTypeDefinitionBuilder<NodeTypeTemplate>
+    implements NodeTypeTemplate {
 
-    private boolean isAbstract = false;
+    private final NodeTypeManager manager;
 
-    private boolean isMixin = false;
+    private final ValueFactory factory;
 
-    private boolean isOrderable = false;
-
-    private boolean isQueryable = true;
-
-    private String primaryItemName = null;
+    private String primaryItemName;
 
     private String[] superTypeNames = new String[0];
 
-    private List<PropertyDefinitionTemplate> propertyDefinitionTemplates =
+    private final List<PropertyDefinitionTemplate> propertyDefinitionTemplates =
             new ArrayList<PropertyDefinitionTemplate>();
 
-    private List<NodeDefinitionTemplate> nodeDefinitionTemplates =
+    private final List<NodeDefinitionTemplate> nodeDefinitionTemplates =
             new ArrayList<NodeDefinitionTemplate>();
 
+    public NodeTypeTemplateImpl(NodeTypeManager manager, ValueFactory factory) {
+        this.manager = manager;
+        this.factory = factory;
+    }
+
     public NodeTypeTemplateImpl() {
+        this(null, ValueFactoryImpl.getInstance());
     }
 
-    public NodeTypeTemplateImpl(NodeTypeDefinition ntd) {
-        this.name = ntd.getName();
-        this.isAbstract = ntd.isAbstract();
-        this.isMixin = ntd.isMixin();
-        this.isOrderable = ntd.hasOrderableChildNodes();
-        this.isQueryable = ntd.isQueryable();
-        this.primaryItemName = ntd.getPrimaryItemName();
-        this.superTypeNames = ntd.getDeclaredSupertypeNames();
-        // TODO: child item templates?
+    public NodeTypeTemplateImpl(
+            NodeTypeManager manager, ValueFactory factory,
+            NodeTypeDefinition ntd) {
+        this(manager, factory);
+
+        setName(ntd.getName());
+        setAbstract(ntd.isAbstract());
+        setMixin(ntd.isMixin());
+        setOrderableChildNodes(ntd.hasOrderableChildNodes());
+        setQueryable(ntd.isQueryable());
+        setPrimaryItemName(ntd.getPrimaryItemName());
+        setDeclaredSuperTypeNames(ntd.getDeclaredSupertypeNames());
+
+        for (PropertyDefinition pd : getDeclaredPropertyDefinitions()) {
+            PropertyDefinitionTemplateImpl pdt = newPropertyDefinitionBuilder();
+            pdt.setDeclaringNodeType(pd.getDeclaringNodeType().getName());
+            pdt.setName(pd.getName());
+            pdt.setProtected(pd.isProtected());
+            pdt.setMandatory(pd.isMandatory());
+            pdt.setAutoCreated(pd.isAutoCreated());
+            pdt.setOnParentVersion(pd.getOnParentVersion());
+            pdt.setMultiple(pd.isMultiple());
+            pdt.setRequiredType(pd.getRequiredType());
+            pdt.setDefaultValues(pd.getDefaultValues());
+            pdt.setValueConstraints(pd.getValueConstraints());
+            pdt.setFullTextSearchable(pd.isFullTextSearchable());
+            pdt.setAvailableQueryOperators(pd.getAvailableQueryOperators());
+            pdt.setQueryOrderable(pd.isQueryOrderable());
+            pdt.build();
+        }
+
+        for (NodeDefinition nd : getDeclaredChildNodeDefinitions()) {
+            NodeDefinitionTemplateImpl ndt = newNodeDefinitionBuilder();
+            ndt.setDeclaringNodeType(nd.getDeclaringNodeType().getName());
+            ndt.setName(nd.getName());
+            ndt.setProtected(nd.isProtected());
+            ndt.setMandatory(nd.isMandatory());
+            ndt.setAutoCreated(nd.isAutoCreated());
+            ndt.setOnParentVersion(nd.getOnParentVersion());
+            ndt.setSameNameSiblings(nd.allowsSameNameSiblings());
+            ndt.setDefaultPrimaryTypeName(nd.getDefaultPrimaryTypeName());
+            ndt.setRequiredPrimaryTypeNames(nd.getRequiredPrimaryTypeNames());
+            ndt.build();
+        }
+    }
+
+    @Override
+    public NodeTypeTemplate build() {
+        return this;
+    }
+
+    @Override
+    public PropertyDefinitionTemplateImpl newPropertyDefinitionBuilder() {
+        return new PropertyDefinitionTemplateImpl() {
+            @Override
+            protected Value createValue(String value)
+                    throws RepositoryException {
+                return factory.createValue(value);
+            }
+            @Override
+            public void build() {
+                propertyDefinitionTemplates.add(this);
+            }
+        };
+    }
+
+    @Override
+    public NodeDefinitionTemplateImpl newNodeDefinitionBuilder() {
+        return new NodeDefinitionTemplateImpl() {
+            @Override
+            protected NodeType getNodeType(String name)
+                    throws RepositoryException  {
+                if (manager != null) {
+                    return manager.getNodeType(name);
+                } else {
+                    return super.getNodeType(name);
+                }
+            }
+            @Override
+            public void build() {
+                nodeDefinitionTemplates.add(this);
+            }
+        };
     }
 
     @Override
@@ -104,12 +188,12 @@ class NodeTypeTemplateImpl implements No
 
     @Override
     public boolean isQueryable() {
-        return isQueryable;
+        return queryable;
     }
 
     @Override
     public void setQueryable(boolean queryable) {
-        this.isQueryable = queryable;
+        this.queryable = queryable;
     }
 
     @Override
@@ -133,6 +217,14 @@ class NodeTypeTemplateImpl implements No
     }
 
     @Override
+    public void addSupertype(String name) throws RepositoryException {
+        String[] names = new String[superTypeNames.length + 1];
+        System.arraycopy(superTypeNames, 0, names, 0, superTypeNames.length);
+        names[superTypeNames.length] = name;
+        superTypeNames = names;
+    }
+
+    @Override
     public List<PropertyDefinitionTemplate> getPropertyDefinitionTemplates() {
         return propertyDefinitionTemplates;
     }
@@ -144,12 +236,14 @@ class NodeTypeTemplateImpl implements No
 
     @Override
     public PropertyDefinition[] getDeclaredPropertyDefinitions() {
-        return null;
+        return propertyDefinitionTemplates.toArray(
+                new PropertyDefinition[propertyDefinitionTemplates.size()]);
     }
 
     @Override
     public NodeDefinition[] getDeclaredChildNodeDefinitions() {
-        return null;
+        return nodeDefinitionTemplates.toArray(
+                new NodeDefinition[nodeDefinitionTemplates.size()]);
     }
 
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionImpl.java Mon Jul 23 20:13:09 2012
@@ -16,75 +16,96 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import java.util.List;
-
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
 import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
 
-import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl;
-import org.apache.jackrabbit.oak.namepath.NameMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class PropertyDefinitionImpl extends ItemDefinitionImpl implements PropertyDefinition {
-
-    private final PropertyDefinitionDelegate dlg;
-
-    private final ValueFactoryImpl vfac;
+import com.google.common.base.Joiner;
 
-    private static final Logger log = LoggerFactory.getLogger(PropertyDefinitionImpl.class);
+/**
+ * Adapter class for turning an in-content property definition
+ * node ("nt:propertyDefinition") to a {@link PropertyDefinition} instance.
+ */
+class PropertyDefinitionImpl extends ItemDefinitionImpl
+        implements PropertyDefinition {
 
-    public PropertyDefinitionImpl(NodeType type, NameMapper mapper, ValueFactoryImpl vfac, PropertyDefinitionDelegate delegate) {
-        super(type, mapper, delegate);
-        this.vfac = vfac;
-        this.dlg = delegate;
+    public PropertyDefinitionImpl(NodeType type, Node node) {
+        super(type, node);
     }
 
+    //------------------------------------------------< PropertyDefinition >--
+
+    /**
+     * CND:
+     * <pre>
+     * - jcr:requiredType (STRING) protected mandatory
+     *   < 'STRING', 'URI', 'BINARY', 'LONG', 'DOUBLE',
+     *     'DECIMAL', 'BOOLEAN', 'DATE', 'NAME', 'PATH',
+     *     'REFERENCE', 'WEAKREFERENCE', 'UNDEFINED'
+     * </pre>
+     */
     @Override
     public int getRequiredType() {
-        return dlg.getRequiredType();
+        try {
+            return PropertyType.valueFromName(
+                    getString(Property.JCR_REQUIRED_TYPE));
+        } catch (IllegalArgumentException e) {
+            throw illegalState(e);
+        }
     }
 
+    /** CND: <pre>- jcr:valueConstraints (STRING) protected multiple</pre> */
     @Override
     public String[] getValueConstraints() {
-        return new String[0];
+        return getStrings(Property.JCR_VALUE_CONSTRAINTS, null);
     }
 
+    /** CND: <pre>- jcr:defaultValues (UNDEFINED) protected multiple</pre> */
     @Override
     public Value[] getDefaultValues() {
-        List<String> defaults = dlg.getDefaultValues();
-        Value[] result = new Value[defaults.size()];
-        for (int i = 0; i < defaults.size(); i++) {
-            try {
-                result[i] = vfac.createValue(defaults.get(i), dlg.getRequiredType());
-            } catch (ValueFormatException e) {
-                log.error("Converting value " + defaults.get(i), e);
-                return null;
-            }
-        }
-        return result;
+        return getValues(Property.JCR_DEFAULT_VALUES, null);
     }
 
+    /** CND: <pre>- jcr:multiple (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isMultiple() {
-        return dlg.isMultiple();
+        return getBoolean(Property.JCR_MULTIPLE);
     }
 
+    /** CND: <pre>- jcr:availableQueryOperators (NAME) protected mandatory multiple</pre> */
     @Override
     public String[] getAvailableQueryOperators() {
-        return new String[0];
+        return getStrings("jcr:availableQueryOperators", null); // TODO: constant
     }
 
+    /** CND: <pre>- jcr:isFullTextSearchable (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isFullTextSearchable() {
-        return false;
+        return getBoolean("jcr:isFullTextSearchable"); // TODO: constant
     }
 
+    /** CND: <pre>- jcr:isQueryOrderable (BOOLEAN) protected mandatory</pre> */
     @Override
     public boolean isQueryOrderable() {
-        return false;
+        return getBoolean("jcr:isQueryOrderable"); // TODO: constant
+    }
+
+    //------------------------------------------------------------< Object >--
+
+    public String toString() {
+        String dv = null;
+        String[] dvs = getStrings(Property.JCR_DEFAULT_VALUES, null);
+        if (dvs != null) {
+            dv = Joiner.on(", ").join(dvs);
+        }
+
+        StringBuilder sb = new StringBuilder("- ");
+        appendItemCND(sb, PropertyType.nameFromValue(getRequiredType()), dv);
+        sb.append(" ..."); // TODO: rest of the info
+        return sb.toString();
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionTemplateImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionTemplateImpl.java?rev=1364781&r1=1364780&r2=1364781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionTemplateImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/PropertyDefinitionTemplateImpl.java Mon Jul 23 20:13:09 2012
@@ -16,50 +16,105 @@
  */
 package org.apache.jackrabbit.oak.jcr.nodetype;
 
-import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeTemplate;
 import javax.jcr.nodetype.PropertyDefinitionTemplate;
 
-class PropertyDefinitionTemplateImpl extends ItemDefinitionTemplateImpl
+import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory.AbstractPropertyDefinitionBuilder;
+
+class PropertyDefinitionTemplateImpl
+        extends AbstractPropertyDefinitionBuilder<NodeTypeTemplate>
         implements PropertyDefinitionTemplate {
 
-    private boolean isMultiple = false;
+    private String[] valueConstraints;
 
-    private Value[] defaultValues = null;
+    private Value[] defaultValues;
 
-    private String[] availableQueryOperators = new String[0];
+    protected Value createValue(String value) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException();
+    }
 
-    private int requiredType = PropertyType.STRING;
+    @Override
+    public void build() {
+        // do nothing by default
+    }
 
-    private boolean fullTextSearchable = true;
+    @Override
+    public NodeType getDeclaringNodeType() {
+        return null;
+    }
 
-    private boolean queryOrderable = true;
+    @Override
+    public void setDeclaringNodeType(String name) {
+        // ignore
+    }
 
-    private String[] valueConstraints = null;
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
 
     @Override
-    public boolean isMultiple() {
-        return isMultiple;
+    public boolean isAutoCreated() {
+        return autocreate;
     }
 
     @Override
-    public void setMultiple(boolean isMultiple) {
-        this.isMultiple = isMultiple;
+    public void setAutoCreated(boolean autocreate) {
+        this.autocreate = autocreate;
     }
 
     @Override
-    public String[] getValueConstraints() {
-        return valueConstraints ;
+    public boolean isProtected() {
+        return isProtected;
     }
 
     @Override
-    public void setValueConstraints(String[] constraints) {
-        this.valueConstraints = constraints;
+    public void setProtected(boolean isProtected) {
+        this.isProtected = isProtected;
+    }
+
+    @Override
+    public boolean isMandatory() {
+        return isMandatory;
+    }
+
+    @Override
+    public void setMandatory(boolean isMandatory) {
+        this.isMandatory = isMandatory;
+    }
+
+    @Override
+    public int getOnParentVersion() {
+        return onParent;
+    }
+
+    @Override
+    public void setOnParentVersion(int onParent) {
+        this.onParent = onParent;
+    }
+
+    @Override
+    public void setRequiredType(int requiredType) {
+        this.requiredType = requiredType;
+    }
+
+    @Override
+    public boolean isMultiple() {
+        return isMultiple;
+    }
+
+    @Override
+    public void setMultiple(boolean isMultiple) {
+        this.isMultiple = isMultiple;
     }
 
     @Override
     public boolean isQueryOrderable() {
-        return queryOrderable ;
+        return queryOrderable;
     }
 
     @Override
@@ -78,13 +133,13 @@ class PropertyDefinitionTemplateImpl ext
     }
 
     @Override
-    public int getRequiredType() {
-        return requiredType ;
+    public String[] getAvailableQueryOperators() {
+        return queryOperators;
     }
 
     @Override
-    public void setRequiredType(int type) {
-        this.requiredType = type;
+    public void setAvailableQueryOperators(String[] queryOperators) {
+        this.queryOperators = queryOperators;
     }
 
     @Override
@@ -98,13 +153,37 @@ class PropertyDefinitionTemplateImpl ext
     }
 
     @Override
-    public String[] getAvailableQueryOperators() {
-        return availableQueryOperators ;
+    public void addDefaultValues(String value) throws RepositoryException {
+        if (defaultValues == null) {
+            defaultValues = new Value[] { createValue(value) };
+        } else {
+            Value[] values = new Value[defaultValues.length + 1];
+            System.arraycopy(defaultValues, 0, values, 0, defaultValues.length);
+            values[defaultValues.length] = createValue(value);
+            defaultValues = values;
+        }
+    }
+
+    @Override
+    public String[] getValueConstraints() {
+        return valueConstraints;
+    }
+
+    @Override
+    public void setValueConstraints(String[] constraints) {
+        this.valueConstraints = constraints;
     }
 
     @Override
-    public void setAvailableQueryOperators(String[] operators) {
-        this.availableQueryOperators = operators;
+    public void addValueConstraint(String constraint) {
+        if (valueConstraints == null) {
+            valueConstraints = new String[] { constraint };
+        } else {
+            String[] constraints = new String[valueConstraints.length + 1];
+            System.arraycopy(valueConstraints, 0, constraints, 0, valueConstraints.length);
+            constraints[valueConstraints.length] = constraint;
+            valueConstraints = constraints;
+        }
     }
 
 }
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/TypeNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/TypeNode.java?rev=1364781&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/TypeNode.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/nodetype/TypeNode.java Mon Jul 23 20:13:09 2012
@@ -0,0 +1,122 @@
+/*
+ * 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.oak.jcr.nodetype;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+
+/**
+ * Base class for node type, property and node definitions based on
+ * in-content definitions.
+ */
+class TypeNode {
+
+    private final Node node;
+
+    protected TypeNode(Node node) {
+        this.node = node;
+    }
+
+    protected IllegalStateException illegalState(Exception e) {
+        return new IllegalStateException(
+                "Unable to access node type information from " + node, e);
+    }
+
+    protected NodeType getType(NodeTypeManager manager, String name) {
+        try {
+            return manager.getNodeType(name);
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected boolean getBoolean(String name) {
+        try {
+            return node.getProperty(name).getBoolean();
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected String getString(String name) {
+        try {
+            return node.getProperty(name).getString();
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected String getString(String name, String ifNotFound) {
+        try {
+            return node.getProperty(name).getString();
+        } catch (PathNotFoundException e) {
+            return ifNotFound;
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected String[] getStrings(String name) {
+        try {
+            return getStrings(node.getProperty(name).getValues());
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected String[] getStrings(String name, String[] ifNotFound) {
+        try {
+            return getStrings(node.getProperty(name).getValues());
+        } catch (PathNotFoundException e) {
+            return ifNotFound;
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    protected Value[] getValues(String name, Value[] ifNotFound) {
+        try {
+            return node.getProperty(name).getValues();
+        } catch (PathNotFoundException e) {
+            return ifNotFound;
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+    private String[] getStrings(Value[] values) throws RepositoryException {
+        String[] strings = new String[values.length];
+        for (int i = 0; i < values.length; i++) {
+            strings[i] = values[i].getString();
+        }
+        return strings;
+    }
+
+    protected NodeIterator getNodes(String name) {
+        try {
+            return node.getNodes(name);
+        } catch (RepositoryException e) {
+            throw illegalState(e);
+        }
+    }
+
+}