[exo-jcr-commits] exo-jcr SVN: r1456 - in jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core: lock and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Jan 18 03:53:57 EST 2010


Author: sergiykarpenko
Date: 2010-01-18 03:53:57 -0500 (Mon, 18 Jan 2010)
New Revision: 1456

Added:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManagerImpl.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableSessionLockManager.java
Modified:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockManager.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheLockImpl.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
Log:
EXOJCR-332: per-session lock manager implemented

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -1596,7 +1596,7 @@
       if (dataManager.hasPendingChanges(getInternalPath()))
          throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
 
-      Lock newLock = session.getLockManager().addPendingLock(this, isDeep, isSessionScoped, -1);
+      Lock newLock = session.getLockManager().addLock(this, isDeep, isSessionScoped, -1);
 
       PlainChangesLog changesLog =
          new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
@@ -1632,7 +1632,7 @@
       if (dataManager.hasPendingChanges(getInternalPath()))
          throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
 
-      Lock newLock = session.getLockManager().addPendingLock(this, isDeep, false, timeOut);
+      Lock newLock = session.getLockManager().addLock(this, isDeep, false, timeOut);
 
       PlainChangesLog changesLog =
          new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -32,6 +32,7 @@
 import org.exoplatform.services.jcr.datamodel.QPathEntry;
 import org.exoplatform.services.jcr.impl.Constants;
 import org.exoplatform.services.jcr.impl.core.lock.AbstractLockManager;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeImpl;
 import org.exoplatform.services.jcr.impl.core.observation.ObservationManagerImpl;
 import org.exoplatform.services.jcr.impl.core.observation.ObservationManagerRegistry;
@@ -120,7 +121,7 @@
 
    private final LocationFactory systemLocationFactory;
 
-   private final AbstractLockManager lockManager;
+   private final SessionLockManager lockManager;
 
    protected final String workspaceName;
 
@@ -145,7 +146,6 @@
    public SessionImpl(String workspaceName, ConversationState userState, ExoContainer container)
       throws RepositoryException
    {
-
       this.workspaceName = workspaceName;
       this.container = container;
       this.live = true;
@@ -156,7 +156,9 @@
       this.systemLocationFactory = (LocationFactory)container.getComponentInstanceOfType(LocationFactory.class);
 
       this.accessManager = (AccessManager)container.getComponentInstanceOfType(AccessManager.class);
-      this.lockManager = (AbstractLockManager)container.getComponentInstanceOfType(AbstractLockManager.class);
+      this.lockManager =
+         ((AbstractLockManager)container.getComponentInstanceOfType(AbstractLockManager.class))
+            .getSessionLockManager(id);
       WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
 
       this.lazyReadThreshold =
@@ -205,7 +207,7 @@
     */
    public void addLockToken(String lt)
    {
-      getLockManager().addLockToken(getId(), lt);
+      getLockManager().addLockToken(lt);
    }
 
    /**
@@ -551,7 +553,7 @@
       return locationFactory;
    }
 
-   public AbstractLockManager getLockManager()
+   public SessionLockManager getLockManager()
    {
       return lockManager;
    }
@@ -561,7 +563,7 @@
     */
    public String[] getLockTokens()
    {
-      return getLockManager().getLockTokens(getId());
+      return getLockManager().getLockTokens();
    }
 
    /**
@@ -919,7 +921,7 @@
     */
    public void removeLockToken(String lt)
    {
-      getLockManager().removeLockToken(getId(), lt);
+      getLockManager().removeLockToken(lt);
    }
 
    /**
@@ -969,7 +971,7 @@
    {
       return this.userState;
    }
-   
+
    int getLazyReadThreshold()
    {
       return lazyReadThreshold;

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockManager.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockManager.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -16,15 +16,6 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-
-import org.exoplatform.services.jcr.core.ExtendedSession;
-import org.exoplatform.services.jcr.core.SessionLifecycleListener;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.core.NodeImpl;
-
 /**
  * Created by The eXo Platform SAS.
  * 
@@ -33,58 +24,7 @@
  * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
  * @version $Id$
  */
-public abstract class AbstractLockManager implements SessionLifecycleListener, LockManager
+public abstract class AbstractLockManager implements LockManager
 {
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract void onCloseSession(ExtendedSession session);
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract void addLockToken(String sessionId, String lt);
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract Lock addPendingLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut)
-            throws LockException, RepositoryException;
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract LockImpl getLock(NodeImpl node) throws LockException, RepositoryException;
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract String[] getLockTokens(String sessionID);
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract boolean holdsLock(NodeData node) throws RepositoryException;
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract boolean isLockHolder(NodeImpl node) throws RepositoryException;
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract boolean isLocked(NodeData node);
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract void removeExpired();
-
-   /**
-    * {@inheritDoc}
-    */
-   public abstract void removeLockToken(String sessionId, String lt);
-
+   //TODO remove this class
 }

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -18,13 +18,6 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock;
 
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.core.NodeImpl;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-
 /**
  * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
  * @version $Id: LockManager.java 11907 2008-03-13 15:36:21Z ksm $
@@ -32,85 +25,15 @@
 public interface LockManager
 {
    /**
-    * Invoked by a session to inform that a lock token has been added.
-    * 
-    * @param session
-    *          session that has a added lock token
-    * @param lt
-    *          added lock token
+    * Remove expired locks. Called by LockRemover timer.
     */
-   public void addLockToken(String sessionId, String lt);
+   void removeExpired();
 
-   public Lock addPendingLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut)
-      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.
+    * Returns session lock manager that interact with this LockManager.
     * 
-    * @param node
-    *          node
-    * @return lock object
-    * @throws LockException
-    *           if this node is not locked
-    * @see javax.jcr.Node#getLock
+    * @param sessionId - sessionId
+    * @return
     */
-   public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException;
-
-   /**
-    * Return lock tokens enshrined by session
-    * 
-    * @param sessionID
-    *          - Id of session.
-    * @return array of lock tokens.
-    */
-   public String[] getLockTokens(String sessionID);
-
-   /**
-    * Returns <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>.
-    * 
-    * @param node
-    *          node
-    * @return <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>
-    * @see javax.jcr.Node#holdsLock
-    */
-   public boolean holdsLock(NodeData node) throws 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>
-    * 
-    * @param node
-    *          node
-    * @return <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>
-    * @see javax.jcr.Node#isLocked
-    */
-   public boolean isLocked(NodeData node);
-
-   /**
-    * Returns <code>true</code> if the specified session holds a lock on the given node; otherwise
-    * returns <code>false</code>. <p/> Note that <code>isLockHolder(session, node)==true</code>
-    * implies <code>holdsLock(node)==true</code>.
-    * 
-    * @param session
-    *          session
-    * @param node
-    *          node
-    * @return if the specified session holds a lock on the given node; otherwise returns
-    *         <code>false</code>
-    */
-   public boolean isLockHolder(NodeImpl node) throws RepositoryException;
-
-   /**
-    * Invoked by a session to inform that a lock token has been removed.
-    * 
-    * @param session
-    *          session that has a removed lock token
-    * @param lt
-    *          removed lock token
-    */
-   public void removeLockToken(String sessionId, String lt);
-
-   public void removeExpired();
+   SessionLockManager getSessionLockManager(String sessionId);
 }

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -18,21 +18,6 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.AccessDeniedException;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-
 import org.exoplatform.management.annotations.Managed;
 import org.exoplatform.management.annotations.ManagedDescription;
 import org.exoplatform.management.jmx.annotations.NameTemplate;
@@ -66,6 +51,21 @@
 import org.exoplatform.services.log.Log;
 import org.picocontainer.Startable;
 
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+
 /**
  * Created by The eXo Platform SAS.
  * 
@@ -793,4 +793,9 @@
    {
       return true;
    }
+
+   public SessionLockManager getSessionLockManager(String sessionId)
+   {
+      return new SessionLockManagerImpl(sessionId, this);
+   }
 }

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.lock;
+
+import org.exoplatform.services.jcr.core.SessionLifecycleListener;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 
+ *
+ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
+ * @version $Id: SessionLockManager.java 111 2008-11-11 11:11:11Z serg $
+ */
+public interface SessionLockManager extends SessionLifecycleListener
+{
+
+   /**
+    * Invoked by a session to inform that a lock token has been added.
+    * 
+    * @param lt
+    *          added lock token
+    */
+   void addLockToken(String lt);
+
+   Lock addLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut) 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.
+    * 
+    * @param node
+    *          node
+    * @return lock object
+    * @throws LockException
+    *           if this node is not locked
+    * @see javax.jcr.Node#getLock
+    */
+   LockImpl getLock(NodeImpl node) throws LockException, RepositoryException;
+
+   /**
+    * Return lock tokens enshrined by session
+    * 
+    * @param sessionID
+    *          - Id of session.
+    * @return array of lock tokens.
+    */
+   String[] getLockTokens();
+
+   /**
+    * Returns <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>.
+    * 
+    * @param node
+    *          node
+    * @return <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>
+    * @see javax.jcr.Node#holdsLock
+    */
+   boolean holdsLock(NodeData node) throws 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>
+    * 
+    * @param node
+    *          node
+    * @return <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>
+    * @see javax.jcr.Node#isLocked
+    */
+   boolean isLocked(NodeData node);
+
+   /**
+    * Returns <code>true</code> if the specified session holds a lock on the given node; otherwise
+    * returns <code>false</code>. <p/> Note that <code>isLockHolder(session, node)==true</code>
+    * implies <code>holdsLock(node)==true</code>.
+    * 
+    * @param session
+    *          session
+    * @param node
+    *          node
+    * @return if the specified session holds a lock on the given node; otherwise returns
+    *         <code>false</code>
+    */
+   boolean isLockHolder(NodeImpl node) throws RepositoryException;
+
+   /**
+    * Invoked by a session to inform that a lock token has been removed.
+    * 
+    * @param session
+    *          session that has a removed lock token
+    * @param lt
+    *          removed lock token
+    */
+   void removeLockToken(String lt);
+
+}

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManagerImpl.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManagerImpl.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.lock;
+
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 
+ *
+ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
+ * @version $Id: SessionLockManagerImpl.java 111 2008-11-11 11:11:11Z serg $
+ */
+public class SessionLockManagerImpl implements SessionLockManager
+{
+
+   private final String sessionId;
+
+   private final LockManagerImpl lockManager;
+
+   public SessionLockManagerImpl(String sessionId, LockManagerImpl lockManager)
+   {
+      this.sessionId = sessionId;
+      this.lockManager = lockManager;
+   }
+
+   public Lock addLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut) throws LockException,
+      RepositoryException
+   {
+      return lockManager.addPendingLock(node, isDeep, isSessionScoped, timeOut);
+   }
+
+   public void addLockToken(String lt)
+   {
+      lockManager.addLockToken(sessionId, lt);
+   }
+
+   public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException
+   {
+      return lockManager.getLock(node);
+   }
+
+   public String[] getLockTokens()
+   {
+      return lockManager.getLockTokens(sessionId);
+   }
+
+   public boolean holdsLock(NodeData node) throws RepositoryException
+   {
+      return lockManager.holdsLock(node);
+   }
+
+   public boolean isLockHolder(NodeImpl node) throws RepositoryException
+   {
+      return lockManager.isLockHolder(node);
+   }
+
+   public boolean isLocked(NodeData node)
+   {
+      return lockManager.isLocked(node);
+   }
+
+   public void removeLockToken(String lt)
+   {
+      lockManager.removeLockToken(sessionId, lt);
+   }
+
+   public void onCloseSession(ExtendedSession session)
+   {
+      lockManager.onCloseSession(session);
+   }
+
+}

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheLockImpl.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheLockImpl.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheLockImpl.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -39,7 +39,7 @@
 
    private SessionImpl session;
 
-   private CacheableLockManager lockManager;
+   private CacheableSessionLockManager lockManager;
 
    /**
     * Constructor.
@@ -48,7 +48,7 @@
     * @param lockData - LockData
     * @param lockManager - CacheableLockManager
     */
-   public CacheLockImpl(SessionImpl session, LockData lockData, CacheableLockManager lockManager)
+   public CacheLockImpl(SessionImpl session, LockData lockData, CacheableSessionLockManager lockManager)
    {
       this.lockData = lockData;
       this.session = session;
@@ -69,7 +69,7 @@
     */
    public String getLockToken()
    {
-      return lockManager.getLockToken(session.getId(), lockData.getTokenHash());
+      return lockManager.getLockToken(lockData.getTokenHash());
    }
 
    /**

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java	2010-01-18 08:39:04 UTC (rev 1455)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -24,7 +24,6 @@
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.SimpleParameterEntry;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.core.ExtendedSession;
 import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
 import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
 import org.exoplatform.services.jcr.dataflow.DataManager;
@@ -40,16 +39,14 @@
 import org.exoplatform.services.jcr.datamodel.QPathEntry;
 import org.exoplatform.services.jcr.impl.Constants;
 import org.exoplatform.services.jcr.impl.core.NodeImpl;
-import org.exoplatform.services.jcr.impl.core.SessionImpl;
 import org.exoplatform.services.jcr.impl.core.lock.AbstractLockManager;
-import org.exoplatform.services.jcr.impl.core.lock.LockImpl;
 import org.exoplatform.services.jcr.impl.core.lock.LockPersister;
 import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
 import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
 import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
 import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
 import org.exoplatform.services.jcr.observation.ExtendedEvent;
-import org.exoplatform.services.jcr.util.IdGenerator;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 import org.jboss.cache.Cache;
@@ -70,10 +67,7 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.jcr.AccessDeniedException;
 import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.lock.Lock;
 import javax.jcr.lock.LockException;
 
 /**
@@ -107,17 +101,17 @@
    /**
     * The exact lock token.
     */
-   private static final int SEARCH_EXECMATCH = 1;
+   protected static final int SEARCH_EXECMATCH = 1;
 
    /**
     * Lock token of closed parent
     */
-   private static final int SEARCH_CLOSEDPARENT = 2;
+   protected static final int SEARCH_CLOSEDPARENT = 2;
 
    /**
     * Lock token of closed child
     */
-   private static final int SEARCH_CLOSEDCHILD = 4;
+   protected static final int SEARCH_CLOSEDCHILD = 4;
 
    /**
     * Name of lock root in jboss-cache.
@@ -145,11 +139,6 @@
    private final Map<String, LockData> pendingLocks;
 
    /**
-    * [session id , [lock token hash, lock tokens id]]
-    */
-   private final Map<String, Map<String, String>> lockTokenHolders;
-
-   /**
     * Run time lock time out.
     */
    private long lockTimeOut;
@@ -198,7 +187,6 @@
       else
          lockTimeOut = DEFAULT_LOCK_TIMEOUT;
 
-      lockTokenHolders = new HashMap<String, Map<String, String>>();
       pendingLocks = new HashMap<String, LockData>();
 
       dataManager.addItemPersistenceListener(this);
@@ -225,53 +213,12 @@
    /*
     * (non-Javadoc)
     * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#lockTokenAdded(org.exoplatform.services
-    * .jcr.impl.core.SessionImpl, java.lang.String)
-    */
-   public synchronized void addLockToken(String sessionId, String lt)
-   {
-      holdLockToken(sessionId, getHash(lt), lt);
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see
     * org.exoplatform.services.jcr.impl.core.lock.LockManager#addPendingLock(org.exoplatform.services
     * .jcr.impl.core.NodeImpl, boolean, boolean, long)
     */
-   public synchronized Lock addPendingLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut)
-      throws LockException
+   public synchronized void addPendingLock(String nodeIdentifier, LockData lData)
    {
-      LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-      if (lData != null)
-      {
-         if (lData.getNodeIdentifier().equals(node.getInternalIdentifier()))
-         {
-            throw new LockException("Node already locked: " + node.getData().getQPath());
-         }
-         else if (lData.isDeep())
-         {
-            throw new LockException("Parent node has deep lock.");
-         }
-      }
-
-      if (isDeep && getLockData((NodeData)node.getData(), SEARCH_CLOSEDCHILD) != null)
-      {
-         throw new LockException("Some child node is locked.");
-      }
-
-      String lockToken = IdGenerator.generate();
-      String lockTokenHash = getHash(lockToken);
-
-      lData =
-         new LockData(node.getInternalIdentifier(), lockTokenHash, isDeep, isSessionScoped, node.getSession()
-            .getUserID(), timeOut > 0 ? timeOut : lockTimeOut);
-
-      holdLockToken(node.getSession().getId(), lockTokenHash, lockToken);
-      pendingLocks.put(node.getInternalIdentifier(), lData);
-
-      LockImpl lock = new CacheLockImpl(node.getSession(), lData, this);
-      return lock;
+      pendingLocks.put(nodeIdentifier, lData);
    }
 
    @Managed
@@ -281,13 +228,18 @@
       removeExpired();
    }
 
+   public long getDefaultLockTimeOut()
+   {
+      return lockTimeOut;
+   }
+
    /*
     * (non-Javadoc)
     * @see
     * org.exoplatform.services.jcr.impl.core.lock.LockManager#getLock(org.exoplatform.services.jcr
     * .impl.core.NodeImpl)
     */
-   public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException
+   public LockData getLockData(NodeImpl node) throws LockException, RepositoryException
    {
 
       LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
@@ -296,29 +248,9 @@
       {
          throw new LockException("Node not locked: " + node.getData().getQPath());
       }
-      return new CacheLockImpl(node.getSession(), lData, this);
+      return lData;
    }
 
-   /*
-    * (non-Javadoc)
-    * @see org.exoplatform.services.jcr.impl.core.lock.LockManager#getLockTokens(java.lang.String)
-    */
-   public synchronized String[] getLockTokens(String sessionID)
-   {
-      Map<String, String> lockTokens = lockTokenHolders.get(sessionID);
-
-      if (lockTokens != null)
-      {
-         String[] arr = new String[lockTokens.size()];
-         lockTokens.values().toArray(arr);
-         return arr;
-      }
-      else
-      {
-         return new String[0];
-      }
-   }
-
    @Managed
    @ManagedDescription("The number of active locks")
    public int getNumLocks()
@@ -326,44 +258,23 @@
       return lockRoot.getChildrenNames().size();
    }
 
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#holdsLock(org.exoplatform.services.
-    * jcr.impl.core.NodeImpl)
+   /**
+    * 
     */
-   public boolean holdsLock(NodeData node) throws RepositoryException
+   public SessionLockManager getSessionLockManager(String sessionId)
    {
-      return getLockData(node, SEARCH_EXECMATCH) != null;
+      CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this);
+      return sessionManager;
    }
 
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#isLocked(org.exoplatform.services.jcr
-    * .datamodel.NodeData)
-    */
-   public boolean isLocked(NodeData node)
+   public boolean isLockLive(String nodeId)
    {
-      LockData lData = getLockData(node, SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
-      if (lData == null || (!node.getIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
+      if (pendingLocks.containsKey(nodeId) || lockRoot.hasChild(Fqn.fromString(nodeId)))
       {
-         return false;
+         return true;
       }
-      return true;
-   }
 
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#isLockHolder(org.exoplatform.services
-    * .jcr.impl.core.NodeImpl)
-    */
-   public boolean isLockHolder(NodeImpl node) throws RepositoryException
-   {
-      LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-      return lData != null && isLockHolder(node.getSession().getId(), lData.getTokenHash());
+      return false;
    }
 
    /**
@@ -376,56 +287,6 @@
 
    /*
     * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.core.SessionLifecycleListener#onCloseSession(org.exoplatform.services
-    * .jcr.core.ExtendedSession)
-    */
-   public synchronized void onCloseSession(ExtendedSession session)
-   {
-      SessionImpl sessionImpl = (SessionImpl)session;
-
-      for (LockData lockData : getLockList())
-      {
-         // check is lock holder
-         if (lockTokenHolders.containsKey(session.getId())
-            && lockTokenHolders.get(session.getId()).containsKey(lockData.getTokenHash()))
-         {
-            if (lockData.isSessionScoped())
-            {
-               // if no session currently holds lock except this
-               try
-               {
-                  ((NodeImpl)sessionImpl.getTransientNodesManager().getItemByIdentifier(lockData.getNodeIdentifier(),
-                     false)).unlock();
-               }
-               catch (UnsupportedRepositoryOperationException e)
-               {
-                  log.error(e.getLocalizedMessage());
-               }
-               catch (LockException e)
-               {
-                  log.error(e.getLocalizedMessage());
-               }
-               catch (AccessDeniedException e)
-               {
-                  log.error(e.getLocalizedMessage());
-               }
-               catch (RepositoryException e)
-               {
-                  log.error(e.getLocalizedMessage());
-               }
-
-            }
-            else
-            {
-               removeLockTokenByHash(session.getId(), lockData.getTokenHash());
-            }
-         }
-      }
-   }
-
-   /*
-    * (non-Javadoc)
     * @seeorg.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener#onSaveItems(org.
     * exoplatform.services.jcr.dataflow.ItemStateChangesLog)
     */
@@ -573,36 +434,11 @@
       }
    }
 
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#lockTokenRemoved(org.exoplatform.services
-    * .jcr.impl.core.SessionImpl, java.lang.String)
-    */
-   public synchronized void removeLockToken(String sessionId, String lt)
+   public void removePendingLock(String nodeId)
    {
-      if (lockTokenHolders.containsKey(sessionId) && lockTokenHolders.get(sessionId).containsValue(lt))
-      {
-         lockTokenHolders.get(sessionId).remove(getHash(lt));
-         if (lockTokenHolders.get(sessionId).size() == 0)
-         {
-            lockTokenHolders.remove(sessionId);
-         }
-      }
+      pendingLocks.remove(nodeId);
    }
 
-   public synchronized void removeLockTokenByHash(String sessionId, String ltHash)
-   {
-      if (lockTokenHolders.containsKey(sessionId) && lockTokenHolders.get(sessionId).containsKey(ltHash))
-      {
-         lockTokenHolders.get(sessionId).remove(ltHash);
-         if (lockTokenHolders.get(sessionId).size() == 0)
-         {
-            lockTokenHolders.remove(sessionId);
-         }
-      }
-   }
-
    /*
     * (non-Javadoc)
     * @see org.picocontainer.Startable#start()
@@ -610,7 +446,6 @@
    public void start()
    {
       cache.start();
-      //tokenRoot = cache.getRoot().addChild(Fqn.fromString(TOKENS));
       lockRoot = cache.getRoot().addChild(Fqn.fromString(LOCKS));
       lockRoot.setResident(true);
       lockRemover = new LockRemover(this);
@@ -625,14 +460,6 @@
       lockRemover.halt();
       lockRemover.interrupt();
       pendingLocks.clear();
-
-      // clear lockTokenHolders
-      for (String sessionId : lockTokenHolders.keySet())
-      {
-         lockTokenHolders.get(sessionId).clear();
-      }
-      lockTokenHolders.clear();
-
       cache.stop();
    }
 
@@ -658,12 +485,70 @@
    }
 
    /**
+    * Internal lock
+    * 
+    * @param nodeIdentifier
+    * @throws LockException
+    */
+   private synchronized void internalLock(String nodeIdentifier) throws LockException
+   {
+      LockData lockData = pendingLocks.get(nodeIdentifier);
+      if (lockData != null)
+      {
+         Fqn<String> lockPath = Fqn.fromString(lockData.getNodeIdentifier());
+
+         // addChild will add if absent or return old if present
+         Node<Serializable, Object> node = lockRoot.addChild(lockPath);
+
+         // this will prevent from deleting by eviction.
+         node.setResident(true);
+
+         // this will return null if success. And old data if something exists...
+         LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
+
+         if (oldLockData != null)
+         {
+            throw new LockException("Unable to write LockData. Node [" + lockData.getNodeIdentifier()
+               + "] already has LockData!");
+         }
+         pendingLocks.remove(nodeIdentifier);
+      }
+      else
+      {
+         throw new LockException("No lock in pending locks");
+      }
+   }
+
+   /**
+    * Internal unlock.
+    * 
+    * @param sessionId
+    * @param nodeIdentifier
+    * @throws LockException
+    */
+   private synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
+   {
+      LockData lData = getLockDataById(nodeIdentifier);
+
+      if (lData != null)
+      {
+         lockRoot.removeChild(Fqn.fromString(nodeIdentifier));
+         // TODO pair nodeId and lockData is not removed from CacheableSessionLockManager 
+      }
+   }
+
+   private boolean lockExist(String nodeId)
+   {
+      return lockRoot.hasChild(Fqn.fromString(nodeId));
+   }
+
+   /**
     * Calculates md5 hash of string.
     * 
     * @param token
     * @return
     */
-   private String getHash(String token)
+   protected String getHash(String token)
    {
       String hash = "";
       try
@@ -686,7 +571,7 @@
     * @param searchType
     * @return
     */
-   private LockData getLockData(NodeData data, int searchType)
+   protected LockData getLockData(NodeData data, int searchType)
    {
       if (data == null)
          return null;
@@ -741,122 +626,6 @@
       return retval;
    }
 
-   private void holdLockToken(String sessionId, String ltHash, String lt)
-   {
-      if (lockTokenHolders.get(sessionId) == null)
-      {
-         lockTokenHolders.put(sessionId, new HashMap<String, String>());
-      }
-      // put token hash and token 
-      lockTokenHolders.get(sessionId).put(ltHash, lt);
-   }
-
-   /**
-    * Internal lock
-    * 
-    * @param nodeIdentifier
-    * @throws LockException
-    */
-   private synchronized void internalLock(String nodeIdentifier) throws LockException
-   {
-      LockData lockData = pendingLocks.get(nodeIdentifier);
-      if (lockData != null)
-      {
-         Fqn<String> lockPath = Fqn.fromString(lockData.getNodeIdentifier());
-
-         // addChild will add if absent or return old if present
-         Node<Serializable, Object> node = lockRoot.addChild(lockPath);
-
-         // this will prevent from deleting by eviction.
-         node.setResident(true);
-
-         // this will return null if success. And old data if something exists...
-         LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
-
-         if (oldLockData != null)
-         {
-            throw new LockException("Unable to write LockData. Node [" + lockData.getNodeIdentifier()
-               + "] already has LockData!");
-         }
-         pendingLocks.remove(nodeIdentifier);
-      }
-      else
-      {
-         throw new LockException("No lock in pending locks");
-      }
-   }
-
-   /**
-    * For locks comes from remote JCRs (replication usecase)
-    * 
-    * @param sessionId
-    *          String
-    * @param nodeIdentifier
-    *          String
-    * @param lockToken
-    *          String
-    * @param isDeep
-    *          boolean
-    * @param sessionScoped
-    *          boolean
-    * @param owner
-    *          String
-    * @return LockData
-    */
-   //   private synchronized LockData createRemoteLock(String sessionId, String nodeIdentifier, String lockToken,
-   //      boolean isDeep, boolean sessionScoped, String owner)
-   //   {
-   //      LockData lData = new LockData(nodeIdentifier, lockToken, isDeep, sessionScoped, owner, lockTimeOut);
-   //      lData.addLockHolder(sessionId);
-   //      locks.put(nodeIdentifier, lData);
-   //      tokensMap.put(lockToken, lData);
-   //
-   //      return lData;
-   //   }
-
-   /**
-    * Internal unlock.
-    * 
-    * @param sessionId
-    * @param nodeIdentifier
-    * @throws LockException
-    */
-   private synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
-   {
-      LockData lData = getLockDataById(nodeIdentifier);
-
-      if (lData != null)
-      {
-         //tokenRoot.removeChild(Fqn.fromString(lData.getToken()));
-         lockRoot.removeChild(Fqn.fromString(nodeIdentifier));
-
-         // remove session holder
-         if (lockTokenHolders.containsKey(sessionId))
-         {
-            lockTokenHolders.get(sessionId).remove(lData.getTokenHash());
-            if (lockTokenHolders.get(sessionId).size() == 0)
-            {
-               lockTokenHolders.remove(sessionId);
-            }
-         }
-      }
-   }
-
-   private boolean isLockHolder(String sessionId, String lockTokenHash)
-   {
-      Map<String, String> lockTokens = lockTokenHolders.get(sessionId);
-      if (lockTokens != null)
-      {
-         return lockTokens.containsKey(lockTokenHash);
-      }
-      return false;
-   }
-
-   private boolean lockExist(String nodeId)
-   {
-      return lockRoot.hasChild(Fqn.fromString(nodeId));
-   }
-
    protected LockData getLockDataById(String nodeId)
    {
       LockData lockData = null;
@@ -920,26 +689,4 @@
          log.error("Error occur during removing lock" + e.getLocalizedMessage(), e);
       }
    }
-
-   public String getLockToken(String sessionId, String tokenHash)
-   {
-      if (lockTokenHolders.containsKey(sessionId))
-      {
-         return lockTokenHolders.get(sessionId).get(tokenHash);
-      }
-      else
-      {
-         return null;
-      }
-   }
-
-   public boolean isLockLive(String nodeId)
-   {
-      if (pendingLocks.containsKey(nodeId) || lockRoot.hasChild(Fqn.fromString(nodeId)))
-      {
-         return true;
-      }
-
-      return false;
-   }
 }

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableSessionLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableSessionLockManager.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableSessionLockManager.java	2010-01-18 08:53:57 UTC (rev 1456)
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.lock.jbosscache;
+
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.lock.LockImpl;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
+import org.exoplatform.services.jcr.util.IdGenerator;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 
+ *
+ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
+ * @version $Id: SessionLockManager.java 111 2008-11-11 11:11:11Z serg $
+ */
+public class CacheableSessionLockManager implements SessionLockManager
+{
+   /**
+    * Logger
+    */
+   private final Log log = ExoLogger.getLogger("jcr.lock.SessionLockManager");
+
+   private final String sessionID;
+
+   /**
+    * [token name, tokens hash]
+    */
+   private final Map<String, String> tokens;
+
+   private final Map<String, LockData> lockedNodes;
+
+   private final CacheableLockManager lockManager;
+
+   public CacheableSessionLockManager(String sessionID, CacheableLockManager lockManager)
+   {
+      this.sessionID = sessionID;
+      this.tokens = new HashMap<String, String>();
+      this.lockedNodes = new HashMap<String, LockData>();
+      this.lockManager = lockManager;
+   }
+
+   public Lock addLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut) throws LockException,
+      RepositoryException
+   {
+
+      String nodeIdentifier = node.getInternalIdentifier();
+      LockData lData =
+         lockManager.getLockData((NodeData)node.getData(), CacheableLockManager.SEARCH_EXECMATCH
+            | CacheableLockManager.SEARCH_CLOSEDPARENT);
+      if (lData != null)
+      {
+         if (lData.getNodeIdentifier().equals(node.getInternalIdentifier()))
+         {
+            throw new LockException("Node already locked: " + node.getData().getQPath());
+         }
+         else if (lData.isDeep())
+         {
+            throw new LockException("Parent node has deep lock.");
+         }
+      }
+
+      if (isDeep && lockManager.getLockData((NodeData)node.getData(), CacheableLockManager.SEARCH_CLOSEDCHILD) != null)
+      {
+         throw new LockException("Some child node is locked.");
+      }
+
+      String lockToken = IdGenerator.generate();
+      String lockTokenHash = lockManager.getHash(lockToken);
+
+      lData =
+         new LockData(nodeIdentifier, lockTokenHash, isDeep, isSessionScoped, node.getSession().getUserID(),
+            timeOut > 0 ? timeOut : lockManager.getDefaultLockTimeOut());
+
+      lockedNodes.put(node.getInternalIdentifier(), lData);
+      lockManager.addPendingLock(nodeIdentifier, lData);
+      tokens.put(lockToken, lockTokenHash);
+
+      LockImpl lock = new CacheLockImpl(node.getSession(), lData, this);
+
+      return lock;
+
+   }
+
+   public void addLockToken(String lt)
+   {
+      tokens.put(lt, lockManager.getHash(lt));
+   }
+
+   public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException
+   {
+      LockData lData =
+         lockManager.getLockData((NodeData)node.getData(), CacheableLockManager.SEARCH_EXECMATCH
+            | CacheableLockManager.SEARCH_CLOSEDPARENT);
+
+      if (lData == null || (!node.getInternalIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
+      {
+         throw new LockException("Node not locked: " + node.getData().getQPath());
+      }
+      return new CacheLockImpl(node.getSession(), lData, this);
+   }
+
+   public String[] getLockTokens()
+   {
+      String[] arr = new String[tokens.size()];
+      tokens.keySet().toArray(arr);
+      return arr;
+   }
+
+   public boolean holdsLock(NodeData node) throws RepositoryException
+   {
+      return lockManager.getLockData(node, CacheableLockManager.SEARCH_EXECMATCH) != null;
+   }
+
+   public boolean isLocked(NodeData node)
+   {
+      LockData lData =
+         lockManager
+            .getLockData(node, CacheableLockManager.SEARCH_EXECMATCH | CacheableLockManager.SEARCH_CLOSEDPARENT);
+
+      if (lData == null || (!node.getIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+   public boolean isLockHolder(NodeImpl node) throws RepositoryException
+   {
+      LockData lData =
+         lockManager.getLockData((NodeData)node.getData(), CacheableLockManager.SEARCH_EXECMATCH
+            | CacheableLockManager.SEARCH_CLOSEDPARENT);
+
+      return lData != null && isLockHolder(lData);
+   }
+
+   public void onCloseSession(ExtendedSession session)
+   {
+      SessionImpl sessionImpl = (SessionImpl)session;
+
+      String[] nodeIds = new String[lockedNodes.size()];
+      lockedNodes.keySet().toArray(nodeIds);
+
+      for (String nodeId : nodeIds)
+      {
+         LockData lock = lockedNodes.remove(nodeId);
+
+         if (lock.isSessionScoped())
+         {
+            try
+            {
+               NodeImpl node =
+                  ((NodeImpl)sessionImpl.getTransientNodesManager()
+                     .getItemByIdentifier(lock.getNodeIdentifier(), false));
+
+               // Node may be null, since cacheablelockManger.internalUnlock does not modify
+               // SessionLockManager.lockedNodes map. So Node and Lock is removed, but exist in lockedNodes list.
+               if (node != null)
+               {
+                  node.unlock();
+               }
+
+            }
+            catch (UnsupportedRepositoryOperationException e)
+            {
+               log.error(e.getLocalizedMessage());
+            }
+            catch (LockException e)
+            {
+               log.error(e.getLocalizedMessage());
+            }
+            catch (AccessDeniedException e)
+            {
+               log.error(e.getLocalizedMessage());
+            }
+            catch (RepositoryException e)
+            {
+               log.error(e.getLocalizedMessage());
+            }
+         }
+         else
+         {
+            lockManager.removePendingLock(nodeId);
+
+            lockedNodes.remove(nodeId);
+
+            //remove token
+            String hash = lock.getTokenHash();
+            for (String token : tokens.keySet())
+            {
+               if (tokens.get(token).equals(hash))
+               {
+                  tokens.remove(token);
+                  break;
+               }
+            }
+         }
+      }
+   }
+
+   public void removeLockToken(String lt)
+   {
+      tokens.remove(lt);
+   }
+
+   /**
+    * Checks if session has token to this lock data or session is System.
+    * 
+    * @param lockData
+    * @return
+    */
+   private boolean isLockHolder(LockData lockData)
+   {
+      return (SystemIdentity.SYSTEM.equals(sessionID) || tokens.containsValue(lockData.getTokenHash()));
+   }
+
+   /**
+    * Returns real token, if session has it
+    * 
+    * @param lockData
+    * @return
+    */
+   protected String getLockToken(String tokenHash)
+   {
+      for (String token : tokens.keySet())
+      {
+         if (tokens.get(token).equals(tokenHash))
+         {
+            return token;
+         }
+      }
+      return null;
+   }
+
+   protected boolean isLockLive(String nodeIdentifier)
+   {
+      return lockManager.isLockLive(nodeIdentifier);
+   }
+
+   protected void refresh(LockData newLockData) throws LockException
+   {
+      lockManager.refresh(newLockData);
+   }
+
+}



More information about the exo-jcr-commits mailing list