You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2008/04/22 10:37:10 UTC

svn commit: r650417 - in /jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ nodetype/ state/ xml/

Author: angela
Date: Tue Apr 22 01:37:08 2008
New Revision: 650417

URL: http://svn.apache.org/viewvc?rev=650417&view=rev
Log:
JCR-1547: JCR2SPI: remove dependency to state-package within entprovider interface

Modified:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/DefinitionValidator.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeProvider.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProvider.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProviderImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Tue Apr 22 01:37:08 2008
@@ -29,7 +29,6 @@
 import org.apache.jackrabbit.jcr2spi.state.Status;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl;
 import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.jcr2spi.operation.SetMixin;
 import org.apache.jackrabbit.jcr2spi.operation.AddProperty;
@@ -624,12 +623,8 @@
         VersionException, ConstraintViolationException, LockException, RepositoryException {
         checkIsWritable();
         Name mixinQName = getQName(mixinName);
-        try {
-            if (!canAddMixin(mixinQName)) {
-                throw new ConstraintViolationException("Cannot add '" + mixinName + "' mixin type.");
-            }
-        } catch (NodeTypeConflictException e) {
-            throw new ConstraintViolationException(e.getMessage());
+        if (!canAddMixin(mixinQName)) {
+            throw new ConstraintViolationException("Cannot add '" + mixinName + "' mixin type.");
         }
 
         // get mixin types present in the jcr:mixintypes property without
@@ -663,14 +658,9 @@
         NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(ntName);
         if (mixin.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
             // build effective node type of remaining mixin's & primary type
-            EffectiveNodeType entRemaining;
             Name[] allRemaining = (Name[]) mixinValue.toArray(new Name[mixinValue.size() + 1]);
             allRemaining[mixinValue.size()] = primaryTypeName;
-            try {
-                entRemaining = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(allRemaining);
-            } catch (NodeTypeConflictException e) {
-                throw new ConstraintViolationException(e);
-            }
+            EffectiveNodeType entRemaining = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(allRemaining);
 
             if (!entRemaining.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
                 PropertyIterator iter = getReferences();
@@ -736,9 +726,6 @@
             session.getValidator().checkIsWritable(getNodeState(), ItemStateValidator.CHECK_ALL);
             // then make sure the new mixin would not conflict.
             return canAddMixin(getQName(mixinName));
-        } catch (NodeTypeConflictException e) {
-            log.debug("Cannot add mixin '" + mixinName + "': " + e.getMessage());
-            return false;
         } catch (LockException e) {
             log.debug("Cannot add mixin '" + mixinName + "': " + e.getMessage());
             return false;
@@ -1161,12 +1148,8 @@
         }
 
         // check effective node type
-        try {
-            EffectiveNodeType effnt = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(getNodeState().getNodeTypeNames());
-            return effnt.includesNodeType(qName);
-        } catch (NodeTypeConflictException e) {
-            throw new RepositoryException(e);
-        }
+        EffectiveNodeType effnt = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(getNodeState().getNodeTypeNames());
+        return effnt.includesNodeType(qName);
     }
 
     //-----------------------------------------------------------< ItemImpl >---
@@ -1427,7 +1410,7 @@
     }
 
     private boolean canAddMixin(Name mixinName) throws NoSuchNodeTypeException,
-        NodeTypeConflictException {
+        ConstraintViolationException {
         NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
 
         // first check characteristics of each mixin
@@ -1446,9 +1429,9 @@
         Name[] existingNts = getNodeState().getNodeTypeNames();
         // build effective node type representing primary type including existing mixin's
         EffectiveNodeType entExisting = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(existingNts);
-        
+
         // check if the base type supports adding this mixin
-        if (! entExisting.supportsMixin(mixinName)) {
+        if (!entExisting.supportsMixin(mixinName)) {
             log.debug(mixin.getName() + ": not supported on node type " + primaryTypeName);
             return false;
         }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/DefinitionValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/DefinitionValidator.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/DefinitionValidator.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/DefinitionValidator.java Tue Apr 22 01:37:08 2008
@@ -22,7 +22,6 @@
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.nodetype.InvalidNodeTypeDefException;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.spi.commons.nodetype.ValueConstraint;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
@@ -33,6 +32,7 @@
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.PropertyType;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.ConstraintViolationException;
 
 import java.util.Stack;
 import java.util.Map;
@@ -125,7 +125,7 @@
      * @throws InvalidNodeTypeDefException
      * @throws RepositoryException
      */
-    public EffectiveNodeTypeImpl validateNodeTypeDef(QNodeTypeDefinition ntDef, Map validatedDefs)
+    public EffectiveNodeType validateNodeTypeDef(QNodeTypeDefinition ntDef, Map validatedDefs)
             throws InvalidNodeTypeDefException, RepositoryException {
         /**
          * the effective (i.e. merged and resolved) node type resulting from
@@ -135,7 +135,7 @@
          * will be created already at an earlier stage during the validation
          * of child node definitions
          */
-        EffectiveNodeTypeImpl ent = null;
+        EffectiveNodeType ent = null;
 
         Name name = ntDef.getName();
         if (name == null) {
@@ -199,14 +199,14 @@
                     log.debug(msg);
                     throw new InvalidNodeTypeDefException(msg);
                 }
-            } catch (NodeTypeConflictException ntce) {
+            } catch (ConstraintViolationException e) {
                 String msg = "[" + name + "] failed to validate supertypes";
                 log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg, ntce);
-            } catch (NoSuchNodeTypeException nsnte) {
+                throw new InvalidNodeTypeDefException(msg, e);
+            } catch (NoSuchNodeTypeException e) {
                 String msg = "[" + name + "] failed to validate supertypes";
                 log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg, nsnte);
+                throw new InvalidNodeTypeDefException(msg, e);
             }
         } else {
             // no supertypes specified: has to be either a mixin type or nt:base
@@ -343,7 +343,7 @@
                          * type just being registered; we have to instantiate it
                          * 'manually'
                          */
-                        ent = EffectiveNodeTypeImpl.create(entProvider, ntDef, validatedDefs);
+                        ent = entProvider.getEffectiveNodeType(ntDef, validatedDefs);
                         defaultENT = ent;
                     }
                     if (cnd.isAutoCreated()) {
@@ -356,16 +356,16 @@
                         definingNTs.push(name);
                         checkForCircularNodeAutoCreation(defaultENT, definingNTs, validatedDefs);
                     }
-                } catch (NodeTypeConflictException ntce) {
+                } catch (ConstraintViolationException e) {
                     String msg = "[" + name + "#" + cnd.getName()
                             + "] failed to validate default primary type";
                     log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, ntce);
-                } catch (NoSuchNodeTypeException nsnte) {
+                    throw new InvalidNodeTypeDefException(msg, e);
+                } catch (NoSuchNodeTypeException e) {
                     String msg = "[" + name + "#" + cnd.getName()
                             + "] failed to validate default primary type";
                     log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, nsnte);
+                    throw new InvalidNodeTypeDefException(msg, e);
                 }
             }
 
@@ -418,19 +418,19 @@
                              * instantiate it 'manually'
                              */
                             if (ent == null) {
-                                ent = EffectiveNodeTypeImpl.create(entProvider, ntDef, validatedDefs);
+                                ent = entProvider.getEffectiveNodeType(ntDef, validatedDefs);
                             }
                         }
-                    } catch (NodeTypeConflictException ntce) {
+                    } catch (ConstraintViolationException e) {
                         String msg = "[" + name + "#" + cnd.getName()
                                 + "] failed to validate required primary type constraint";
                         log.debug(msg);
-                        throw new InvalidNodeTypeDefException(msg, ntce);
-                    } catch (NoSuchNodeTypeException nsnte) {
+                        throw new InvalidNodeTypeDefException(msg, e);
+                    } catch (NoSuchNodeTypeException e) {
                         String msg = "[" + name + "#" + cnd.getName()
                                 + "] failed to validate required primary type constraint";
                         log.debug(msg);
-                        throw new InvalidNodeTypeDefException(msg, nsnte);
+                        throw new InvalidNodeTypeDefException(msg, e);
                     }
                 }
             }
@@ -443,15 +443,15 @@
          */
         if (ent == null) {
             try {
-                ent = EffectiveNodeTypeImpl.create(entProvider, ntDef, validatedDefs);
-            } catch (NodeTypeConflictException ntce) {
+                ent = entProvider.getEffectiveNodeType(ntDef, validatedDefs);
+            } catch (ConstraintViolationException e) {
                 String msg = "[" + name + "] failed to resolve node type definition";
                 log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg, ntce);
-            } catch (NoSuchNodeTypeException nsnte) {
+                throw new InvalidNodeTypeDefException(msg, e);
+            } catch (NoSuchNodeTypeException e) {
                 String msg = "[" + name + "] failed to resolve node type definition";
                 log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg, nsnte);
+                throw new InvalidNodeTypeDefException(msg, e);
             }
         }
         return ent;
@@ -548,7 +548,7 @@
                 String msg = definingNT + " defines invalid default node type for child node " + nodeDefs[i].getName();
                 log.debug(msg);
                 throw new InvalidNodeTypeDefException(msg, e);
-            } catch (NodeTypeConflictException e) {
+            } catch (ConstraintViolationException e) {
                 String msg = definingNT + " defines invalid default node type for child node " + nodeDefs[i].getName();
                 log.debug(msg);
                 throw new InvalidNodeTypeDefException(msg, e);

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeImpl.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeImpl.java Tue Apr 22 01:37:08 2008
@@ -20,15 +20,12 @@
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
@@ -36,6 +33,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Map;
+import java.util.HashMap;
 
 /**
  * An <code>EffectiveNodeType</code> represents one or more
@@ -48,174 +46,40 @@
     private static Logger log = LoggerFactory.getLogger(EffectiveNodeTypeImpl.class);
 
     // list of explicitly aggregated {i.e. merged) node types
-    private final TreeSet mergedNodeTypes;
+    private final TreeSet mergedNodeTypes = new TreeSet();
     // list of implicitly aggregated {through inheritance) node types
-    private final TreeSet inheritedNodeTypes;
+    private final TreeSet inheritedNodeTypes = new TreeSet();
     // list of all either explicitly (through aggregation) or implicitly
     // (through inheritance) included node types.
-    private final TreeSet allNodeTypes;
+    private final TreeSet allNodeTypes = new TreeSet();
     // map of named item definitions (maps name to list of definitions)
-    private final HashMap namedItemDefs;
+    private final Map namedItemDefs = new HashMap();
     // list of unnamed item definitions (i.e. residual definitions)
-    private final ArrayList unnamedItemDefs;
+    private final List unnamedItemDefs = new ArrayList();
     // (optional) set of additional mixins supported on node type
     private Set supportedMixins;
 
     /**
-     * private constructor.
-     */
-    private EffectiveNodeTypeImpl() {
-        mergedNodeTypes = new TreeSet();
-        inheritedNodeTypes = new TreeSet();
-        allNodeTypes = new TreeSet();
-        namedItemDefs = new HashMap();
-        unnamedItemDefs = new ArrayList();
-        supportedMixins = null;
-    }
-
-    /**
-     * Factory method: creates an effective node type
-     * representation of a node type definition. Whereas all referenced
-     * node types must exist (i.e. must be registered), the definition itself
-     * is not required to be registered.
-     *
-     * @param entProvider
-     * @param ntd
-     * @param ntdMap
-     * @return
-     * @throws NodeTypeConflictException
-     * @throws NoSuchNodeTypeException
+     * constructor.
      */
-    static EffectiveNodeTypeImpl create(EffectiveNodeTypeProvider entProvider, QNodeTypeDefinition ntd, Map ntdMap)
-            throws NodeTypeConflictException, NoSuchNodeTypeException {
-        // create empty effective node type instance
-        EffectiveNodeTypeImpl ent = new EffectiveNodeTypeImpl();
-        Name ntName = ntd.getName();
-
-        // prepare new instance
-        ent.mergedNodeTypes.add(ntName);
-        ent.allNodeTypes.add(ntName);
-
-        Name[] smixins = ntd.getSupportedMixinTypes();
-    
-        if (smixins != null) {
-            ent.supportedMixins = new HashSet();
-            for (int i = 0; i < smixins.length; i++) {
-                ent.supportedMixins.add(smixins[i]);
-            }
-        }
-        
-        // map of all item definitions (maps id to definition)
-        // used to effectively detect ambiguous child definitions where
-        // ambiguity is defined in terms of definition identity
-        Set itemDefIds = new HashSet();
-
-        QNodeDefinition[] cnda = ntd.getChildNodeDefs();
-        for (int i = 0; i < cnda.length; i++) {
-            // check if child node definition would be ambiguous within
-            // this node type definition
-            if (itemDefIds.contains(cnda[i])) {
-                // conflict
-                String msg;
-                if (cnda[i].definesResidual()) {
-                    msg = ntName + " contains ambiguous residual child node definitions";
-                } else {
-                    msg = ntName + " contains ambiguous definitions for child node named "
-                            + cnda[i].getName();
-                }
-                log.debug(msg);
-                throw new NodeTypeConflictException(msg);
-            } else {
-                itemDefIds.add(cnda[i]);
-            }
-            if (cnda[i].definesResidual()) {
-                // residual node definition
-                ent.unnamedItemDefs.add(cnda[i]);
-            } else {
-                // named node definition
-                Name name = cnda[i].getName();
-                List defs = (List) ent.namedItemDefs.get(name);
-                if (defs == null) {
-                    defs = new ArrayList();
-                    ent.namedItemDefs.put(name, defs);
-                }
-                if (defs.size() > 0) {
-                    /**
-                     * there already exists at least one definition with that
-                     * name; make sure none of them is auto-create
-                     */
-                    for (int j = 0; j < defs.size(); j++) {
-                        QItemDefinition qDef = (QItemDefinition) defs.get(j);
-                        if (cnda[i].isAutoCreated() || qDef.isAutoCreated()) {
-                            // conflict
-                            String msg = "There are more than one 'auto-create' item definitions for '"
-                                    + name + "' in node type '" + ntName + "'";
-                            log.debug(msg);
-                            throw new NodeTypeConflictException(msg);
-                        }
-                    }
-                }
-                defs.add(cnda[i]);
-            }
-        }
-        QPropertyDefinition[] pda = ntd.getPropertyDefs();
-        for (int i = 0; i < pda.length; i++) {
-            // check if property definition would be ambiguous within
-            // this node type definition
-            if (itemDefIds.contains(pda[i])) {
-                // conflict
-                String msg;
-                if (pda[i].definesResidual()) {
-                    msg = ntName + " contains ambiguous residual property definitions";
-                } else {
-                    msg = ntName + " contains ambiguous definitions for property named "
-                            + pda[i].getName();
-                }
-                log.debug(msg);
-                throw new NodeTypeConflictException(msg);
-            } else {
-                itemDefIds.add(pda[i]);
-            }
-            if (pda[i].definesResidual()) {
-                // residual property definition
-                ent.unnamedItemDefs.add(pda[i]);
-            } else {
-                // named property definition
-                Name name = pda[i].getName();
-                List defs = (List) ent.namedItemDefs.get(name);
-                if (defs == null) {
-                    defs = new ArrayList();
-                    ent.namedItemDefs.put(name, defs);
-                }
-                if (defs.size() > 0) {
-                    /**
-                     * there already exists at least one definition with that
-                     * name; make sure none of them is auto-create
-                     */
-                    for (int j = 0; j < defs.size(); j++) {
-                        QItemDefinition qDef = (QItemDefinition) defs.get(j);
-                        if (pda[i].isAutoCreated() || qDef.isAutoCreated()) {
-                            // conflict
-                            String msg = "There are more than one 'auto-create' item definitions for '"
-                                    + name + "' in node type '" + ntName + "'";
-                            log.debug(msg);
-                            throw new NodeTypeConflictException(msg);
-                        }
-                    }
-                }
-                defs.add(pda[i]);
-            }
+    EffectiveNodeTypeImpl(TreeSet mergedNodeTypes, TreeSet inheritedNodeTypes,
+                          TreeSet allNodeTypes, Map namedItemDefs,
+                          List unnamedItemDefs, Set supportedMixins) {
+        this.mergedNodeTypes.addAll(mergedNodeTypes);
+        this.inheritedNodeTypes.addAll(inheritedNodeTypes);
+        this.allNodeTypes.addAll(allNodeTypes);
+        Iterator iter = namedItemDefs.keySet().iterator();
+        while (iter.hasNext()) {
+            Object key = iter.next();
+            List list = (List) namedItemDefs.get(key);
+            this.namedItemDefs.put(key, new ArrayList(list));
         }
+        this.unnamedItemDefs.addAll(unnamedItemDefs);
 
-        // resolve supertypes recursively
-        Name[] supertypes = ntd.getSupertypes();
-        if (supertypes.length > 0) {
-            EffectiveNodeTypeImpl effSuperType = (EffectiveNodeTypeImpl)entProvider.getEffectiveNodeType(supertypes, ntdMap);
-            ent.internalMerge(effSuperType, true);
+        if (supportedMixins != null) {
+            this.supportedMixins = new HashSet();
+            this.supportedMixins.addAll(supportedMixins);
         }
-
-        // we're done
-        return ent;
     }
 
     //--------------------------------------------------< EffectiveNodeType >---
@@ -615,10 +479,10 @@
      *
      * @param other
      * @return
-     * @throws NodeTypeConflictException
+     * @throws ConstraintViolationException
      */
     EffectiveNodeTypeImpl merge(EffectiveNodeTypeImpl other)
-            throws NodeTypeConflictException {
+            throws ConstraintViolationException {
         // create a clone of this instance and perform the merge on
         // the 'clone' to avoid a potentially inconsistant state
         // of this instance if an exception is thrown during
@@ -639,10 +503,10 @@
      * @param supertype true if the merge is a result of inheritance, i.e. <code>other</code>
      *                  represents one or more supertypes of this instance; otherwise false, i.e.
      *                  the merge is the result of an explicit aggregation
-     * @throws NodeTypeConflictException
+     * @throws ConstraintViolationException
      */
-    private synchronized void internalMerge(EffectiveNodeTypeImpl other, boolean supertype)
-            throws NodeTypeConflictException {
+    synchronized void internalMerge(EffectiveNodeTypeImpl other, boolean supertype)
+            throws ConstraintViolationException {
         Name[] nta = other.getAllNodeTypes();
         int includedCount = 0;
         for (int i = 0; i < nta.length; i++) {
@@ -682,7 +546,7 @@
                                     + qItemDef.getDeclaringNodeType()
                                     + "': name collision with auto-create definition";
                             log.debug(msg);
-                            throw new NodeTypeConflictException(msg);
+                            throw new ConstraintViolationException(msg);
                         }
                         // check ambiguous definitions
                         if (qDef.definesNode() == qItemDef.definesNode()) {
@@ -703,7 +567,7 @@
                                             + "they must differ in required type "
                                             + "or cardinality.";
                                     log.debug(msg);
-                                    throw new NodeTypeConflictException(msg);
+                                    throw new ConstraintViolationException(msg);
                                 }
                             } else {
                                 // child node definition
@@ -715,7 +579,7 @@
                                         + qItemDef.getDeclaringNodeType()
                                         + "': ambiguous child node definition. name must differ.";
                                 log.debug(msg);
-                                throw new NodeTypeConflictException(msg);
+                                throw new ConstraintViolationException(msg);
                             }
                         }
                     }
@@ -757,7 +621,7 @@
                                     + existing.getDeclaringNodeType()
                                     + "': ambiguous residual property definition";
                             log.debug(msg);
-                            throw new NodeTypeConflictException(msg);
+                            throw new ConstraintViolationException(msg);
                         }
                     } else {
                         // child node definition
@@ -775,7 +639,7 @@
                                     + existing.getDeclaringNodeType()
                                     + "': ambiguous residual child node definition";
                             log.debug(msg);
-                            throw new NodeTypeConflictException(msg);
+                            throw new ConstraintViolationException(msg);
                         }
                     }
                 }
@@ -816,24 +680,9 @@
     }
 
     protected Object clone() {
-        EffectiveNodeTypeImpl clone = new EffectiveNodeTypeImpl();
-
-        clone.mergedNodeTypes.addAll(mergedNodeTypes);
-        clone.inheritedNodeTypes.addAll(inheritedNodeTypes);
-        clone.allNodeTypes.addAll(allNodeTypes);
-        Iterator iter = namedItemDefs.keySet().iterator();
-        while (iter.hasNext()) {
-            Object key = iter.next();
-            List list = (List) namedItemDefs.get(key);
-            clone.namedItemDefs.put(key, new ArrayList(list));
-        }
-        clone.unnamedItemDefs.addAll(unnamedItemDefs);
-        
-        if (supportedMixins != null) {
-            clone.supportedMixins = new HashSet();
-            clone.supportedMixins.addAll(supportedMixins);
-        }
-
+        EffectiveNodeTypeImpl clone = new EffectiveNodeTypeImpl(mergedNodeTypes,
+                inheritedNodeTypes, allNodeTypes, namedItemDefs, unnamedItemDefs,
+                supportedMixins);
         return clone;
     }
 }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeProvider.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeTypeProvider.java Tue Apr 22 01:37:08 2008
@@ -17,8 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.nodetype;
 
 import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
 
 import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.nodetype.ConstraintViolationException;
@@ -46,31 +45,35 @@
      *
      * @param ntNames
      * @return
-     * @throws NodeTypeConflictException
+     * @throws ConstraintViolationException
      * @throws NoSuchNodeTypeException
      */
     public EffectiveNodeType getEffectiveNodeType(Name[] ntNames)
-            throws NodeTypeConflictException, NoSuchNodeTypeException;
+            throws ConstraintViolationException, NoSuchNodeTypeException;
 
     /**
      * @param ntNames
      * @param ntdMap
      * @return
-     * @throws NodeTypeConflictException
+     * @throws ConstraintViolationException
      * @throws NoSuchNodeTypeException
      */
     public EffectiveNodeType getEffectiveNodeType(Name[] ntNames, Map ntdMap)
-            throws NodeTypeConflictException, NoSuchNodeTypeException;
+            throws ConstraintViolationException, NoSuchNodeTypeException;
 
     /**
-     * Build the effective (i.e. merged and resolved) node type representation
-     * of the specified node's primary and mixin node types.
+     * Builds an effective node type representation from the given node type
+     * definition. Whereas all referenced node types must exist (i.e. must be
+     * present in the specified map), the definition itself is not required to
+     * be registered.
      *
-     * @param nodeState
+     * @param ntd
+     * @param ntdMap
      * @return
+     * @throws ConstraintViolationException
      * @throws NoSuchNodeTypeException
      */
-    public EffectiveNodeType getEffectiveNodeType(NodeState nodeState)
-            throws NoSuchNodeTypeException, ConstraintViolationException;
-
-}
\ No newline at end of file
+    public EffectiveNodeType getEffectiveNodeType(QNodeTypeDefinition ntd,
+                                                  Map ntdMap)
+            throws ConstraintViolationException, NoSuchNodeTypeException;
+}

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProvider.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProvider.java Tue Apr 22 01:37:08 2008
@@ -115,7 +115,7 @@
      * Returns the applicable property definition for a property with the
      * specified name and type. The multiValued flag is not taken into account
      * in the selection algorithm. Other than
-     * <code>{@link #getApplicablePropertyDefinition(Name, int, boolean)}</code>
+     * <code>{@link #getQPropertyDefinition(NodeState, Name, int, boolean)}</code>
      * this method does not take the multiValued flag into account in the
      * selection algorithm. If there more than one applicable definitions then
      * the following rules are applied:
@@ -133,6 +133,7 @@
      * @throws ConstraintViolationException if no applicable property definition
      *                                      could be found
      */
-    public QPropertyDefinition getQPropertyDefinition(NodeState parentState, Name name, int type)
+    public QPropertyDefinition getQPropertyDefinition(NodeState parentState,
+                                                      Name name, int type)
             throws ConstraintViolationException, NoSuchNodeTypeException;
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProviderImpl.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProviderImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionProviderImpl.java Tue Apr 22 01:37:08 2008
@@ -74,7 +74,7 @@
         QNodeDefinition definition;
         try {
             /*
-             Don't use 'getEffectiveNodeType(NodeState) here:
+             Don't use 'getEffectiveNodeType(NodeState.getAllNodeTypeNames()) here:
              for NEW-states the definition is always set upon creation.
              for all other states the definion must be retrieved only taking
              the effective nodetypes present on the parent into account
@@ -97,7 +97,7 @@
      */
     public QNodeDefinition getQNodeDefinition(NodeState parentState, Name name, Name nodeTypeName)
             throws NoSuchNodeTypeException, ConstraintViolationException {
-       EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState);
+       EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState.getAllNodeTypeNames());
        EffectiveNodeType entTarget = getEffectiveNodeType(nodeTypeName);
        return getQNodeDefinition(ent, entTarget, name);
     }
@@ -151,7 +151,7 @@
                                                       Name name, int type,
                                                       boolean multiValued)
             throws ConstraintViolationException, NoSuchNodeTypeException {
-        EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState);
+        EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState.getAllNodeTypeNames());
         return getQPropertyDefinition(ent, name, type, multiValued, false);
     }
 
@@ -161,7 +161,7 @@
     public QPropertyDefinition getQPropertyDefinition(NodeState parentState,
                                                       Name name, int type)
             throws ConstraintViolationException, NoSuchNodeTypeException {
-        EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState);
+        EffectiveNodeType ent = entProvider.getEffectiveNodeType(parentState.getAllNodeTypeNames());
         return getQPropertyDefinition(ent, name, type);
     }
 
@@ -377,4 +377,4 @@
         return match;
     }
 
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java Tue Apr 22 01:37:08 2008
@@ -16,22 +16,18 @@
  */
 package org.apache.jackrabbit.jcr2spi.nodetype;
 
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
 import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.jcr2spi.util.Dumpable;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.Status;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
-import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.QItemDefinition;
 import org.apache.jackrabbit.spi.commons.nodetype.InvalidNodeTypeDefException;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.PropertyType;
@@ -46,8 +42,10 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.TreeSet;
+import java.util.HashMap;
 
 /**
  * A <code>NodeTypeRegistry</code> ...
@@ -163,7 +161,7 @@
     public synchronized EffectiveNodeType registerNodeType(QNodeTypeDefinition ntDef)
             throws InvalidNodeTypeDefException, RepositoryException {
         // validate the new nodetype definition
-        EffectiveNodeTypeImpl ent = validator.validateNodeTypeDef(ntDef, registeredNTDefs);
+        EffectiveNodeType ent = validator.validateNodeTypeDef(ntDef, registeredNTDefs);
 
         // persist new node type definition
         storage.registerNodeTypes(new QNodeTypeDefinition[] {ntDef});
@@ -255,7 +253,7 @@
             throw new NoSuchNodeTypeException(name.toString());
         }
         /* validate new node type definition */
-        EffectiveNodeTypeImpl ent = validator.validateNodeTypeDef(ntd, registeredNTDefs);
+        EffectiveNodeType ent = validator.validateNodeTypeDef(ntd, registeredNTDefs);
 
         // first call reregistering on storage
         storage.reregisterNodeTypes(new QNodeTypeDefinition[]{ntd});
@@ -294,7 +292,7 @@
      * @see EffectiveNodeTypeProvider#getEffectiveNodeType(Name[])
      */
     public synchronized EffectiveNodeType getEffectiveNodeType(Name[] ntNames)
-            throws NodeTypeConflictException, NoSuchNodeTypeException {
+            throws ConstraintViolationException, NoSuchNodeTypeException {
         return getEffectiveNodeType(ntNames, entCache, registeredNTDefs);
     }
 
@@ -302,46 +300,150 @@
      * @see EffectiveNodeTypeProvider#getEffectiveNodeType(Name[], Map)
      */
     public EffectiveNodeType getEffectiveNodeType(Name[] ntNames, Map ntdMap)
-        throws NodeTypeConflictException, NoSuchNodeTypeException {
+        throws ConstraintViolationException, NoSuchNodeTypeException {
         return getEffectiveNodeType(ntNames, entCache, ntdMap);
     }
 
     /**
-     * @see EffectiveNodeTypeProvider#getEffectiveNodeType(NodeState)
-     * @inheritDoc
-     * In case the status of the given node state is not {@link Status#EXISTING}
-     * the transiently added mixin types are taken into account as well.
-     */
-    public EffectiveNodeType getEffectiveNodeType(NodeState nodeState) throws ConstraintViolationException, NoSuchNodeTypeException {
-        try {
-            Name[] allNtNames;
-            if (nodeState.getStatus() == Status.EXISTING) {
-                allNtNames = nodeState.getNodeTypeNames();
+     * @see EffectiveNodeTypeProvider#getEffectiveNodeType(QNodeTypeDefinition, Map)
+     */
+    public EffectiveNodeType getEffectiveNodeType(QNodeTypeDefinition ntd, Map ntdMap)
+            throws ConstraintViolationException, NoSuchNodeTypeException {
+        TreeSet mergedNodeTypes = new TreeSet();
+        TreeSet inheritedNodeTypes = new TreeSet();
+        TreeSet allNodeTypes = new TreeSet();
+        Map namedItemDefs = new HashMap();
+        List unnamedItemDefs = new ArrayList();
+        Set supportedMixins = null;
+
+        Name ntName = ntd.getName();
+        // prepare new instance
+        mergedNodeTypes.add(ntName);
+        allNodeTypes.add(ntName);
+
+        Name[] smixins = ntd.getSupportedMixinTypes();
+
+        if (smixins != null) {
+            supportedMixins = new HashSet();
+            for (int i = 0; i < smixins.length; i++) {
+                supportedMixins.add(smixins[i]);
+            }
+        }
+
+        // map of all item definitions (maps id to definition)
+        // used to effectively detect ambiguous child definitions where
+        // ambiguity is defined in terms of definition identity
+        Set itemDefIds = new HashSet();
+
+        QNodeDefinition[] cnda = ntd.getChildNodeDefs();
+        for (int i = 0; i < cnda.length; i++) {
+            // check if child node definition would be ambiguous within
+            // this node type definition
+            if (itemDefIds.contains(cnda[i])) {
+                // conflict
+                String msg;
+                if (cnda[i].definesResidual()) {
+                    msg = ntName + " contains ambiguous residual child node definitions";
+                } else {
+                    msg = ntName + " contains ambiguous definitions for child node named "
+                            + cnda[i].getName();
+                }
+                log.debug(msg);
+                throw new ConstraintViolationException(msg);
+            } else {
+                itemDefIds.add(cnda[i]);
+            }
+            if (cnda[i].definesResidual()) {
+                // residual node definition
+                unnamedItemDefs.add(cnda[i]);
             } else {
-                // TODO: check if correct (and only used for creating new)
-                Name primaryType = nodeState.getNodeTypeName();
-                allNtNames = new Name[] { primaryType }; // default
-                try {
-                    PropertyEntry pe = nodeState.getNodeEntry().getPropertyEntry(NameConstants.JCR_MIXINTYPES, true);
-                    if (pe != null) {
-                        PropertyState mixins = pe.getPropertyState();
-                        QValue[] values = mixins.getValues();
-                        allNtNames = new Name[values.length + 1];
-                        for (int i = 0; i < values.length; i++) {
-                            allNtNames[i] = values[i].getName();
+                // named node definition
+                Name name = cnda[i].getName();
+                List defs = (List) namedItemDefs.get(name);
+                if (defs == null) {
+                    defs = new ArrayList();
+                    namedItemDefs.put(name, defs);
+                }
+                if (defs.size() > 0) {
+                    /**
+                     * there already exists at least one definition with that
+                     * name; make sure none of them is auto-create
+                     */
+                    for (int j = 0; j < defs.size(); j++) {
+                        QItemDefinition qDef = (QItemDefinition) defs.get(j);
+                        if (cnda[i].isAutoCreated() || qDef.isAutoCreated()) {
+                            // conflict
+                            String msg = "There are more than one 'auto-create' item definitions for '"
+                                    + name + "' in node type '" + ntName + "'";
+                            log.debug(msg);
+                            throw new ConstraintViolationException(msg);
                         }
-                        allNtNames[values.length] = primaryType;
-                    } // else: no jcr:mixinTypes property exists -> ignore
-                } catch (RepositoryException e) {
-                    // unexpected error: ignore
+                    }
                 }
+                defs.add(cnda[i]);
             }
-            return getEffectiveNodeType(allNtNames);
-        } catch (NodeTypeConflictException e) {
-            String msg = "Internal error: failed to build effective node type from node types defined with " + nodeState;
-            log.debug(msg);
-            throw new ConstraintViolationException(msg, e);
         }
+        QPropertyDefinition[] pda = ntd.getPropertyDefs();
+        for (int i = 0; i < pda.length; i++) {
+            // check if property definition would be ambiguous within
+            // this node type definition
+            if (itemDefIds.contains(pda[i])) {
+                // conflict
+                String msg;
+                if (pda[i].definesResidual()) {
+                    msg = ntName + " contains ambiguous residual property definitions";
+                } else {
+                    msg = ntName + " contains ambiguous definitions for property named "
+                            + pda[i].getName();
+                }
+                log.debug(msg);
+                throw new ConstraintViolationException(msg);
+            } else {
+                itemDefIds.add(pda[i]);
+            }
+            if (pda[i].definesResidual()) {
+                // residual property definition
+                unnamedItemDefs.add(pda[i]);
+            } else {
+                // named property definition
+                Name name = pda[i].getName();
+                List defs = (List) namedItemDefs.get(name);
+                if (defs == null) {
+                    defs = new ArrayList();
+                    namedItemDefs.put(name, defs);
+                }
+                if (defs.size() > 0) {
+                    /**
+                     * there already exists at least one definition with that
+                     * name; make sure none of them is auto-create
+                     */
+                    for (int j = 0; j < defs.size(); j++) {
+                        QItemDefinition qDef = (QItemDefinition) defs.get(j);
+                        if (pda[i].isAutoCreated() || qDef.isAutoCreated()) {
+                            // conflict
+                            String msg = "There are more than one 'auto-create' item definitions for '"
+                                    + name + "' in node type '" + ntName + "'";
+                            log.debug(msg);
+                            throw new ConstraintViolationException(msg);
+                        }
+                    }
+                }
+                defs.add(pda[i]);
+            }
+        }
+
+        // create empty effective node type instance
+        EffectiveNodeTypeImpl ent = new EffectiveNodeTypeImpl(mergedNodeTypes,
+                inheritedNodeTypes, allNodeTypes, namedItemDefs,
+                unnamedItemDefs, supportedMixins);
+
+        // resolve supertypes recursively
+        Name[] supertypes = ntd.getSupertypes();
+        if (supertypes.length > 0) {
+            EffectiveNodeTypeImpl effSuperType = (EffectiveNodeTypeImpl) getEffectiveNodeType(supertypes, ntdMap);
+            ent.internalMerge(effSuperType, true);
+        }
+        return ent;
     }
 
     /**
@@ -372,15 +474,15 @@
         // 3. build effective node type
         synchronized (entCache) {
             try {
-                ent = EffectiveNodeTypeImpl.create(this, ntd, ntdCache);
+                ent = getEffectiveNodeType(ntd, ntdCache);
                 // store new effective node type
                 entCache.put(ent);
                 return ent;
-            } catch (NodeTypeConflictException ntce) {
+            } catch (ConstraintViolationException e) {
                 // should never get here as all known node types should be valid!
                 String msg = "Internal error: encountered invalid registered node type " + ntName;
                 log.debug(msg);
-                throw new NoSuchNodeTypeException(msg, ntce);
+                throw new NoSuchNodeTypeException(msg, e);
             }
         }
     }
@@ -390,13 +492,13 @@
      * @param entCache
      * @param ntdCache
      * @return
-     * @throws NodeTypeConflictException
+     * @throws ConstraintViolationException
      * @throws NoSuchNodeTypeException
      */
     private EffectiveNodeType getEffectiveNodeType(Name[] ntNames,
                                                    EffectiveNodeTypeCache entCache,
                                                    Map ntdCache)
-        throws NodeTypeConflictException, NoSuchNodeTypeException {
+        throws ConstraintViolationException, NoSuchNodeTypeException {
 
         EffectiveNodeTypeCache.Key key = entCache.getKey(ntNames);
         // 1. check if aggregate has already been built
@@ -438,13 +540,13 @@
                     Name[] remainder = key.getNames();
                     for (int i = 0; i < remainder.length; i++) {
                         QNodeTypeDefinition ntd = (QNodeTypeDefinition) ntdCache.get(remainder[i]);
-                        EffectiveNodeTypeImpl ent = EffectiveNodeTypeImpl.create(this, ntd, ntdCache);
+                        EffectiveNodeType ent = getEffectiveNodeType(ntd, ntdCache);
                         // store new effective node type
                         entCache.put(ent);
                         if (result == null) {
-                            result = ent;
+                            result = (EffectiveNodeTypeImpl) ent;
                         } else {
-                            result = result.merge(ent);
+                            result = result.merge((EffectiveNodeTypeImpl) ent);
                             // store intermediate result (sub-aggregate)
                             entCache.put(result);
                         }
@@ -462,8 +564,6 @@
         return result;
     }
 
-
-
     //------------------------------------------------------------< private >---
     /**
      * Notify the listeners that a node type <code>ntName</code> has been registered.
@@ -528,7 +628,7 @@
         }
     }
 
-    private void internalRegister(QNodeTypeDefinition ntd, EffectiveNodeTypeImpl ent) {
+    private void internalRegister(QNodeTypeDefinition ntd, EffectiveNodeType ent) {
         // store new effective node type instance if present. otherwise it
         // will be created on demand.
         if (ent != null) {

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java Tue Apr 22 01:37:08 2008
@@ -16,32 +16,31 @@
  */
 package org.apache.jackrabbit.jcr2spi.state;
 
-import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.jcr2spi.ManagerProvider;
 import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
-import org.apache.jackrabbit.jcr2spi.util.LogUtil;
+import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.jcr2spi.security.AccessManager;
-import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.jcr2spi.util.LogUtil;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.PathFactory;
+import org.apache.jackrabbit.spi.QItemDefinition;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.ItemNotFoundException;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.ItemExistsException;
-import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.PathNotFoundException;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
 import javax.jcr.lock.LockException;
-import javax.jcr.version.VersionException;
-import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
-import org.apache.jackrabbit.spi.QItemDefinition;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.Path;
-import org.apache.jackrabbit.spi.PathFactory;
-
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.VersionException;
 
 /**
  * Utility class for validating an item state against constraints
@@ -139,7 +138,8 @@
         }
         // mandatory properties
         // effective node type (primary type incl. mixins)
-        EffectiveNodeType entPrimaryAndMixins = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(nodeState);
+        Name[] ntNames = nodeState.getAllNodeTypeNames();
+        EffectiveNodeType entPrimaryAndMixins = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(ntNames);
         QPropertyDefinition[] pda = entPrimaryAndMixins.getMandatoryQPropertyDefinitions();
         for (int i = 0; i < pda.length; i++) {
             QPropertyDefinition pd = pda[i];
@@ -381,7 +381,8 @@
         // node type constraints
         if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
             // make sure there's an applicable definition for new child node
-            EffectiveNodeType entParent = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(parentState);
+            Name[] ntNames = parentState.getAllNodeTypeNames();
+            EffectiveNodeType entParent = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(ntNames);
             entParent.checkAddNodeConstraints(nodeName, nodeTypeName, mgrProvider.getItemDefinitionProvider());
         }
         // collisions

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java Tue Apr 22 01:37:08 2008
@@ -27,6 +27,7 @@
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.NodeInfo;
+import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -373,6 +374,39 @@
         // primary type
         types[types.length - 1] = getNodeTypeName();
         return types;
+    }
+
+    /**
+     * TODO: clarify usage
+     * In case the status of the given node state is not {@link Status#EXISTING}
+     * the transiently added mixin types are taken into account as well.
+     * 
+     * @return
+     */
+    public synchronized Name[] getAllNodeTypeNames() {
+        Name[] allNtNames;
+        if (getStatus() == Status.EXISTING) {
+            allNtNames = getNodeTypeNames();
+        } else {
+            // TODO: check if correct (and only used for creating new)
+            Name primaryType = getNodeTypeName();
+            allNtNames = new Name[] { primaryType }; // default
+            try {
+                PropertyEntry pe = getNodeEntry().getPropertyEntry(NameConstants.JCR_MIXINTYPES, true);
+                if (pe != null) {
+                    PropertyState mixins = pe.getPropertyState();
+                    QValue[] values = mixins.getValues();
+                    allNtNames = new Name[values.length + 1];
+                    for (int i = 0; i < values.length; i++) {
+                        allNtNames[i] = values[i].getName();
+                    }
+                    allNtNames[values.length] = primaryType;
+                } // else: no jcr:mixinTypes property exists -> ignore
+            } catch (RepositoryException e) {
+                // unexpected error: ignore
+            }
+        }
+        return allNtNames;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java?rev=650417&r1=650416&r2=650417&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java Tue Apr 22 01:37:08 2008
@@ -38,7 +38,6 @@
 import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.jcr2spi.util.ReferenceChangeTracker;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.Path;
@@ -185,7 +184,8 @@
                if (!def.allowsSameNameSiblings()) {
                    // existing doesn't allow same-name siblings, check for conflicts
                    EffectiveNodeTypeProvider provider = session.getEffectiveNodeTypeProvider();
-                   EffectiveNodeType entExisting = provider.getEffectiveNodeType(existing);
+                   Name[] ntNames = existing.getAllNodeTypeNames();
+                   EffectiveNodeType entExisting = provider.getEffectiveNodeType(ntNames);
                    if (def.isProtected() && entExisting.includesNodeType(nodeInfo.getNodeTypeName())) {
                        // skip protected node
                        parents.push(null); // push null onto stack for skipped node
@@ -649,13 +649,9 @@
             return;
         }
         Name[] ntNames = (Name[]) l.toArray(new Name[l.size()]);
-        try {
-            EffectiveNodeType ent = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(ntNames);
-            if (!ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
-                throw new ConstraintViolationException("XML defines jcr:uuid without defining import node to be referenceable.");
-            }
-        } catch (NodeTypeConflictException e) {
-            throw new RepositoryException("Internal error", e);
+        EffectiveNodeType ent = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(ntNames);
+        if (!ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
+            throw new ConstraintViolationException("XML defines jcr:uuid without defining import node to be referenceable.");
         }
     }
 }