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/17 15:28:59 UTC

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

Author: angela
Date: Thu Aug 17 06:28:58 2006
New Revision: 432234

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

- Restore: pass NodeState(s) and Path instead of NodeId(s)
- LockManager: make sure lockmanager only remembers workspace states
- LockManager: make sure operations are executed using workspace states
- LockManager: improve isLocked/getLock/checkIsLocked and respect locks that
have been accessed before.
- VersionManager: make sure operations are executed using workspace states
- VersionManager: add checkIsCheckedOut
- VersionManager: force manager to have a WorkspaceManager
- NodeReferences:
  > make interface package protected
  > clarify method naming
  > add implementation to WorkspaceItemStateFactory
  > add NodeReferences field to NodeState
  > TO_IMPROVE: references are currently always retrieve from the SPI.
- ItemStateManager + NodeReferences
  > rename interfaces methods
  > change method signature to take NodeState instead of NodeId
  > 'getReferences' returns the property states directly

- remove some JR DIFFs. 

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/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/lock/DefaultLockManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateManager.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/NodeReferences.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/SessionItemStateManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.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/version/DefaultVersionManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java
    jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.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?rev=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -32,7 +32,6 @@
 import org.apache.jackrabbit.name.NameFormat;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateException;
-import org.apache.jackrabbit.jcr2spi.state.NodeReferences;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
 import org.apache.jackrabbit.jcr2spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.jcr2spi.state.PropertyState;
@@ -573,10 +572,8 @@
         checkStatus();
         try {
             ItemStateManager itemStateMgr = session.getItemStateManager();
-            if (itemStateMgr.hasNodeReferences(getNodeId())) {
-                NodeReferences refs = itemStateMgr.getNodeReferences(getNodeId());
-                // refs.getReferences() returns a list of Property states
-                Collection refStates = refs.getReferences();
+            if (itemStateMgr.hasReferingStates(getNodeState())) {
+                Collection refStates = itemStateMgr.getReferingStates(getNodeState());
                 return new LazyItemIterator(itemMgr, refStates);
             } else {
                 // there are no references, return empty iterator
@@ -849,7 +846,7 @@
             NodeState versionState = ((NodeImpl)version).getNodeState();
             session.getVersionManager().resolveMergeConflict(getNodeState(), versionState, done);
         } else {
-            throw new RepositoryException("Incompatible Version object :" + version);
+            throw new RepositoryException("Incompatible Version object: " + version.getPath());
         }
     }
 
@@ -1002,11 +999,8 @@
     public void restore(Version version, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
         checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
         checkSessionHasPendingChanges();
-        checkIsWritable();
-        checkIsVersionable();
-        checkIsLocked();
 
-        restore(getNodeId(), version, removeExisting);
+        restore(this, null, version, removeExisting);
     }
 
     /**
@@ -1015,44 +1009,58 @@
     public void restore(Version version, String relPath, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
         checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
         checkSessionHasPendingChanges();
+
         // additional checks are performed with subsequest calls.
         if (hasNode(relPath)) {
-            // node at 'relPath' exists -> call restore on that node
+            // node at 'relPath' exists -> call restore on the target Node
             getNode(relPath).restore(version, removeExisting);
         } else {
             // node at 'relPath' does not yet exist -> build the NodeId
             Path nPath = getQPath(relPath);
             Path parentPath = nPath.getAncestor(1);
-            NodeId nId;
             if (itemMgr.itemExists(parentPath)) {
-                // If the would-be parent of the location relPath is actually a
-                // property, or if a node type restriction would be violated,
-                // then a ConstraintViolationException is thrown.
                 Item parent = itemMgr.getItem(parentPath);
                 if (parent.isNode()) {
                     try {
                         Path relQPath = parentPath.computeRelativePath(nPath);
-                        NodeId parentId = ((NodeImpl)parent).getNodeId();
-                        nId = session.getIdFactory().createNodeId(parentId, relQPath);
+                        NodeImpl parentNode = ((NodeImpl)parent);
+                        // call the restore
+                        restore(parentNode, relQPath, version, removeExisting);
                     } catch (MalformedPathException e) {
                         // should not occur
                         throw new RepositoryException(e);
                     }
                 } else {
+                    // the item at parentParentPath is Property
                     throw new ConstraintViolationException("Cannot restore to a parent presenting a property (relative path = '" + relPath + "'");
                 }
             } else {
                 // although the node itself must not exist, is direct ancestor must.
                 throw new PathNotFoundException("Cannot restore to relative path '" + relPath + ": Ancestor does not exist.");
             }
-            restore(nId, version, removeExisting);
         }
     }
 
     /**
+     * @see Node#restoreByLabel(String, boolean)
+     */
+    public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
+        checkSessionHasPendingChanges();
+
+        // check for version-enabled and lock are performed with subsequent calls.
+        Version v = getVersionHistory().getVersionByLabel(versionLabel);
+        if (v == null) {
+            throw new VersionException("No version for label " + versionLabel + " found.");
+        }
+        restore(this, null, v, removeExisting);
+    }
+
+    /**
      * Common internal restore method for the various Node#restore calls.
      *
-     * @param nodeId
+     * @param targetNode
+     * @param relQPath
      * @param version
      * @param removeExisting
      * @throws PathNotFoundException
@@ -1064,27 +1072,43 @@
      * @throws InvalidItemStateException
      * @throws RepositoryException
      */
-    private void restore(NodeId nodeId, Version version, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
-        if (version instanceof VersionImpl) {
-            NodeId versionId = ((NodeImpl)version).getNodeId();
-            session.getVersionManager().restore(nodeId, versionId, removeExisting);
+    private void restore(NodeImpl targetNode, Path relQPath, Version version, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        targetNode.checkIsWritable();
+        targetNode.checkIsLocked();
+
+
+        if (relQPath == null) {
+            /* restore target already exists. */
+            // target must be versionable
+            targetNode.checkIsVersionable();
+
+            VersionHistory vH = targetNode.getVersionHistory();
+            // version must be a version of the target node
+            if (!vH.isSame(version.getContainingHistory())) {
+                throw new VersionException("Version " + version + " does not correspond to the restore target.");
+            }
+            // version must not be the root version
+            if (vH.getRootVersion().isSame(version)) {
+                throw new VersionException("Attempt to restore root version.");
+            }
         } else {
-            throw new RepositoryException("Unexpected error: Failed to retrieve a valid ID for the given version " + version.getPath());
+            /* If no node exists at relPath then a VersionException is thrown if
+               the parent node is not checked out. */
+            if (!targetNode.isCheckedOut()) {
+                throw new VersionException("Parent " + targetNode.safeGetJCRPath()
+                    + " for non-existing restore target '"
+                    + LogUtil.safeGetJCRPath(relQPath, session.getNamespaceResolver())
+                    + "' must be checked out.");
+            }
+            // NOTE: check for nodetype constraint violation is left to the 'server'
         }
-    }
 
-    /**
-     * @see Node#restoreByLabel(String, boolean)
-     */
-    public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
-        checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
-        checkSessionHasPendingChanges();
-        // check for version-enabled and lock are performed with subsequent calls.
-        Version v = getVersionHistory().getVersionByLabel(versionLabel);
-        if (v == null) {
-            throw new VersionException("No version for label " + versionLabel + " found.");
+        if (version instanceof VersionImpl) {
+            NodeState versionState = ((NodeImpl)version).getNodeState();
+            session.getVersionManager().restore(targetNode.getNodeState(), relQPath, versionState, removeExisting);
+        } else {
+            throw new RepositoryException("Incompatible Version object: " + version.getPath());
         }
-        restore(getNodeId(), v, removeExisting);
     }
 
     /**

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -162,10 +162,8 @@
         validator = new ItemStateValidator(workspace.getNodeTypeRegistry(), this);
 
         // build the state mananger
-        // DIFF JACKRABBIT: itemStateMgr = createSessionItemStateManager(wsp.getSessionItemStateManager());
         itemStateManager = createSessionItemStateManager(workspace.getUpdatableItemStateManager(), nsMappings);
 
-        // DIFF JACKRABBIT: itemManager = createItemManager(itemStateMgr, hierMgr);
         itemManager = createItemManager(getHierarchyManager());
     }
 

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -20,6 +20,8 @@
 import org.apache.jackrabbit.jcr2spi.state.UpdatableItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemStateManager;
 import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.jcr2spi.query.QueryManagerImpl;
 import org.apache.jackrabbit.jcr2spi.operation.Move;
@@ -75,9 +77,19 @@
 
     private static Logger log = LoggerFactory.getLogger(WorkspaceImpl.class);
 
+    /**
+     * The name of this <code>Workspace</code>.
+     */
     private final String name;
+    /**
+     * The Session that created this <code>Workspace</code> object
+     */
     private final SessionImpl session;
 
+    /**
+     * WorkspaceManager acting as ItemStateManager on the workspace level
+     * and as connection to the SPI implementation.
+     */
     private final WorkspaceManager wspManager;
 
     /**
@@ -86,11 +98,11 @@
      * the session)
      */
     private HierarchyManager hierManager;
-
-    private QueryManager qManager;
-    private ObservationManager obsManager;
     private LockManager lockManager;
+    private ObservationManager obsManager;
+    private QueryManager qManager;
     private VersionManager versionManager;
+    private ItemStateValidator validator;
 
     public WorkspaceImpl(String name, SessionImpl session, RepositoryService service, SessionInfo sessionInfo) throws RepositoryException {
         this.name = name;
@@ -151,7 +163,6 @@
 
         // copy (i.e. pull) subtree at srcAbsPath from srcWorkspace
         // to 'this' workspace at destAbsPath
-
         SessionImpl srcSession = null;
         try {
             // create session on other workspace for current subject
@@ -235,16 +246,16 @@
         session.checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
         session.checkHasPendingChanges();
 
-        NodeId[] versionIds = new NodeId[versions.length];
+        NodeState[] versionStates = new NodeState[versions.length];
         for (int i = 0; i < versions.length; i++) {
             if (versions[i] instanceof VersionImpl) {
                 ItemState vState = ((NodeImpl)versions[i]).getItemState();
-                versionIds[i] = (NodeId) vState.getId();
+                versionStates[i] = (NodeState) vState;
             } else {
                 throw new RepositoryException("Unexpected error: Failed to retrieve a valid ID for the given version " + versions[i].getPath());
             }
         }
-        getVersionManager().restore(versionIds, removeExisting);
+        getVersionManager().restore(versionStates, removeExisting);
     }
 
     /**
@@ -281,6 +292,7 @@
     public ObservationManager getObservationManager() throws UnsupportedRepositoryOperationException, RepositoryException {
         session.checkSupportedOption(Repository.OPTION_OBSERVATION_SUPPORTED);
         session.checkIsAlive();
+
         if (obsManager == null) {
             obsManager = createObservationManager(getNamespaceResolver(), getNodeTypeRegistry());
         }
@@ -301,12 +313,18 @@
     public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior)
         throws PathNotFoundException, ConstraintViolationException, VersionException,
         LockException, RepositoryException {
+
         session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
         session.checkIsAlive();
 
         Path parentPath = session.getQPath(parentAbsPath);
         ItemState parentState = getHierarchyManager().getItemState(parentPath);
         if (parentState.isNode()) {
+            // make sure the given import target is accessible, not locked and checked out.
+            int options = ItemStateValidator.CHECK_ACCESS | ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
+            getValidator().checkIsWritable((NodeState) parentState, options);
+
+            // build the content handler
             return new WorkspaceContentHandler(this, parentAbsPath, uuidBehavior);
         } else {
             throw new PathNotFoundException("No node at path " + parentAbsPath);
@@ -322,10 +340,19 @@
         ConstraintViolationException, InvalidSerializedDataException,
         LockException, RepositoryException {
 
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
         Path parentPath = session.getQPath(parentAbsPath);
-        ItemState parentState = getHierarchyManager().getItemState(parentPath);
-        if (parentState.isNode()) {
-            wspManager.importXml((NodeId) parentState.getId(), in, uuidBehavior);
+        ItemState itemState = getHierarchyManager().getItemState(parentPath);
+        if (itemState.isNode()) {
+            // make sure the given import target is accessible, not locked and checked out.
+            NodeState parentState = (NodeState) itemState;
+            int options = ItemStateValidator.CHECK_ACCESS | ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
+            getValidator().checkIsWritable(parentState, options);
+
+            // run the import
+            wspManager.importXml(parentState, in, uuidBehavior);
         } else {
             throw new PathNotFoundException("No node at path " + parentAbsPath);
         }
@@ -405,6 +432,18 @@
     UpdatableItemStateManager getUpdatableItemStateManager() {
         return wspManager;
     }
+
+    /**
+     * Validator for the <code>Workspace</code>. It contrast from {@link SessionImpl#getValidator()}
+     * in terms of <code>HierarchyManager</code> and <code>ItemManager</code>.
+     * @return
+     */
+    private ItemStateValidator getValidator() {
+        if (validator == null) {
+            validator = new ItemStateValidator(getNodeTypeRegistry(), this);
+        }
+        return validator;
+    }
     //-----------------------------------------------------< initialization >---
     /**
      * Create the workspace state manager. May be overridden by subclasses.
@@ -434,12 +473,12 @@
 
     /**
      *
-     * @param stateMgr
+     * @param wspManager
      * @return
      */
-    protected VersionManager createVersionManager(UpdatableItemStateManager stateMgr) {
+    protected VersionManager createVersionManager(WorkspaceManager wspManager) {
         if (session.isSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED)) {
-            return new VersionManagerImpl(stateMgr);
+            return new VersionManagerImpl(wspManager);
         } else {
             return new DefaultVersionManager();
         }

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -27,7 +27,6 @@
 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.ItemStateFactory;
 import org.apache.jackrabbit.jcr2spi.state.WorkspaceItemStateFactory;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
@@ -116,7 +115,6 @@
     private final RepositoryService service;
     private final SessionInfo sessionInfo;
 
-    // TODO: TO-BE-FIXED. Major refactoring of caching mechanism with change to SPI ids
     private final WorkspaceItemStateManager cache;
 
     private final NamespaceRegistryImpl nsRegistry;
@@ -136,20 +134,16 @@
     private Set listeners = new HashSet();
 
     public WorkspaceManager(RepositoryService service, SessionInfo sessionInfo) throws RepositoryException {
-        try {
-            this.service = service;
-            this.sessionInfo = sessionInfo;
+        this.service = service;
+        this.sessionInfo = sessionInfo;
 
-            ItemStateFactory isf = createItemStateFactory();
-            cache = new WorkspaceItemStateManager(isf, service.getIdFactory());
-            addEventListener(cache);
-
-            nsRegistry = createNamespaceRegistry();
-            ntRegistry = createNodeTypeRegistry(nsRegistry);
-            externalChangeListener = createChangeListener();
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
-        }
+        ItemStateFactory isf = createItemStateFactory();
+        cache = new WorkspaceItemStateManager(isf, service.getIdFactory());
+        addEventListener(cache);
+
+        nsRegistry = createNamespaceRegistry();
+        ntRegistry = createNodeTypeRegistry(nsRegistry);
+        externalChangeListener = createChangeListener();
     }
 
     public NamespaceRegistryImpl getNamespaceRegistryImpl() {
@@ -327,21 +321,23 @@
 
     /**
      * @inheritDoc
-     * @see ItemStateManager#getNodeReferences(NodeId)
+     * @see ItemStateManager#getReferingStates(NodeState)
+     * @param nodeState
      */
-    public NodeReferences getNodeReferences(NodeId id) throws NoSuchItemStateException, ItemStateException {
+    public Collection getReferingStates(NodeState nodeState) throws ItemStateException {
         synchronized (cache) {
-            return cache.getNodeReferences(id);
+            return cache.getReferingStates(nodeState);
         }
     }
 
     /**
      * @inheritDoc
-     * @see ItemStateManager#hasNodeReferences(NodeId)
+     * @see ItemStateManager#hasReferingStates(NodeState)
+     * @param nodeState
      */
-    public boolean hasNodeReferences(NodeId id) {
+    public boolean hasReferingStates(NodeState nodeState) {
         synchronized (cache) {
-            return cache.hasNodeReferences(id);
+            return cache.hasReferingStates(nodeState);
         }
     }
 
@@ -428,7 +424,9 @@
     }
 
     //---------------------------------------------------------< XML import >---
-    public void importXml(NodeId parentId, InputStream xmlStream, int uuidBehaviour) throws RepositoryException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, ItemExistsException, VersionException {
+    public void importXml(NodeState parentState, InputStream xmlStream, int uuidBehaviour) throws RepositoryException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, ItemExistsException, VersionException {
+        // TODO check retrieval of nodeId
+        NodeId parentId = parentState.getNodeId();
         service.importXml(sessionInfo, parentId, xmlStream, uuidBehaviour);
     }
 
@@ -671,20 +669,32 @@
         }
 
         public void visit(Restore operation) throws VersionException, PathNotFoundException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
-            NodeId nId = operation.getNodeId();
-            NodeId[] versionIds = operation.getVersionIds();
-            NodeId[] vIds = new NodeId[versionIds.length];
+            NodeState nState = operation.getNodeState();
+            NodeState[] versionStates = operation.getVersionStates();
+            if (versionStates == null || versionStates.length == 0) {
+                throw new IllegalArgumentException("Restore must specify at least a singe version.");
+            }
+
+            NodeId[] vIds = new NodeId[versionStates.length];
             for (int i = 0; i < vIds.length; i++) {
-                vIds[i] = versionIds[i];
+                vIds[i] = versionStates[i].getNodeId();
             }
 
-            if (nId == null) {
+            if (nState == null) {
                 events = service.restore(sessionInfo, vIds, operation.removeExisting());
             } else {
                 if (vIds.length > 1) {
                     throw new IllegalArgumentException("Restore from a single node must specify but one single Version.");
                 }
-                events = service.restore(sessionInfo, nId, vIds[0], operation.removeExisting());
+
+                NodeId targetId;
+                Path relPath = operation.getRelativePath();
+                if (relPath != null) {
+                    targetId = getIdFactory().createNodeId(nState.getNodeId(), relPath);
+                } else {
+                    targetId = nState.getNodeId();
+                }
+                events = service.restore(sessionInfo, targetId, vIds[0], operation.removeExisting());
             }
         }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java Thu Aug 17 06:28:58 2006
@@ -36,11 +36,11 @@
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
-    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
+    public void unlock(NodeState nodeState) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
-    public void unlock(NodeState nodeState) throws LockException, RepositoryException {
+    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java Thu Aug 17 06:28:58 2006
@@ -44,6 +44,17 @@
         throws LockException, RepositoryException;
 
     /**
+     * Removes the lock on a node.
+     *
+     * @param nodeState
+     * @throws LockException if this node is not locked or the session does not
+     * have the correct lock token
+     * @see javax.jcr.Node#unlock
+     */
+    void unlock(NodeState nodeState) throws LockException, RepositoryException;
+
+
+    /**
      * Returns the Lock object that applies to a node. This may be either a lock
      * on this node itself or a deep lock on a node above this node.
      *
@@ -55,16 +66,6 @@
     Lock getLock(NodeState nodeState) throws LockException, RepositoryException;
 
     /**
-     * Removes the lock on a node.
-     *
-     * @param nodeState
-     * @throws LockException if this node is not locked or the session does not
-     * have the correct lock token
-     * @see javax.jcr.Node#unlock
-     */
-    void unlock(NodeState nodeState) throws LockException, RepositoryException;
-
-    /**
      * Returns <code>true</code> if this node is locked either as a result
      * of a lock held by this node or by a deep lock on a node above this
      * node; otherwise returns <code>false</code>.
@@ -78,7 +79,7 @@
     boolean isLocked(NodeState nodeState) throws RepositoryException;
 
     /**
-     * Check whether the node given is locked by somebody else than the
+     * Check whether the given node state is locked by somebody else than the
      * current session. Access is allowed if the node is not locked or
      * if the session itself holds the lock to this node, i.e. the session
      * contains the lock token for the lock. If the node is not locked at

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java Thu Aug 17 06:28:58 2006
@@ -25,6 +25,7 @@
 import org.apache.jackrabbit.jcr2spi.operation.LockRelease;
 import org.apache.jackrabbit.jcr2spi.operation.LockRefresh;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.state.ItemState;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.spi.EventIterator;
 import org.apache.jackrabbit.spi.Event;
@@ -50,6 +51,11 @@
 
     private static Logger log = LoggerFactory.getLogger(LockManagerImpl.class);
 
+    /**
+     * WorkspaceManager used to apply and release locks as well as to retrieve
+     * Lock information for a given NodeState.
+     * NOTE: The workspace manager must not be used as ItemStateManager.
+     */
     private final WorkspaceManager wspManager;
     private final ItemManager itemManager;
 
@@ -76,6 +82,8 @@
     public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
         // retrieve node first
         Node lhNode;
+        // NOTE: Node must be retrieved from the given NodeState and not from
+        // the overlayed workspace nodestate. See below.
         Item item = itemManager.getItem(nodeState);
         if (item.isNode()) {
             lhNode = (Node) item;
@@ -84,83 +92,80 @@
         }
 
         // execute the operation
-        Operation op = LockOperation.create(nodeState, isDeep, isSessionScoped);
+        NodeState wspNodeState = getWorkspaceState(nodeState);
+        Operation op = LockOperation.create(wspNodeState, isDeep, isSessionScoped);
         wspManager.execute(op);
 
-        Lock lock = new LockImpl(nodeState, lhNode, isSessionScoped);
+        Lock lock = new LockImpl(wspNodeState, lhNode, isSessionScoped);
         return lock;
     }
 
     /**
-     * If the session created a lock on the node with the given id, we already
-     * know the lock. Otherwise, we look in the node state and the states of
-     * the ancestor nodes for properties indicating a lock.<br>
-     * Note, that the flag indicating session-scoped lock cannot be retrieved
-     * and the lock will always report 'false'.
-     *
-     * @see LockManager#getLock(NodeState)
-     * @param nodeState
-     */
-    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
-        // shortcut: check if lock has been accessed before
-        if (lockMap.containsKey(nodeState)) {
-            return (Lock) lockMap.get(nodeState);
-        }
-
-        // try to retrieve parent state that holds a lock.
-        NodeState lockHoldingState = getLockHoldingState(nodeState);
-        if (lockHoldingState == null) {
-            throw new LockException("Node with id '" + nodeState.getNodeId() + "' is not locked.");
-        } else {
-            // check lockMap again with the lockholding state
-            if (lockMap.containsKey(lockHoldingState)) {
-                return (Lock) lockMap.get(lockHoldingState);
-            }
-
-            // retrieve lock holding node. note that this may fail if the session
-            // does not have permission to see this node.
-            Item lockHoldingNode = itemManager.getItem(lockHoldingState);
-            // TODO: we don;t know if lock is session scoped -> set flag to false
-            // TODO: ev. add 'isSessionScoped' to RepositoryService lock-call.
-            Lock l = new LockImpl(lockHoldingState, (Node)lockHoldingNode, false);
-            return l;
-        }
-    }
-
-    /**
      * @see LockManager#unlock(NodeState)
      * @param nodeState
      */
     public void unlock(NodeState nodeState) throws LockException, RepositoryException {
+        NodeState wspNodeState = getWorkspaceState(nodeState);
         // execute the operation. Note, that its possible that the session is
         // lock holder and still the lock was never accessed. thus the lockMap
         // does not provide sufficient and relyable information.
-        Operation op = LockRelease.create(nodeState);
+        Operation op = LockRelease.create(wspNodeState);
         wspManager.execute(op);
 
         // if unlock was successfull: clean up lock map and lock life cycle
         // in case the corresponding Lock object exists (and thus has been
         // added to the map.
-        if (lockMap.containsKey(nodeState)) {
-            LockImpl l = (LockImpl) lockMap.remove(nodeState);
+        if (lockMap.containsKey(wspNodeState)) {
+            LockImpl l = (LockImpl) lockMap.remove(wspNodeState);
             l.unlocked();
         }
     }
 
     /**
+     * If the session created a lock on the node with the given state, we already
+     * know the lock. Otherwise, the node state and its ancestores are searched
+     * for properties indicating a lock.<br>
+     * Note, that the flag indicating session-scoped lock cannot be retrieved
+     * unless the current session is the lock holder.
+     *
+     * @see LockManager#getLock(NodeState)
+     * @param nodeState
+     */
+    public Lock getLock(NodeState nodeState) throws LockException, RepositoryException {
+        NodeState wspNodeState;
+        // a lock can never exist on a new state -> access parent
+        if (nodeState.getStatus() == ItemState.STATUS_NEW) {
+            wspNodeState = getWorkspaceState(nodeState.getParent());
+        } else {
+            wspNodeState = getWorkspaceState(nodeState);
+        }
+
+        LockImpl l = internalGetLock(wspNodeState);
+        // no-lock found or lock doesn't apply to this state -> throw
+        if (l == null) {
+            throw new LockException("Node with id '" + nodeState.getNodeId() + "' is not locked.");
+        }
+
+        // a lock exists either on the given node state or as deep lock inherited
+        // from any of the ancestor states.
+        return l;
+    }
+
+    /**
      * @see LockManager#isLocked(NodeState)
      * @param nodeState
      */
     public boolean isLocked(NodeState nodeState) throws RepositoryException {
-        // shortcut: check if a given node holds a lock and lock has been
-        // accessed before (thus is known to the manager).
-        if (lockMap.containsKey(nodeState)) {
-            return true;
+        NodeState wspNodeState;
+        // a lock can never exist on a new state -> access parent
+        if (nodeState.getStatus() == ItemState.STATUS_NEW) {
+            wspNodeState = getWorkspaceState(nodeState.getParent());
         } else {
-            // check if any lock is present (checking lock-specific properties)
-            LockInfo lInfo = getLockInfo(nodeState);
-            return lInfo != null;
+            wspNodeState = getWorkspaceState(nodeState);
         }
+
+        LockImpl l = internalGetLock(wspNodeState);
+        return l != null;
     }
 
     /**
@@ -168,20 +173,18 @@
      * @param nodeState
      */
     public void checkLock(NodeState nodeState) throws LockException, RepositoryException {
-        LockInfo lInfo;
-        // shortcut: check if a given node holds a lock and lock has been
-        // accessed before (thus is known to the manager).
-        if (lockMap.containsKey(nodeState)) {
-            lInfo = ((LockImpl)lockMap.get(nodeState)).lockInfo;
-        } else {
-            // check if any lock is present (checking lock-specific properties)
-            lInfo = getLockInfo(nodeState);
+        // shortcut: new status indicates that a new state was already added
+        // thus, the parent state is not locked by foreign lock.
+        if (nodeState.getStatus() == ItemState.STATUS_NEW) {
+            return;
         }
 
-        if (lInfo != null && lInfo.getLockToken() == null) {
+        NodeState wspNodeState = getWorkspaceState(nodeState);
+        LockImpl l = internalGetLock(wspNodeState);
+        if (l != null && l.lockInfo.getLockToken() == null) {
             // lock is present and token is null -> session is not lock-holder.
             throw new LockException("Node with id '" + nodeState + "' is locked.");
-        }
+        } // else: state is not locked at all || session is lock-holder
     }
 
     /**
@@ -286,43 +289,95 @@
 
     //------------------------------------------------------------< private >---
     /**
+     * If the given <code>NodeState</code> has an overlayed state, the overlayed
+     * (workspace) state will be returned. Otherwise the given state is returned.
      *
      * @param nodeState
-     * @return
-     * @throws LockException
-     * @throws RepositoryException
+     * @return The overlayed state or the given state, if this one does not have
+     * an overlayed state.
      */
-    private LockInfo getLockInfo(NodeState nodeState) throws RepositoryException {
-        try {
-            return wspManager.getLockInfo(nodeState.getNodeId());
-        } catch (LockException e) {
-            log.debug("No lock present on node with id '" + nodeState.getNodeId() + "'", e);
-            return null;
+    private NodeState getWorkspaceState(NodeState nodeState) {
+        if (nodeState.hasOverlayedState()) {
+            // nodestate has been obtained from  Session-ISM
+            return (NodeState) nodeState.getOverlayedState();
+        } else {
+            // nodestate has been obtained from Workspace-ISM already
+            return nodeState;
         }
     }
 
     /**
-     * Search nearest ancestor that is locked. Returns <code>null</code> if no
-     * lock ancestor could be found.
+     * Search nearest ancestor that is locked. Returns <code>null</code> if neither
+     * the given state nor any of its ancestors is locked.
+     * Note, that this methods does NOT check if the given node state would
+     * be affected by the lock present on an ancestor state.
      *
-     * @param nodeState <code>NodeState</code> from which searching starts.
-     * @return lock ancestor node or <code>null</code>.
+     * @param wspNodeState <code>NodeState</code> from which searching starts.
+     * Note, that the given state must not have an overlayed state.
+     * @return a state holding a lock or <code>null</code> if neither the
+     * given state nor any of its ancestors is locked.
      */
-    private NodeState getLockHoldingState(NodeState nodeState) {
+    private NodeState getLockHoldingState(NodeState wspNodeState) {
         /**
-         * FIXME should not only rely on existence of jcr:lockIsDeep property
+         * TODO: should not only rely on existence of jcr:lockIsDeep property
          * but also verify that node.isNodeType("mix:lockable")==true;
          * this would have a negative impact on performance though...
          */
-        while (!nodeState.hasPropertyName(QName.JCR_LOCKISDEEP)) {
-            NodeState parentState = nodeState.getParent();
+        while (!wspNodeState.hasPropertyName(QName.JCR_LOCKISDEEP)) {
+            NodeState parentState = wspNodeState.getParent();
             if (parentState == null) {
                 // reached root state without finding a locked node
                 return null;
             }
-            nodeState = parentState;
+            wspNodeState = parentState;
+        }
+        return wspNodeState;
+    }
+
+    /**
+     * Returns the Lock that applies to the given node state (directly or
+     * by an inherited deep lock) or <code>null</code> if the state is not
+     * locked at all.
+     *
+     * @param wspNodeState
+     * @return LockImpl that applies to the given state or <code>null</code>.
+     * @throws RepositoryException
+     */
+    private LockImpl internalGetLock(NodeState wspNodeState) throws RepositoryException {
+        // shortcut: check if a given state holds a lock, which has been
+        // accessed before (thus is known to the manager) irrespective if the
+        // current session is the lock holder or not.
+        if (lockMap.containsKey(wspNodeState)) {
+            return (LockImpl) lockMap.get(wspNodeState);
+        }
+
+        // try to retrieve a state (ev. a parent state) that holds a lock.
+        NodeState lockHoldingState = getLockHoldingState(wspNodeState);
+        if (lockHoldingState == null) {
+            // no lock
+            return null;
+        } else {
+            // check lockMap again with the lockholding state
+            if (lockMap.containsKey(lockHoldingState)) {
+                return (LockImpl) lockMap.get(lockHoldingState);
+            }
+
+            // Lock has never been access -> build the lock object
+            // retrieve lock holding node. note that this may fail if the session
+            // does not have permission to see this node.
+            Item lockHoldingNode = itemManager.getItem(lockHoldingState);
+            // TODO: we don;t know if lock is session scoped -> set flag to false
+            // TODO: ev. add 'isSessionScoped' to RepositoryService lock-call.
+            LockImpl l = new LockImpl(lockHoldingState, (Node)lockHoldingNode, false);
+
+            if (l.appliesToNodeState(wspNodeState)) {
+                return l;
+            } else {
+                // lock exists but does not apply to the workspace node state
+                // passed to this method.
+                return null;
+            }
         }
-        return nodeState;
     }
 
     //----------------------------< Notification about modified lock-tokens >---
@@ -373,10 +428,15 @@
         /**
          *
          * @param lockHoldingState The NodeState of the lock holding <code>Node</code>.
+         * Note, that the given state must not have an overlayed state.
          * @param lockHoldingNode the lock holding <code>Node</code> itself.
          * @param lockHoldingNode
          */
         public LockImpl(NodeState lockHoldingState, Node lockHoldingNode, boolean isSessionScoped) throws LockException, RepositoryException {
+            if (lockHoldingState.hasOverlayedState()) {
+                throw new IllegalArgumentException("Cannot build Lock object from a node state that has an overlayed state.");
+            }
+
             this.lockHoldingState = lockHoldingState;
             this.node = lockHoldingNode;
             this.isSessionScoped = isSessionScoped;
@@ -553,6 +613,24 @@
             if (isLive) {
                 isLive = false;
                 release();
+            }
+        }
+
+        /**
+         * Returns true, if the given node state is the lockholding state of
+         * this Lock object OR if this Lock is deep.
+         * Note, that in the latter case this method does not assert, that the
+         * given node state is a child state of the lockholding state.
+         *
+         * @param nodeState that must be the same or a child of the lock holding
+         * state stored within this lock object.
+         * @return true if this lock applies to the given node state.
+         */
+        private boolean appliesToNodeState(NodeState nodeState) {
+            if (lockHoldingState.equals(nodeState)) {
+                return true;
+            } else {
+                return isDeep();
             }
         }
     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java Thu Aug 17 06:28:58 2006
@@ -101,7 +101,7 @@
         Path.PathElement destElement = destPath.getNameElement();
         // destination must not contain an index
         int index = destElement.getIndex();
-        if (index > org.apache.jackrabbit.name.Path.INDEX_UNDEFINED) {
+        if (index > Path.INDEX_UNDEFINED) {
             // subscript in name element
             String msg = "Invalid destination path: subscript in name element is not allowed (" + LogUtil.safeGetJCRPath(destPath, nsResolver) + ")";
             log.debug(msg);

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java Thu Aug 17 06:28:58 2006
@@ -16,7 +16,8 @@
  */
 package org.apache.jackrabbit.jcr2spi.operation;
 
-import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.name.Path;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.ItemExistsException;
@@ -25,6 +26,7 @@
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.lock.LockException;
 import javax.jcr.version.VersionException;
+import javax.jcr.version.Version;
 import javax.jcr.nodetype.ConstraintViolationException;
 
 /**
@@ -32,13 +34,17 @@
  */
 public class Restore extends AbstractOperation {
 
-    private final NodeId nodeId;
-    private final NodeId[] versionIds;
+    // TODO: since the restore target can point to a non-existing item -> use NodeId
+    // TODO: review this.
+    private final NodeState nodeState;
+    private final Path relQPath;
+    private final NodeState[] versionStates;
     private final boolean removeExisting;
 
-    private Restore(NodeId nodeId, NodeId[] versionIds, boolean removeExisting) {
-        this.nodeId = nodeId;
-        this.versionIds = versionIds;
+    private Restore(NodeState nodeState, Path relQPath, NodeState[] versionStates, boolean removeExisting) {
+        this.nodeState = nodeState;
+        this.relQPath = relQPath;
+        this.versionStates = versionStates;
         this.removeExisting = removeExisting;
 
         // TODO: affected states... needed?
@@ -53,12 +59,30 @@
     }
 
     //----------------------------------------< Access Operation Parameters >---
-    public NodeId getNodeId() {
-        return nodeId;
+
+    /**
+     * Returns state or the closest existing state of the restore target or
+     * <code>null</code> in case of a {@link javax.jcr.Workspace#restore(Version[], boolean)}
+     *
+     * @return
+     */
+    public NodeState getNodeState() {
+        return nodeState;
+    }
+
+    /**
+     * Relative qualified path to the non-existing restore target or <code>null</code>
+     * if the state returned by {@link #getNodeState()} is the target.
+     *
+     * @return
+     * @see javax.jcr.Node#restore(Version, String, boolean) 
+     */
+    public Path getRelativePath() {
+        return relQPath;
     }
 
-    public NodeId[] getVersionIds() {
-        return versionIds;
+    public NodeState[] getVersionStates() {
+        return versionStates;
     }
 
     public boolean removeExisting() {
@@ -68,28 +92,28 @@
     //------------------------------------------------------------< Factory >---
     /**
      *
-     * @param nodeId
-     * @param versionId
+     * @param nodeState
+     * @param versionState
      * @return
      */
-    public static Operation create(NodeId nodeId, NodeId versionId, boolean removeExisting) {
-        if (nodeId == null || versionId == null) {
-            throw new IllegalArgumentException("Neither nodeId nor versionId must be null.");
+    public static Operation create(NodeState nodeState, Path relQPath, NodeState versionState, boolean removeExisting) {
+        if (nodeState == null || versionState == null) {
+            throw new IllegalArgumentException("Neither nodeId nor versionState must be null.");
         }
-        Restore up = new Restore(nodeId, new NodeId[] {versionId}, removeExisting);
+        Restore up = new Restore(nodeState, relQPath, new NodeState[] {versionState}, removeExisting);
         return up;
     }
 
     /**
      *
-     * @param versionIds
+     * @param versionStates
      * @return
      */
-    public static Operation create(NodeId[] versionIds, boolean removeExisting) {
-        if (versionIds == null) {
-            throw new IllegalArgumentException("Neither versionIds must not be null.");
+    public static Operation create(NodeState[] versionStates, boolean removeExisting) {
+        if (versionStates == null) {
+            throw new IllegalArgumentException("Version states must not be null.");
         }
-        Restore up = new Restore(null, versionIds, removeExisting);
+        Restore up = new Restore(null, null, versionStates, removeExisting);
         return up;
     }
 }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java Thu Aug 17 06:28:58 2006
@@ -20,12 +20,18 @@
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.commons.collections.map.LRUMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
 
 /**
  * <code>CachingItemStateManager</code> implements an {@link ItemStateManager}
@@ -118,21 +124,31 @@
 
     /**
      * @inheritDoc
-     * @see ItemStateManager#getNodeReferences(NodeId)
+     * @see ItemStateManager#getReferingStates(NodeState)
+     * @param nodeState
      */
-    public NodeReferences getNodeReferences(NodeId id)
-            throws NoSuchItemStateException, ItemStateException {
-        // TODO: implement
-        return null;
+    public Collection getReferingStates(NodeState nodeState) throws ItemStateException {
+        if (hasReferingStates(nodeState)) {
+            Set refStates = new HashSet();
+            Iterator it =  nodeState.getNodeReferences().iterator();
+            while (it.hasNext()) {
+                PropertyId pId = (PropertyId) it.next();
+                refStates.add(getItemState(pId));
+            }
+            return Collections.unmodifiableCollection(refStates);
+        } else {
+            return Collections.EMPTY_SET;
+        }
     }
 
     /**
      * @inheritDoc
-     * @see ItemStateManager#hasNodeReferences(NodeId)
+     * @see ItemStateManager#hasReferingStates(NodeState)
+     * @param nodeState
      */
-    public boolean hasNodeReferences(NodeId id) {
-        // TODO: caching implement
-        return false;
+    public boolean hasReferingStates(NodeState nodeState) {
+        NodeReferences nr = nodeState.getNodeReferences();
+        return nr != null && !nr.isEmpty();
     }
 
     //------------------------------< internal >--------------------------------

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateManager.java Thu Aug 17 06:28:58 2006
@@ -17,7 +17,8 @@
 package org.apache.jackrabbit.jcr2spi.state;
 
 import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.NodeId;
+
+import java.util.Collection;
 
 /**
  * The <code>ItemStateManager</code> interface provides methods for retrieving
@@ -53,26 +54,25 @@
      */
     boolean hasItemState(ItemId id);  // TODO: throw ItemStateException in case of error?
 
-    // DIFF JR: NodeId param instead of NodeReferenceId
     /**
-     * Return a node references object, given its target id.
+     * Return a collection of <code>PropertyState</code>s referring to the
+     * Node identified by the given <code>NodeState</code>.
      *
-     * @param id target id
-     * @return node references object
-     * @throws NoSuchItemStateException if the item does not exist
-     * @throws ItemStateException if an error occurs
+     * @param nodeState
+     * @return property states refering to the node identified by the given id.
+     * @throws ItemStateException if the <code>PropertyState</code>s could not
+     * be retrieved or if some other error occurs.
      */
-    NodeReferences getNodeReferences(NodeId id)
-        throws NoSuchItemStateException, ItemStateException;
+    Collection getReferingStates(NodeState nodeState) throws ItemStateException;
 
-    // DIFF JR: NodeId param instead of NodeReferenceId
     /**
-     * Return a flag indicating whether a node references object
-     * for a given target id exists.
+     * Return a flag indicating whether any references to the <code>Node</code>
+     * identified by the given state exist. In case the <code>Node</code> is not
+     * referenceable this method will always return false.
      *
-     * @param id target id
-     * @return <code>true</code> if a node reference object exists for the given
-     *         id, otherwise <code>false</code>.
+     * @param nodeState
+     * @return <code>true</code> if any references exist to the <code>Node</code>
+     * identified by the given node state.
      */
-    boolean hasNodeReferences(NodeId id);
+    boolean hasReferingStates(NodeState nodeState);
 }

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -39,7 +39,6 @@
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QItemDefinition;
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.NamespaceResolver;
@@ -547,8 +546,7 @@
         // access restrictions on new node
         if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
             // make sure current session is granted write access on parent node
-            // TODO build Id instead 
-            Path relPath = Path.create(nodeName, org.apache.jackrabbit.name.Path.INDEX_UNDEFINED);
+            Path relPath = Path.create(nodeName, Path.INDEX_UNDEFINED);
             if (!mgrProvider.getAccessManager().isGranted(parentState, relPath, new String[] {AccessManager.ADD_NODE_ACTION})) {
                 throw new AccessDeniedException(safeGetJCRPath(parentState) + ": not allowed to add child node '" + nodeName +"'");
             }
@@ -657,14 +655,8 @@
      */
     private void checkIsCheckedOut(ItemState itemState)
             throws PathNotFoundException, VersionException, RepositoryException {
-        // shortcut: if state is new, its ancestor must be checkout
-        if (itemState.getStatus() == ItemState.STATUS_NEW) {
-            return;
-        }
         NodeState nodeState = (itemState.isNode()) ? (NodeState)itemState : itemState.getParent();
-        if (!mgrProvider.getVersionManager().isCheckedOut(nodeState)) {
-            throw new VersionException(safeGetJCRPath(nodeState) + " is checked-in");
-        }
+        mgrProvider.getVersionManager().checkIsCheckedOut(nodeState);
     }
 
     /**
@@ -817,14 +809,12 @@
         }
 
         NodeState targetState = (NodeState)toDelete;
-        NodeId targetId = targetState.getNodeId();
         EffectiveNodeType ent = getEffectiveNodeType(targetState);
         if (ent.includesNodeType(QName.MIX_REFERENCEABLE)) {
             ItemStateManager stateMgr = mgrProvider.getItemStateManager();
-            if (stateMgr.hasNodeReferences(targetId)) {
+            if (stateMgr.hasReferingStates(targetState)) {
                 try {
-                    NodeReferences refs = stateMgr.getNodeReferences(targetId);
-                    if (refs.hasReferences()) {
+                    if (!stateMgr.getReferingStates(targetState).isEmpty()) {
                         throw new ReferentialIntegrityException(safeGetJCRPath(targetState)
                             + ": cannot remove node with references");
                     }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeReferences.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeReferences.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeReferences.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeReferences.java Thu Aug 17 06:28:58 2006
@@ -16,35 +16,25 @@
  */
 package org.apache.jackrabbit.jcr2spi.state;
 
-import org.apache.jackrabbit.spi.NodeId;
-
-import java.util.Collection;
+import java.util.Iterator;
 
 /**
  * <code>NodeReferences</code>...
  */
-public interface NodeReferences {
-
-    // TODO: probably not needed with spi -> remove
-    // DIFF JR: return NodeId instead of NodeReferenceId
-    /**
-     * Returns the identifier of this node references object.
-     *
-     * @return the id of this node references object.
-     */
-    public NodeId getId();
+interface NodeReferences {
 
     /**
-     * Returns a flag indicating whether this object holds any references
+     * Returns a flag indicating whether the <code>Node</code> identified by this
+     * <code>NodeReferences</code> object is referenced by any Property.
      *
-     * @return <code>true</code> if this object holds references,
-     *         <code>false</code> otherwise
+     * @return <code>true</code> if this object will return a non-empty iterator
+     * upon calls to {@link #iterator()}, <code>false</code> otherwise.
      */
-    public boolean hasReferences();
+    public boolean isEmpty();
 
     /**
-     * @return the collection of states referring to the node identified by this
-     * <code>NodeReference</code>.
+     * @return an iterator over the <code>PropertyId</code>s refering to the
+     * node state identified by this <code>NodeReference</code>.
      */
-    public Collection getReferences();
+    public Iterator iterator();
 }

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -107,6 +107,11 @@
     private HashMap properties = new HashMap();
 
     /**
+     * NodeReferences for this node state.
+     */
+    private NodeReferences references;
+
+    /**
      * Listeners (weak references)
      */
     private final transient Collection listeners = new WeakIdentityCollection(3);
@@ -871,7 +876,15 @@
             throw new RepositoryException("Unexpected error: Child state to be renamed does not exist.");
         }
     }
-    
+
+    void addNodeReferences(NodeReferences references) {
+        this.references = references;
+    }
+
+    NodeReferences getNodeReferences() {
+        return references;
+    }
+
     /**
      * 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

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=432234&r1=432233&r2=432234&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 Thu Aug 17 06:28:58 2006
@@ -51,7 +51,6 @@
 import org.slf4j.Logger;
 
 import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.ItemId;
@@ -83,6 +82,7 @@
 import java.util.HashSet;
 import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collection;
 import java.io.InputStream;
 import java.io.IOException;
 
@@ -218,20 +218,26 @@
 
     /**
      * {@inheritDoc}
-     * @see ItemStateManager#getNodeReferences(NodeId)
+     * Since node references cannot be managed within the transient space,
+     * this call is delegated to the workspace itemstate manager.
+     *
+     * @see ItemStateManager#getReferingStates(NodeState)
+     * @param nodeState
      */
-    public NodeReferences getNodeReferences(NodeId id)
-            throws NoSuchItemStateException, ItemStateException {
-
-        return workspaceItemStateMgr.getNodeReferences(id);
+    public Collection getReferingStates(NodeState nodeState) throws ItemStateException {
+        return workspaceItemStateMgr.getReferingStates(nodeState);
     }
 
     /**
      * {@inheritDoc}
-     * @see ItemStateManager#hasNodeReferences(NodeId)
+     * Since node references cannot be managed within the transient space,
+     * this call is delegated to the workspace itemstate manager.
+     * 
+     * @see ItemStateManager#hasReferingStates(NodeState)
+     * @param nodeState
      */
-    public boolean hasNodeReferences(NodeId id) {
-        return workspaceItemStateMgr.hasNodeReferences(id);
+    public boolean hasReferingStates(NodeState nodeState) {
+        return workspaceItemStateMgr.hasReferingStates(nodeState);
     }
 
     //------------------------------------------< UpdatableItemStateManager >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java Thu Aug 17 06:28:58 2006
@@ -28,6 +28,7 @@
 
 import javax.jcr.ItemExistsException;
 import java.util.Iterator;
+import java.util.Collection;
 
 /**
  * <code>TransientItemStateManager</code> implements a {@link ItemStateManager}
@@ -130,19 +131,25 @@
 
     /**
      * Always throws an {@link UnsupportedOperationException}. A transient item
-     * state manager does not maintain node reference.
-     * @see ItemStateManager#getNodeReferences(NodeId)
+     * state manager cannot not maintain node references.
+     *
+     * @param nodeState
+     * @throws UnsupportedOperationException
+     * @see ItemStateManager#getReferingStates(NodeState)
      */
-    public NodeReferences getNodeReferences(NodeId id) {
+    public Collection getReferingStates(NodeState nodeState) {
         throw new UnsupportedOperationException("getNodeReferences() not implemented");
     }
 
     /**
      * Always throws an {@link UnsupportedOperationException}. A transient item
-     * state manager does not maintain node reference.
-     * @see ItemStateManager#hasNodeReferences(NodeId)
+     * state manager cannot not maintain node references.
+     *
+     * @param nodeState
+     * @throws UnsupportedOperationException
+     * @see ItemStateManager#hasReferingStates(NodeState)
      */
-    public boolean hasNodeReferences(NodeId id) {
+    public boolean hasReferingStates(NodeState nodeState) {
         throw new UnsupportedOperationException("hasNodeReferences() not implemented");
     }
 
@@ -518,20 +525,30 @@
         }
 
         /**
-         * {@inheritDoc}
+         * Always throws <code>UnsupportedOperationException</code>. Within the
+         * transient space node references cannot be managed.
+         *
+         * @param nodeState
+         * @throws UnsupportedOperationException
+         * @see ItemStateManager#getReferingStates(NodeState)
          */
-        public NodeReferences getNodeReferences(NodeId id)
+        public Collection getReferingStates(NodeState nodeState)
                 throws NoSuchItemStateException, ItemStateException {
             // n/a
-            throw new ItemStateException("getNodeReferences() not implemented");
+            throw new UnsupportedOperationException("getNodeReferences() not implemented");
         }
 
         /**
-         * {@inheritDoc}
+         * Always throws <code>UnsupportedOperationException</code>. Within the
+         * transient space node references cannot be managed.
+         *
+         * @param nodeState
+         * @throws UnsupportedOperationException
+         * @see ItemStateManager#hasReferingStates(NodeState)
          */
-        public boolean hasNodeReferences(NodeId id) {
+        public boolean hasReferingStates(NodeState nodeState) {
             // n/a
-            return false;
+            throw new UnsupportedOperationException("getNodeReferences() not implemented");
         }
     }
 

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?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- 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 Thu Aug 17 06:28:58 2006
@@ -33,6 +33,11 @@
 import javax.jcr.PropertyType;
 import java.io.InputStream;
 import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Collections;
+import java.util.Arrays;
+import java.util.Iterator;
 
 /**
  * <code>WorkspaceItemStateFactory</code>...
@@ -133,6 +138,13 @@
                 state.addPropertyName(pId.getQName());
             }
 
+            // If the uuid is not null, the state could include mix:referenceable.
+            // Therefore build a NodeReference instance and add it to the state.
+            if (uuid != null) {
+                PropertyId[] references = info.getReferences();
+                state.addNodeReferences(new NodeReferencesImpl(info.getId(), references));
+            }
+
             // copied from local-state-mgr TODO... check
             // register as listener
             // TODO check if needed
@@ -230,6 +242,68 @@
             return state;
         } catch (IOException e) {
             throw new ItemStateException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * <code>NodeReferences</code> represents the references (i.e. properties of
+     * type <code>REFERENCE</code>) to a particular node (denoted by its uuid).
+     */
+    private class NodeReferencesImpl implements NodeReferences {
+
+        /**
+         * Identifier of this <code>NodeReferences</code> instance. Since the
+         * id of target state consists of a UUID and contains not relative
+         * path, the id will be stable and can be stored.
+         */
+        private NodeId nodeId;
+
+        /**
+         * Private constructor
+         *
+         * @param nodeId
+         * @param referenceIds
+         */
+        private NodeReferencesImpl(NodeId nodeId, PropertyId[] referenceIds) {
+            this.nodeId = nodeId;
+
+            // TODO: modify in order to 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.
+        }
+
+        //-------------------------------------------------< NodeReferences >---
+        /**
+         * @see NodeReferences#isEmpty()
+         */
+        public boolean isEmpty() {
+            try {
+                NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
+                return info.getReferences().length > 0;
+            } catch (RepositoryException e) {
+                log.error("Internal error.",e);
+                return false;
+            }
+        }
+
+        /**
+         * @see NodeReferences#iterator()
+         */
+        public Iterator iterator() {
+            try {
+                NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
+                if (info.getReferences().length > 0) {
+                    Set referenceIds = new HashSet();
+                    referenceIds.addAll(Arrays.asList(info.getReferences()));
+                    return Collections.unmodifiableSet(referenceIds).iterator();
+                } else {
+                    return Collections.EMPTY_SET.iterator();
+                }
+            } catch (RepositoryException e) {
+                log.error("Internal error.",e);
+                return Collections.EMPTY_SET.iterator();
+            }
         }
     }
 }

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?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- 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 Thu Aug 17 06:28:58 2006
@@ -36,8 +36,7 @@
         extends CachingItemStateManager
         implements InternalEventListener {
 
-    public WorkspaceItemStateManager(ItemStateFactory isf, IdFactory idFactory)
-            throws ItemStateException, NoSuchItemStateException {
+    public WorkspaceItemStateManager(ItemStateFactory isf, IdFactory idFactory) {
         super(isf, idFactory);
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java Thu Aug 17 06:28:58 2006
@@ -21,9 +21,11 @@
 
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.version.VersionException;
+
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.spi.NodeId;
 
 import java.util.Collection;
 
@@ -47,6 +49,10 @@
         return true;
     }
 
+    public void checkIsCheckedOut(NodeState nodeState) throws VersionException, RepositoryException {
+        // ignore
+    }
+
     public void removeVersion(NodeState versionHistoryState, NodeState versionState) throws RepositoryException {
         throw new UnsupportedRepositoryOperationException("Versioning ist not supported by this repository.");
     }
@@ -59,11 +65,11 @@
         throw new UnsupportedRepositoryOperationException("Versioning ist not supported by this repository.");
     }
 
-    public void restore(NodeId nodeId, NodeId versionId, boolean removeExisting) throws RepositoryException {
+    public void restore(NodeState nodeState, Path relativePath, NodeState versionState, boolean removeExisting) throws RepositoryException {
         throw new UnsupportedRepositoryOperationException("Versioning ist not supported by this repository.");
     }
 
-    public void restore(NodeId[] versionIds, boolean removeExisting) throws RepositoryException {
+    public void restore(NodeState[] versionStates, boolean removeExisting) throws RepositoryException {
         throw new UnsupportedRepositoryOperationException("Versioning ist not supported by this repository.");
     }
 

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java?rev=432234&r1=432233&r2=432234&view=diff
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManager.java Thu Aug 17 06:28:58 2006
@@ -16,11 +16,12 @@
  */
 package org.apache.jackrabbit.jcr2spi.version;
 
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 
 import javax.jcr.RepositoryException;
+import javax.jcr.version.VersionException;
 import java.util.Collection;
 
 /**
@@ -37,15 +38,17 @@
 
     public boolean isCheckedOut(NodeState nodeState) throws RepositoryException;
 
+    public void checkIsCheckedOut(NodeState nodeState) throws VersionException, RepositoryException;
+
     public void removeVersion(NodeState versionHistoryState, NodeState versionState) throws RepositoryException;
 
     public void addVersionLabel(NodeState versionHistoryState, NodeState versionState, QName qLabel, boolean moveLabel) throws RepositoryException;
 
     public void removeVersionLabel(NodeState versionHistoryState, NodeState versionState, QName qLabel) throws RepositoryException;
 
-    public void restore(NodeId nodeId, NodeId versionId, boolean removeExisting) throws RepositoryException;
+    public void restore(NodeState nodeState, Path relativePath, NodeState versionState, boolean removeExisting) throws RepositoryException;
 
-    public void restore(NodeId[] versionIds, boolean removeExisting) throws RepositoryException;
+    public void restore(NodeState[] versionStates, boolean removeExisting) throws RepositoryException;
 
     /**
      *