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/12/05 15:08:07 UTC

svn commit: r482657 [1/2] - in /jackrabbit/trunk/contrib/spi: jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ jcr2spi/src/mai...

Author: angela
Date: Tue Dec  5 06:08:03 2006
New Revision: 482657

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

- NodeInfo does not load information about child-node-entries
  -> add separate SPI call
  -> add initial draft ChildInfo interface
  -> ChildNodeEntries are not built upon creation of the NodeState
  -> ItemStateFactory: add method to retrieve ChildNodeEntries

- respect CacheBehaviour while persisting transient modifications

- LockInfo.getNodeId() -> not used so far -> remove

- SessionItemStateManager: getHierarchyManager() only used by SessionImpl -> moved

- Improve TODO comments
- Javadoc

Added:
    jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java   (with props)
Modified:
    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/WorkspaceManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChildNodeEntries.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/ItemStateFactory.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/state/Status.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewSAXEventGenerator.java
    jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java
    jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/NodeInfo.java
    jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
    jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java
    jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java
    jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
    jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/URIResolverImpl.java

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -1319,7 +1319,7 @@
         try {
             List cne = getNodeState().getChildNodeEntries(nodeName);
             if (definition.allowsSameNameSiblings()) {
-                // TODO: find proper solution. problem with same-name-siblings
+                // TODO: find proper solution. problem with SNSs
                 childState = ((ChildNodeEntry)cne.get(cne.size()-1)).getNodeState();
             } else {
                 childState = ((ChildNodeEntry)cne.get(0)).getNodeState();

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -118,6 +118,7 @@
     private final NodeTypeManagerImpl ntManager;
 
     private final SessionItemStateManager itemStateManager;
+    private final HierarchyManager hierarchyManager;
     private final ItemManager itemManager;
     private final ItemStateValidator validator;
 
@@ -139,10 +140,9 @@
 
         validator = new ItemStateValidator(workspace.getNodeTypeRegistry(), this);
 
-        // build the state mananger
-        itemStateManager = createSessionItemStateManager(workspace.getUpdatableItemStateManager(), nsMappings);
-
-        itemManager = createItemManager(getHierarchyManager());
+        itemStateManager = createSessionItemStateManager(workspace.getUpdatableItemStateManager());
+        hierarchyManager = createHierarchyManager();
+        itemManager = createItemManager();
     }
 
     //--------------------------------------------------< Session interface >---
@@ -677,12 +677,16 @@
         return new WorkspaceImpl(sessionInfo.getWorkspaceName(), this, config, sessionInfo);
     }
 
-    protected SessionItemStateManager createSessionItemStateManager(UpdatableItemStateManager workspaceStateManager, NamespaceResolver nsResolver) {
-        return new SessionItemStateManager(workspaceStateManager, getIdFactory(), getValidator(), nsResolver);
+    protected SessionItemStateManager createSessionItemStateManager(UpdatableItemStateManager workspaceStateManager) {
+        return new SessionItemStateManager(workspaceStateManager, getIdFactory(), getValidator());
+    }
+
+    protected HierarchyManager createHierarchyManager() {
+        return new HierarchyManagerImpl(getItemStateManager(), getNamespaceResolver());
     }
 
-    protected ItemManager createItemManager(HierarchyManager hierarchyMgr) {
-        return new ItemManagerImpl(hierarchyMgr, this);
+    protected ItemManager createItemManager() {
+        return new ItemManagerImpl(getHierarchyManager(), this);
     }
 
     //---------------------------------------------------< ManagerProvider > ---
@@ -691,7 +695,7 @@
     }
 
     public HierarchyManager getHierarchyManager() {
-        return itemStateManager.getHierarchyManager();
+        return hierarchyManager;
     }
 
     public ItemStateManager getItemStateManager() {

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -218,8 +218,6 @@
         // TODO: JSR170 defines that a token can be present with one session only.
         //       however, we cannot find out about another session holding the lock.
         //       and neither knows the server, which session is holding a lock token.
-        // TODO: check if throwing would be more appropriate
-        throw new UnsupportedRepositoryOperationException("Session.addLockToken is not possible on the client.");
         */
     }
 
@@ -448,7 +446,7 @@
             Sync eventSignal;
             synchronized (updateMonitor) {
                 new OperationVisitorImpl(sessionInfo).execute(changes);
-                changes.persisted();
+                changes.persisted(cacheBehaviour);
                 eventSignal = getEventPollingRequest();
             }
             try {
@@ -459,7 +457,7 @@
             }
         } else {
             new OperationVisitorImpl(sessionInfo).execute(changes);
-            changes.persisted();
+            changes.persisted(cacheBehaviour);
         }
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java Tue Dec  5 06:08:03 2006
@@ -73,8 +73,9 @@
                 NodeState rootState = destMgrProvider.getItemStateManager().getRootState();
                 rootState.invalidate(true);
             } catch (ItemStateException e) {
-                // TODO: fallback behaviour?
                 log.error("Cannot invalidate root state.", e.getMessage());
+                // fallback
+                super.persisted();
             }
         } else {
             super.persisted();

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java Tue Dec  5 06:08:03 2006
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.jcr2spi.state;
 
 import org.apache.jackrabbit.jcr2spi.operation.Operation;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 
 import javax.jcr.nodetype.ConstraintViolationException;
 import java.util.Iterator;
@@ -110,11 +111,11 @@
 
     /**
      * Call this method when this change log has been sucessfully persisted.
-     * This implementation will call {@link ItemState#persisted(ChangeLog)
+     * This implementation will call {@link ItemState#persisted(ChangeLog, CacheBehaviour)
      * ItemState.refresh(this)} on the target item of this change log.
      */
-    public void persisted() {
-        target.persisted(this);
+    public void persisted(CacheBehaviour cacheBehaviour) {
+        target.persisted(this, cacheBehaviour);
     }
 
     //----------------------< Retrieve information present in the ChangeLog >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChildNodeEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChildNodeEntries.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChildNodeEntries.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChildNodeEntries.java Tue Dec  5 06:08:03 2006
@@ -70,7 +70,20 @@
     ChildNodeEntries(NodeState nodeState) {
         this.nodeState = nodeState;
     }
-    
+
+    /**
+     * Create <code>ChildNodeEntries</code> for the given node state.
+     *
+     * @param nodeState
+     */
+    ChildNodeEntries(NodeState nodeState, ChildNodeEntries base) {
+        this.nodeState = nodeState;
+        for (Iterator it = base.iterator(); it.hasNext();) {
+            ChildNodeEntry cne = (ChildNodeEntry) it.next();
+            add(cne.getName(), cne.getUUID(), cne.getIndex());
+        }
+    }
+
     /**
      *
      * @param name
@@ -288,8 +301,8 @@
      * @return
      */
     ChildNodeEntry add(QName nodeName, String uuid, int index) {
-        ChildNodeEntry cne = add(nodeName, uuid);
-        // TODO: in case of SNS, move new cne to the right position.
+        ChildNodeEntry cne = ChildNodeReference.create(nodeState, nodeName, uuid, nodeState.isf, nodeState.idFactory);
+        add(cne, index);
         return cne;
     }
 
@@ -305,21 +318,6 @@
         add(cne);
         return cne;
     }
-
-    /**
-     * Adds a <code>ChildNodeEntry</code> for a child node with the given
-     * name and an optional <code>uuid</code>.
-     *
-     * @param nodeName The name of the child node.
-     * @param uuid The UUID of the child node if it can be identified with a UUID;
-     * otherwise <code>null</code>.
-     * @return the created ChildNodeEntry.
-     */
-    private ChildNodeEntry add(QName nodeName, String uuid) {
-        ChildNodeEntry cne = ChildNodeReference.create(nodeState, nodeName, uuid, nodeState.isf, nodeState.idFactory);
-        add(cne);
-        return cne;
-    }
     
     /**
      * Adds a <code>ChildNodeEntry</code> to the end of the list.
@@ -353,6 +351,49 @@
     }
 
     /**
+     * Adds a <code>ChildNodeEntry</code>. If an entry with the given index
+     * already exists, the the new sibling is inserted before.
+     *
+     * @param cne the <code>ChildNodeEntry</code> to add.
+     */
+    private void add(ChildNodeEntry cne, int index) {
+        QName nodeName = cne.getName();
+
+        // retrieve ev. sibling node with same index
+        // if index is 'undefined' behave just as '#add(ChildNodeEntry).
+        LinkedEntries.LinkNode existing = (index < Path.INDEX_DEFAULT) ? null : getLinkNode(nodeName, index);
+
+        // add new entry (same as #add(ChildNodeEntry)
+        List siblings = null;
+        Object obj = nameMap.get(nodeName);
+        if (obj != null) {
+            if (obj instanceof List) {
+                // map entry is a list of siblings
+                siblings = (ArrayList) obj;
+            } else {
+                // map entry is a single child node entry,
+                // convert to siblings list
+                siblings = new ArrayList();
+                siblings.add(obj);
+                nameMap.put(nodeName, siblings);
+            }
+        }
+
+        LinkedEntries.LinkNode ln = entries.add(cne);
+        if (siblings != null) {
+            siblings.add(ln);
+        } else {
+            nameMap.put(nodeName, ln);
+        }
+
+        // if new entry must be inserted instead of appended at the end
+        // reorder entries now
+        if (existing != null) {
+            reorder(obj, ln, existing);
+        }
+    }
+
+    /**
      * Removes the child node entry with the given <code>nodeName</code> and
      * <code>index</code>.
      *
@@ -436,14 +477,6 @@
     }
 
     /**
-     * Removes all child node entries
-     */
-    void removeAll() {
-        nameMap.clear();
-        entries.clear();
-    }
-
-    /**
      * Reorders an existing <code>NodeState</code> before another
      * <code>NodeState</code>. If <code>beforeNode</code> is
      * <code>null</code> <code>insertNode</code> is moved to the end of the
@@ -463,19 +496,28 @@
         // the link node where insertLN is ordered before
         LinkedEntries.LinkNode beforeLN = (beforeNode != null) ? getLinkNode(beforeNode) : null;
 
+        reorder(insertObj, insertLN, beforeLN);
+    }
+
+    /**
+     *
+     * @param insertObj
+     * @param insertLN
+     * @param beforeLN
+     */
+    private void reorder(Object insertObj, LinkedEntries.LinkNode insertLN, LinkedEntries.LinkNode beforeLN) {
         if (insertObj instanceof List) {
             // adapt name lookup lists
             List insertList = (List) insertObj;
-            if (beforeNode == null) {
+            if (beforeLN == null) {
                 // simply move to end of list
                 insertList.remove(insertLN);
                 insertList.add(insertLN);
             } else {
                 // move based on position of beforeLN
-
                 // count our same name siblings until we reach beforeLN
                 int snsCount = 0;
-                QName insertName = insertNode.getQName();
+                QName insertName = insertLN.getChildNodeEntry().getName();
                 for (Iterator it = entries.linkNodeIterator(); it.hasNext(); ) {
                     LinkedEntries.LinkNode ln = (LinkedEntries.LinkNode) it.next();
                     if (ln == beforeLN) {
@@ -522,7 +564,7 @@
      * state name or due to missing availability of the <code>ChildNodeEntry</code>.
      *
      * @param nodeState the <code>NodeState</code> that is compared to the
-     * resolution of any ChildNodeEntry that matches by name.
+     * resolution of any <code>ChildNodeEntry</code> that matches by name.
      * @return the matching <code>LinkNode</code>.
      * @throws NoSuchItemStateException if none of the <code>LinkNode</code>s
      * matches.
@@ -563,6 +605,42 @@
         throw new NoSuchItemStateException(nodeState.getQName().toString());
     }
 
+    /**
+     * Returns the matching <code>LinkNode</code> from a list or a single
+     * <code>LinkNode</code>. This method will return <code>null</code>
+     * if none of the entries matches.
+     *
+     * @param name
+     * @param index
+     * @return the matching <code>LinkNode</code> or <code>null</code>.
+     */
+    private LinkedEntries.LinkNode getLinkNode(QName name, int index) {
+        Object listOrLinkNode = nameMap.get(name);
+        if (listOrLinkNode == null) {
+            // no matching child node entry
+            return null;
+        }
+
+        if (listOrLinkNode instanceof List) {
+            // has same name sibling
+            for (Iterator it = ((List) listOrLinkNode).iterator(); it.hasNext();) {
+                LinkedEntries.LinkNode n = (LinkedEntries.LinkNode) it.next();
+                ChildNodeEntry cne = n.getChildNodeEntry();
+                if (cne.getIndex() == index) {
+                    return n;
+                }
+            }
+        } else {
+            // single child node with this name
+            ChildNodeEntry cne = ((LinkedEntries.LinkNode) listOrLinkNode).getChildNodeEntry();
+            if (cne.getIndex() == index) {
+                return (LinkedEntries.LinkNode) listOrLinkNode;
+            }
+        }
+
+        // no matching entry
+        return null;
+    }
     //--------------------------------------------< unmodifiable Collection >---
     /**
      * @see Collection#contains(Object)

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -23,6 +23,7 @@
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -88,8 +89,8 @@
      * @param parent
      * @param initialStatus the initial status of the item state object
      */
-    protected ItemState(NodeState parent, int initialStatus, ItemStateFactory isf, IdFactory idFactory,
-                        boolean isWorkspaceState) {
+    protected ItemState(NodeState parent, int initialStatus, ItemStateFactory isf,
+                        IdFactory idFactory, boolean isWorkspaceState) {
         switch (initialStatus) {
             case Status.EXISTING:
             case Status.NEW:
@@ -485,9 +486,9 @@
      * successfully submitted to the SPI..
      *
      * @param changeLog
-     * @throws IllegalStateException if this state is a 'session' state.
+     * @throws IllegalStateException if this state is a 'workspace' state.
      */
-    abstract void persisted(ChangeLog changeLog) throws IllegalStateException;
+    abstract void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour) throws IllegalStateException;
 
     /**
      * Connect this state to some underlying overlayed state.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java Tue Dec  5 06:08:03 2006
@@ -80,6 +80,12 @@
 
 
     /**
+     *
+     * @param nodeState
+     */
+    public ChildNodeEntries getChildNodeEntries(NodeState nodeState) throws NoSuchItemStateException, ItemStateException;
+
+    /**
      * Set the cache used to retrieve item states that have already been
      * built before.
      *

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -28,6 +28,7 @@
 import org.apache.jackrabbit.jcr2spi.state.entry.ChildPropertyEntry;
 import org.apache.jackrabbit.jcr2spi.state.entry.PropertyReference;
 import org.apache.jackrabbit.jcr2spi.state.entry.ChildItemEntry;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.value.QValue;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -80,7 +81,7 @@
     /**
      * insertion-ordered collection of ChildNodeEntry objects
      */
-    private ChildNodeEntries childNodeEntries = new ChildNodeEntries(this);
+    private ChildNodeEntries childNodeEntries;
 
     /**
      * Map of properties. Key = {@link QName} of property. Value = {@link
@@ -146,7 +147,7 @@
                 nodeTypeName = wspState.nodeTypeName;
                 definition = wspState.definition;
 
-                init(wspState.getMixinTypeNames(), wspState.getChildNodeEntries(), wspState.getPropertyNames(), wspState.getNodeReferences());
+                init(wspState.getMixinTypeNames(), wspState.getPropertyNames(), wspState.getNodeReferences());
             }
         }
     }
@@ -154,11 +155,10 @@
     /**
      *
      * @param mixinTypeNames
-     * @param childEntries
      * @param propertyNames
      * @param references
      */
-    void init(QName[] mixinTypeNames, Collection childEntries, Collection propertyNames, NodeReferences references) {
+    void init(QName[] mixinTypeNames, Collection propertyNames, NodeReferences references) {
         if (mixinTypeNames != null) {
             this.mixinTypeNames = mixinTypeNames;
         }
@@ -173,15 +173,19 @@
             ChildPropertyEntry pe = PropertyReference.create(this, propName, isf, idFactory);
             properties.put(propName, pe);
         }
-        // add child node entries
-        childNodeEntries.removeAll();
-        it = childEntries.iterator();
-        while (it.hasNext()) {
-            ChildNodeEntry cne = (ChildNodeEntry) it.next();
-            childNodeEntries.add(cne.getName(), cne.getUUID(), cne.getIndex());
-        }
     }
 
+    private ChildNodeEntries childNodeEntries() {
+        if (childNodeEntries == null) {
+            try {
+                childNodeEntries = isf.getChildNodeEntries(this);
+            } catch (ItemStateException e) {
+                // TODO improve
+                throw new IllegalStateException();
+            }
+        }
+        return childNodeEntries;
+    }
     //----------------------------------------------------------< ItemState >---
     /**
      * Determines if this item state represents a node.
@@ -229,17 +233,17 @@
         if (isWorkspaceState()) {
             // reload from persistent storage ('keepChanges' not relevant).
             try {
-                NodeState tmp = isf.createNodeState(getNodeId(), parent);
+                NodeState tmp = isf.createNodeState(getNodeId(), getParent());
                 if (merge(tmp, false) || getStatus() == Status.INVALIDATED) {
                     setStatus(Status.MODIFIED);
                 }
             } catch (NoSuchItemStateException e) {
                 // remove entry from parent
-                parent.childNodeEntries.remove(this);
+                getParent().childNodeEntries().remove(this);
                 // inform overlaying state and listeners
                 setStatus(Status.REMOVED);
             } catch (ItemStateException e) {
-                // todo rather throw? remove from parent?
+                // TODO rather throw? remove from parent?
                 log.warn("Exception while refreshing property state: " + e);
                 log.debug("Stacktrace: ", e);
             }
@@ -290,9 +294,9 @@
                 if (ce.denotesNode()) {
                     ChildNodeEntry cne = (ChildNodeEntry) ce;
                     int index = cne.getIndex();
-                    if (!childNodeEntries.contains(childName, index, cne.getUUID())) {
+                    if (!childNodeEntries().contains(childName, index, cne.getUUID())) {
                         modified = true;
-                        childNodeEntries.add(childName, cne.getUUID(), index);
+                        childNodeEntries().add(childName, cne.getUUID(), index);
                     }
                 } else {
                     if (!hasPropertyName(childName)) {
@@ -312,7 +316,7 @@
                     if (ce.denotesNode()) {
                         ChildNodeEntry cne = (ChildNodeEntry) ce;
                         int index = cne.getIndex();
-                        toRemove = !nState.childNodeEntries.contains(childName, index, cne.getUUID());
+                        toRemove = !nState.childNodeEntries().contains(childName, index, cne.getUUID());
                     } else {
                         toRemove = !nState.properties.containsKey(childName);
                     }
@@ -334,7 +338,7 @@
                         }
                         // and remove the corresponding entry
                         if (ce.denotesNode()) {
-                            childNodeEntries.remove(childName, ((ChildNodeEntry)ce).getIndex());
+                            childNodeEntries().remove(childName, ((ChildNodeEntry)ce).getIndex());
                         } else {
                             properties.remove(childName);
                         }
@@ -352,7 +356,9 @@
      */
     public void invalidate(boolean recursive) {
         if (recursive) {
-            for (Iterator it = getAllChildEntries(false, false); it.hasNext();) {
+            // invalidate all child entries including properties present in the
+            // attic (removed props shadowed by a new property with the same name).
+            for (Iterator it = getAllChildEntries(false, true); it.hasNext();) {
                 ChildItemEntry ce = (ChildItemEntry) it.next();
                 if (ce.isAvailable()) {
                     try {
@@ -362,14 +368,13 @@
                     }
                 }
             }
-            // TODO: props-in-attic?
         }
         // ... and invalidate this state
         if (isWorkspaceState()) {
             // workspace state
             setStatus(Status.INVALIDATED);
         } else {
-            // todo only invalidate if existing?
+            // TODO only invalidate if existing?
             if (getStatus() == Status.EXISTING) {
                 // set workspace state invalidated, this will in turn invalidate
                 // this (session) state as well
@@ -384,12 +389,17 @@
      * @return the id of this node state.
      */
     public NodeId getNodeId() {
-        NodeState parent = getParent();
         if (uuid != null) {
             return idFactory.createNodeId(uuid);
-        } else if (parent != null) {
+        }
+
+        NodeState parent = getParent();
+        if (parent == null) {
+           // root node
+            return idFactory.createNodeId((String) null, Path.ROOT);
+        } else {
             // find this in parent child node entries
-            for (Iterator it = parent.childNodeEntries.get(name).iterator(); it.hasNext(); ) {
+            for (Iterator it = parent.childNodeEntries().get(name).iterator(); it.hasNext(); ) {
                 ChildNodeEntry cne = (ChildNodeEntry) it.next();
                 try {
                     if (cne.getNodeState() == this) {
@@ -400,9 +410,6 @@
                     log.warn("Unable to access child node entry: " + cne.getId());
                 }
             }
-        } else {
-            // root node
-            return idFactory.createNodeId((String) null, Path.ROOT);
         }
         // TODO: replace with ItemStateException instead of error.
         throw new InternalError("Unable to retrieve NodeId for NodeState");
@@ -430,7 +437,7 @@
         if (mod) {
             this.uuid = uuid;
             if (getParent() != null) {
-                getParent().childNodeEntries.replaceEntry(this);
+                getParent().childNodeEntries().replaceEntry(this);
             }
         }
     }
@@ -441,13 +448,13 @@
      * @return the index.
      */
     public int getIndex() throws ItemNotFoundException {
-        if (parent == null) {
+        if (getParent() == null) {
             // the root state may never have siblings
             return Path.INDEX_DEFAULT;
         }
 
         if (getDefinition().allowsSameNameSiblings()) {
-            ChildNodeEntry entry = getParent().childNodeEntries.get(this);
+            ChildNodeEntry entry = getParent().childNodeEntries().get(this);
             if (entry == null) {
                 String msg = "Unable to retrieve index for: " + this;
                 throw new ItemNotFoundException(msg);
@@ -521,7 +528,7 @@
      * <code>false</code> otherwise.
      */
     public boolean hasChildNodeEntries() {
-        return containsValidChildNodeEntry(childNodeEntries);
+        return containsValidChildNodeEntry(childNodeEntries());
     }
 
     /**
@@ -533,7 +540,7 @@
      *         the specified <code>name</code>.
      */
     public synchronized boolean hasChildNodeEntry(QName name) {
-        return containsValidChildNodeEntry(childNodeEntries.get(name));
+        return containsValidChildNodeEntry(childNodeEntries().get(name));
     }
 
     /**
@@ -546,7 +553,7 @@
      * the specified <code>name</code> and <code>index</code>.
      */
     public synchronized boolean hasChildNodeEntry(QName name, int index) {
-        return isValidChildNodeEntry(childNodeEntries.get(name, index));
+        return isValidChildNodeEntry(childNodeEntries().get(name, index));
     }
 
     /**
@@ -559,7 +566,7 @@
      * or <code>null</code> if there's no matching entry.
      */
     public synchronized ChildNodeEntry getChildNodeEntry(QName nodeName, int index) {
-        ChildNodeEntry cne = childNodeEntries.get(nodeName, index);
+        ChildNodeEntry cne = childNodeEntries().get(nodeName, index);
         if (isValidChildNodeEntry(cne)) {
             return cne;
         } else {
@@ -582,11 +589,11 @@
         ChildNodeEntry cne;
         if (uuid != null && path == null) {
             // retrieve child-entry by uuid
-            cne = childNodeEntries.get(null, uuid);
+            cne = childNodeEntries().get(null, uuid);
         } else {
            // retrieve child-entry by name and index
             Path.PathElement nameElement = path.getNameElement();
-            cne = childNodeEntries.get(nameElement.getName(), nameElement.getIndex());
+            cne = childNodeEntries().get(nameElement.getName(), nameElement.getIndex());
         }
 
         if (isValidChildNodeEntry(cne)) {
@@ -604,7 +611,7 @@
      */
     public synchronized Collection getChildNodeEntries() {
         Collection entries = new ArrayList();
-        for (Iterator it = childNodeEntries.iterator(); it.hasNext();) {
+        for (Iterator it = childNodeEntries().iterator(); it.hasNext();) {
             ChildNodeEntry cne = (ChildNodeEntry) it.next();
             if (isValidChildNodeEntry(cne)) {
                 entries.add(cne);
@@ -622,7 +629,7 @@
      */
     public synchronized List getChildNodeEntries(QName nodeName) {
         List entries = new ArrayList();
-        for (Iterator it = childNodeEntries.get(nodeName).iterator(); it.hasNext();) {
+        for (Iterator it = childNodeEntries().get(nodeName).iterator(); it.hasNext();) {
             ChildNodeEntry cne = (ChildNodeEntry) it.next();
             if (isValidChildNodeEntry(cne)) {
                 entries.add(cne);
@@ -764,7 +771,7 @@
      * if it is not found in this <code>NodeState</code>.
      */
     public int getChildNodeIndex(ChildNodeEntry cne) {
-        List sns = childNodeEntries.get(cne.getName());
+        List sns = childNodeEntries().get(cne.getName());
         // index is one based
         int index = 1;
         for (Iterator it = sns.iterator(); it.hasNext(); ) {
@@ -801,9 +808,9 @@
                 // add new childNodeEntry if it has not been added by
                 // some earlier 'add' event
                 // TODO: TOBEFIXED for SNSs
-                ChildNodeEntry cne = (uuid != null) ? childNodeEntries.get(name, uuid) : childNodeEntries.get(name, index);
+                ChildNodeEntry cne = (uuid != null) ? childNodeEntries().get(name, uuid) : childNodeEntries().get(name, index);
                 if (cne == null) {
-                    cne = childNodeEntries.add(name, uuid, index);
+                    cne = childNodeEntries().add(name, uuid, index);
                 }
                 // and let the transiently modified session state now, that
                 // its workspace state has been touched.
@@ -825,7 +832,7 @@
             case Event.NODE_REMOVED:
                 if (id.equals(event.getParentId())) {
                     index = event.getQPath().getNameElement().getNormalizedIndex();
-                    childNodeEntries.remove(name, index);
+                    childNodeEntries().remove(name, index);
                     setStatus(Status.MODIFIED);
                 } else if (id.equals(event.getItemId())) {
                     setStatus(Status.REMOVED);
@@ -860,10 +867,12 @@
     //----------------------------------------------------< Session - State >---
     /**
      * {@inheritDoc}
-     * @see ItemState#persisted(ChangeLog)
+     * @see ItemState#persisted(ChangeLog, CacheBehaviour)
      */
-    void persisted(ChangeLog changeLog) throws IllegalStateException {
-        // TODO: review...in case of CacheBehaviour.MANUAL and .INVALIDATION, some states must be invalidate (e.g. autocreated)
+    void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour)
+        throws IllegalStateException {
+        checkIsSessionState();
+
         // remember parent states that have need to adjust their uuid/mixintypes
         // or that got a new child entry added or existing entries removed.
         Map modParents = new HashMap();
@@ -879,7 +888,7 @@
             if (!changeLog.containsDeletedState(parent)) {
                 NodeState overlayedParent = (NodeState) parent.overlayedState;
                 if (state.isNode()) {
-                    overlayedParent.childNodeEntries.remove((NodeState)state.overlayedState);
+                    overlayedParent.childNodeEntries().remove((NodeState)state.overlayedState);
                 } else {
                     overlayedParent.removePropertyEntry(state.overlayedState.getQName());
                 }
@@ -893,23 +902,23 @@
         for (Iterator it = changeLog.addedStates(); it.hasNext();) {
             ItemState addedState = (ItemState) it.next();
             NodeState parent = addedState.getParent();
-            // TODO: only retrieve overlayed state, if necessary
+            // TODO: improve. only retrieve overlayed state, if necessary
             try {
                 // adjust parent child-entries
                 NodeState overlayedParent = (NodeState) parent.overlayedState;
                 QName addedName = addedState.getQName();
                 if (addedState.isNode()) {
-                    int index = parent.childNodeEntries.get((NodeState)addedState).getIndex();
+                    int index = parent.childNodeEntries().get((NodeState)addedState).getIndex();
                     ChildNodeEntry cne;
                     // check for existing, valid child-node-entry
                     if (overlayedParent.hasChildNodeEntry(addedName, index)) {
                         cne = overlayedParent.getChildNodeEntry(addedName, index);
                     } else {
-                        cne = overlayedParent.childNodeEntries.add(addedState.getQName(), null, index);
+                        cne = overlayedParent.childNodeEntries().add(addedState.getQName(), null, index);
                     }
                     NodeState overlayed = cne.getNodeState();
                     if (overlayed.getUUID() != null) {
-                        overlayedParent.childNodeEntries.replaceEntry(overlayed);
+                        overlayedParent.childNodeEntries().replaceEntry(overlayed);
                     }
                     addedState.connect(overlayed);
                 } else {
@@ -945,10 +954,10 @@
                 // handle moved nodes
                 if (isMovedState(modNodeState)) {
                     // move overlayed state as well
-                    NodeState newParent = (NodeState) modState.parent.overlayedState;
+                    NodeState newParent = (NodeState) modState.getParent().overlayedState;
                     NodeState overlayed = (NodeState) modState.overlayedState;
                     try {
-                        overlayed.parent.moveEntry(newParent, overlayed, modNodeState.getQName(), modNodeState.getDefinition());
+                        overlayed.getParent().moveEntry(newParent, overlayed, modNodeState.getQName(), modNodeState.getDefinition());
                     } catch (RepositoryException e) {
                         // should never occur
                         log.error("Internal error while moving childnode entries.", e);
@@ -983,7 +992,12 @@
         for (Iterator it = modParents.keySet().iterator(); it.hasNext();) {
             NodeState parent = (NodeState) it.next();
             List l = (List) modParents.get(parent);
-            adjustNodeState(parent, (PropertyState[]) l.toArray(new PropertyState[l.size()]));
+            if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+                adjustNodeState(parent, (PropertyState[]) l.toArray(new PropertyState[l.size()]));
+            } else {
+                // TODO: improve. invalidate necessary states only
+                parent.invalidate(false);
+            }
         }
 
         /* finally check if all entries in the changelog have been processed
@@ -996,8 +1010,9 @@
             if (!(state.getStatus() == Status.EXISTING ||
                   state.getStatus() == Status.REMOVED ||
                   state.getStatus() == Status.INVALIDATED)) {
-                // error: state has not been processed
-                // TODO: discard state and force reload of all data
+                // should not occur: state has not been processed
+                log.error("State " + state + " has not been processed upon ChangeLog.persisted => invalidate");
+                state.invalidate(false);
             }
         }
     }
@@ -1093,7 +1108,7 @@
         if (child.getParent() != this) {
             throw new IllegalArgumentException("This NodeState is not the parent of child");
         }
-        childNodeEntries.add(child);
+        childNodeEntries().add(child);
         markModified();
     }
 
@@ -1155,11 +1170,11 @@
                 break;
             case Status.REMOVED:
                 if (childState.isNode()) {
-                    childNodeEntries.remove((NodeState) childState);
+                    childNodeEntries().remove((NodeState) childState);
                 } else {
                     removePropertyEntry(childState.getQName());
                 }
-                // TODO: not correct. removing a NEW state may even remove the 'modified'
+                // TODO: TOBEFIXED. removing a NEW state may even remove the 'modified'
                 // flag from the parent, if this NEW state was the only modification.
                 if (previousStatus != Status.NEW) {
                     markModified();
@@ -1191,7 +1206,7 @@
         throws NoSuchItemStateException {
         checkIsSessionState();
 
-        childNodeEntries.reorder(insertNode, beforeNode);
+        childNodeEntries().reorder(insertNode, beforeNode);
         // mark this state as modified
         markModified();
     }
@@ -1228,7 +1243,7 @@
      * @throws RepositoryException
      */
     private void moveEntry(NodeState newParent, NodeState childState, QName newName, QNodeDefinition newDefinition) throws RepositoryException {
-        ChildNodeEntry oldEntry = childNodeEntries.remove(childState);
+        ChildNodeEntry oldEntry = childNodeEntries().remove(childState);
         if (oldEntry != null) {
             childState.name = newName;
             // re-parent target node
@@ -1236,7 +1251,7 @@
             // set definition according to new definition required by the new parent
             childState.definition = newDefinition;
             // add child node entry to new parent
-            newParent.childNodeEntries.add(childState);
+            newParent.childNodeEntries().add(childState);
         } else {
             throw new RepositoryException("Unexpected error: Child state to be moved does not exist.");
         }
@@ -1254,7 +1269,7 @@
         Iterator[] its;
         if (createNewList) {
             List props = new ArrayList(properties.values());
-            List children = new ArrayList(childNodeEntries);
+            List children = new ArrayList(childNodeEntries());
             if (includeAttic) {
                 List attic = new ArrayList(propertiesInAttic.values());
                 its = new Iterator[] {attic.iterator(), props.iterator(), children.iterator()};
@@ -1263,10 +1278,9 @@
             }
         } else {
             if (includeAttic) {
-                its = new Iterator[] {propertiesInAttic.values().iterator(), properties.values().iterator(), childNodeEntries.iterator()};
+                its = new Iterator[] {propertiesInAttic.values().iterator(), properties.values().iterator(), childNodeEntries().iterator()};
             } else {
-                its = new Iterator[] {properties.values().iterator(),
-                    childNodeEntries.iterator()};
+                its = new Iterator[] {properties.values().iterator(), childNodeEntries().iterator()};
             }
         }
         IteratorChain chain = new IteratorChain(its);
@@ -1423,11 +1437,11 @@
     }
 
     private static boolean isMovedState(NodeState modState) {
-        if (modState.parent == null) {
+        if (modState.getParent() == null) {
             // the root state cannot be moved
             return false;
         } else {
-            return modState.overlayedState.parent != modState.parent.overlayedState;
+            return modState.overlayedState.getParent() != modState.getParent().overlayedState;
         }
     }
 }

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -29,10 +29,10 @@
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.value.QValue;
 import org.apache.jackrabbit.jcr2spi.nodetype.ValueConstraint;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
 import java.util.Iterator;
 
 /**
@@ -157,16 +157,16 @@
         if (isWorkspaceState()) {
             // refresh from persistent storage ('keepChanges' not relevant).
             try {
-                PropertyState tmp = isf.createPropertyState(getPropertyId(), parent);
+                PropertyState tmp = isf.createPropertyState(getPropertyId(), getParent());
                 if (merge(tmp, false) || getStatus() == Status.INVALIDATED) {
                     setStatus(Status.MODIFIED);
                 }
             } catch (NoSuchItemStateException e) {
-                // TODO: make sure the property-entry is removed from the parent state
+                // TODO: improve. make sure the property-entry is removed from the parent state
                 // inform overlaying state and listeners
                 setStatus(Status.REMOVED);
             } catch (ItemStateException e) {
-                // todo rather throw? remove from parent?
+                // TODO: rather throw? remove from parent?
                 log.warn("Exception while refreshing property state: " + e);
                 log.debug("Stacktrace: ", e);
             }
@@ -218,7 +218,7 @@
             // workspace state
             setStatus(Status.INVALIDATED);
         } else {
-            // todo only invalidate if existing?
+            // TODO: only invalidate if existing?
             if (getStatus() == Status.EXISTING) {
                 // set workspace state invalidated, this will in turn invalidate
                 // this (session) state as well
@@ -324,9 +324,11 @@
     //----------------------------------------------------< Session - State >---
     /**
      * {@inheritDoc}
-     * @see ItemState#persisted(ChangeLog)
+     * @see ItemState#persisted(ChangeLog, CacheBehaviour)
      */
-    void persisted(ChangeLog changeLog) throws IllegalStateException {
+    void persisted(ChangeLog changeLog, CacheBehaviour cacheBehaviour)
+        throws IllegalStateException {
+        checkIsSessionState();
         for (Iterator it = changeLog.modifiedStates(); it.hasNext();) {
             ItemState modState = (ItemState) it.next();
             if (modState == this) {

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?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- 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 Tue Dec  5 06:08:03 2006
@@ -16,10 +16,7 @@
  */
 package org.apache.jackrabbit.jcr2spi.state;
 
-import org.apache.jackrabbit.jcr2spi.HierarchyManager;
-import org.apache.jackrabbit.jcr2spi.HierarchyManagerImpl;
 import org.apache.jackrabbit.jcr2spi.util.ReferenceChangeTracker;
-import org.apache.jackrabbit.jcr2spi.util.LogUtil;
 import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.jcr2spi.operation.Operation;
@@ -45,7 +42,6 @@
 import org.apache.jackrabbit.jcr2spi.operation.AddLabel;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveLabel;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveVersion;
-import org.apache.jackrabbit.name.NamespaceResolver;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -104,38 +100,23 @@
     /**
      * Hierarchy manager
      */
-    private final HierarchyManager hierMgr;
-    private final NamespaceResolver nsResolver;
+    //private final HierarchyManager hierMgr;
+    //private final NamespaceResolver nsResolver;
     private final ItemStateValidator validator;
 
     /**
      * Creates a new <code>SessionItemStateManager</code> instance.
      *
      * @param workspaceItemStateMgr
-     * @param nsResolver
      */
     public SessionItemStateManager(UpdatableItemStateManager workspaceItemStateMgr,
                                    IdFactory idFactory,
-                                   ItemStateValidator validator,
-                                   NamespaceResolver nsResolver) {
+                                   ItemStateValidator validator) {
         this.workspaceItemStateMgr = workspaceItemStateMgr;
         this.transientStateMgr = new TransientItemStateManager(idFactory, workspaceItemStateMgr);
         this.validator = validator;
-        this.nsResolver = nsResolver;
-
-        // create hierarchy manager
-        hierMgr = new HierarchyManagerImpl(this, nsResolver);
-    }
-
-    /**
-     *
-     * @return
-     */
-    public HierarchyManager getHierarchyManager() {
-        return hierMgr;
     }
 
-
     //---------------------------------------------------< ItemStateManager >---
     /**
      * {@inheritDoc}
@@ -353,9 +334,9 @@
                 }
             }
             if (modified) {
-                // TODO improve
-                int options = ItemStateValidator.CHECK_LOCK //| ItemStateValidator.CHECK_COLLISION
-                    | ItemStateValidator.CHECK_VERSIONING | ItemStateValidator.CHECK_CONSTRAINTS;
+                int options = ItemStateValidator.CHECK_LOCK |
+                    ItemStateValidator.CHECK_VERSIONING |
+                    ItemStateValidator.CHECK_CONSTRAINTS;
                 setPropertyStateValue(propState, newVals, PropertyType.REFERENCE, options);
             }
         }
@@ -382,12 +363,12 @@
         ChangeLog changeLog = new ChangeLog(itemState);
         // fail-fast test: check status of this item's state
         if (itemState.getStatus() == Status.NEW) {
-            String msg = "Cannot save an item with status NEW (" +LogUtil.safeGetJCRPath(itemState, nsResolver)+ ").";
+            String msg = "Cannot save an item with status NEW (" +itemState+ ").";
             log.debug(msg);
             throw new ItemStateException(msg);
         }
         if (throwOnStale && Status.isStale(itemState.getStatus())) {
-            String msg =  "Attempt to save an item, that has been externally modified (" +LogUtil.safeGetJCRPath(itemState, nsResolver)+ ").";
+            String msg =  "Attempt to save an item, that has been externally modified (" +itemState+ ").";
             log.debug(msg);
             throw new StaleItemStateException(msg);
         }
@@ -462,7 +443,6 @@
             | ItemStateValidator.CHECK_CONSTRAINTS);
         
         // retrieve applicable definition at the new place
-        // TODO: improve. definition has already retrieve within the checkAddNode...
         QNodeDefinition newDefinition = validator.getApplicableNodeDefinition(operation.getDestinationName(), srcState.getNodeTypeName(), destParent);
 
         // perform the move (modifying states)
@@ -539,9 +519,9 @@
      */
     public void visit(SetPropertyValue operation) throws ValueFormatException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
         PropertyState pState = operation.getPropertyState();
-        // TODO improve
-        int options = ItemStateValidator.CHECK_LOCK //| ItemStateValidator.CHECK_COLLISION
-            | ItemStateValidator.CHECK_VERSIONING | ItemStateValidator.CHECK_CONSTRAINTS;
+        int options = ItemStateValidator.CHECK_LOCK
+            | ItemStateValidator.CHECK_VERSIONING
+            | ItemStateValidator.CHECK_CONSTRAINTS;
         setPropertyStateValue(pState, operation.getValues(), operation.getPropertyType(), options);
         transientStateMgr.addOperation(operation);
     }
@@ -655,7 +635,6 @@
         UnsupportedRepositoryOperationException, NoSuchNodeTypeException,
         ItemExistsException, VersionException {
 
-        // TODO: improve...
         // check if add node is possible. note, that the options differ if
         // the 'addNode' is called from inside a regular add-node to create
         // autocreated child nodes that my are 'protected' by their def.
@@ -713,7 +692,7 @@
             throw new RepositoryException("Cannot remove item: " + e.getMessage(), e);
         } finally {
             if (!success) {
-                // TODO: undo state modifications
+                // TODO: TOBEFIXED undo state modifications
             }
         }
     }
@@ -751,10 +730,6 @@
     private QValue[] computeSystemGeneratedPropertyValues(NodeState parent,
                                                           QPropertyDefinition def) {
         QValue[] genValues = null;
-        /**
-         * todo: need to come up with some callback mechanism for applying system generated values
-         * (e.g. using a NodeTypeInstanceHandler interface)
-         */
         String[] qDefaultValues = def.getDefaultValues();
         if (qDefaultValues != null && qDefaultValues.length > 0) {
             if (def.getRequiredType() == PropertyType.BINARY) {
@@ -767,9 +742,9 @@
             } else {
                genValues = QValue.create(qDefaultValues, def.getRequiredType());
             }
-        } else {
-            // some predefined nodetypes declare auto-created properties without
-            // default values
+        } else if (def.isAutoCreated()) {
+            // handle known predefined nodetypes that declare auto-created
+            // properties without default values
             QName declaringNT = def.getDeclaringNodeType();
             QName name = def.getQName();
             if (QName.MIX_REFERENCEABLE.equals(declaringNT) && QName.JCR_UUID.equals(name)) {
@@ -801,8 +776,10 @@
             } else if (QName.NT_VERSION.equals(declaringNT) && QName.JCR_CREATED.equals(name)) {
                 // nt:version node type defines jcr:created property
                 genValues = new QValue[]{QValue.create(Calendar.getInstance())};
+            } else {
+                // TODO: TOBEFIXED. other nodetype -> build some default value
+                log.warn("Missing implementation. Nodetype " + def.getDeclaringNodeType() + " defines autocreated property " + def.getQName() + " without default value.");
             }
-            // TODO: defaults???
         }
         return genValues;
     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java Tue Dec  5 06:08:03 2006
@@ -13,16 +13,11 @@
  */
 package org.apache.jackrabbit.jcr2spi.state;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * <code>Status</code>...
  */
 public class Status {
 
-    private static Logger log = LoggerFactory.getLogger(Status.class);
-
     /**
      * A state once read from persistent storage has been set to invalid. This
      * means that the state needs to be re-fetched from persistent storage when
@@ -78,7 +73,7 @@
      * </ul>
      *
      * @param status
-     * @return
+     * @return true if the given status is terminal.
      */
     public static boolean isTerminal(int status) {
         return status == REMOVED || status == STALE_DESTROYED;
@@ -94,7 +89,7 @@
      * </ul>
      *
      * @param status
-     * @return
+     * @return true if the given status indicates a valid ItemState.
      */
     public static boolean isValid(int status) {
         return status == EXISTING || status == EXISTING_MODIFIED || status == NEW;
@@ -139,7 +134,8 @@
      * @param oldStatus
      * @param newStatus
      * @param isWorkspaceState
-     * @return
+     * @return true if a status change from <code>oldStatus</code> to
+     * <code>newStatus</code> is allowed or if the two status are the same.
      */
     public static boolean isValidStatusChange(int oldStatus, int newStatus,
                                               boolean isWorkspaceState) {
@@ -201,7 +197,7 @@
                 case MODIFIED:
                     isValid = (oldStatus == EXISTING || oldStatus == INVALIDATED);
                     break;
-                    /* default:
+                /* default:
                     NEW cannot change state to NEW -> false */
             }
         }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java Tue Dec  5 06:08:03 2006
@@ -182,6 +182,16 @@
         return propState;
     }
 
+    public ChildNodeEntries getChildNodeEntries(NodeState nodeState) throws NoSuchItemStateException, ItemStateException {
+        if (nodeState.getStatus() == Status.NEW) {
+            return new ChildNodeEntries(nodeState);
+        } else {
+            NodeState overlayed = (NodeState) nodeState.getWorkspaceState();
+            ChildNodeEntries overlayedEntries = overlayed.isf.getChildNodeEntries(overlayed);
+            return new ChildNodeEntries(nodeState, overlayedEntries);
+        }
+    }
+
     /**
      * @inheritDoc
      * @see ItemStateFactory#setCache(ItemStateCache)

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java Tue Dec  5 06:08:03 2006
@@ -27,12 +27,11 @@
 import org.apache.jackrabbit.spi.RepositoryService;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.jackrabbit.value.QValue;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildNodeEntry;
 import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
-import org.apache.jackrabbit.name.QName;
 
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
@@ -47,6 +46,7 @@
 import java.util.Collections;
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.Collection;
 
 /**
  * <code>WorkspaceItemStateFactory</code>...
@@ -154,17 +154,6 @@
             NodeState state = new NodeState(info.getQName(), uuid, parent, info.getNodetype(),
                 definition, Status.EXISTING, this, service.getIdFactory(), true);
 
-            // child node entries
-            Set childNodeEntries = new HashSet();
-            for (IdIterator it = info.getNodeIds(); it.hasNext(); ) {
-                NodeInfo childInfo = service.getNodeInfo(sessionInfo, (NodeId) it.nextId());
-                String childUUID = null;
-                if (childInfo.getId().getPath() == null) {
-                    childUUID = childInfo.getId().getUUID();
-                }
-                childNodeEntries.add(new CNE(childInfo.getQName(), childInfo.getIndex(), childUUID));
-            }
-
             // names of child property entries
             Set propNames = new HashSet();
             for (IdIterator it = info.getPropertyIds(); it.hasNext(); ) {
@@ -176,14 +165,12 @@
             PropertyId[] references = info.getReferences();
             NodeReferences nodeRefs = new NodeReferencesImpl(state, references);
 
-            state.init(info.getMixins(), childNodeEntries, propNames, nodeRefs);
+            state.init(info.getMixins(), propNames, nodeRefs);
 
             state.addListener(cache);
             cache.created(state);
 
             return state;
-        } catch (PathNotFoundException e) {
-            throw new NoSuchItemStateException(e.getMessage(), e);
         } catch (NodeTypeConflictException e) {
             String msg = "Internal error: failed to retrieve node definition.";
             log.debug(msg);
@@ -221,6 +208,23 @@
         }
     }
 
+    public ChildNodeEntries getChildNodeEntries(NodeState nodeState)
+        throws NoSuchItemStateException, ItemStateException {
+        try {
+            ChildNodeEntries entries = new ChildNodeEntries(nodeState);
+            Collection childInfos = service.getChildNodeInfos(sessionInfo, nodeState.getNodeId());
+            for (Iterator it = childInfos.iterator(); it.hasNext();) {
+                ChildInfo ci = (ChildInfo) it.next();
+                entries.add(ci.getName(), ci.getUUID(), ci.getIndex());
+            }
+            return entries;
+        } 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>.
      *
@@ -285,52 +289,7 @@
         this.cache = cache;
     }
 
-    //-----------------------------------------------------< ChildNodeEntry >---
-    private class CNE implements ChildNodeEntry {
-
-        private final QName name;
-        private final int index;
-        private final String uuid;
-
-        private CNE(QName name, int index, String uuid) {
-            this.name = name;
-            this.index = index;
-            this.uuid = uuid;
-        }
-
-        public NodeId getId() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean denotesNode() {
-            return true;
-        }
-
-        public QName getName() {
-            return name;
-        }
-
-        public String getUUID() {
-            return uuid;
-        }
-
-        public int getIndex() {
-            return index;
-        }
-
-        public NodeState getNodeState() throws NoSuchItemStateException, ItemStateException {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isAvailable() {
-            throw new UnsupportedOperationException();
-        }
-
-        public ItemState getItemState() throws NoSuchItemStateException, ItemStateException {
-            throw new UnsupportedOperationException();
-        }
-    }
-
+    //-----------------------------------------------------< NodeReferences >---
     /**
      * <code>NodeReferences</code> represents the references (i.e. properties of
      * type <code>REFERENCE</code>) to a particular node (denoted by its uuid).
@@ -348,7 +307,7 @@
         private NodeReferencesImpl(NodeState nodeState, PropertyId[] referenceIds) {
             this.nodeState = nodeState;
 
-            // TODO: modify in order to make usage of the references returned
+            // TODO: improve. make usage of the references returned
             // with NodeInfo that was just retrieved and implement a notification
             // mechanism that updates this NodeReference object if references
             // are modified.

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java Tue Dec  5 06:08:03 2006
@@ -55,7 +55,7 @@
         if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
             EventFilter filter = null;
             try {
-                // todo for now listen to everything
+                // TODO: improve. for now listen to everything
                 filter = wspManager.createEventFilter(Event.ALL_TYPES, Path.ROOT, true, null, null, false);
             } catch (RepositoryException e) {
                 // spi does not support observation, or another error occurred.
@@ -165,7 +165,7 @@
                 if (state != null) {
                     state.refresh(event);
                 }
-                // TODO: check again. parent must be notified if mixintypes or jcr:uuid prop is changed.
+                // parent must be notified in case mixintypes or uuid is changed.
                 if (parent != null) {
                     parent.refresh(event);
                 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewImportHandler.java Tue Dec  5 06:08:03 2006
@@ -187,7 +187,7 @@
                 // until a way of properly serializing/detecting multi-valued
                 // properties on re-import is found (see JCR-325);
                 // see also DocViewSAXEventGenerator#leavingProperties(Node, int)
-                // todo proper multi-value serialization support
+                // TODO: proper multi-value serialization support
                 propValues = new Importer.TextValue[1];
                 propValues[0] = new StringValue(attrValue);
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewSAXEventGenerator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewSAXEventGenerator.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewSAXEventGenerator.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/DocViewSAXEventGenerator.java Tue Dec  5 06:08:03 2006
@@ -140,7 +140,7 @@
                 String propName = prop.getName();
 
                 if (prop.getDefinition().isMultiple()) {
-                    // todo proper multi-value serialization support
+                    // TODO: proper multi-value serialization support
                     // skip multi-valued properties for the time being
                     // until a way of properly handling/detecting multi-valued
                     // properties on re-import is found (see JCR-325);

Added: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java?view=auto&rev=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java (added)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java Tue Dec  5 06:08:03 2006
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.spi;
+
+import org.apache.jackrabbit.name.QName;
+
+/**
+ * <code>ChildInfo</code>...
+ */
+public interface ChildInfo {
+
+    public QName getName();
+
+    public String getUUID();
+
+    public int getIndex();
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/ChildInfo.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java Tue Dec  5 06:08:03 2006
@@ -21,15 +21,6 @@
  */
 public interface LockInfo {
 
-    /**
-     * Id of the node this <code>LockInfo</code> was requested for. Note, that
-     * the id does not represent the id of the lock-holding node.
-     *
-     * @return
-     */
-    // TODO: review if this is needed
-    public NodeId getNodeId();
-
     public String getLockToken();
 
     public String getOwner();

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/NodeInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/NodeInfo.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/NodeInfo.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/NodeInfo.java Tue Dec  5 06:08:03 2006
@@ -56,12 +56,6 @@
     public PropertyId[] getReferences();
 
     /**
-     * @return ids of children nodes
-     * @see NodeInfo#getId()
-     */
-    public IdIterator getNodeIds();
-
-    /**
      * @return ids of children properties
      * @see PropertyInfo#getId()
      */

Modified: jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java (original)
+++ jackrabbit/trunk/contrib/spi/spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java Tue Dec  5 06:08:03 2006
@@ -40,6 +40,7 @@
 import javax.jcr.LoginException;
 import javax.jcr.ReferentialIntegrityException;
 import java.util.Map;
+import java.util.Collection;
 import java.io.InputStream;
 
 /**
@@ -112,8 +113,6 @@
      */
     public String[] getWorkspaceNames(SessionInfo sessionInfo) throws RepositoryException;
 
-    // todo: createWorkspace required????
-
     //-----------------------------------------------------< Access Control >---
     /**
      * @param sessionInfo
@@ -186,6 +185,18 @@
      * @see javax.jcr.version.Version#getContainingHistory()
      */
     public NodeInfo getNodeInfo(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException;
+
+    /**
+     * Returns a collection of child node entries present on the
+     * Node represented by the given parentId.
+     *
+     * @param sessionInfo
+     * @param parentId
+     * @return
+     * @throws ItemNotFoundException
+     * @throws RepositoryException
+     */
+    public Collection getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws ItemNotFoundException, RepositoryException;
 
     /**
      * @param sessionInfo

Added: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java?view=auto&rev=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java (added)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java Tue Dec  5 06:08:03 2006
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.spi2dav;
+
+import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.name.QName;
+
+/**
+ * <code>ChildInfoImpl</code>...
+ */
+class ChildInfoImpl implements ChildInfo {
+
+    private final QName qName;
+    private final int index;
+    private final String uuid;
+
+    ChildInfoImpl(QName qName, int index, String uuid) {
+        this.qName = qName;
+        this.index = index;
+        this.uuid = uuid;
+    }
+
+    /**
+     * @see ChildInfo#getName()
+     */
+    public QName getName() {
+        return qName;
+    }
+
+    /**
+     * @see ChildInfo#getUUID()
+     */
+    public String getUUID() {
+        return this.uuid;
+    }
+
+    /**
+     * @see ChildInfo#getIndex()
+     */
+    public int getIndex() {
+        return index;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ChildInfoImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java Tue Dec  5 06:08:03 2006
@@ -37,7 +37,6 @@
 
     private static Logger log = LoggerFactory.getLogger(LockInfoImpl.class);
 
-    private final NodeId nodeId;
     private ActiveLock activeLock;
 
     public LockInfoImpl(LockDiscovery ld, NodeId nodeId) throws LockException, RepositoryException {
@@ -58,11 +57,6 @@
         if (activeLock == null) {
             throw new LockException("No lock present on node " + nodeId);
         }
-        this.nodeId = nodeId;
-    }
-
-    public NodeId getNodeId() {
-        return nodeId;
     }
 
     public String getLockToken() {

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/NodeInfoImpl.java Tue Dec  5 06:08:03 2006
@@ -29,7 +29,6 @@
 import org.apache.jackrabbit.spi.IdIterator;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.PropertyId;
-import org.apache.jackrabbit.spi.ItemId;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -50,11 +49,10 @@
     private final QName qName;
     private final int index;
 
-    private QName primaryNodeTypeName = null;
-    private QName[] mixinNodeTypeNames = new QName[0];
-    private List references = new ArrayList();
+    private final QName primaryNodeTypeName;
+    private final QName[] mixinNodeTypeNames;
 
-    private final List nodeIds = new ArrayList();
+    private final List references = new ArrayList();
     private final List propertyIds = new ArrayList();
 
     public NodeInfoImpl(NodeId id, NodeId parentId, DavPropertySet propSet,
@@ -116,6 +114,8 @@
                     mixinNodeTypeNames[i] = NameFormat.parse(jcrName, nsResolver);
                     i++;
                 }
+            } else {
+                mixinNodeTypeNames = QName.EMPTY_ARRAY;
             }
         } catch (NameException e) {
             throw new RepositoryException("Error while resolving nodetype names: " + e.getMessage());
@@ -152,10 +152,6 @@
         return (PropertyId[]) references.toArray(new PropertyId[references.size()]);
     }
 
-    public IdIterator getNodeIds() {
-        return new IteratorHelper(nodeIds);
-    }
-
     public IdIterator getPropertyIds() {
         return new IteratorHelper(propertyIds);
     }
@@ -165,11 +161,7 @@
         references.add(referenceId);
     }
 
-    void addChildId(ItemId childId) {
-        if (childId.denotesNode()) {
-           nodeIds.add(childId);
-        } else {
-           propertyIds.add(childId);
-        }
+    void addPropertyId(PropertyId childId) {
+        propertyIds.add(childId);
     }
 }

Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=diff&rev=482657&r1=482656&r2=482657
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Tue Dec  5 06:08:03 2006
@@ -119,6 +119,7 @@
 import org.apache.jackrabbit.spi.IdIterator;
 import org.apache.jackrabbit.spi.EventFilter;
 import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.uuid.UUID;
 import org.apache.jackrabbit.value.ValueFormat;
@@ -167,7 +168,6 @@
  * <code>RepositoryServiceImpl</code>...
  */
 // TODO: encapsulate URI building, escaping, unescaping...
-// TODO: cache info objects
 // TODO: TO-BE-FIXED. caches don't get adjusted upon removal/move of items
 public class RepositoryServiceImpl implements RepositoryService, DavConstants {
 
@@ -679,8 +679,9 @@
                     childResponses.add(responses[i]);
                 }
             }
+
             if (nodeResponse == null) {
-                throw new ItemNotFoundException("Unable to retrieve the node with id " + nodeId);
+                throw new ItemNotFoundException("Unable to retrieve the node " + nodeId);
             }
 
             DavPropertySet propSet = nodeResponse.getProperties(DavServletResponse.SC_OK);
@@ -688,32 +689,87 @@
             NodeId id = uriResolver.buildNodeId(parentId, nodeResponse, sessionInfo.getWorkspaceName());
 
             NodeInfoImpl nInfo = new NodeInfoImpl(id, parentId, propSet, nsResolver);
-
+            if (propSet.contains(ItemResourceConstants.JCR_REFERENCES)) {
+                HrefProperty refProp = new HrefProperty(propSet.get(ItemResourceConstants.JCR_REFERENCES));
+                Iterator hrefIter = refProp.getHrefs().iterator();
+                while(hrefIter.hasNext()) {
+                    String propertyHref = hrefIter.next().toString();
+                    PropertyId propertyId = uriResolver.getPropertyId(propertyHref, sessionInfo);
+                    nInfo.addReference(propertyId);
+                }
+            }
             for (Iterator it = childResponses.iterator(); it.hasNext();) {
                 MultiStatusResponse resp = (MultiStatusResponse) it.next();
                 DavPropertySet childProps = resp.getProperties(DavServletResponse.SC_OK);
                 if (childProps.contains(DavPropertyName.RESOURCETYPE) &&
                     childProps.get(DavPropertyName.RESOURCETYPE).getValue() != null) {
                     // any other resource type than default (empty) is represented by a node item
-                    NodeId childId = uriResolver.buildNodeId(id, resp, sessionInfo.getWorkspaceName());
-                    nInfo.addChildId(childId);
+                    // --> ignore
                 } else {
-                    PropertyId childId = uriResolver.buildPropertyId(id, resp, sessionInfo.getWorkspaceName());
-                    nInfo.addChildId(childId);
+                    PropertyId childId = uriResolver.buildPropertyId(nInfo.getId(), resp, sessionInfo.getWorkspaceName());
+                    nInfo.addPropertyId(childId);
                 }
             }
+            return nInfo;
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        } finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
+    }
 
-            if (propSet.contains(ItemResourceConstants.JCR_REFERENCES)) {
-                HrefProperty refProp = new HrefProperty(propSet.get(ItemResourceConstants.JCR_REFERENCES));
-                Iterator hrefIter = refProp.getHrefs().iterator();
-                while(hrefIter.hasNext()) {
-                    String propertyHref = hrefIter.next().toString();
-                    PropertyId propertyId = uriResolver.getPropertyId(propertyHref, sessionInfo);
-                    nInfo.addReference(propertyId);
-                }
+    /**
+     * @see RepositoryService#getChildInfos(SessionInfo, NodeId)
+     */
+    public Collection getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws ItemNotFoundException, RepositoryException {
+        // set of properties to be retrieved
+        DavPropertyNameSet nameSet = new DavPropertyNameSet();
+        nameSet.add(ItemResourceConstants.JCR_NAME);
+        nameSet.add(ItemResourceConstants.JCR_INDEX);
+        nameSet.add(ItemResourceConstants.JCR_PARENT);
+        nameSet.add(ItemResourceConstants.JCR_PRIMARYNODETYPE);
+        nameSet.add(ItemResourceConstants.JCR_MIXINNODETYPES);
+        nameSet.add(ItemResourceConstants.JCR_REFERENCES);
+        nameSet.add(ItemResourceConstants.JCR_UUID);
+        nameSet.add(DavPropertyName.RESOURCETYPE);
+
+        DavMethodBase method = null;
+        try {
+            String uri = getItemUri(parentId, sessionInfo);
+            method = new PropFindMethod(uri, nameSet, DEPTH_1);
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+
+            MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
+            if (responses.length < 1) {
+                throw new ItemNotFoundException("Unable to retrieve the node with id " + parentId);
+            } else if (responses.length == 1) {
+                // no child nodes nor properties
+                return Collections.EMPTY_LIST;
             }
 
-            return nInfo;
+            Set childEntries = new HashSet();
+            for (int i = 0; i < responses.length; i++) {
+                if (!isSameResource(uri, responses[i])) {
+                    MultiStatusResponse resp = responses[i];
+                    DavPropertySet childProps = resp.getProperties(DavServletResponse.SC_OK);
+                    if (childProps.contains(DavPropertyName.RESOURCETYPE) &&
+                        childProps.get(DavPropertyName.RESOURCETYPE).getValue() != null) {
+
+                        QName qName = uriResolver.getQName(childProps);
+                        int index = uriResolver.getIndex(childProps);
+                        String uuid = uriResolver.getUUID(childProps);
+
+                        ChildInfo childInfo = new ChildInfoImpl(qName, index, uuid);
+                        childEntries.add(childInfo);
+                    } // else: property -> ignore
+                } // else: ignore the response related to the parent
+            }
+            return childEntries;
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {