jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r792142 [6/35] - in /jackrabbit/sandbox/JCR-1456: ./ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-core/ jackrabbit-core/src/main/java/org/apache/jackrabb...
Date Wed, 08 Jul 2009 13:57:46 GMT
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java Wed Jul  8 13:57:13 2009
@@ -16,18 +16,24 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-
-import javax.jcr.PropertyType;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValueConstraint;
+import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+
 /**
  * A <code>NodeTypeDef</code> holds the definition of a node type.
  */
@@ -48,9 +54,9 @@
     private boolean abstractStatus;
     private Name primaryItemName;
 
-    private HashSet propDefs;
-    private HashSet nodeDefs;
-    private Set dependencies;
+    private Set<PropDef> propDefs;
+    private Set<NodeDef> nodeDefs;
+    private Set<Name> dependencies;
 
     /**
      * Default constructor.
@@ -59,13 +65,65 @@
         dependencies = null;
         name = null;
         primaryItemName = null;
-        nodeDefs = new HashSet();
-        propDefs = new HashSet();
         supertypes = Name.EMPTY_ARRAY;
         mixin = false;
         orderableChildNodes = false;
         abstractStatus = false;
         queryable = true;
+        nodeDefs = new HashSet<NodeDef>();
+        propDefs = new HashSet<PropDef>();
+    }
+
+    /**
+     * Creates a node type def from a spi QNodeTypeDefinition
+     * @param def definition
+     */
+    public NodeTypeDef(QNodeTypeDefinition def) {
+        name = def.getName();
+        primaryItemName = def.getPrimaryItemName();
+        supertypes = def.getSupertypes();
+        mixin = def.isMixin();
+        orderableChildNodes = def.hasOrderableChildNodes();
+        abstractStatus = def.isAbstract();
+        queryable = def.isQueryable();
+        nodeDefs = new HashSet<NodeDef>();
+        for (QNodeDefinition nd: def.getChildNodeDefs()) {
+            nodeDefs.add(new NodeDefImpl(nd));
+        }
+        propDefs = new HashSet<PropDef>();
+        for (QPropertyDefinition pd: def.getPropertyDefs()) {
+            propDefs.add(new PropDefImpl(pd));
+        }
+    }
+
+    /**
+     * Returns the QNodeTypeDefintion for this NodeTypeDef
+     * @return the QNodeTypeDefintion
+     */
+    public QNodeTypeDefinition getQNodeTypeDefinition() {
+        QNodeDefinition[] qNodeDefs = new QNodeDefinition[nodeDefs.size()];
+        int i=0;
+        for (NodeDef nd: nodeDefs) {
+            qNodeDefs[i++] = ((NodeDefImpl) nd).getQNodeDefinition();
+        }
+        QPropertyDefinition[] qPropDefs = new QPropertyDefinition[propDefs.size()];
+        i=0;
+        for (PropDef pd: propDefs) {
+            qPropDefs[i++] = ((PropDefImpl) pd).getQPropertyDefinition();
+        }
+
+        return new QNodeTypeDefinitionImpl(
+                getName(),
+                getSupertypes(),
+                null,
+                isMixin(),
+                isAbstract(),
+                isQueryable(),
+                hasOrderableChildNodes(),
+                getPrimaryItemName(),
+                qPropDefs,
+                qNodeDefs
+        );
     }
 
     /**
@@ -82,12 +140,11 @@
      */
     public Collection getDependencies() {
         if (dependencies == null) {
-            dependencies = new HashSet();
+            dependencies = new HashSet<Name>();
             // supertypes
             dependencies.addAll(Arrays.asList(supertypes));
             // child node definitions
-            for (Iterator iter = nodeDefs.iterator(); iter.hasNext();) {
-                NodeDef nd = (NodeDef) iter.next();
+            for (NodeDef nd: nodeDefs) {
                 // default primary type
                 Name ntName = nd.getDefaultPrimaryType();
                 if (ntName != null && !name.equals(ntName)) {
@@ -95,23 +152,23 @@
                 }
                 // required primary type
                 Name[] ntNames = nd.getRequiredPrimaryTypes();
-                for (int j = 0; j < ntNames.length; j++) {
-                    if (ntNames[j] != null && !name.equals(ntNames[j])) {
-                        dependencies.add(ntNames[j]);
+                for (Name ntName1 : ntNames) {
+                    if (ntName1 != null && !name.equals(ntName1)) {
+                        dependencies.add(ntName1);
                     }
                 }
             }
             // property definitions
-            for (Iterator iter = propDefs.iterator(); iter.hasNext();) {
-                PropDef pd = (PropDef) iter.next();
-                // REFERENCE value constraints
-                if (pd.getRequiredType() == PropertyType.REFERENCE) {
-                    ValueConstraint[] ca = pd.getValueConstraints();
+            for (PropDef pd : propDefs) {
+                // [WEAK]REFERENCE value constraints
+                if (pd.getRequiredType() == PropertyType.REFERENCE
+                        || pd.getRequiredType() == PropertyType.WEAKREFERENCE) {
+                    QValueConstraint[] ca = pd.getValueConstraints();
                     if (ca != null) {
-                        for (int j = 0; j < ca.length; j++) {
-                            ReferenceConstraint rc = (ReferenceConstraint) ca[j];
-                            if (!name.equals(rc.getNodeTypeName())) {
-                                dependencies.add(rc.getNodeTypeName());
+                        for (QValueConstraint aCa : ca) {
+                            Name rcName = NameFactoryImpl.getInstance().create(aCa.getString());
+                            if (!name.equals(rcName)) {
+                                dependencies.add(rcName);
                             }
                         }
                     }
@@ -149,9 +206,9 @@
             supertypes = new Name[] { names[0] };
         } else {
             // Sort and remove duplicates
-            SortedSet types = new TreeSet();
+            SortedSet<Name> types = new TreeSet<Name>();
             types.addAll(Arrays.asList(names));
-            supertypes = (Name[]) types.toArray(new Name[types.size()]);
+            supertypes = types.toArray(new Name[types.size()]);
         }
     }
 
@@ -309,7 +366,7 @@
         if (propDefs.isEmpty()) {
             return PropDef.EMPTY_ARRAY;
         }
-        return (PropDef[]) propDefs.toArray(new PropDef[propDefs.size()]);
+        return propDefs.toArray(new PropDef[propDefs.size()]);
     }
 
     /**
@@ -323,7 +380,7 @@
         if (nodeDefs.isEmpty()) {
             return NodeDef.EMPTY_ARRAY;
         }
-        return (NodeDef[]) nodeDefs.toArray(new NodeDef[nodeDefs.size()]);
+        return nodeDefs.toArray(new NodeDef[nodeDefs.size()]);
     }
 
     //-------------------------------------------< java.lang.Object overrides >
@@ -336,8 +393,10 @@
         clone.orderableChildNodes = orderableChildNodes;
         clone.abstractStatus = abstractStatus;
         clone.queryable = queryable;
-        clone.nodeDefs = (HashSet) nodeDefs.clone();
-        clone.propDefs = (HashSet) propDefs.clone();
+        clone.nodeDefs = new HashSet<NodeDef>();
+        // todo: itemdefs should be cloned as well, since mutable
+        clone.nodeDefs = new HashSet<NodeDef>(nodeDefs);
+        clone.propDefs = new HashSet<PropDef>(propDefs);
         return clone;
     }
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefDiff.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefDiff.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefDiff.java Wed Jul  8 13:57:13 2009
@@ -26,6 +26,8 @@
 
 import javax.jcr.PropertyType;
 
+import org.apache.jackrabbit.spi.QValueConstraint;
+
 /**
  * A <code>NodeTypeDefDiff</code> represents the result of the comparison of
  * two node type definitions.
@@ -529,15 +531,15 @@
                  * check if valueConstraints were made more restrictive
                  * (constraints are ORed)
                  */
-                ValueConstraint[] vca1 = getOldDef().getValueConstraints();
+                QValueConstraint[] vca1 = getOldDef().getValueConstraints();
                 HashSet set1 = new HashSet();
                 for (int i = 0; i < vca1.length; i++) {
-                    set1.add(vca1[i].getDefinition());
+                    set1.add(vca1[i].getString());
                 }
-                ValueConstraint[] vca2 = getNewDef().getValueConstraints();
+                QValueConstraint[] vca2 = getNewDef().getValueConstraints();
                 HashSet set2 = new HashSet();
                 for (int i = 0; i < vca2.length; i++) {
-                    set2.add(vca2[i].getDefinition());
+                    set2.add(vca2[i].getString());
                 }
 
                 if (set1.isEmpty() && !set2.isEmpty()) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java Wed Jul  8 13:57:13 2009
@@ -16,14 +16,6 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter;
-import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
-import org.apache.jackrabbit.spi.Name;
-
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.RepositoryException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -31,7 +23,17 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.CompactNodeTypeDefReader;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
 
 /**
  * <code>NodeTypeDefStore</code> ...
@@ -39,13 +41,13 @@
 public class NodeTypeDefStore {
 
     /** Map of node type names to node type definitions. */
-    private final HashMap ntDefs;
+    private final Map<Name, NodeTypeDef> ntDefs;
 
     /**
      * Empty default constructor.
      */
     public NodeTypeDefStore() throws RepositoryException {
-        ntDefs = new HashMap();
+        ntDefs = new HashMap<Name, NodeTypeDef>();
     }
 
     /**
@@ -57,8 +59,8 @@
             throws IOException, InvalidNodeTypeDefException,
             RepositoryException {
         NodeTypeDef[] types = NodeTypeReader.read(in);
-        for (int i = 0; i < types.length; i++) {
-            add(types[i]);
+        for (NodeTypeDef type : types) {
+            add(type);
         }
     }
 
@@ -75,9 +77,8 @@
             throws IOException, InvalidNodeTypeDefException {
         try {
             CompactNodeTypeDefReader r = new CompactNodeTypeDefReader(in, systemId);
-            Iterator iter = r.getNodeTypeDefs().iterator();
-            while (iter.hasNext()) {
-                add((NodeTypeDef) iter.next());
+            for (QNodeTypeDefinition qdef: r.getNodeTypeDefinitions()) {
+                add(new NodeTypeDef(qdef));
             }
         } catch (ParseException e) {
             throw new InvalidNodeTypeDefException("Unable to parse CND stream.", e);
@@ -92,8 +93,7 @@
      */
     public void store(OutputStream out, NamespaceRegistry registry)
             throws IOException, RepositoryException {
-        NodeTypeDef[] types = (NodeTypeDef[])
-            ntDefs.values().toArray(new NodeTypeDef[ntDefs.size()]);
+        NodeTypeDef[] types = ntDefs.values().toArray(new NodeTypeDef[ntDefs.size()]);
         NodeTypeWriter.write(out, types, registry);
     }
 
@@ -132,13 +132,13 @@
      * @return
      */
     public NodeTypeDef get(Name name) {
-        return (NodeTypeDef) ntDefs.get(name);
+        return ntDefs.get(name);
     }
 
     /**
      * @return
      */
-    public Collection all() {
+    public Collection<NodeTypeDef> all() {
         return Collections.unmodifiableCollection(ntDefs.values());
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefinitionImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefinitionImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefinitionImpl.java Wed Jul  8 13:57:13 2009
@@ -38,7 +38,7 @@
     private static Logger log = LoggerFactory.getLogger(NodeTypeDefinitionImpl.class);
 
     private final NodeTypeDef ntd;
-    // resolver used to translate qualified names to JCR names
+    // resolver used to translate <code>Name</code>s to JCR name strings.
     private final NamePathResolver resolver;
     private final ValueFactory valueFactory;
 
@@ -79,11 +79,11 @@
         String[] supertypes = new String[ntNames.length];
         for (int i = 0; i < ntNames.length; i++) {
             try {
-                supertypes[i] = resolver.getJCRName(ntd.getName());
+                supertypes[i] = resolver.getJCRName(ntNames[i]);
             } catch (NamespaceException e) {
                 // should never get here
                 log.error("encountered unregistered namespace in node type name", e);
-                supertypes[i] = ntd.getName().toString();
+                supertypes[i] = ntNames[i].toString();
             }
         }
         return supertypes;

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java Wed Jul  8 13:57:13 2009
@@ -51,7 +51,7 @@
     private final NodeTypeDef ntd;
     private final EffectiveNodeType ent;
     private final NodeTypeManagerImpl ntMgr;
-    // resolver used to translate qualified names to JCR names
+    // resolver used to translate translate <code>Name</code>s to JCR name strings.
     private final NamePathResolver resolver;
     // value factory used for type conversion
     private final ValueFactory valueFactory;
@@ -186,9 +186,9 @@
     }
 
     /**
-     * Returns the 'internal', i.e. the fully qualified name.
+     * Returns the <code>Name</code> of this node type.
      *
-     * @return the qualified name
+     * @return the name
      */
     public Name getQName() {
         return ntd.getName();
@@ -264,7 +264,7 @@
             } catch (NamespaceException e) {
                 // should never get here
                 log.error("encountered unregistered namespace in node type name", e);
-                supertypes[i] = ntd.getName().toString();
+                supertypes[i] = ntNames[i].toString();
             }
         }
         return supertypes;
@@ -305,13 +305,14 @@
      * {@inheritDoc}
      */
     public boolean hasOrderableChildNodes() {
-        return ntd.hasOrderableChildNodes();
+        return ent.hasOrderableChildNodes();
     }
 
     /**
      * {@inheritDoc}
      */
     public String getPrimaryItemName() {
+        // TODO JCR-1947: JSR 283: Node Type Attribute Subtyping Rules
         try {
             Name piName = ntd.getPrimaryItemName();
             if (piName != null) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java Wed Jul  8 13:57:13 2009
@@ -16,40 +16,6 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
-import javax.jcr.nodetype.InvalidNodeTypeDefinitionException;
-import org.apache.jackrabbit.commons.NamespaceHelper;
-import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
-import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
-import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.data.DataStore;
-import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
-
-import javax.jcr.nodetype.NodeTypeDefinition;
-import javax.jcr.nodetype.NodeTypeExistsException;
-
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
-import org.apache.jackrabbit.core.util.Dumpable;
-import org.apache.jackrabbit.core.value.InternalValue;
-import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
-import org.apache.jackrabbit.spi.commons.nodetype.AbstractNodeTypeManager;
-import org.apache.jackrabbit.spi.Name;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.jcr.NamespaceException;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
-import javax.jcr.ValueFactory;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeIterator;
-import javax.jcr.nodetype.PropertyDefinition;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -66,6 +32,43 @@
 import java.util.Properties;
 import java.util.Set;
 
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.InvalidNodeTypeDefinitionException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeDefinition;
+import javax.jcr.nodetype.NodeTypeExistsException;
+import javax.jcr.nodetype.NodeTypeIterator;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
+import org.apache.jackrabbit.commons.NamespaceHelper;
+import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.data.DataStore;
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
+import org.apache.jackrabbit.core.util.Dumpable;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QValueConstraint;
+import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
+import org.apache.jackrabbit.spi.commons.nodetype.AbstractNodeTypeManager;
+import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.CompactNodeTypeDefReader;
+import org.apache.jackrabbit.spi.commons.nodetype.compact.ParseException;
+import org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
 /**
  * A <code>NodeTypeManagerImpl</code> implements a session dependant
  * NodeTypeManager.
@@ -97,19 +100,19 @@
      * A cache for <code>NodeType</code> instances created by this
      * <code>NodeTypeManager</code>
      */
-    private final Map ntCache;
+    private final Map<Name, NodeTypeImpl> ntCache;
 
     /**
      * A cache for <code>PropertyDefinition</code> instances created by this
      * <code>NodeTypeManager</code>
      */
-    private final Map pdCache;
+    private final Map<PropDefId, PropertyDefinitionImpl> pdCache;
 
     /**
      * A cache for <code>NodeDefinition</code> instances created by this
      * <code>NodeTypeManager</code>
      */
-    private final Map ndCache;
+    private final Map<NodeDefId, NodeDefinitionImpl> ndCache;
 
     private final DataStore store;
 
@@ -118,8 +121,10 @@
      *
      * @param ntReg      node type registry
      * @param session    current session
+     * @param store      the data store
      * @throws RepositoryException If an error occurs.
      */
+    @SuppressWarnings("unchecked")
     public NodeTypeManagerImpl(
             NodeTypeRegistry ntReg, SessionImpl session, DataStore store)
             throws RepositoryException {
@@ -148,12 +153,12 @@
     }
 
     /**
-     * @param id
+     * @param id node def id
      * @return the node definition
      */
     public NodeDefinitionImpl getNodeDefinition(NodeDefId id) {
         synchronized (ndCache) {
-            NodeDefinitionImpl ndi = (NodeDefinitionImpl) ndCache.get(id);
+            NodeDefinitionImpl ndi = ndCache.get(id);
             if (ndi == null) {
                 NodeDef nd = ntReg.getNodeDef(id);
                 if (nd != null) {
@@ -166,12 +171,12 @@
     }
 
     /**
-     * @param id
+     * @param id prop def id
      * @return the property definition
      */
     public PropertyDefinitionImpl getPropertyDefinition(PropDefId id) {
         synchronized (pdCache) {
-            PropertyDefinitionImpl pdi = (PropertyDefinitionImpl) pdCache.get(id);
+            PropertyDefinitionImpl pdi = pdCache.get(id);
             if (pdi == null) {
                 PropDef pd = ntReg.getPropDef(id);
                 if (pd != null) {
@@ -184,13 +189,13 @@
     }
 
     /**
-     * @param name
-     * @return
-     * @throws NoSuchNodeTypeException
+     * @param name node type name
+     * @return node type
+     * @throws NoSuchNodeTypeException if the nodetype does not exit
      */
     public NodeTypeImpl getNodeType(Name name) throws NoSuchNodeTypeException {
         synchronized (ntCache) {
-            NodeTypeImpl nt = (NodeTypeImpl) ntCache.get(name);
+            NodeTypeImpl nt = ntCache.get(name);
             if (nt == null) {
                 EffectiveNodeType ent = ntReg.getEffectiveNodeType(name);
                 NodeTypeDef def = ntReg.getNodeTypeDef(name);
@@ -228,8 +233,8 @@
             throws IOException, RepositoryException {
 
         try {
-            Map namespaceMap = new HashMap();
-            List nodeTypeDefs = new ArrayList();
+            Map<String, String> namespaceMap = new HashMap<String, String>();
+            List<NodeTypeDef> nodeTypeDefs = new ArrayList<NodeTypeDef>();
 
             if (contentType.equalsIgnoreCase(TEXT_XML)
                     || contentType.equalsIgnoreCase(APPLICATION_XML)) {
@@ -258,8 +263,9 @@
                             new InputStreamReader(in), "cnd input stream", mapping);
 
                     namespaceMap.putAll(mapping.getPrefixToURIMapping());
-
-                    nodeTypeDefs.addAll(reader.getNodeTypeDefs());
+                    for (QNodeTypeDefinition ntDef: reader.getNodeTypeDefinitions()) {
+                        nodeTypeDefs.add(new NodeTypeDef(ntDef));
+                    }
                 } catch (ParseException e) {
                     IOException e2 = new IOException(e.getMessage());
                     e2.initCause(e);
@@ -276,10 +282,9 @@
                 // split the node types into new and already registered node types.
                 // this way we can register new node types together with already
                 // registered node types which make circular dependencies possible
-                List newNodeTypeDefs = new ArrayList();
-                List registeredNodeTypeDefs = new ArrayList();
-                for (Iterator iter = nodeTypeDefs.iterator(); iter.hasNext();) {
-                    NodeTypeDef nodeTypeDef = (NodeTypeDef) iter.next();
+                List<NodeTypeDef> newNodeTypeDefs = new ArrayList<NodeTypeDef>();
+                List<NodeTypeDef> registeredNodeTypeDefs = new ArrayList<NodeTypeDef>();
+                for (NodeTypeDef nodeTypeDef: nodeTypeDefs) {
                     if (ntReg.isRegistered(nodeTypeDef.getName())) {
                         registeredNodeTypeDefs.add(nodeTypeDef);
                     } else {
@@ -287,21 +292,20 @@
                     }
                 }
 
-                ArrayList nodeTypes = new ArrayList();
+                ArrayList<NodeType> nodeTypes = new ArrayList<NodeType>();
 
                 // register new node types
                 nodeTypes.addAll(registerNodeTypes(newNodeTypeDefs));
 
-                // reregister already existing node types
-                for (Iterator iter = registeredNodeTypeDefs.iterator(); iter.hasNext();) {
-                    NodeTypeDef nodeTypeDef = (NodeTypeDef) iter.next();
+                // re-register already existing node types
+                for (NodeTypeDef nodeTypeDef: registeredNodeTypeDefs) {
                     ntReg.reregisterNodeType(nodeTypeDef);
                     nodeTypes.add(getNodeType(nodeTypeDef.getName()));
                 }
-                return (NodeType[]) nodeTypes.toArray(new NodeType[nodeTypes.size()]);
+                return nodeTypes.toArray(new NodeType[nodeTypes.size()]);
             } else {
-                Collection types = registerNodeTypes(nodeTypeDefs);
-                return (NodeType[]) types.toArray(new NodeType[types.size()]);
+                Collection<NodeType> types = registerNodeTypes(nodeTypeDefs);
+                return types.toArray(new NodeType[types.size()]);
             }
 
         } catch (InvalidNodeTypeDefException e) {
@@ -375,9 +379,10 @@
      */
     public NodeTypeIterator getAllNodeTypes() throws RepositoryException {
         Name[] ntNames = ntReg.getRegisteredNodeTypes();
-        ArrayList list = new ArrayList(ntNames.length);
-        for (int i = 0; i < ntNames.length; i++) {
-            list.add(getNodeType(ntNames[i]));
+        Arrays.sort(ntNames);
+        ArrayList<NodeType> list = new ArrayList<NodeType>(ntNames.length);
+        for (Name ntName : ntNames) {
+            list.add(getNodeType(ntName));
         }
         return new NodeTypeIteratorAdapter(list);
     }
@@ -387,9 +392,10 @@
      */
     public NodeTypeIterator getPrimaryNodeTypes() throws RepositoryException {
         Name[] ntNames = ntReg.getRegisteredNodeTypes();
-        ArrayList list = new ArrayList(ntNames.length);
-        for (int i = 0; i < ntNames.length; i++) {
-            NodeType nt = getNodeType(ntNames[i]);
+        Arrays.sort(ntNames);
+        ArrayList<NodeType> list = new ArrayList<NodeType>(ntNames.length);
+        for (Name ntName : ntNames) {
+            NodeType nt = getNodeType(ntName);
             if (!nt.isMixin()) {
                 list.add(nt);
             }
@@ -402,9 +408,10 @@
      */
     public NodeTypeIterator getMixinNodeTypes() throws RepositoryException {
         Name[] ntNames = ntReg.getRegisteredNodeTypes();
-        ArrayList list = new ArrayList(ntNames.length);
-        for (int i = 0; i < ntNames.length; i++) {
-            NodeType nt = getNodeType(ntNames[i]);
+        Arrays.sort(ntNames);
+        ArrayList<NodeType> list = new ArrayList<NodeType>(ntNames.length);
+        for (Name ntName : ntNames) {
+            NodeType nt = getNodeType(ntName);
             if (nt.isMixin()) {
                 list.add(nt);
             }
@@ -433,19 +440,17 @@
      * Returns a collection containing the registered node types.
      *
      * @param defs a collection of <code>NodeTypeDef<code> objects
-     * @returns registered node types
-     * @throws InvalidNodeTypeDefException
-     * @throws RepositoryException
+     * @return registered node types
+     * @throws InvalidNodeTypeDefException if a nodetype is invalid
+     * @throws RepositoryException if an error occurs
      */
-    private Collection registerNodeTypes(List defs)
+    private Collection<NodeType> registerNodeTypes(List<NodeTypeDef> defs)
             throws InvalidNodeTypeDefException, RepositoryException {
         ntReg.registerNodeTypes(defs);
 
-        Set types = new HashSet();
-        Iterator iterator = defs.iterator();
-        while (iterator.hasNext()) {
+        Set<NodeType> types = new HashSet<NodeType>();
+        for (NodeTypeDef def : defs) {
             try {
-                NodeTypeDef def = (NodeTypeDef) iterator.next();
                 types.add(getNodeType(def.getName()));
             } catch (NoSuchNodeTypeException e) {
                 // ignore
@@ -553,8 +558,8 @@
         // split the node types into new and already registered node types.
         // this way we can register new node types together with already
         // registered node types which make circular dependencies possible
-        List addedDefs = new ArrayList();
-        List modifiedDefs = new ArrayList();
+        List<NodeTypeDef> addedDefs = new ArrayList<NodeTypeDef>();
+        List<NodeTypeDef> modifiedDefs = new ArrayList<NodeTypeDef>();
         for (NodeTypeDefinition definition : definitions) {
             // convert to NodeTypeDef
             NodeTypeDef def = toNodeTypeDef(definition);
@@ -570,14 +575,13 @@
         }
 
         try {
-            ArrayList result = new ArrayList();
+            ArrayList<NodeType> result = new ArrayList<NodeType>();
 
             // register new node types
             result.addAll(registerNodeTypes(addedDefs));
 
-            // reregister already existing node types
-            for (Iterator iter = modifiedDefs.iterator(); iter.hasNext();) {
-                NodeTypeDef nodeTypeDef = (NodeTypeDef) iter.next();
+            // re-register already existing node types
+            for (NodeTypeDef nodeTypeDef: modifiedDefs) {
                 ntReg.reregisterNodeType(nodeTypeDef);
                 result.add(getNodeType(nodeTypeDef.getName()));
             }
@@ -605,14 +609,14 @@
     public void unregisterNodeTypes(String[] names)
             throws UnsupportedRepositoryOperationException,
             NoSuchNodeTypeException, RepositoryException {
-        HashSet ntNames = new HashSet();
-        for (int i = 0; i < names.length; i++) {
+        Set<Name> ntNames = new HashSet<Name>();
+        for (String name : names) {
             try {
-                ntNames.add(session.getQName(names[i]));
+                ntNames.add(session.getQName(name));
             } catch (NamespaceException e) {
-                throw new RepositoryException("Invalid name: " + names[i], e);
+                throw new RepositoryException("Invalid name: " + name, e);
             } catch (NameException e) {
-                throw new RepositoryException("Invalid name: " + names[i], e);
+                throw new RepositoryException("Invalid name: " + name, e);
             }
         }
         getNodeTypeRegistry().unregisterNodeTypes(ntNames);
@@ -623,10 +627,10 @@
      * (using prefixed JCR names) to a <code>NodeTypeDef</code> (using
      * namespace-qualified names).
      *
-     * @param definition
+     * @param definition the definition
      * @return a <code>NodeTypeDef</code>
-     * @throws InvalidNodeTypeDefinitionException
-     * @throws RepositoryException
+     * @throws InvalidNodeTypeDefinitionException if the definiton is invalid
+     * @throws RepositoryException if a repository error occurs
      */
     private NodeTypeDef toNodeTypeDef(NodeTypeDefinition definition)
             throws InvalidNodeTypeDefinitionException, RepositoryException {
@@ -770,13 +774,13 @@
                 // value constraints
                 String[] constraints = pdefs[i].getValueConstraints();
                 if (constraints != null) {
-                    ValueConstraint[] qconstraints = new ValueConstraint[constraints.length];
+                    QValueConstraint[] qconstraints = new QValueConstraint[constraints.length];
                     for (int j = 0; j < constraints.length; j++) {
                         try {
-                            qconstraints[j] = ValueConstraint.create(type, constraints[i], session);
+                            qconstraints[j] = ValueConstraint.create(type, constraints[j], session);
                         } catch (InvalidConstraintException e) {
                             throw new InvalidNodeTypeDefinitionException(
-                                    "Invalid value constraint " + constraints[i], e);
+                                    "Invalid value constraint: " + constraints[j], e);
                         }
                     }
                     qpdef.setValueConstraints(qconstraints);
@@ -787,10 +791,10 @@
                     InternalValue[] qvalues = new InternalValue[values.length];
                     for (int j = 0; j < values.length; j++) {
                         try {
-                            qvalues[j] = InternalValue.create(values[i], session);
+                            qvalues[j] = InternalValue.create(values[j], session);
                         } catch (ValueFormatException e) {
                             throw new InvalidNodeTypeDefinitionException(
-                                    "Invalid default value format", e);
+                                    "Invalid default value format: " + values[j], e);
                         }
                     }
                     qpdef.setDefaultValues(qvalues);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java Wed Jul  8 13:57:13 2009
@@ -16,35 +16,21 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.core.cluster.NodeTypeEventChannel;
-import org.apache.jackrabbit.core.cluster.NodeTypeEventListener;
-import org.apache.jackrabbit.core.fs.FileSystem;
-import org.apache.jackrabbit.core.fs.FileSystemException;
-import org.apache.jackrabbit.core.fs.FileSystemResource;
-import org.apache.jackrabbit.core.util.Dumpable;
-import org.apache.jackrabbit.core.value.InternalValue;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.io.InputStreamReader;
 import java.io.Reader;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
+import java.util.TreeSet;
 
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.PropertyType;
@@ -53,6 +39,24 @@
 import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.version.OnParentVersionAction;
 
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.core.cluster.NodeTypeEventChannel;
+import org.apache.jackrabbit.core.cluster.NodeTypeEventListener;
+import org.apache.jackrabbit.core.fs.FileSystem;
+import org.apache.jackrabbit.core.fs.FileSystemException;
+import org.apache.jackrabbit.core.fs.FileSystemResource;
+import org.apache.jackrabbit.core.util.Dumpable;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QValueConstraint;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+
 /**
  * A <code>NodeTypeRegistry</code> ...
  */
@@ -82,15 +86,15 @@
     private EffectiveNodeTypeCache entCache;
 
     // map of node type names and node type definitions
-    private final ConcurrentReaderHashMap registeredNTDefs;
+    private final Map<Name, NodeTypeDef> registeredNTDefs;
 
     // definition of the root node
     private final NodeDef rootNodeDef;
 
     // map of id's and property definitions
-    private final ConcurrentReaderHashMap propDefs;
+    private final Map<PropDefId, PropDef> propDefs;
     // map of id's and node definitions
-    private final ConcurrentReaderHashMap nodeDefs;
+    private final Map<NodeDefId, NodeDef> nodeDefs;
 
     /**
      * namespace registry for resolving prefixes and namespace URI's;
@@ -101,7 +105,7 @@
     /**
      * Listeners (soft references)
      */
-    private final Map listeners =
+    private final Map<NodeTypeRegistryListener, NodeTypeRegistryListener> listeners =
             Collections.synchronizedMap(new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK));
 
     /**
@@ -112,10 +116,10 @@
     /**
      * Create a new <code>NodeTypeRegistry</codes>
      *
-     * @param nsReg
-     * @param ntStore
+     * @param nsReg namespace registry
+     * @param ntStore node type store
      * @return <code>NodeTypeRegistry</codes> object
-     * @throws RepositoryException
+     * @throws RepositoryException if an error occurs
      */
     public static NodeTypeRegistry create(NamespaceRegistry nsReg, FileSystem ntStore)
             throws RepositoryException {
@@ -131,7 +135,7 @@
      * @return the names of all registered node types.
      */
     public Name[] getRegisteredNodeTypes() {
-        return (Name[]) registeredNTDefs.keySet().toArray(new Name[registeredNTDefs.size()]);
+        return registeredNTDefs.keySet().toArray(new Name[registeredNTDefs.size()]);
     }
 
     /**
@@ -181,7 +185,7 @@
         persistCustomNodeTypeDefs(customNTDefs);
 
         if (eventChannel != null) {
-            HashSet ntDefs = new HashSet();
+            Set<NodeTypeDef> ntDefs = new HashSet<NodeTypeDef>();
             ntDefs.add(ntd);
             eventChannel.registered(ntDefs);
         }
@@ -204,7 +208,7 @@
      * @throws InvalidNodeTypeDefException if the given node type definition is invalid.
      * @throws RepositoryException if a repository error occurs.
      */
-    public void registerNodeTypes(Collection ntDefs)
+    public void registerNodeTypes(Collection<NodeTypeDef> ntDefs)
             throws InvalidNodeTypeDefException, RepositoryException {
 
         registerNodeTypes(ntDefs, false);
@@ -218,14 +222,14 @@
      * @throws InvalidNodeTypeDefException if the given node type definition is invalid.
      * @throws RepositoryException if a repository error occurs.
      */
-    private synchronized void registerNodeTypes(Collection ntDefs, boolean external)
+    private synchronized void registerNodeTypes(Collection<NodeTypeDef> ntDefs,
+                                                boolean external)
             throws InvalidNodeTypeDefException, RepositoryException {
 
         // validate and register new node type definitions
         internalRegister(ntDefs);
         // persist new node type definitions
-        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
-            NodeTypeDef ntDef = (NodeTypeDef) iter.next();
+        for (NodeTypeDef ntDef: ntDefs) {
             customNTDefs.add(ntDef);
         }
         persistCustomNodeTypeDefs(customNTDefs);
@@ -236,8 +240,7 @@
         }
 
         // notify listeners
-        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
-            NodeTypeDef ntDef = (NodeTypeDef) iter.next();
+        for (NodeTypeDef ntDef : ntDefs) {
             notifyRegistered(ntDef.getName());
         }
     }
@@ -256,7 +259,7 @@
      * @throws RepositoryException if another error occurs
      * @see #unregisterNodeType(Name)
      */
-    public void unregisterNodeTypes(Collection ntNames)
+    public void unregisterNodeTypes(Collection<Name> ntNames)
             throws NoSuchNodeTypeException, RepositoryException {
 
         unregisterNodeTypes(ntNames, false);
@@ -272,12 +275,11 @@
      *                                 denote a registered node type.
      * @throws RepositoryException if another error occurs
      */
-    private synchronized void unregisterNodeTypes(Collection ntNames, boolean external)
+    private synchronized void unregisterNodeTypes(Collection<Name> ntNames, boolean external)
             throws NoSuchNodeTypeException, RepositoryException {
 
         // do some preliminary checks
-        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
-            Name ntName = (Name) iter.next();
+        for (Name ntName: ntNames) {
             if (!registeredNTDefs.containsKey(ntName)) {
                 throw new NoSuchNodeTypeException(ntName.toString());
             }
@@ -287,13 +289,13 @@
             }
             // check for node types other than those to be unregistered
             // that depend on the given node types
-            Set dependents = getDependentNodeTypes(ntName);
+            Set<Name> dependents = getDependentNodeTypes(ntName);
             dependents.removeAll(ntNames);
             if (dependents.size() > 0) {
                 StringBuffer msg = new StringBuffer();
                 msg.append(ntName).append(" can not be removed because the following node types depend on it: ");
-                for (Iterator depIter = dependents.iterator(); depIter.hasNext();) {
-                    msg.append(depIter.next());
+                for (Name dependent : dependents) {
+                    msg.append(dependent);
                     msg.append(" ");
                 }
                 throw new RepositoryException(msg.toString());
@@ -301,8 +303,7 @@
         }
 
         // make sure node types are not currently in use
-        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
-            Name ntName = (Name) iter.next();
+        for (Name ntName : ntNames) {
             checkForReferencesInContent(ntName);
         }
 
@@ -315,8 +316,7 @@
         }
 
         // persist removal of node type definitions & notify listeners
-        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
-            Name ntName = (Name) iter.next();
+        for (Name ntName : ntNames) {
             customNTDefs.remove(ntName);
             notifyUnregistered(ntName);
         }
@@ -342,7 +342,7 @@
      */
     public void unregisterNodeType(Name ntName)
             throws NoSuchNodeTypeException, RepositoryException {
-        HashSet ntNames = new HashSet();
+        HashSet<Name> ntNames = new HashSet<Name>();
         ntNames.add(ntName);
         unregisterNodeTypes(ntNames);
     }
@@ -393,12 +393,13 @@
         /**
          * validate new node type definition
          */
+        checkNtBaseSubtyping(ntd, registeredNTDefs);
         validateNodeTypeDef(ntd, entCache, registeredNTDefs, nsReg, false);
 
         /**
          * build diff of current and new definition and determine type of change
          */
-        NodeTypeDef ntdOld = (NodeTypeDef) registeredNTDefs.get(name);
+        NodeTypeDef ntdOld = registeredNTDefs.get(name);
         NodeTypeDefDiff diff = NodeTypeDefDiff.create(ntdOld, ntd);
         if (!diff.isModified()) {
             // the definition has not been modified, there's nothing to do here...
@@ -462,9 +463,9 @@
     }
 
     /**
-     * @param ntName
-     * @return
-     * @throws NoSuchNodeTypeException
+     * @param ntName name
+     * @return effective node type
+     * @throws NoSuchNodeTypeException if node type does not exist
      */
     public EffectiveNodeType getEffectiveNodeType(Name ntName)
             throws NoSuchNodeTypeException {
@@ -481,7 +482,7 @@
      * @throws NodeTypeConflictException if the given types are conflicting
      * @throws NoSuchNodeTypeException if one of the given types is not found
      */
-    public EffectiveNodeType getEffectiveNodeType(Name primary, Set mixins)
+    public EffectiveNodeType getEffectiveNodeType(Name primary, Set<Name> mixins)
             throws NodeTypeConflictException, NoSuchNodeTypeException {
         if (mixins.isEmpty()) {
             return getEffectiveNodeType(primary);
@@ -499,9 +500,9 @@
      *
      * @param nodeTypeName node type name
      * @return a set of node type <code>Name</code>s
-     * @throws NoSuchNodeTypeException
+     * @throws NoSuchNodeTypeException if node type does not exist
      */
-    public Set getDependentNodeTypes(Name nodeTypeName)
+    public Set<Name> getDependentNodeTypes(Name nodeTypeName)
             throws NoSuchNodeTypeException {
         if (!registeredNTDefs.containsKey(nodeTypeName)) {
             throw new NoSuchNodeTypeException(nodeTypeName.toString());
@@ -511,10 +512,8 @@
          * collect names of those node types that have dependencies on the given
          * node type
          */
-        HashSet names = new HashSet();
-        Iterator iter = registeredNTDefs.values().iterator();
-        while (iter.hasNext()) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+        HashSet<Name> names = new HashSet<Name>();
+        for (NodeTypeDef ntd : registeredNTDefs.values()) {
             if (ntd.getDependencies().contains(nodeTypeName)) {
                 names.add(ntd.getName());
             }
@@ -532,7 +531,7 @@
      */
     public NodeTypeDef getNodeTypeDef(Name nodeTypeName)
             throws NoSuchNodeTypeException {
-        NodeTypeDef def = (NodeTypeDef) registeredNTDefs.get(nodeTypeName);
+        NodeTypeDef def = registeredNTDefs.get(nodeTypeName);
         if (def == null) {
             throw new NoSuchNodeTypeException(nodeTypeName.toString());
         }
@@ -541,7 +540,7 @@
     }
 
     /**
-     * @param nodeTypeName
+     * @param nodeTypeName node type name
      * @return <code>true</code> if the specified node type is registered;
      *         <code>false</code> otherwise.
      */
@@ -550,7 +549,7 @@
     }
 
     /**
-     * @param nodeTypeName
+     * @param nodeTypeName node type name
      * @return <code>true</code> if the specified node type is built-in;
      *         <code>false</code> otherwise.
      */
@@ -559,19 +558,19 @@
     }
 
     /**
-     * @param id
+     * @param id node def id
      * @return the node definition for the given id.
      */
     public NodeDef getNodeDef(NodeDefId id) {
-        return (NodeDef) nodeDefs.get(id);
+        return nodeDefs.get(id);
     }
 
     /**
-     * @param id
+     * @param id property def id
      * @return the property definition for the given id.
      */
     public PropDef getPropDef(PropDefId id) {
-        return (PropDef) propDefs.get(id);
+        return propDefs.get(id);
     }
 
     /**
@@ -604,77 +603,75 @@
         ps.println();
         ps.println("Registered NodeTypes:");
         ps.println();
-        Iterator iter = registeredNTDefs.values().iterator();
-        while (iter.hasNext()) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+        for (NodeTypeDef ntd : registeredNTDefs.values()) {
             ps.println(ntd.getName());
             Name[] supertypes = ntd.getSupertypes();
             ps.println("\tSupertypes");
-            for (int i = 0; i < supertypes.length; i++) {
-                ps.println("\t\t" + supertypes[i]);
+            for (Name supertype : supertypes) {
+                ps.println("\t\t" + supertype);
             }
             ps.println("\tMixin\t" + ntd.isMixin());
             ps.println("\tOrderableChildNodes\t" + ntd.hasOrderableChildNodes());
             ps.println("\tPrimaryItemName\t" + (ntd.getPrimaryItemName() == null ? "<null>" : ntd.getPrimaryItemName().toString()));
             PropDef[] pd = ntd.getPropertyDefs();
-            for (int i = 0; i < pd.length; i++) {
+            for (PropDef aPd : pd) {
                 ps.print("\tPropertyDefinition");
-                ps.println(" (declared in " + pd[i].getDeclaringNodeType() + ") id=" + pd[i].getId());
-                ps.println("\t\tName\t\t" + (pd[i].definesResidual() ? "*" : pd[i].getName().toString()));
-                String type = pd[i].getRequiredType() == 0 ? "null" : PropertyType.nameFromValue(pd[i].getRequiredType());
+                ps.println(" (declared in " + aPd.getDeclaringNodeType() + ") id=" + aPd.getId());
+                ps.println("\t\tName\t\t" + (aPd.definesResidual() ? "*" : aPd.getName().toString()));
+                String type = aPd.getRequiredType() == 0 ? "null" : PropertyType.nameFromValue(aPd.getRequiredType());
                 ps.println("\t\tRequiredType\t" + type);
-                ValueConstraint[] vca = pd[i].getValueConstraints();
+                QValueConstraint[] vca = aPd.getValueConstraints();
                 StringBuffer constraints = new StringBuffer();
                 if (vca == null) {
                     constraints.append("<null>");
                 } else {
-                    for (int n = 0; n < vca.length; n++) {
+                    for (QValueConstraint aVca : vca) {
                         if (constraints.length() > 0) {
                             constraints.append(", ");
                         }
-                        constraints.append(vca[n].getDefinition());
+                        constraints.append(aVca.getString());
                     }
                 }
                 ps.println("\t\tValueConstraints\t" + constraints.toString());
-                InternalValue[] defVals = pd[i].getDefaultValues();
+                InternalValue[] defVals = aPd.getDefaultValues();
                 StringBuffer defaultValues = new StringBuffer();
                 if (defVals == null) {
                     defaultValues.append("<null>");
                 } else {
-                    for (int n = 0; n < defVals.length; n++) {
+                    for (InternalValue defVal : defVals) {
                         if (defaultValues.length() > 0) {
                             defaultValues.append(", ");
                         }
-                        defaultValues.append(defVals[n].toString());
+                        defaultValues.append(defVal.toString());
                     }
                 }
                 ps.println("\t\tDefaultValue\t" + defaultValues.toString());
-                ps.println("\t\tAutoCreated\t" + pd[i].isAutoCreated());
-                ps.println("\t\tMandatory\t" + pd[i].isMandatory());
-                ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(pd[i].getOnParentVersion()));
-                ps.println("\t\tProtected\t" + pd[i].isProtected());
-                ps.println("\t\tMultiple\t" + pd[i].isMultiple());
+                ps.println("\t\tAutoCreated\t" + aPd.isAutoCreated());
+                ps.println("\t\tMandatory\t" + aPd.isMandatory());
+                ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(aPd.getOnParentVersion()));
+                ps.println("\t\tProtected\t" + aPd.isProtected());
+                ps.println("\t\tMultiple\t" + aPd.isMultiple());
             }
             NodeDef[] nd = ntd.getChildNodeDefs();
-            for (int i = 0; i < nd.length; i++) {
+            for (NodeDef aNd : nd) {
                 ps.print("\tNodeDefinition");
-                ps.println(" (declared in " + nd[i].getDeclaringNodeType() + ") id=" + nd[i].getId());
-                ps.println("\t\tName\t\t" + (nd[i].definesResidual() ? "*" : nd[i].getName().toString()));
-                Name[] reqPrimaryTypes = nd[i].getRequiredPrimaryTypes();
+                ps.println(" (declared in " + aNd.getDeclaringNodeType() + ") id=" + aNd.getId());
+                ps.println("\t\tName\t\t" + (aNd.definesResidual() ? "*" : aNd.getName().toString()));
+                Name[] reqPrimaryTypes = aNd.getRequiredPrimaryTypes();
                 if (reqPrimaryTypes != null && reqPrimaryTypes.length > 0) {
-                    for (int n = 0; n < reqPrimaryTypes.length; n++) {
-                        ps.print("\t\tRequiredPrimaryType\t" + reqPrimaryTypes[n]);
+                    for (Name reqPrimaryType : reqPrimaryTypes) {
+                        ps.print("\t\tRequiredPrimaryType\t" + reqPrimaryType);
                     }
                 }
-                Name defPrimaryType = nd[i].getDefaultPrimaryType();
+                Name defPrimaryType = aNd.getDefaultPrimaryType();
                 if (defPrimaryType != null) {
                     ps.print("\n\t\tDefaultPrimaryType\t" + defPrimaryType);
                 }
-                ps.println("\n\t\tAutoCreated\t" + nd[i].isAutoCreated());
-                ps.println("\t\tMandatory\t" + nd[i].isMandatory());
-                ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(nd[i].getOnParentVersion()));
-                ps.println("\t\tProtected\t" + nd[i].isProtected());
-                ps.println("\t\tAllowsSameNameSiblings\t" + nd[i].allowsSameNameSiblings());
+                ps.println("\n\t\tAutoCreated\t" + aNd.isAutoCreated());
+                ps.println("\t\tMandatory\t" + aNd.isMandatory());
+                ps.println("\t\tOnVersion\t" + OnParentVersionAction.nameFromValue(aNd.getOnParentVersion()));
+                ps.println("\t\tProtected\t" + aNd.isProtected());
+                ps.println("\t\tAllowsSameNameSiblings\t" + aNd.allowsSameNameSiblings());
             }
         }
         ps.println();
@@ -716,10 +713,11 @@
     /**
      * Protected constructor
      *
-     * @param nsReg
-     * @param ntStore
-     * @throws RepositoryException
+     * @param nsReg name space registry
+     * @param ntStore store
+     * @throws RepositoryException if an error occurs
      */
+    @SuppressWarnings("unchecked")
     protected NodeTypeRegistry(NamespaceRegistry nsReg, FileSystem ntStore)
             throws RepositoryException {
         this.nsReg = nsReg;
@@ -996,20 +994,16 @@
     }
 
     /**
-     * @param ntName
-     * @param entCache
-     * @param ntdCache
-     * @return
-     * @throws NoSuchNodeTypeException
+     * @param ntName node type name
      * @param entCache cache of already-built effective node types
      * @param ntdCache cache of node type definitions
-     * @return
+     * @return the effective node type
      * @throws NoSuchNodeTypeException if a node type reference (e.g. a supertype)
      *                                 could not be resolved.
      */
     static EffectiveNodeType getEffectiveNodeType(Name ntName,
                                                   EffectiveNodeTypeCache entCache,
-                                                  Map ntdCache)
+                                                  Map<Name, NodeTypeDef> ntdCache)
             throws NoSuchNodeTypeException {
         // 1. check if effective node type has already been built
         EffectiveNodeTypeCache.Key key = entCache.getKey(new Name[]{ntName});
@@ -1019,7 +1013,7 @@
         }
 
         // 2. make sure we've got the definition of the specified node type
-        NodeTypeDef ntd = (NodeTypeDef) ntdCache.get(ntName);
+        NodeTypeDef ntd = ntdCache.get(ntName);
         if (ntd == null) {
             throw new NoSuchNodeTypeException(ntName.toString());
         }
@@ -1055,7 +1049,7 @@
      */
     static EffectiveNodeType getEffectiveNodeType(Name[] ntNames,
                                                   EffectiveNodeTypeCache entCache,
-                                                  Map ntdCache)
+                                                  Map<Name, NodeTypeDef> ntdCache)
             throws NodeTypeConflictException, NoSuchNodeTypeException {
 
         EffectiveNodeTypeCache.Key key = entCache.getKey(ntNames);
@@ -1066,9 +1060,9 @@
         }
 
         // 2. make sure we've got the definitions of the specified node types
-        for (int i = 0; i < ntNames.length; i++) {
-            if (!ntdCache.containsKey(ntNames[i])) {
-                throw new NoSuchNodeTypeException(ntNames[i].toString());
+        for (Name ntName : ntNames) {
+            if (!ntdCache.containsKey(ntName)) {
+                throw new NoSuchNodeTypeException(ntName.toString());
             }
         }
 
@@ -1097,8 +1091,8 @@
                      * build aggregate of remaining node types through iteration
                      */
                     Name[] remainder = key.getNames();
-                    for (int i = 0; i < remainder.length; i++) {
-                        NodeTypeDef ntd = (NodeTypeDef) ntdCache.get(remainder[i]);
+                    for (Name aRemainder : remainder) {
+                        NodeTypeDef ntd = ntdCache.get(aRemainder);
                         EffectiveNodeType ent =
                                 EffectiveNodeType.create(ntd, entCache, ntdCache);
                         // store new effective node type
@@ -1125,11 +1119,10 @@
     }
 
     static void checkForCircularInheritance(Name[] supertypes,
-                                            Stack inheritanceChain,
-                                            Map ntDefCache)
+                                            Stack<Name> inheritanceChain,
+                                            Map<Name, NodeTypeDef> ntDefCache)
             throws InvalidNodeTypeDefException, RepositoryException {
-        for (int i = 0; i < supertypes.length; i++) {
-            Name nt = supertypes[i];
+        for (Name nt : supertypes) {
             int pos = inheritanceChain.lastIndexOf(nt);
             if (pos >= 0) {
                 StringBuffer buf = new StringBuffer();
@@ -1146,8 +1139,7 @@
             }
 
             try {
-
-                NodeTypeDef ntd = (NodeTypeDef) ntDefCache.get(nt);
+                NodeTypeDef ntd = ntDefCache.get(nt);
                 Name[] sta = ntd.getSupertypes();
                 if (sta.length > 0) {
                     // check recursively
@@ -1164,15 +1156,14 @@
     }
 
     static void checkForCircularNodeAutoCreation(EffectiveNodeType childNodeENT,
-                                                 Stack definingParentNTs,
+                                                 Stack<Name> definingParentNTs,
                                                  EffectiveNodeTypeCache anEntCache,
-                                                 Map ntDefCache)
+                                                 Map<Name, NodeTypeDef> ntDefCache)
             throws InvalidNodeTypeDefException {
         // check for circularity through default node types of auto-created child nodes
         // (node type 'a' defines auto-created child node with default node type 'a')
         Name[] childNodeNTs = childNodeENT.getAllNodeTypes();
-        for (int i = 0; i < childNodeNTs.length; i++) {
-            Name nt = childNodeNTs[i];
+        for (Name nt : childNodeNTs) {
             int pos = definingParentNTs.lastIndexOf(nt);
             if (pos >= 0) {
                 StringBuffer buf = new StringBuffer();
@@ -1193,9 +1184,9 @@
         }
 
         NodeDef[] nodeDefs = childNodeENT.getAutoCreateNodeDefs();
-        for (int i = 0; i < nodeDefs.length; i++) {
-            Name dnt = nodeDefs[i].getDefaultPrimaryType();
-            Name definingNT = nodeDefs[i].getDeclaringNodeType();
+        for (NodeDef nodeDef : nodeDefs) {
+            Name dnt = nodeDef.getDefaultPrimaryType();
+            Name definingNT = nodeDef.getDeclaringNodeType();
             try {
                 if (dnt != null) {
                     // check recursively
@@ -1206,7 +1197,7 @@
                 }
             } catch (NoSuchNodeTypeException nsnte) {
                 String msg = definingNT
-                        + " defines invalid default node type for child node " + nodeDefs[i].getName();
+                        + " defines invalid default node type for child node " + nodeDef.getName();
                 log.debug(msg);
                 throw new InvalidNodeTypeDefException(msg, nsnte);
             }
@@ -1222,6 +1213,7 @@
             throw new InvalidNodeTypeDefException(msg);
         }
 
+        checkNtBaseSubtyping(ntd, registeredNTDefs);
         EffectiveNodeType ent =
                 validateNodeTypeDef(ntd, entCache, registeredNTDefs, nsReg, false);
 
@@ -1234,12 +1226,12 @@
 
         // store property & child node definitions of new node type by id
         PropDef[] pda = ntd.getPropertyDefs();
-        for (int i = 0; i < pda.length; i++) {
-            propDefs.put(pda[i].getId(), pda[i]);
+        for (PropDef aPda : pda) {
+            propDefs.put(aPda.getId(), aPda);
         }
         NodeDef[] nda = ntd.getChildNodeDefs();
-        for (int i = 0; i < nda.length; i++) {
-            nodeDefs.put(nda[i].getId(), nda[i]);
+        for (NodeDef aNda : nda) {
+            nodeDefs.put(aNda.getId(), aNda);
         }
 
         return ent;
@@ -1254,11 +1246,11 @@
      * eventually registered.
      *
      * @param ntDefs collection of <code>NodeTypeDef</code> objects
-     * @throws InvalidNodeTypeDefException
-     * @throws RepositoryException
+     * @throws InvalidNodeTypeDefException if the node type is not valid
+     * @throws RepositoryException if an error occurs
      * @see #registerNodeType
      */
-    private void internalRegister(Collection ntDefs)
+    private void internalRegister(Collection<NodeTypeDef> ntDefs)
             throws InvalidNodeTypeDefException, RepositoryException {
         internalRegister(ntDefs, false);
     }
@@ -1273,19 +1265,15 @@
      * that can be exposed in a property definition because it is
      * system-generated (such as jcr:primaryType in nt:base).
      */
-    private void internalRegister(Collection ntDefs, boolean lenient)
+    private void internalRegister(Collection<NodeTypeDef> ntDefs, boolean lenient)
             throws InvalidNodeTypeDefException, RepositoryException {
 
-        // create working copies of current ent & ntd caches:
-        // cache of pre-built aggregations of node types
-        EffectiveNodeTypeCache tmpENTCache = (EffectiveNodeTypeCache) entCache.clone();
         // map of node type names and node type definitions
-        Map tmpNTDefCache = new HashMap(registeredNTDefs);
+        Map<Name, NodeTypeDef> tmpNTDefCache = new HashMap<Name, NodeTypeDef>(registeredNTDefs);
 
         // temporarily register the node type definition
         // and do some preliminary checks
-        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+        for (NodeTypeDef ntd : ntDefs) {
             Name name = ntd.getName();
             if (name != null && registeredNTDefs.containsKey(name)) {
                 String msg = name + " already exists";
@@ -1296,12 +1284,17 @@
             tmpNTDefCache.put(ntd.getName(), ntd);
         }
 
-        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+        // check if all node type defs have proper nt:base subtyping
+        for (NodeTypeDef ntd : ntDefs) {
+            checkNtBaseSubtyping(ntd, tmpNTDefCache);
+        }
 
-            EffectiveNodeType ent =
-                    validateNodeTypeDef(ntd, tmpENTCache, tmpNTDefCache, nsReg,
-                            lenient);
+        // create working copies of current ent & ntd caches:
+        // cache of pre-built aggregations of node types
+        EffectiveNodeTypeCache tmpENTCache = (EffectiveNodeTypeCache) entCache.clone();
+        for (NodeTypeDef ntd : ntDefs) {
+            EffectiveNodeType ent = validateNodeTypeDef(ntd, tmpENTCache,
+                    tmpNTDefCache, nsReg, lenient);
 
             // store new effective node type instance
             tmpENTCache.put(ent);
@@ -1309,20 +1302,18 @@
 
         // since no exception was thrown so far the definitions are assumed to
         // be valid
-        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
-
+        for (NodeTypeDef ntd : ntDefs) {
             // register clone of node type definition
             ntd = (NodeTypeDef) ntd.clone();
             registeredNTDefs.put(ntd.getName(), ntd);
             // store property & child node definitions of new node type by id
             PropDef[] pda = ntd.getPropertyDefs();
-            for (int i = 0; i < pda.length; i++) {
-                propDefs.put(pda[i].getId(), pda[i]);
+            for (PropDef aPda : pda) {
+                propDefs.put(aPda.getId(), aPda);
             }
             NodeDef[] nda = ntd.getChildNodeDefs();
-            for (int i = 0; i < nda.length; i++) {
-                nodeDefs.put(nda[i].getId(), nda[i]);
+            for (NodeDef aNda : nda) {
+                nodeDefs.put(aNda.getId(), aNda);
             }
         }
 
@@ -1331,7 +1322,7 @@
     }
 
     private void internalUnregister(Name name) throws NoSuchNodeTypeException {
-        NodeTypeDef ntd = (NodeTypeDef) registeredNTDefs.get(name);
+        NodeTypeDef ntd = registeredNTDefs.get(name);
         if (ntd == null) {
             throw new NoSuchNodeTypeException(name.toString());
         }
@@ -1340,19 +1331,18 @@
 
         // remove property & child node definitions
         PropDef[] pda = ntd.getPropertyDefs();
-        for (int i = 0; i < pda.length; i++) {
-            propDefs.remove(pda[i].getId());
+        for (PropDef aPda : pda) {
+            propDefs.remove(aPda.getId());
         }
         NodeDef[] nda = ntd.getChildNodeDefs();
-        for (int i = 0; i < nda.length; i++) {
-            nodeDefs.remove(nda[i].getId());
+        for (NodeDef aNda : nda) {
+            nodeDefs.remove(aNda.getId());
         }
     }
 
-    private void internalUnregister(Collection ntNames)
+    private void internalUnregister(Collection<Name> ntNames)
             throws NoSuchNodeTypeException {
-        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
-            Name name = (Name) iter.next();
+        for (Name name : ntNames) {
             internalUnregister(name);
         }
     }
@@ -1375,21 +1365,72 @@
     }
 
     /**
+     * Checks if the given node type def has the correct supertypes in respect
+     * to nt:base. all mixin nodetypes must not have a nt:base, the primary
+     * ones only if they don't inherit it from another supertype.
+     *
+     * @param ntd the node type def to check
+     * @param ntdCache cache for lookup
+     * @return <code>true</code> if the ntd was modified
+     */
+    private static boolean checkNtBaseSubtyping(NodeTypeDef ntd, Map<Name, NodeTypeDef> ntdCache) {
+        if (NameConstants.NT_BASE.equals(ntd.getName())) {
+            return false;
+        }
+        Set<Name> supertypes = new TreeSet<Name>(Arrays.asList(ntd.getSupertypes()));
+        if (supertypes.isEmpty()) {
+            return false;
+        }
+        boolean modified;
+        if (ntd.isMixin()) {
+            // if mixin, remove possible nt:base supertype
+            modified = supertypes.remove(NameConstants.NT_BASE);
+        } else {
+            // check if all supertypes (except nt:base) are mixins
+            boolean allMixins = true;
+            for (Name name: supertypes) {
+                if (!name.equals(NameConstants.NT_BASE)) {
+                    NodeTypeDef def = ntdCache.get(name);
+                    if (def != null && !def.isMixin()) {
+                        allMixins = false;
+                        break;
+                    }
+                }
+            }
+            if (allMixins) {
+                // ntd is a primary node type and has only mixins as supertypes,
+                // so it needs a nt:base
+                modified = supertypes.add(NameConstants.NT_BASE);
+            } else {
+                // ntd is a primary node type and at least one of the supertypes
+                // is too, so ensure that no nt:base is added. note that the
+                // trivial case, where there would be no supertype left is handled
+                // in the NodeTypeDef directly
+                modified = supertypes.remove(NameConstants.NT_BASE);
+            }
+        }
+        if (modified) {
+            ntd.setSupertypes(supertypes.toArray(new Name[supertypes.size()]));
+        }
+        return modified;
+    }
+
+    /**
      * Validates the specified <code>NodeTypeDef</code> within the context of
      * the two other given collections and returns an <code>EffectiveNodeType</code>.
      *
-     * @param ntd
-     * @param entCache
+     * @param ntd node type definition
+     * @param entCache effective node type cache
      * @param ntdCache cache of 'known' node type definitions, used to resolve dependencies
-     * @param nsReg    namespace registry used for validating qualified names
+     * @param nsReg    namespace registry used for validatingatch names
      * @param lenient flag governing whether validation can be lenient or has to be strict
      * @return an effective node type representation of the specified <code>NodeTypeDef</code>
-     * @throws InvalidNodeTypeDefException
+     * @throws InvalidNodeTypeDefException if the node type is not valid
      * @throws RepositoryException         if another error occurs
      */
     private static EffectiveNodeType validateNodeTypeDef(NodeTypeDef ntd,
                                                          EffectiveNodeTypeCache entCache,
-                                                         Map ntdCache,
+                                                         Map<Name, NodeTypeDef> ntdCache,
                                                          NamespaceRegistry nsReg,
                                                          boolean lenient)
             throws InvalidNodeTypeDefException, RepositoryException {
@@ -1415,21 +1456,21 @@
         // validate supertypes
         Name[] supertypes = ntd.getSupertypes();
         if (supertypes.length > 0) {
-            for (int i = 0; i < supertypes.length; i++) {
-                checkNamespace(supertypes[i], nsReg);
+            for (Name supertype : supertypes) {
+                checkNamespace(supertype, nsReg);
                 /**
                  * simple check for infinite recursion
                  * (won't trap recursion on a deeper inheritance level)
                  */
-                if (name.equals(supertypes[i])) {
+                if (name.equals(supertype)) {
                     String msg = "[" + name + "] invalid supertype: "
-                            + supertypes[i] + " (infinite recursion))";
+                            + supertype + " (infinite recursion))";
                     log.debug(msg);
                     throw new InvalidNodeTypeDefException(msg);
                 }
-                if (!ntdCache.containsKey(supertypes[i])) {
+                if (!ntdCache.containsKey(supertype)) {
                     String msg = "[" + name + "] invalid supertype: "
-                            + supertypes[i];
+                            + supertype;
                     log.debug(msg);
                     throw new InvalidNodeTypeDefException(msg);
                 }
@@ -1439,7 +1480,7 @@
              * check for circularity in inheritance chain
              * ('a' extends 'b' extends 'a')
              */
-            Stack inheritanceChain = new Stack();
+            Stack<Name> inheritanceChain = new Stack<Name>();
             inheritanceChain.push(name);
             checkForCircularInheritance(supertypes, inheritanceChain, ntdCache);
         }
@@ -1458,13 +1499,14 @@
         if (supertypes.length > 0) {
             try {
                 EffectiveNodeType est = getEffectiveNodeType(supertypes, entCache, ntdCache);
-                // make sure that all primary types except nt:base extend from nt:base
-                if (!ntd.isMixin() && !NameConstants.NT_BASE.equals(ntd.getName())
-                        && !est.includesNodeType(NameConstants.NT_BASE)) {
-                    String msg = "[" + name + "] all primary node types except"
-                            + " nt:base itself must be (directly or indirectly) derived from nt:base";
+                // check whether specified node type definition overrides
+                // a supertypes's primaryItem -> illegal (JCR-1947)
+                if (ntd.getPrimaryItemName() != null
+                        && est.getPrimaryItemName() != null) {
+                    String msg = "[" + name + "] primaryItemName is already specified by a supertype and must therefore not be overridden.";
                     log.debug(msg);
                     throw new InvalidNodeTypeDefException(msg);
+
                 }
             } catch (NodeTypeConflictException ntce) {
                 String msg = "[" + name + "] failed to validate supertypes";
@@ -1481,8 +1523,7 @@
 
         // validate property definitions
         PropDef[] pda = ntd.getPropertyDefs();
-        for (int i = 0; i < pda.length; i++) {
-            PropDef pd = pda[i];
+        for (PropDef pd : pda) {
             /**
              * sanity check:
              * make sure declaring node type matches name of node type definition
@@ -1516,11 +1557,11 @@
             InternalValue[] defVals = pd.getDefaultValues();
             if (defVals != null && defVals.length != 0) {
                 int reqType = pd.getRequiredType();
-                for (int j = 0; j < defVals.length; j++) {
+                for (InternalValue defVal : defVals) {
                     if (reqType == PropertyType.UNDEFINED) {
-                        reqType = defVals[j].getType();
+                        reqType = defVal.getType();
                     } else {
-                        if (defVals[j].getType() != reqType) {
+                        if (defVal.getType() != reqType) {
                             String msg = "[" + name + "#" + pd.getName()
                                     + "] type of default value(s) is not consistent with required property type";
                             log.debug(msg);
@@ -1542,23 +1583,22 @@
             }
 
             // check that default values satisfy value constraints
-            ValueConstraint[] constraints = pd.getValueConstraints();
+            QValueConstraint[] constraints = pd.getValueConstraints();
             if (constraints != null && constraints.length > 0) {
                 if (defVals != null && defVals.length > 0) {
                     // check value constraints on every value
-                    for (int j = 0; j < defVals.length; j++) {
+                    for (InternalValue defVal : defVals) {
                         // constraints are OR-ed together
                         boolean satisfied = false;
                         ConstraintViolationException cve = null;
-                        for (int k = 0; k < constraints.length; k++) {
+                        for (QValueConstraint constraint : constraints) {
                             try {
-                                constraints[k].check(defVals[j]);
+                                constraint.check(defVal);
                                 // at least one constraint is satisfied
                                 satisfied = true;
                                 break;
                             } catch (ConstraintViolationException e) {
                                 cve = e;
-                                continue;
                             }
                         }
                         if (!satisfied) {
@@ -1576,13 +1616,15 @@
                  * the specified node type must be registered, with one notable
                  * exception: the node type just being registered
                  */
-                if (pd.getRequiredType() == PropertyType.REFERENCE) {
-                    for (int j = 0; j < constraints.length; j++) {
-                        ReferenceConstraint rc = (ReferenceConstraint) constraints[j];
-                        Name ntName = rc.getNodeTypeName();
+                if (pd.getRequiredType() == PropertyType.REFERENCE
+                        || pd.getRequiredType() == PropertyType.WEAKREFERENCE) {
+                    for (QValueConstraint constraint : constraints) {
+                        Name ntName = NameFactoryImpl.getInstance().create(constraint.getString());
                         if (!name.equals(ntName) && !ntdCache.containsKey(ntName)) {
                             String msg = "[" + name + "#" + pd.getName()
-                                    + "] invalid REFERENCE value constraint '"
+                                    + "] invalid "
+                                    + (pd.getRequiredType() == PropertyType.REFERENCE ? "REFERENCE" : "WEAKREFERENCE")
+                                    + " value constraint '"
                                     + ntName + "' (unknown node type)";
                             log.debug(msg);
                             throw new InvalidNodeTypeDefException(msg);
@@ -1594,8 +1636,7 @@
 
         // validate child-node definitions
         NodeDef[] cnda = ntd.getChildNodeDefs();
-        for (int i = 0; i < cnda.length; i++) {
-            NodeDef cnd = cnda[i];
+        for (NodeDef cnd : cnda) {
             /**
              * sanity check:
              * make sure declaring node type matches name of node type definition
@@ -1664,7 +1705,7 @@
                          * of auto-created child nodes (node type 'a' defines
                          * auto-created child node with default primary type 'a')
                          */
-                        Stack definingNTs = new Stack();
+                        Stack<Name> definingNTs = new Stack<Name>();
                         definingNTs.push(name);
                         checkForCircularNodeAutoCreation(defaultENT, definingNTs, entCache, ntdCache);
                     }
@@ -1684,8 +1725,11 @@
             // check required primary types
             Name[] reqTypes = cnd.getRequiredPrimaryTypes();
             if (reqTypes != null && reqTypes.length > 0) {
-                for (int n = 0; n < reqTypes.length; n++) {
-                    Name rpt = reqTypes[n];
+                for (Name rpt : reqTypes) {
+                    // skip nt:base required types
+                    if (NameConstants.NT_BASE.equals(rpt)) {
+                        continue;
+                    }
                     checkNamespace(rpt, nsReg);
                     referenceToSelf = false;
                     /**
@@ -1787,45 +1831,45 @@
 
     /**
      * Notify the listeners that a node type <code>ntName</code> has been registered.
+     * @param ntName node type name
      */
     private void notifyRegistered(Name ntName) {
         // copy listeners to array to avoid ConcurrentModificationException
-        NodeTypeRegistryListener[] la =
-                (NodeTypeRegistryListener[]) listeners.values().toArray(
+        NodeTypeRegistryListener[] la = listeners.values().toArray(
                         new NodeTypeRegistryListener[listeners.size()]);
-        for (int i = 0; i < la.length; i++) {
-            if (la[i] != null) {
-                la[i].nodeTypeRegistered(ntName);
+        for (NodeTypeRegistryListener aLa : la) {
+            if (aLa != null) {
+                aLa.nodeTypeRegistered(ntName);
             }
         }
     }
 
     /**
      * Notify the listeners that a node type <code>ntName</code> has been re-registered.
+     * @param ntName node type name
      */
     private void notifyReRegistered(Name ntName) {
         // copy listeners to array to avoid ConcurrentModificationException
-        NodeTypeRegistryListener[] la =
-                (NodeTypeRegistryListener[]) listeners.values().toArray(
+        NodeTypeRegistryListener[] la = listeners.values().toArray(
                         new NodeTypeRegistryListener[listeners.size()]);
-        for (int i = 0; i < la.length; i++) {
-            if (la[i] != null) {
-                la[i].nodeTypeReRegistered(ntName);
+        for (NodeTypeRegistryListener aLa : la) {
+            if (aLa != null) {
+                aLa.nodeTypeReRegistered(ntName);
             }
         }
     }
 
     /**
      * Notify the listeners that a node type <code>ntName</code> has been unregistered.
+     * @param ntName node type name
      */
     private void notifyUnregistered(Name ntName) {
         // copy listeners to array to avoid ConcurrentModificationException
-        NodeTypeRegistryListener[] la =
-                (NodeTypeRegistryListener[]) listeners.values().toArray(
+        NodeTypeRegistryListener[] la = listeners.values().toArray(
                         new NodeTypeRegistryListener[listeners.size()]);
-        for (int i = 0; i < la.length; i++) {
-            if (la[i] != null) {
-                la[i].nodeTypeUnregistered(ntName);
+        for (NodeTypeRegistryListener aLa : la) {
+            if (aLa != null) {
+                aLa.nodeTypeUnregistered(ntName);
             }
         }
     }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDef.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDef.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDef.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDef.java Wed Jul  8 13:57:13 2009
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.core.nodetype;
 
 import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.QValueConstraint;
 
 /**
  * <code>PropDef</code> is the internal representation of
@@ -48,7 +49,7 @@
      *
      * @return the array of value constraints.
      */
-    ValueConstraint[] getValueConstraints();
+    QValueConstraint[] getValueConstraints();
 
     /**
      * Returns the array of default values.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDefImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDefImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDefImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/PropDefImpl.java Wed Jul  8 13:57:13 2009
@@ -18,10 +18,15 @@
 
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValueConstraint;
+import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.query.qom.Operator;
+import org.apache.jackrabbit.spi.commons.QPropertyDefinitionImpl;
 
 import javax.jcr.PropertyType;
-import javax.jcr.query.qom.QueryObjectModelConstants;
+import javax.jcr.RepositoryException;
+
 import java.util.Arrays;
 
 /**
@@ -38,7 +43,7 @@
     /**
      * The value constraints.
      */
-    private ValueConstraint[] valueConstraints = ValueConstraint.EMPTY_ARRAY;
+    private QValueConstraint[] valueConstraints = QValueConstraint.EMPTY_ARRAY;
 
     /**
      * The default values.
@@ -79,6 +84,49 @@
     public PropDefImpl() {
     }
 
+    public PropDefImpl(QPropertyDefinition pd) {
+        super(pd);
+        requiredType = pd.getRequiredType();
+        valueConstraints = pd.getValueConstraints();
+        QValue[] vs = pd.getDefaultValues();
+        if (vs != null) {
+            defaultValues = new InternalValue[vs.length];
+            for (int i=0; i<vs.length; i++) {
+                try {
+                    defaultValues[i] = InternalValue.create(vs[i]);
+                } catch (RepositoryException e) {
+                    throw new IllegalStateException("Error while converting default values.", e);
+                }
+            }
+        }
+        multiple = pd.isMultiple();
+        fullTextSearchable = pd.isFullTextSearchable();
+        queryOrderable = pd.isQueryOrderable();
+        queryOperators = pd.getAvailableQueryOperators();
+    }
+
+    /**
+     * Returns the QPropertyDefinition of this PropDef
+     * @return the QPropertyDefinition
+     */
+    public QPropertyDefinition getQPropertyDefinition() {
+        return new QPropertyDefinitionImpl(
+                getName(),
+                getDeclaringNodeType(),
+                isAutoCreated(),
+                isMandatory(),
+                getOnParentVersion(),
+                isProtected(),
+                getDefaultValues(),
+                isMultiple(),
+                getRequiredType(),
+                getValueConstraints(),
+                getAvailableQueryOperators(),
+                isFullTextSearchable(),
+                isQueryOrderable()
+        );
+    }
+
     /**
      * Sets the required type
      *
@@ -95,13 +143,13 @@
      *
      * @param valueConstraints
      */
-    public void setValueConstraints(ValueConstraint[] valueConstraints) {
+    public void setValueConstraints(QValueConstraint[] valueConstraints) {
         // reset id field in order to force lazy recomputation of identifier
         id = null;
         if (valueConstraints != null) {
             this.valueConstraints = valueConstraints;
         } else {
-            this.valueConstraints = ValueConstraint.EMPTY_ARRAY;
+            this.valueConstraints = QValueConstraint.EMPTY_ARRAY;
         }
     }
 
@@ -249,7 +297,7 @@
     /**
      * {@inheritDoc}
      */
-    public ValueConstraint[] getValueConstraints() {
+    public QValueConstraint[] getValueConstraints() {
         return valueConstraints;
     }
 



Mime
View raw message