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 2006/08/09 12:50:10 UTC

svn commit: r430031 [1/2] - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ nodetype/ state/ version/ xml/

Author: angela
Date: Wed Aug  9 03:50:09 2006
New Revision: 430031

URL: http://svn.apache.org/viewvc?rev=430031&view=rev
Log:
work in progress

- replace ItemImpl by Item in ItemManager interface and adjust
  usages.
- change all setters on ItemState and derived classes from public to
  package private
- NodeState: use collection return value instead of set/list whereever possible
- WorkspaceManager: put ItemStateFactory to a separate class and
  remove unused inner class NodeReferenceImpl 
- add methods to NodeState/PropertyState that avoids return a null
  QItemDefinition and remove corresponding methods from NodeTypeManagerImpl
- remove ItemDefinitionManager.
- VersionHistoryImpl: add safety check if cne for root version really exists
- Fix ImporterImpl: ItemState.getDefinition() may return 'null' value.
  use method instead, that sets the definition if it is still missing.
- javadoc and code formatting

Added:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java   (with props)
Removed:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/ItemDefinitionManager.java
Modified:
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/ImporterImpl.java

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/HierarchyManagerImpl.java Wed Aug  9 03:50:09 2006
@@ -129,7 +129,7 @@
      * @see ZombieHierarchyManager#getChildNodeEntry(NodeState, NodeId)
      */
     protected ChildNodeEntry getChildNodeEntry(NodeState parent,
-                                                         NodeId id) {
+                                               NodeId id) {
         return parent.getChildNodeEntry(id);
     }
 
@@ -149,8 +149,8 @@
      * @see ZombieHierarchyManager#getChildNodeEntry(NodeState, QName, int)
      */
     protected ChildNodeEntry getChildNodeEntry(NodeState parent,
-                                                         QName name,
-                                                         int index) {
+                                               QName name,
+                                               int index) {
         return parent.getChildNodeEntry(name, index);
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java Wed Aug  9 03:50:09 2006
@@ -69,8 +69,6 @@
     protected static final int STATUS_DESTROYED = 2;
     protected static final int STATUS_INVALIDATED = 3;
 
-    private ItemId id;
-
     private int status;
     private ItemState state;
 
@@ -89,7 +87,7 @@
         //DIFF JACKRABBIT: rep = (RepositoryImpl) session.getRepository();
         //DIFF JACKRABBIT: stateMgr = session.getSessionItemStateManager();
         itemStateMgr = session.getSessionItemStateManager();
-        this.id = state.getId();
+
         this.itemMgr = itemManager;
         this.state = state;
         status = STATUS_NORMAL;
@@ -425,7 +423,7 @@
         // copy listeners to array to avoid ConcurrentModificationException
         ItemLifeCycleListener[] la = (ItemLifeCycleListener[]) listeners.values().toArray(new ItemLifeCycleListener[listeners.size()]);
         for (int i = 0; i < la.length; i++) {
-            la[i].itemCreated(id, this);
+            la[i].itemCreated(this);
         }
     }
 
@@ -438,7 +436,7 @@
         ItemLifeCycleListener[] la = (ItemLifeCycleListener[]) listeners.values().toArray(new ItemLifeCycleListener[listeners.size()]);
         for (int i = 0; i < la.length; i++) {
             if (la[i] != null) {
-                la[i].itemInvalidated(id, this);
+                la[i].itemInvalidated(this);
             }
         }
     }
@@ -452,7 +450,7 @@
         ItemLifeCycleListener[] la = (ItemLifeCycleListener[]) listeners.values().toArray(new ItemLifeCycleListener[listeners.size()]);
         for (int i = 0; i < la.length; i++) {
             if (la[i] != null) {
-                la[i].itemDestroyed(id, this);
+                la[i].itemDestroyed(this);
             }
         }
     }
@@ -495,7 +493,7 @@
 
             case STATUS_DESTROYED:
             case STATUS_INVALIDATED:
-                throw new InvalidItemStateException("Item '" + id + "' doesn't exist anymore");
+                throw new InvalidItemStateException("Item '" + getPath() + "' doesn't exist anymore");
         }
     }
 
@@ -564,7 +562,7 @@
      * @return the id of this <code>Item</code>
      */
     public ItemId getId() {
-        return id;
+        return getItemState().getId();
     }
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemLifeCycleListener.java Wed Aug  9 03:50:09 2006
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.jcr2spi;
 
-import org.apache.jackrabbit.spi.ItemId;
-
 /**
  * The <code>ItemLifeCycleListener</code> interface allows an implementing
  * object to be informed about changes on an <code>Item</code> instance.
@@ -29,10 +27,9 @@
     /**
      * Called when an <code>Item</code> instance has been created.
      *
-     * @param id
      * @param item the instance which has been created
      */
-    public void itemCreated(ItemId id, ItemImpl item);
+    public void itemCreated(ItemImpl item);
 
     /**
      * Called when an <code>ItemImpl</code> instance has been invalidated
@@ -43,10 +40,9 @@
      * methods will throw an <code>InvalidItemStateException</code> when called
      * on an 'invalidated' item.
      *
-     * @param id   the id of the instance that has been discarded
      * @param item the instance which has been discarded
      */
-    void itemInvalidated(ItemId id, ItemImpl item);
+    void itemInvalidated(ItemImpl item);
 
     /**
      * Called when an <code>ItemImpl</code> instance has been destroyed
@@ -57,8 +53,7 @@
      * methods will throw an <code>InvalidItemStateException</code> when called
      * on a 'destroyed' item.
      *
-     * @param id   the id of the instance that has been destroyed
      * @param item the instance which has been destroyed
      */
-    void itemDestroyed(ItemId id, ItemImpl item);
+    void itemDestroyed(ItemImpl item);
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java Wed Aug  9 03:50:09 2006
@@ -26,6 +26,7 @@
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.NodeIterator;
 import javax.jcr.PropertyIterator;
+import javax.jcr.Item;
 
 /**
  * <code>ItemManager</code>...
@@ -33,7 +34,7 @@
 public interface ItemManager extends ItemLifeCycleListener {
 
     // DIFF JR: removed 'getRootNode' shortcut
-    
+
     /**
      * Disposes this <code>ItemManager</code> and frees resources.
      */
@@ -63,7 +64,7 @@
      * @throws javax.jcr.AccessDeniedException
      * @throws javax.jcr.RepositoryException
      */
-    public ItemImpl getItem(Path path)
+    public Item getItem(Path path)
         throws PathNotFoundException, AccessDeniedException, RepositoryException;
 
     /**
@@ -74,7 +75,7 @@
      * @throws AccessDeniedException
      * @throws RepositoryException
      */
-    public ItemImpl getItem(ItemState itemState)
+    public Item getItem(ItemState itemState)
         throws ItemNotFoundException, AccessDeniedException, RepositoryException;
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManagerImpl.java Wed Aug  9 03:50:09 2006
@@ -30,6 +30,9 @@
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.commons.collections.map.ReferenceMap;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -39,10 +42,12 @@
 import javax.jcr.PathNotFoundException;
 import javax.jcr.PropertyIterator;
 import javax.jcr.RepositoryException;
+import javax.jcr.Item;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.PropertyDefinition;
 import java.io.PrintStream;
 import java.util.Iterator;
+import java.util.Map;
 
 /**
  * There's one <code>ItemManagerImpl</code> instance per <code>Session</code>
@@ -76,11 +81,11 @@
     //private final ItemStateManager itemStateMgr;
     private final HierarchyManager hierMgr;
 
+    // TODO: TO-BE-FIXED. With SPI_ItemId simple map cannot be used any more
     /**
      * A cache for item instances created by this <code>ItemManagerImpl</code>
      */
-    // TODO: TO-BE-FIXED. Usage of SPI-Id required refactoring of the cache
-    private IdKeyMap itemCache;
+    private Map itemCache;
 
     /**
      * Creates a new per-session instance <code>ItemManagerImpl</code> instance.
@@ -92,19 +97,19 @@
         this.hierMgr = hierMgr;
         this.session = session;
         // setup item cache with weak references to items
-        itemCache = new DefaultIdKeyMap(); // TODO, JR: new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
+        itemCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
     }
 
     //--------------------------------------------------------< ItemManager >---
     /**
-     * @inheritDoc
+     * @see ItemManager#dispose()
      */
     public void dispose() {
         itemCache.clear();
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#itemExists(Path)
      */
     public boolean itemExists(Path path) {
         try {
@@ -124,7 +129,7 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#itemExists(ItemState)
      */
     public boolean itemExists(ItemState itemState) {
         try {
@@ -144,9 +149,9 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#getItem(Path)
      */
-    public synchronized ItemImpl getItem(Path path)
+    public synchronized Item getItem(Path path)
             throws PathNotFoundException, AccessDeniedException, RepositoryException {
         ItemState itemState = hierMgr.getItemState(path);
         try {
@@ -157,9 +162,9 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#getItem(ItemState)
      */
-    public ItemImpl getItem(ItemState itemState) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+    public Item getItem(ItemState itemState) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
         ItemId id = itemState.getId();
         // first try to access item from cache
         ItemImpl item = retrieveItem(id);
@@ -178,7 +183,7 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#hasChildNodes(NodeState)
      */
     public synchronized boolean hasChildNodes(NodeState parentState)
             throws ItemNotFoundException, AccessDeniedException, RepositoryException {
@@ -199,7 +204,7 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#getChildNodes(NodeState)
      */
     public synchronized NodeIterator getChildNodes(NodeState parentState)
             throws ItemNotFoundException, AccessDeniedException, RepositoryException {
@@ -225,7 +230,7 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#hasChildProperties(NodeState)
      */
     public synchronized boolean hasChildProperties(NodeState parentState)
             throws ItemNotFoundException, AccessDeniedException, RepositoryException {
@@ -247,7 +252,7 @@
     }
 
     /**
-     * @inheritDoc
+     * @see ItemManager#getChildProperties(NodeState)
      */
     public synchronized PropertyIterator getChildProperties(NodeState parentState)
             throws ItemNotFoundException, AccessDeniedException, RepositoryException {
@@ -279,43 +284,43 @@
 
     //----------------------------------------------< ItemLifeCycleListener >---
     /**
-     * {@inheritDoc}
+     * @see ItemLifeCycleListener#itemCreated(ItemImpl)
      */
-    public void itemCreated(ItemId id, ItemImpl item) {
+    public void itemCreated(ItemImpl item) {
         if (log.isDebugEnabled()) {
-            log.debug("created item " + id);
+            log.debug("created item " + item);
         }
         // add instance to cache
         cacheItem(item);
     }
 
     /**
-     * {@inheritDoc}
+     * @see ItemLifeCycleListener#itemInvalidated(ItemImpl)
      */
-    public void itemInvalidated(ItemId id, ItemImpl item) {
+    public void itemInvalidated(ItemImpl item) {
         if (log.isDebugEnabled()) {
-            log.debug("invalidated item " + id);
+            log.debug("invalidated item " + item);
         }
         // remove instance from cache
-        evictItem(id);
+        evictItem(item.getId());
     }
 
     /**
-     * {@inheritDoc}
+     * @see ItemLifeCycleListener#itemDestroyed(ItemImpl)
      */
-    public void itemDestroyed(ItemId id, ItemImpl item) {
+    public void itemDestroyed(ItemImpl item) {
         if (log.isDebugEnabled()) {
-            log.debug("destroyed item " + id);
+            log.debug("destroyed item " + item);
         }
         // we're no longer interested in this item
         item.removeLifeCycleListener(this);
         // remove instance from cache
-        evictItem(id);
+        evictItem(item.getId());
     }
 
     //-----------------------------------------------------------< Dumpable >---
     /**
-     * {@inheritDoc}
+     * @see Dumpable#dump(PrintStream)
      */
     public void dump(PrintStream ps) {
         ps.println("ItemManagerImpl (" + this + ")");
@@ -341,6 +346,12 @@
     }
 
     //----------------------------------------------------< private methods >---
+    /**
+     *
+     * @param state
+     * @param removeFromCache
+     * @throws RepositoryException
+     */
     private void checkAccess(ItemState state, boolean removeFromCache) throws RepositoryException {
         // check privileges
         ItemId id = state.getId();
@@ -356,8 +367,12 @@
         }
     }
 
-    private NodeImpl createNodeInstance(NodeState state, NodeDefinition def)
-            throws RepositoryException {
+    private NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
+        // 1. get definition of the specified node
+        QNodeDefinition qnd = state.getDefinition(session.getNodeTypeRegistry());
+        NodeDefinition def = session.getNodeTypeManager().getNodeDefinition(qnd);
+
+        // 2. create instance
         // we want to be informed on life cycle changes of the new node object
         // in order to maintain item cache consistency
         ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{this};
@@ -373,20 +388,16 @@
             // create common node object
             return new NodeImpl(this, session, state, def, listeners);
         }
-
     }
 
-    private NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
-        // 1. get definition of the specified node
-        NodeState parentState = state.getParent();
-        NodeDefinition def = session.getItemDefinitionManager().getNodeDefinition(state, parentState);
-        // 2. create instance
-        return createNodeInstance(state, def);
-    }
+    private PropertyImpl createPropertyInstance(PropertyState state)
+            throws RepositoryException {
+        // 1. get definition for the specified property
+        QPropertyDefinition qpd = state.getDefinition(session.getNodeTypeRegistry());
+        PropertyDefinition def = session.getNodeTypeManager().getPropertyDefinition(qpd);
 
-    private PropertyImpl createPropertyInstance(PropertyState state,
-                                                PropertyDefinition def) {
-        // we want to be informed on life cycle changes of the new property object
+        // 2. create instance
+                // we want to be informed on life cycle changes of the new property object
         // in order to maintain item cache consistency
         ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{this};
         // create property object
@@ -394,17 +405,7 @@
         return prop;
     }
 
-    private PropertyImpl createPropertyInstance(PropertyState state)
-            throws RepositoryException {
-        // 1. get definition for the specified property
-        NodeState parentState = state.getParent();
-        PropertyDefinition def = session.getItemDefinitionManager().getPropertyDefinition(state, parentState);
-
-        // 2. create instance
-        return createPropertyInstance(state, def);
-    }
-
-    //---------------------------------------------------< item cache methods >
+    //-------------------------------------------------< item cache methods >---
 
     /**
      * Returns an item reference from the cache.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Wed Aug  9 03:50:09 2006
@@ -206,8 +206,13 @@
                 String msg = "Cannot add a node to property " + parentPath;
                 log.debug(msg);
                 throw new ConstraintViolationException(msg);
+            } else if (!(parent instanceof NodeImpl)) {
+                String msg = "Incompatible Node object: " + parent + "(" + safeGetJCRPath() + ")";
+                log.debug(msg);
+                throw new RepositoryException(msg);
+            } else {
+                parentNode = (NodeImpl) parent;
             }
-            parentNode = (NodeImpl) parent;
         } catch (AccessDeniedException ade) {
             throw new PathNotFoundException(relPath);
         }
@@ -564,7 +569,7 @@
                 return IteratorHelper.EMPTY;
             }
         } catch (ItemStateException e) {
-            String msg = "Unable to retrieve REFERENCE properties that refer to " + getId();
+            String msg = "Unable to retrieve REFERENCE properties that refer to " + getPath();
             log.debug(msg);
             throw new RepositoryException(msg, e);
         }
@@ -888,7 +893,8 @@
 
             // search nearest ancestor that is referenceable
             NodeImpl referenceableNode = this;
-            while (referenceableNode.getDepth() != Path.ROOT_DEPTH && !referenceableNode.isNodeType(QName.MIX_REFERENCEABLE)) {
+            while (referenceableNode.getDepth() != Path.ROOT_DEPTH
+                && !referenceableNode.isNodeType(QName.MIX_REFERENCEABLE)) {
                 referenceableNode = (NodeImpl) referenceableNode.getParent();
             }
 
@@ -994,7 +1000,8 @@
                 if (parent.isNode()) {
                     try {
                         Path relQPath = parentPath.computeRelativePath(nPath);
-                        nId = session.getIdFactory().createNodeId(((NodeImpl)parent).getNodeId(), relQPath);
+                        NodeId parentId = ((NodeImpl)parent).getNodeId();
+                        nId = session.getIdFactory().createNodeId(parentId, relQPath);
                     } catch (MalformedPathException e) {
                         // should not occur
                         throw new RepositoryException(e);

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java Wed Aug  9 03:50:09 2006
@@ -17,7 +17,7 @@
 package org.apache.jackrabbit.jcr2spi;
 
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl;
-import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionManager;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.jcr2spi.security.SecurityConstants;
 import org.apache.jackrabbit.jcr2spi.security.AccessManager;
 import org.apache.jackrabbit.jcr2spi.state.SessionItemStateManager;
@@ -43,6 +43,8 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.PathFormat;
+import org.apache.jackrabbit.name.NameFormat;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.spi.RepositoryService;
 import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.NodeId;
@@ -256,10 +258,20 @@
      */
     public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException {
         // sanity check performed by getNodeById
-        NodeImpl node = getNodeById(getIdFactory().createNodeId(uuid));
-        if (node.isNodeType(QName.MIX_REFERENCEABLE)) {
+        Node node = getNodeById(getIdFactory().createNodeId(uuid));
+        if (node instanceof NodeImpl && ((NodeImpl)node).isNodeType(QName.MIX_REFERENCEABLE)) {
             return node;
         } else {
+            // fall back
+            try {
+                String mixReferenceable = NameFormat.format(QName.MIX_REFERENCEABLE, getNamespaceResolver());
+                if (node.isNodeType(mixReferenceable)) {
+                    return node;
+                }
+            } catch (NoPrefixDeclaredException e) {
+                // should not occur.
+                throw new RepositoryException(e);
+            }
             // there is a node with that uuid but the node does not expose it
             throw new ItemNotFoundException(uuid);
         }
@@ -274,12 +286,18 @@
      * <code>Session</code> does not have permission to access the node.
      * @throws RepositoryException
      */
-    private NodeImpl getNodeById(NodeId id) throws ItemNotFoundException, RepositoryException {
+    private Node getNodeById(NodeId id) throws ItemNotFoundException, RepositoryException {
         // check sanity of this session
         checkIsAlive();
         try {
             ItemState state = getItemStateManager().getItemState(id);
-            return (NodeImpl) getItemManager().getItem(state);
+            Item item = getItemManager().getItem(state);
+            if (item.isNode()) {
+                return (Node) item;
+            } else {
+                log.error("NodeId '" + id + " does not point to a Node");
+                throw new ItemNotFoundException(id.toString());
+            }
         } catch (AccessDeniedException ade) {
             throw new ItemNotFoundException(id.toString());
         } catch (NoSuchItemStateException e) {
@@ -757,8 +775,8 @@
         return ntManager;
     }
 
-    public ItemDefinitionManager getItemDefinitionManager() {
-        return ntManager;
+    public NodeTypeRegistry getNodeTypeRegistry() {
+        return workspace.getNodeTypeRegistry();
     }
 
     //--------------------------------------------------------------------------

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java Wed Aug  9 03:50:09 2006
@@ -18,7 +18,6 @@
 
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.jcr2spi.state.UpdatableItemStateManager;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
@@ -93,14 +92,11 @@
     private LockManager lockManager;
     private VersionManager versionManager;
 
-    private final ItemStateValidator validator;
-
     public WorkspaceImpl(String name, SessionImpl session, RepositoryService service, SessionInfo sessionInfo) throws RepositoryException {
         this.name = name;
         this.session = session;
 
         wspManager = this.createManager(service, sessionInfo);
-        validator = new ItemStateValidator(getNodeTypeRegistry(), this);
     }
 
     //----------------------------------------------------------< Workspace >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java Wed Aug  9 03:50:09 2006
@@ -24,14 +24,13 @@
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.jcr2spi.state.NoSuchItemStateException;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
 import org.apache.jackrabbit.jcr2spi.state.ChangeLog;
 import org.apache.jackrabbit.jcr2spi.state.UpdatableItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.NodeReferences;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.CachingItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateFactory;
+import org.apache.jackrabbit.jcr2spi.state.WorkspaceItemStateFactory;
 import org.apache.jackrabbit.jcr2spi.operation.OperationVisitor;
 import org.apache.jackrabbit.jcr2spi.operation.AddNode;
 import org.apache.jackrabbit.jcr2spi.operation.AddProperty;
@@ -70,12 +69,8 @@
 import org.apache.jackrabbit.spi.EventIterator;
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.PropertyId;
-import org.apache.jackrabbit.spi.NodeInfo;
-import org.apache.jackrabbit.spi.PropertyInfo;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.IdIterator;
 import org.apache.jackrabbit.value.QValue;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -106,15 +101,12 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collection;
-import java.util.Collections;
 import java.io.InputStream;
-import java.io.IOException;
 
 /**
  * <code>WorkspaceManager</code>...
  */
-public class WorkspaceManager implements UpdatableItemStateManager,
-        ItemStateFactory, NamespaceStorage, NodeTypeStorage, AccessManager {
+public class WorkspaceManager implements UpdatableItemStateManager, NamespaceStorage, NodeTypeStorage, AccessManager {
 
     private static Logger log = LoggerFactory.getLogger(WorkspaceManager.class);
 
@@ -148,7 +140,8 @@
             this.service = service;
             this.sessionInfo = sessionInfo;
 
-            cache = new CachingItemStateManager(this, service.getIdFactory());
+            ItemStateFactory isf = createItemStateFactory();
+            cache = new CachingItemStateManager(isf, service.getIdFactory());
             addEventListener(cache);
 
             nsRegistry = createNamespaceRegistry();
@@ -256,8 +249,11 @@
     public void removeEventListener(InternalEventListener listener) {
         listeners.remove(listener);
     }
-    //--------------------------------------------------------------------------
 
+    //--------------------------------------------------------------------------
+    private ItemStateFactory createItemStateFactory() {
+        return new WorkspaceItemStateFactory(service, sessionInfo);
+    }
 
     private NamespaceRegistryImpl createNamespaceRegistry() throws RepositoryException {
         return new NamespaceRegistryImpl(this, service.getRegisteredNamespaces(sessionInfo));
@@ -453,185 +449,6 @@
         service.unregisterNodeTypes(sessionInfo, nodeTypeNames);
     }
 
-    //---------------------------------------------------< ItemStateFactory >---
-
-    /**
-     * Creates the node with information retrieved from the
-     * <code>RepositoryService</code>.
-     *
-     * @inheritDoc
-     * @see ItemStateFactory#createNodeState(NodeId, ItemStateManager)
-     */
-    public NodeState createNodeState(NodeId nodeId, ItemStateManager ism)
-            throws NoSuchItemStateException, ItemStateException {
-        try {
-            NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
-
-            // get parent
-            NodeId parentId = (info.getParentId() != null) ? info.getParentId() : null;
-            NodeState parent = (parentId != null) ? (NodeState) ism.getItemState(parentId) : null;
-
-            return createNodeState(info, parent);
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
-        } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Creates the node with information retrieved from the
-     * <code>RepositoryService</code>.
-     *
-     * @inheritDoc
-     * @see ItemStateFactory#createNodeState(NodeId, NodeState)
-     */
-    public NodeState createNodeState(NodeId nodeId, NodeState parent)
-            throws NoSuchItemStateException, ItemStateException {
-        try {
-            NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
-            return createNodeState(info, parent);
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
-        } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Creates the node with information retrieved from <code>info</code>.
-     *
-     * @param info   the <code>NodeInfo</code> to use to create the
-     *               <code>NodeState</code>.
-     * @param parent the parent <code>NodeState</code>.
-     * @return the new <code>NodeState</code>.
-     */
-    private NodeState createNodeState(NodeInfo info, NodeState parent)
-            throws NoSuchItemStateException, ItemStateException {
-        try {
-            QName ntName = info.getNodetype();
-
-            // build the node state
-            // NOTE: unable to retrieve definitionId -> needs to be retrieved
-            // by the itemManager upon Node creation.
-            NodeState state = new NodeState(info.getId(), parent, ntName, ItemState.STATUS_EXISTING, false, this);
-            // set mixin nodetypes
-            state.setMixinTypeNames(info.getMixins());
-
-            // references to child items
-            for (IdIterator it = info.getNodeIds(); it.hasNext(); ) {
-                NodeInfo childInfo = service.getNodeInfo(sessionInfo, (NodeId) it.nextId());
-                NodeId childId = childInfo.getId();
-                state.addChildNodeEntry(childInfo.getQName(), childId);
-            }
-
-            // references to properties
-            for (IdIterator it = info.getPropertyIds(); it.hasNext(); ) {
-                PropertyId pId = (PropertyId) it.nextId();
-                state.addPropertyName(pId.getQName());
-            }
-
-            // copied from local-state-mgr TODO... check
-            // register as listener
-            // TODO check if needed
-            //state.addListener(this);
-            return state;
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
-        } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Creates the property with information retrieved from the
-     * <code>RepositoryService</code>.
-     *
-     * @inheritDoc
-     * @see ItemStateFactory#createPropertyState(PropertyId, ItemStateManager)
-     */
-    public PropertyState createPropertyState(PropertyId propertyId,
-                                             ItemStateManager ism)
-            throws NoSuchItemStateException, ItemStateException {
-        try {
-            PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
-            NodeState parent = (NodeState) ism.getItemState(info.getParentId());
-            return createPropertyState(info, parent);
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
-        } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Creates the property with information retrieved from the
-     * <code>RepositoryService</code>.
-     *
-     * @inheritDoc
-     * @see ItemStateFactory#createPropertyState(PropertyId, NodeState)
-     */
-    public PropertyState createPropertyState(PropertyId propertyId,
-                                             NodeState parent)
-            throws NoSuchItemStateException, ItemStateException {
-        try {
-            PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
-            return createPropertyState(info, parent);
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
-        } catch (RepositoryException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Creates the property with information retrieved from <code>info</code>.
-     *
-     * @param info   the <code>PropertyInfo</code> to use to create the
-     *               <code>PropertyState</code>.
-     * @param parent the parent <code>NodeState</code>.
-     * @return the new <code>PropertyState</code>.
-     * @throws ItemStateException if an error occurs while retrieving the
-     *                            <code>PropertyState</code>.
-     */
-    private PropertyState createPropertyState(PropertyInfo info,
-                                              NodeState parent)
-            throws ItemStateException {
-        try {
-            // TODO: pass parent in constructor of PropertyState
-
-            // build the PropertyState
-            // NOTE: unable to retrieve definitionId -> needs to be retrieved
-            // by the itemManager upon Property creation.
-            PropertyState state = new PropertyState(info.getId(), parent, ItemState.STATUS_EXISTING, false);
-            state.setMultiValued(info.isMultiValued());
-            state.setType(info.getType());
-            QValue[] qValues;
-            if (info.getType() == PropertyType.BINARY) {
-                InputStream[] ins = info.getValuesAsStream();
-                qValues = new QValue[ins.length];
-                for (int i = 0; i < ins.length; i++) {
-                    qValues[i] = QValue.create(ins[i]);
-                }
-            } else {
-                String[] str = info.getValues();
-                qValues = new QValue[str.length];
-                for (int i = 0; i < str.length; i++) {
-                    qValues[i] = QValue.create(str[i], info.getType());
-                }
-            }
-
-            state.internalSetValues(qValues);
-
-            // register as listener
-            // TODO check if needed
-            // state.addListener(this);
-            return state;
-        } catch (IOException e) {
-            throw new ItemStateException(e.getMessage(), e);
-        }
-    }
-
     //--------------------------------------------------------------------------
 
     /**
@@ -920,80 +737,4 @@
             return (Event) next();
         }
     }
-
-    /**
-     * <code>NodeReferences</code> represents the references (i.e. properties of
-     * type <code>REFERENCE</code>) to a particular node (denoted by its uuid).
-     */
-    public class NodeReferencesImpl implements NodeReferences {
-
-        /**
-         * identifier of this <code>NodeReferences</code> instance.
-         */
-        private NodeId id;
-
-        /**
-         * list of PropertyId's (i.e. the id's of the properties that refer to
-         * the target node denoted by <code>id.getTargetId()</code>).
-         * <p/>
-         * note that the list can contain duplicate entries because a specific
-         * REFERENCE property can contain multiple references (if it's multi-valued)
-         * to potentially the same target node.
-         */
-        private ArrayList references = new ArrayList();
-
-        /**
-         * Package private constructor
-         *
-         * @param id
-         */
-        private NodeReferencesImpl(NodeId id) {
-            this.id = id;
-        }
-
-        //-------------------------------------------------< NodeReferences >---
-        /**
-         * Returns the identifier of this node references object.
-         *
-         * @return the id of this node references object.
-         */
-        public NodeId getId() {
-            return id;
-        }
-
-        /**
-         * Returns a flag indicating whether this object holds any references
-         *
-         * @return <code>true</code> if this object holds references,
-         *         <code>false</code> otherwise
-         */
-        public boolean hasReferences() {
-            return !references.isEmpty();
-        }
-
-        /**
-         * @return the list of references
-         */
-        public List getReferences() {
-            return Collections.unmodifiableList(references);
-        }
-
-        //--------------------------------------------------------< private >---
-        /**
-         * @param refId
-         */
-        private void addReference(PropertyId refId) {
-            references.add(refId);
-        }
-
-        /**
-         * @param refId
-         * @return <code>true</code> if the reference was removed;
-         *        <code>false</code> otherwise.
-         */
-        private boolean removeReference(PropertyId refId) {
-            return references.remove(refId);
-        }
-    }
-
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ZombieHierarchyManager.java Wed Aug  9 03:50:09 2006
@@ -138,8 +138,7 @@
         // check removed child node entries first
         Iterator iter = parent.getRemovedChildNodeEntries().iterator();
         while (iter.hasNext()) {
-            ChildNodeEntry entry =
-                    (ChildNodeEntry) iter.next();
+            ChildNodeEntry entry = (ChildNodeEntry) iter.next();
             if (entry.getId().equals(id)) {
                 return entry;
             }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeManagerImpl.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeManagerImpl.java Wed Aug  9 03:50:09 2006
@@ -24,9 +24,6 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.NameFormat;
 import org.apache.jackrabbit.util.IteratorHelper;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
-import org.apache.jackrabbit.jcr2spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.jcr2spi.util.Dumpable;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
@@ -55,8 +52,7 @@
  * A <code>NodeTypeManagerImpl</code> implements a session dependant
  * NodeTypeManager.
  */
-public class NodeTypeManagerImpl implements NodeTypeManager, ItemDefinitionManager,
-        NodeTypeRegistryListener, Dumpable {
+public class NodeTypeManagerImpl implements NodeTypeManager, NodeTypeRegistryListener, Dumpable {
 
     /**
      * Logger instance for this class
@@ -109,13 +105,12 @@
         this.ntReg.addListener(this);
         this.valueFactory = valueFactory;
 
-        // initialize ItemDefinitionManager
-        // 1) setup caches with soft references to node type
+        // setup caches with soft references to node type
         ntCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
         pdCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
         ndCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
 
-        // 2) setup root definition and update cache
+        // setup root definition and update cache
         QNodeDefinition rootDef = ntReg.getRootNodeDef();
         NodeDefinition rootNodeDefinition = new NodeDefinitionImpl(rootDef, this, nsResolver);
         ndCache.put(rootDef, rootNodeDefinition);
@@ -153,10 +148,12 @@
         return isRegistered;
     }
 
-    //----------------------------------------------< ItemDefinitionManager >---
-    // DIFF JR: new interface ItemDefinitionManager -> avoid usage of NodeTypeManagerImpl
     /**
-     * @inheritDoc
+     * Retrieve the <code>NodeDefinition</code> for the given
+     * <code>QNodeDefinition</code>.
+     *
+     * @param def
+     * @return
      */
     public NodeDefinition getNodeDefinition(QNodeDefinition def) {
         synchronized (ndCache) {
@@ -170,7 +167,11 @@
     }
 
     /**
-     * @inheritDoc
+     * Retrieve the <code>PropertyDefinition</code> for the given
+     * <code>QPropertyDefinition</code>.
+     *
+     * @param def
+     * @return
      */
     public PropertyDefinition getPropertyDefinition(QPropertyDefinition def) {
         synchronized (pdCache) {
@@ -182,52 +183,7 @@
             return pdi;
         }
     }
-
-    /**
-     * @inheritDoc
-     */
-    // DIFF JACKRABBIT: method added (JR defines similar in ItemManager)
-    public NodeDefinition getNodeDefinition(NodeState nodeState, NodeState parentState) throws RepositoryException {
-        QNodeDefinition def = nodeState.getDefinition();
-        if (def == null) {
-            try {
-                if (parentState == null) {
-                    // special case for root state
-                    def = ntReg.getRootNodeDef();
-                } else {
-                    ChildNodeEntry cne = parentState.getChildNodeEntry(nodeState.getNodeId());
-                    def = ntReg.getEffectiveNodeType(parentState.getNodeTypeNames()).getApplicableNodeDefinition(cne.getName(), nodeState.getNodeTypeName());
-                }
-            } catch (NodeTypeConflictException e) {
-                String msg = "internal error: failed to build effective node type.";
-                log.debug(msg);
-                throw new RepositoryException(msg, e);
-            }
-            // make sure the state has the definition set now
-            nodeState.setDefinition(def);
-        }
-        return getNodeDefinition(def);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    // DIFF JACKRABBIT: method added (JR defines similar in ItemManager)
-    public PropertyDefinition getPropertyDefinition(PropertyState propState, NodeState parentState) throws RepositoryException {
-        QPropertyDefinition def = propState.getDefinition();
-        if (def == null) {
-            try {
-                def = ntReg.getEffectiveNodeType(parentState.getNodeTypeNames()).getApplicablePropertyDefinition(propState.getQName(), propState.getType(), propState.isMultiValued());
-                propState.setDefinition(def);
-            } catch (NodeTypeConflictException e) {
-                String msg = "internal error: failed to build effective node type.";
-                log.debug(msg);
-                throw new RepositoryException(msg, e);
-            }
-        }
-        return getPropertyDefinition(def);
-    }
-
+    
     //-------------------------------------------< NodeTypeRegistryListener >---
     /**
      * {@inheritDoc}

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java Wed Aug  9 03:50:09 2006
@@ -369,7 +369,7 @@
      * if either this item state represents the root node or this item state is
      * 'free floating', i.e. not attached to the repository's hierarchy.
      *
-     * @return the parent <code>NodeState</code>'s Id
+     * @return the parent <code>NodeState</code>
      */
     public abstract NodeState getParent();
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateValidator.java Wed Aug  9 03:50:09 2006
@@ -142,7 +142,7 @@
         EffectiveNodeType entPrimary = ntReg.getEffectiveNodeType(nodeState.getNodeTypeName());
         // effective node type (primary type incl. mixins)
         EffectiveNodeType entPrimaryAndMixins = getEffectiveNodeType(nodeState);
-        QNodeDefinition def = nodeState.getDefinition();
+        QNodeDefinition def = nodeState.getDefinition(ntReg);
 
         // check if primary type satisfies the 'required node types' constraint
         QName[] requiredPrimaryTypes = def.getRequiredPrimaryTypes();
@@ -409,7 +409,8 @@
         VersionException, LockException, ItemNotFoundException,
         ItemExistsException, PathNotFoundException, RepositoryException {
 
-        checkWriteProperty(propState.getParent(), propState.getQName(), propState.getDefinition(), options);
+        QPropertyDefinition def = propState.getDefinition(ntReg);
+        checkWriteProperty(propState.getParent(), propState.getQName(), def, options);
     }
 
     /**
@@ -672,12 +673,13 @@
      * item state indicates that the state is protected.
      * @see QItemDefinition#isProtected()
      */
-    private void checkProtection(ItemState itemState) throws ConstraintViolationException {
+    private void checkProtection(ItemState itemState)
+        throws ConstraintViolationException, RepositoryException {
         QItemDefinition def;
         if (itemState.isNode()) {
-            def = ((NodeState)itemState).getDefinition();
+            def = ((NodeState)itemState).getDefinition(ntReg);
         } else {
-            def = ((PropertyState)itemState).getDefinition();
+            def = ((PropertyState)itemState).getDefinition(ntReg);
         }
         checkProtection(def);
     }
@@ -702,12 +704,13 @@
      * @throws ConstraintViolationException
      * @see #checkProtection(ItemState)
      */
-    private void checkRemoveConstraints(ItemState itemState) throws ConstraintViolationException {
+    private void checkRemoveConstraints(ItemState itemState)
+        throws ConstraintViolationException, RepositoryException {
         QItemDefinition definition;
         if (itemState.isNode()) {
-            definition = ((NodeState)itemState).getDefinition();
+            definition = ((NodeState)itemState).getDefinition(ntReg);
         } else {
-            definition = ((PropertyState)itemState).getDefinition();
+            definition = ((PropertyState)itemState).getDefinition(ntReg);
         }
         checkProtection(definition);
         if (definition.isMandatory()) {
@@ -761,9 +764,10 @@
         } else if (parentState.hasChildNodeEntry(nodeName)) {
             // retrieve the existing node state that ev. conflicts with the new one.
             try {
-                ChildNodeEntry entry = parentState.getChildNodeEntry(nodeName, 1);
-                NodeState conflictingState = entry.getNodeState();
-                QNodeDefinition conflictDef = conflictingState.getDefinition();
+                ChildNodeEntry cne = parentState.getChildNodeEntry(nodeName, Path.INDEX_DEFAULT);
+                // cne must not be null, since existence has been checked before
+                NodeState conflictingState = cne.getNodeState();
+                QNodeDefinition conflictDef = conflictingState.getDefinition(ntReg);
                 QNodeDefinition newDef = getApplicableNodeDefinition(nodeName, nodeTypeName, parentState);
 
                 // check same-name sibling setting of both target and existing node

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java Wed Aug  9 03:50:09 2006
@@ -26,9 +26,13 @@
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
+import javax.jcr.RepositoryException;
 import javax.jcr.ItemExistsException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -68,7 +72,7 @@
      * instance represents the root node.
      */
     private NodeState parent;
-    
+
     /**
      * this node's definition
      */
@@ -152,22 +156,24 @@
             parent = nodeState.parent; // TODO: parent from wrong ism layer
             nodeTypeName = nodeState.nodeTypeName;
             mixinTypeNames = nodeState.mixinTypeNames;
-            def = nodeState.getDefinition();
+            def = nodeState.def;
             // re-create property references
             properties.clear(); // TODO: any more cleanup work to do? try some kind of merging?
-            for (Iterator it = nodeState.getPropertyNames().iterator(); it.hasNext(); ) {
+            Iterator it = nodeState.getPropertyNames().iterator();
+            while (it.hasNext()) {
                 addPropertyName((QName) it.next());
             }
             // re-create child node entries
             childNodeEntries.clear(); // TODO: any mre cleanup work to do? try some kind of merging?
-            for (Iterator it = nodeState.getChildNodeEntries().iterator(); it.hasNext(); ) {
+            it = nodeState.getChildNodeEntries().iterator();
+            while (it.hasNext()) {
                 ChildNodeEntry cne = (ChildNodeEntry) it.next();
                 childNodeEntries.add(cne.getName(), cne.getId());
             }
         }
     }
 
-    //-----------------------------------------------------< public methods >---
+    //----------------------< public READ methods and package private WRITE >---
     /**
      * Determines if this item state represents a node.
      *
@@ -186,6 +192,18 @@
     }
 
     /**
+     * Sets the the parent <code>NodeState</code>.
+     *
+     * @param parent the parent <code>NodeState</code> or <code>null</code>
+     * if either this node state should represent the root node or this node
+     * state should be 'free floating', i.e. detached from the repository's
+     * hierarchy.
+     */
+    void setParent(NodeState parent) {
+        this.parent = parent;
+    }
+
+    /**
      * {@inheritDoc}
      */
     public ItemId getId() {
@@ -201,24 +219,22 @@
     }
 
     /**
-     * Sets the Id of the parent <code>NodeState</code>.
+     * Returns the name of this node's node type.
      *
-     * @param parent the parent <code>NodeState</code> or <code>null</code>
-     * if either this node state should represent the root node or this node
-     * state should be 'free floating', i.e. detached from the repository's
-     * hierarchy.
+     * @return the name of this node's node type.
      */
-    public void setParent(NodeState parent) {
-        this.parent = parent;
+    public QName getNodeTypeName() {
+        return nodeTypeName;
     }
 
     /**
-     * Returns the name of this node's node type.
+     * Set the node type name. Needed for deserialization and should therefore
+     * not change the internal status.
      *
-     * @return the name of this node's node type.
+     * @param nodeTypeName node type name
      */
-    public QName getNodeTypeName() {
-        return nodeTypeName;
+    synchronized void setNodeTypeName(QName nodeTypeName) {
+        this.nodeTypeName = nodeTypeName;
     }
 
     /**
@@ -235,7 +251,7 @@
      *
      * @param mixinTypeNames set of names of mixin types
      */
-    public synchronized void setMixinTypeNames(QName[] mixinTypeNames) {
+    synchronized void setMixinTypeNames(QName[] mixinTypeNames) {
         if (mixinTypeNames != null) {
             this.mixinTypeNames = mixinTypeNames;
         } else {
@@ -259,20 +275,57 @@
     }
 
     /**
-     * Returns the id of the definition applicable to this node state.
-     *
-     * @return the id of the definition
+     * Returns the {@link QNodeDefinition definition} defined for this
+     * node state or <code>null</code> if the definition has not been
+     * set before (i.e. the corresponding item has not been accessed before).
+     *
+     * @return definition of this state
+     * @see #getDefinition(NodeTypeRegistry) for the corresponding method
+     * that never returns <code>null</code>.
      */
     public QNodeDefinition getDefinition() {
         return def;
     }
 
     /**
+     * Returns the definition applicable to this node state. Since the definition
+     * is not defined upon state creation this state may have to retrieve
+     * the definition from the given <code>NodeTypeRegistry</code> first.
+     *
+     * @param ntRegistry
+     * @return the definition of this state
+     * @see #getDefinition()
+     */
+    public QNodeDefinition getDefinition(NodeTypeRegistry ntRegistry)
+        throws RepositoryException {
+        // make sure the state has the definition set now
+        if (def == null) {
+            NodeState parentState = getParent();
+            try {
+                if (parentState == null) {
+                    // special case for root state
+                    def = ntRegistry.getRootNodeDef();
+                } else {
+                    ChildNodeEntry cne = parentState.getChildNodeEntry(getNodeId());
+                    EffectiveNodeType ent = ntRegistry.getEffectiveNodeType(parentState.getNodeTypeNames());
+                    setDefinition(ent.getApplicableNodeDefinition(cne.getName(), getNodeTypeName()));
+                }
+            } catch (NodeTypeConflictException e) {
+                String msg = "internal error: failed to build effective node type.";
+                log.debug(msg);
+                throw new RepositoryException(msg, e);
+            }
+
+        }
+        return def;
+    }
+
+    /**
      * Sets the id of the definition applicable to this node state.
      *
      * @param def the definition
      */
-    public void setDefinition(QNodeDefinition def) {
+    void setDefinition(QNodeDefinition def) {
         this.def = def;
     }
 
@@ -300,18 +353,6 @@
 
     /**
      * Determines if there is a <code>ChildNodeEntry</code> with the
-     * specified <code>NodeId</code>.
-     *
-     * @param id the id of the child node
-     * @return <code>true</code> if there is a <code>ChildNodeEntry</code> with
-     *         the specified <code>name</code>.
-     */
-    public synchronized boolean hasChildNodeEntry(NodeId id) {
-        return childNodeEntries.get(id) != null;
-    }
-
-    /**
-     * Determines if there is a <code>ChildNodeEntry</code> with the
      * specified <code>name</code> and <code>index</code>.
      *
      * @param name  <code>QName</code> object specifying a node name
@@ -324,18 +365,6 @@
     }
 
     /**
-     * Determines if there is a property entry with the specified
-     * <code>QName</code>.
-     *
-     * @param propName <code>QName</code> object specifying a property name
-     * @return <code>true</code> if there is a property entry with the specified
-     *         <code>QName</code>.
-     */
-    public synchronized boolean hasPropertyName(QName propName) {
-        return properties.containsKey(propName);
-    }
-
-    /**
      * Returns the <code>ChildNodeEntry</code> with the specified name and index
      * or <code>null</code> if there's no matching entry.
      *
@@ -363,19 +392,21 @@
     }
 
     /**
-     * Returns a list of <code>ChildNodeEntry</code> objects denoting the
-     * child nodes of this node.
+     * Returns a unmodifiable collection of <code>ChildNodeEntry</code> objects
+     * denoting the child nodes of this node.
      *
-     * @return list of <code>ChildNodeEntry</code> objects
+     * @return collection of <code>ChildNodeEntry</code> objects
      * @see #addChildNodeEntry
      * @see #removeChildNodeEntry
      */
-    public synchronized List getChildNodeEntries() {
-        return Collections.unmodifiableList(childNodeEntries);
+    public synchronized Collection getChildNodeEntries() {
+        // NOTE: List representation of 'ChildNodeEntries' is already unmodifiable
+        return childNodeEntries;
     }
 
     /**
-     * Returns a list of <code>ChildNodeEntry</code>s with the specified name.
+     * Returns a unmodifiable list of <code>ChildNodeEntry</code>s with the
+     * specified name.
      *
      * @param nodeName name of the child node entries that should be returned
      * @return list of <code>ChildNodeEntry</code> objects
@@ -383,7 +414,8 @@
      * @see #removeChildNodeEntry
      */
     public synchronized List getChildNodeEntries(QName nodeName) {
-        return Collections.unmodifiableList(childNodeEntries.get(nodeName));
+        // NOTE: SubList retrieved from 'ChildNodeEntries' is already unmodifiable
+        return childNodeEntries.get(nodeName);
     }
 
     /**
@@ -393,7 +425,7 @@
      * @param id the id the new entry is refering to.
      * @return the newly added <code>ChildNodeEntry</code>
      */
-    public synchronized ChildNodeEntry addChildNodeEntry(QName nodeName,
+    synchronized ChildNodeEntry addChildNodeEntry(QName nodeName,
                                                          NodeId id) {
         ChildNodeEntry entry = childNodeEntries.add(nodeName, id);
         notifyNodeAdded(entry);
@@ -434,7 +466,7 @@
      * @return <code>true</code> if the entry was sucessfully renamed;
      *         otherwise <code>false</code>
      */
-    public synchronized boolean renameChildNodeEntry(QName oldName, int index,
+    synchronized boolean renameChildNodeEntry(QName oldName, int index,
                                                      QName newName) {
         ChildNodeEntry oldEntry = childNodeEntries.remove(oldName, index);
         if (oldEntry != null) {
@@ -454,7 +486,7 @@
      * @return <code>true</code> if the specified child node entry was found
      *         in the list of child node entries and could be removed.
      */
-    public synchronized boolean removeChildNodeEntry(QName nodeName, int index) {
+    synchronized boolean removeChildNodeEntry(QName nodeName, int index) {
         ChildNodeEntry entry = childNodeEntries.remove(nodeName, index);
         if (entry != null) {
             notifyNodeRemoved(entry);
@@ -469,7 +501,7 @@
      * @return <code>true</code> if the specified child node entry was found
      *         in the list of child node entries and could be removed.
      */
-    public synchronized boolean removeChildNodeEntry(NodeId id) {
+    synchronized boolean removeChildNodeEntry(NodeId id) {
         ChildNodeEntry entry = childNodeEntries.remove(id);
         if (entry != null) {
             notifyNodeRemoved(entry);
@@ -480,7 +512,7 @@
     /**
      * Removes all <code>ChildNodeEntry</code>s.
      */
-    public synchronized void removeAllChildNodeEntries() {
+    synchronized void removeAllChildNodeEntries() {
         childNodeEntries.removeAll();
     }
 
@@ -488,7 +520,7 @@
      * Sets the list of <code>ChildNodeEntry</code> objects denoting the
      * child nodes of this node.
      */
-    public synchronized void setChildNodeEntries(List nodeEntries) {
+    synchronized void setChildNodeEntries(List nodeEntries) {
         // re-create child node entries
         childNodeEntries.clear(); // TODO: any mre cleanup work to do? try some kind of merging?
         for (Iterator it = nodeEntries.iterator(); it.hasNext(); ) {
@@ -499,6 +531,18 @@
     }
 
     /**
+     * Determines if there is a property entry with the specified
+     * <code>QName</code>.
+     *
+     * @param propName <code>QName</code> object specifying a property name
+     * @return <code>true</code> if there is a property entry with the specified
+     *         <code>QName</code>.
+     */
+    public synchronized boolean hasPropertyName(QName propName) {
+        return properties.containsKey(propName);
+    }
+
+    /**
      * Returns the names of this node's properties as a set of
      * <code>QNames</code> objects.
      *
@@ -506,7 +550,7 @@
      * @see #addPropertyName
      * @see #removePropertyName
      */
-    public synchronized Set getPropertyNames() {
+    public synchronized Collection getPropertyNames() {
         return Collections.unmodifiableSet(properties.keySet());
     }
 
@@ -526,7 +570,7 @@
      *
      * @param propName <code>QName</code> object specifying the property name
      */
-    public synchronized void addPropertyName(QName propName) {
+    synchronized void addPropertyName(QName propName) {
         properties.put(propName, new PropertyReference(this, propName, isf, idFactory));
     }
 
@@ -561,14 +605,14 @@
      * @return <code>true</code> if the specified property name was found
      *         in the list of property name entries and could be removed.
      */
-    public synchronized boolean removePropertyName(QName propName) {
+    synchronized boolean removePropertyName(QName propName) {
         return properties.remove(propName) != null;
     }
 
     /**
      * Removes all property name entries.
      */
-    public synchronized void removeAllPropertyNames() {
+    synchronized void removeAllPropertyNames() {
         properties.clear();
     }
 
@@ -576,7 +620,7 @@
      * Sets the set of <code>QName</code> objects denoting the
      * properties of this node.
      */
-    public synchronized void setPropertyNames(Set propNames) {
+    synchronized void setPropertyNames(Set propNames) {
         removeAllPropertyNames();
         for (Iterator it = propNames.iterator(); it.hasNext(); ) {
             addPropertyName((QName) it.next());
@@ -584,16 +628,6 @@
     }
 
     /**
-     * Set the node type name. Needed for deserialization and should therefore
-     * not change the internal status.
-     *
-     * @param nodeTypeName node type name
-     */
-    public synchronized void setNodeTypeName(QName nodeTypeName) {
-        this.nodeTypeName = nodeTypeName;
-    }
-
-    /**
      * Returns the property state with the given name.
      *
      * @param propertyName the name of the property state to return.
@@ -608,29 +642,7 @@
         if (propRef == null) {
             throw new NoSuchItemStateException(idFactory.createPropertyId(getNodeId(), propertyName).toString());
         }
-        return (PropertyState) propRef.resolve();
-    }
-
-    /**
-     * Returns the node state with the given relative path.
-     *
-     * @param relPath the relative path (actually PathElement) of the child node
-     *                state.
-     * @return the child node state
-     * @throws NoSuchItemStateException if there is no node state with the given
-     *                                  <code>relPath</code>.
-     * @throws ItemStateException       if an error occurs while retrieving the
-     *                                  node state.
-     */
-    public synchronized NodeState getNodeState(Path.PathElement relPath)
-            throws NoSuchItemStateException, ItemStateException {
-        ChildNodeEntry cne = childNodeEntries.get(relPath.getName(), relPath.getNormalizedIndex());
-        if (cne == null) {
-            Path p = Path.create(relPath.getName(), relPath.getIndex());
-            NodeId id = idFactory.createNodeId(getNodeId(), p);
-            throw new NoSuchItemStateException(id.toString());
-        }
-        return cne.getNodeState();
+        return propRef.getPropertyState();
     }
 
     //---------------------------------------------------------< diff methods >
@@ -809,7 +821,22 @@
         }
     }
 
-    //--------------------------------------------------< ItemState overrides >
+    /**
+     * TODO: find a better way to provide the index of a child node entry
+     * Returns the index of the given <code>ChildNodeEntry</code> and with
+     * <code>name</code>.
+     *
+     * @param name the name of the child node.
+     * @param cne  the <code>ChildNodeEntry</code> instance.
+     * @return the index of the child node entry or <code>0</code> if it is not
+     *         found in this <code>NodeState</code>.
+     */
+    int getChildNodeIndex(QName name, ChildNodeEntry cne) {
+        List sns = childNodeEntries.get(name);
+        return sns.indexOf(cne) + 1;
+    }
+
+    //---------------------------------------------------< Listener support >---
     /**
      * {@inheritDoc}
      * <p/>
@@ -846,22 +873,7 @@
         super.removeListener(listener);
     }
 
-    /**
-     * TODO: find a better way to provide the index of a child node entry
-     * Returns the index of the given <code>ChildNodeEntry</code> and with
-     * <code>name</code>.
-     *
-     * @param name the name of the child node.
-     * @param cne  the <code>ChildNodeEntry</code> instance.
-     * @return the index of the child node entry or <code>0</code> if it is not
-     *         found in this <code>NodeState</code>.
-     */
-    int getChildNodeIndex(QName name, ChildNodeEntry cne) {
-        List sns = childNodeEntries.get(name);
-        return sns.indexOf(cne) + 1;
-    }
-
-    //-------------------------------------------------< misc. helper methods >
+    //----------------------------------------------< Listener notification >---
     /**
      * Notify the listeners that a child node entry has been added
      */
@@ -908,7 +920,7 @@
         }
     }
 
-    //--------------------------------------------------------< inner classes >
+    //------------------------------------------------------< inner classes >---
     /**
      * <code>ChildNodeEntries</code> represents an insertion-ordered
      * collection of <code>ChildNodeEntry</code>s that also maintains
@@ -1405,5 +1417,4 @@
             }
         }
     }
-
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java Wed Aug  9 03:50:09 2006
@@ -18,17 +18,26 @@
 
 import javax.jcr.PropertyType;
 import javax.jcr.ValueFormatException;
+import javax.jcr.RepositoryException;
+
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.value.QValue;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * <code>PropertyState</code> represents the state of a <code>Property</code>.
  */
 public class PropertyState extends ItemState {
 
+    private static Logger log = LoggerFactory.getLogger(PropertyState.class);
+
     /**
      * the id of this property state
      */
@@ -96,13 +105,13 @@
             id = propState.id;
             parent = propState.parent;
             type = propState.type;
-            def = propState.getDefinition();
+            def = propState.def;
             values = propState.values;
             multiValued = propState.multiValued;
         }
     }
 
-    //-------------------------------------------------------< public methods >
+    //----------------------< public READ methods and package private WRITE >---
     /**
      * Determines if this item state represents a node.
      *
@@ -146,25 +155,6 @@
     }
 
     /**
-     * Sets the type of the property value(s)
-     *
-     * @param type the type to be set
-     * @see PropertyType
-     */
-    public void setType(int type) {
-        this.type = type;
-    }
-
-    /**
-     * Sets the flag indicating whether this property is multi-valued.
-     *
-     * @param multiValued flag indicating whether this property is multi-valued
-     */
-    public void setMultiValued(boolean multiValued) {
-        this.multiValued = multiValued;
-    }
-
-    /**
      * Returns the type of the property value(s).
      *
      * @return the type of the property value(s).
@@ -178,6 +168,17 @@
     }
 
     /**
+     * Sets the type of the property value(s)
+     *
+     * @param type the type to be set
+     * @see PropertyType
+     */
+    void setType(int type) {
+        this.type = type;
+    }
+
+
+    /**
      * Returns true if this property is multi-valued, otherwise false.
      *
      * @return true if this property is multi-valued, otherwise false.
@@ -187,29 +188,77 @@
     }
 
     /**
-     * Returns the id of the definition applicable to this property state.
+     * Sets the flag indicating whether this property is multi-valued.
      *
-     * @return the id of the definition
+     * @param multiValued flag indicating whether this property is multi-valued
+     */
+    void setMultiValued(boolean multiValued) {
+        this.multiValued = multiValued;
+    }
+
+
+    /**
+     * Returns the {@link QPropertyDefinition definition} defined for this
+     * property state or <code>null</code> if the definition has not been
+     * set before (i.e. the corresponding item has not been accessed before).
+     *
+     * @return definition of this state
+     * @see #getDefinition(NodeTypeRegistry) for the corresponding method
+     * that never returns <code>null</code>.
      */
     public QPropertyDefinition getDefinition() {
         return def;
     }
 
     /**
+     * Returns the definition applicable to this property state. Since the definition
+     * is not defined upon state creation this state may have to retrieve
+     * the definition from the given <code>NodeTypeRegistry</code> first.
+     *
+     * @param ntRegistry
+     * @return definition of this state
+     * @see #getDefinition()
+     */
+    public QPropertyDefinition getDefinition(NodeTypeRegistry ntRegistry)
+        throws RepositoryException {
+        if (def == null) {
+            try {
+                NodeState parentState = getParent();
+                EffectiveNodeType ent = ntRegistry.getEffectiveNodeType(parentState.getNodeTypeNames());
+                setDefinition(ent.getApplicablePropertyDefinition(getQName(), getType(), isMultiValued()));
+            } catch (NodeTypeConflictException e) {
+                String msg = "internal error: failed to build effective node type.";
+                log.debug(msg);
+                throw new RepositoryException(msg, e);
+            }
+        }
+        return def;
+    }
+
+    /**
      * Sets the id of the definition applicable to this property state.
      *
      * @param def the id of the definition
      */
-    public void setDefinition(QPropertyDefinition def) {
+    void setDefinition(QPropertyDefinition def) {
         this.def = def;
     }
 
     /**
+     * Returns the value(s) of this property.
+     *
+     * @return the value(s) of this property.
+     */
+    public QValue[] getValues() {
+        return values;
+    }
+
+    /**
      * Sets the value(s) of this property.
      *
      * @param values the new values
      */
-    public void setValues(QValue[] values) {
+    void setValues(QValue[] values) {
         internalSetValues(values);
         markModified();
     }
@@ -222,17 +271,8 @@
      *
      * @param values the new values
      */
-    public void internalSetValues(QValue[] values) {
+    void internalSetValues(QValue[] values) {
         this.values = values;
-    }
-
-    /**
-     * Returns the value(s) of this property.
-     *
-     * @return the value(s) of this property.
-     */
-    public QValue[] getValues() {
-        return values;
     }
 
     /**

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java?rev=430031&r1=430030&r2=430031&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java Wed Aug  9 03:50:09 2006
@@ -968,6 +968,11 @@
         // TODO: TO-BE-FIXED. Move with SPI id       
         boolean renameOnly = srcParent.getNodeId().equals(destParent.getNodeId());
         ChildNodeEntry cne = srcParent.getChildNodeEntry(srcState.getNodeId());
+        if (cne == null) {
+            String msg = "Unexpected error: Move source " + LogUtil.safeGetJCRPath(srcParent, nsResolver, hierMgr) + " does not contain a child node entry with the given id" + LogUtil.safeGetJCRPath(srcState, nsResolver, hierMgr);
+            log.error(msg);
+            throw new RepositoryException(msg);
+        }
         QName srcName = cne.getName();
         int srcIndex = cne.getIndex();
         if (renameOnly) {