[exo-jcr-commits] exo-jcr SVN: r723 - in jcr/branches/1.12.0-JBC/component/core/src: main/java/org/exoplatform/services/jcr/impl and 5 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Nov 17 11:18:15 EST 2009


Author: nzamosenchuk
Date: 2009-11-17 11:18:15 -0500 (Tue, 17 Nov 2009)
New Revision: 723

Added:
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
Removed:
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java
   jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java
   jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java
Modified:
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java
   jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
Log:
EXOJCR-243: Initial implementation of new lock manager: Created class: SessionLockManager, updated NodeImpl and SessionImpl to use it, reworked LockData and LockImpl. Removed LockCacheLoaders and it's tests, old LockManager and LockRemover*. Needed to implement: Lock removing on session logout, lock removing by time out. Fill JBossCacheWorkspaceDataManager with functionality. 

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -18,6 +18,8 @@
  */
 package org.exoplatform.services.jcr.core.lock;
 
+import org.exoplatform.services.jcr.impl.core.lock.LockData;
+
 import javax.jcr.lock.Lock;
 
 /**
@@ -31,4 +33,9 @@
     * @return The time to death in sec
     */
    public long getTimeToDeath();
+
+   /**
+    * @return LockData instance
+    */
+   public LockData getLockData();
 }

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -40,7 +40,6 @@
 import org.exoplatform.services.jcr.impl.core.SessionRegistry;
 import org.exoplatform.services.jcr.impl.core.WorkspaceInitializer;
 import org.exoplatform.services.jcr.impl.core.access.DefaultAccessManagerImpl;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeDataManagerImpl;
 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
 import org.exoplatform.services.jcr.impl.core.nodetype.registration.JcrNodeTypeDataPersister;
@@ -259,23 +258,6 @@
          workspaceContainer.registerComponentImplementation(LocalWorkspaceDataManagerStub.class);
          workspaceContainer.registerComponentImplementation(ObservationManagerRegistry.class);
 
-         // Lock manager and Lock persister is a optional parameters
-         if (wsConfig.getLockManager() != null && wsConfig.getLockManager().getPersister() != null)
-         {
-            try
-            {
-               Class<?> lockPersister = Class.forName(wsConfig.getLockManager().getPersister().getType());
-               workspaceContainer.registerComponentImplementation(lockPersister);
-            }
-            catch (ClassNotFoundException e)
-            {
-               throw new RepositoryConfigurationException("Class not found for workspace lock persister "
-                  + wsConfig.getLockManager().getPersister().getType() + ", container " + wsConfig.getUniqueName()
-                  + " : " + e);
-            }
-         }
-         workspaceContainer.registerComponentImplementation(LockManagerImpl.class);
-
          // Query handler
          if (wsConfig.getQueryHandler() != null)
          {

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -29,6 +29,7 @@
 import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
 import org.exoplatform.services.jcr.core.nodetype.PropertyDefinitionData;
 import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.LockPlainChangesLogImpl;
 import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
 import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
 import org.exoplatform.services.jcr.datamodel.Identifier;
@@ -895,7 +896,7 @@
 
       checkValid();
 
-      LockImpl lock = session.getLockManager().getLock(this);
+      LockImpl lock = session.getLockManager().getLock((NodeData)this.getData());
       if (lock == null)
          throw new LockException("Lock not found " + getPath());
       return lock;
@@ -1279,7 +1280,6 @@
     */
    public boolean isLocked() throws RepositoryException
    {
-
       checkValid();
       return session.getLockManager().isLocked((NodeData)this.getData());
    }
@@ -1359,7 +1359,7 @@
    public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException,
       LockException, AccessDeniedException, RepositoryException
    {
-
+      // checks
       checkValid();
 
       if (!isNodeType(Constants.MIX_LOCKABLE))
@@ -1368,25 +1368,14 @@
       if (dataManager.hasPendingChanges(getInternalPath()))
          throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
 
-      Lock newLock = session.getLockManager().addPendingLock(this, isDeep, isSessionScoped, -1);
+      if (session.getLockManager().isLocked((NodeData)this.getData()))
+      {
+         throw new LockException("Node is already locked itself or due to deep lock of parent, ");
+      }
+      Lock lock = session.getLockManager().lock((NodeData)data, isDeep, isSessionScoped, -1);
 
-      PlainChangesLog changesLog =
-         new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
-
-      PropertyData propData =
-         TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
-            new TransientValueData(session.getUserID()));
-      changesLog.add(ItemState.createAddedState(propData));
-
-      propData =
-         TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
-            new TransientValueData(isDeep));
-      changesLog.add(ItemState.createAddedState(propData));
-
-      dataManager.getTransactManager().save(changesLog);
-
       session.getActionHandler().postLock(this);
-      return newLock;
+      return lock;
 
    }
 
@@ -1396,6 +1385,7 @@
    public Lock lock(boolean isDeep, long timeOut) throws UnsupportedRepositoryOperationException, LockException,
       AccessDeniedException, RepositoryException
    {
+      // checks
       checkValid();
 
       if (!isNodeType(Constants.MIX_LOCKABLE))
@@ -1404,25 +1394,15 @@
       if (dataManager.hasPendingChanges(getInternalPath()))
          throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
 
-      Lock newLock = session.getLockManager().addPendingLock(this, isDeep, false, timeOut);
+      if (session.getLockManager().isLocked((NodeData)this.getData()))
+      {
+         throw new LockException("Node is already locked itself or due to deep lock of parent, ");
+      }
 
-      PlainChangesLog changesLog =
-         new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+      Lock lock = session.getLockManager().lock((NodeData)data, isDeep, false, timeOut);
 
-      PropertyData propData =
-         TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
-            new TransientValueData(session.getUserID()));
-      changesLog.add(ItemState.createAddedState(propData));
-
-      propData =
-         TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
-            new TransientValueData(isDeep));
-      changesLog.add(ItemState.createAddedState(propData));
-
-      dataManager.getTransactManager().save(changesLog);
-
       session.getActionHandler().postLock(this);
-      return newLock;
+      return lock;
 
    }
 
@@ -2023,13 +2003,13 @@
       if (!session.getLockManager().holdsLock((NodeData)this.getData()))
          throw new LockException("The node not locked " + getPath());
 
-      if (!session.getLockManager().isLockHolder(this))
+      if (!session.getLockManager().isLockHolder((NodeData)this.getData()))
          throw new LockException("There are no permission to unlock the node " + getPath());
 
       if (dataManager.hasPendingChanges(getInternalPath()))
          throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
 
-      doUnlock();
+      session.getLockManager().unlock((NodeData)data);
 
       session.getActionHandler().postUnlock(this);
    }
@@ -2167,8 +2147,8 @@
 
    boolean checkLocking() throws RepositoryException
    {
-      return (!isLocked() || session.getLockManager().isLockHolder(this) || session.getUserID().equals(
-         SystemIdentity.SYSTEM));
+      return (!isLocked() || session.getLockManager().isLockHolder((NodeData)this.getData()) || session.getUserID()
+         .equals(SystemIdentity.SYSTEM));
    }
 
    protected void doOrderBefore(QPath srcPath, QPath destPath) throws RepositoryException
@@ -2330,28 +2310,6 @@
       dataManager.getChangesLog().addAll(changes);
    }
 
-   /**
-    * Remove mix:lockable properties.
-    * 
-    * @throws RepositoryException if error occurs
-    */
-   protected void doUnlock() throws RepositoryException
-   {
-
-      PlainChangesLog changesLog =
-         new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.UNLOCK);
-
-      ItemData lockOwner = dataManager.getItemData(nodeData(), new QPathEntry(Constants.JCR_LOCKOWNER, 0));
-
-      changesLog.add(ItemState.createDeletedState(lockOwner));
-
-      ItemData lockIsDeep = dataManager.getItemData(nodeData(), new QPathEntry(Constants.JCR_LOCKISDEEP, 0));
-
-      changesLog.add(ItemState.createDeletedState(lockIsDeep));
-
-      dataManager.getTransactManager().save(changesLog);
-   }
-
    protected NodeData nodeData()
    {
       return (NodeData)data;
@@ -2372,11 +2330,11 @@
       {
          // locked, should be unlocked
 
-         if (!session.getLockManager().isLockHolder(this))
+         if (!session.getLockManager().isLockHolder((NodeData)this.getData()))
             throw new LockException("There are no permission to unlock the node " + getPath());
 
          // remove mix:lockable properties (as the node is locked)
-         doUnlock();
+         session.getLockManager().unlock((NodeData)data);
       }
    }
 

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -31,7 +31,7 @@
 import org.exoplatform.services.jcr.datamodel.NodeData;
 import org.exoplatform.services.jcr.datamodel.QPathEntry;
 import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
+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;
@@ -118,7 +118,7 @@
 
    private final LocationFactory systemLocationFactory;
 
-   private final LockManagerImpl lockManager;
+   private final SessionLockManager sessionLockManager;
 
    protected final String workspaceName;
 
@@ -152,7 +152,6 @@
       this.systemLocationFactory = (LocationFactory)container.getComponentInstanceOfType(LocationFactory.class);
 
       this.accessManager = (AccessManager)container.getComponentInstanceOfType(AccessManager.class);
-      this.lockManager = (LockManagerImpl)container.getComponentInstanceOfType(LockManagerImpl.class);
       WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
       WorkspaceFileCleanerHolder cleanerHolder =
          (WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
@@ -177,9 +176,12 @@
 
       this.workspace = new WorkspaceImpl(workspaceName, container, this, observationManager);
 
+      // TODO: try to get lock time out from workspace configuration, as it was before
+      this.sessionLockManager = new SessionLockManager(this, SessionLockManager.DEFAULT_LOCK_TIMEOUT);
+
       this.lifecycleListeners = new ArrayList<SessionLifecycleListener>();
       this.registerLifecycleListener((ObservationManagerImpl)observationManager);
-      this.registerLifecycleListener(lockManager);
+      this.registerLifecycleListener(sessionLockManager);
 
       SessionActionCatalog catalog =
          (SessionActionCatalog)container.getComponentInstanceOfType(SessionActionCatalog.class);
@@ -197,7 +199,7 @@
     */
    public void addLockToken(String lt)
    {
-      getLockManager().addLockToken(getId(), lt);
+      sessionLockManager.addLockToken(lt);
    }
 
    /**
@@ -543,9 +545,9 @@
       return locationFactory;
    }
 
-   public LockManagerImpl getLockManager()
+   public SessionLockManager getLockManager()
    {
-      return lockManager;
+      return sessionLockManager;
    }
 
    /**
@@ -553,7 +555,7 @@
     */
    public String[] getLockTokens()
    {
-      return getLockManager().getLockTokens(getId());
+      return sessionLockManager.getLockTokens();
    }
 
    /**
@@ -901,7 +903,7 @@
     */
    public void removeLockToken(String lt)
    {
-      getLockManager().removeLockToken(getId(), lt);
+      sessionLockManager.removeLockToken(lt);
    }
 
    /**

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -18,11 +18,6 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock;
 
-import org.exoplatform.services.jcr.access.SystemIdentity;
-
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * Created by The eXo Platform SAS.
  * 
@@ -49,15 +44,10 @@
    private boolean live;
 
    /**
-    * List of session id's which holds a lock tokens.
-    */
-   private final Set<String> lockHolders = new HashSet<String>();
-
-   /**
     * A lock token is a string that uniquely identifies a particular lock and acts as a “key”
-    * allowing a user to alter a locked node.
+    * allowing a user to alter a locked node. LockData stores only token hash.
     */
-   private String lockToken;
+   private String tokenHash;
 
    /**
     * Identifier of locked node.
@@ -95,7 +85,7 @@
       long timeOut)
    {
       this.nodeIdentifier = nodeIdentifier;
-      this.lockToken = lockToken;
+      this.tokenHash = lockToken;
       this.deep = deep;
       this.sessionScoped = sessionScoped;
       this.owner = owner;
@@ -104,15 +94,6 @@
       this.birthday = System.currentTimeMillis() / 1000;
    }
 
-   /**
-    * @param sessionId
-    * @return
-    */
-   public boolean addLockHolder(String sessionId)
-   {
-      return lockHolders.add(sessionId);
-   }
-
    /*
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
@@ -131,20 +112,11 @@
       return false;
    }
 
-   public int getLockHolderSize()
+   public String getTokenHash()
    {
-      return lockHolders.size();
+      return tokenHash;
    }
 
-   public String getLockToken(String sessionId)
-   {
-      if (isLockHolder(sessionId))
-      {
-         return lockToken;
-      }
-      return null;
-   }
-
    /**
     * @return the nodeIdentifier
     */
@@ -176,7 +148,7 @@
    @Override
    public int hashCode()
    {
-      return super.hashCode() + lockToken.hashCode();
+      return super.hashCode() + tokenHash.hashCode();
    }
 
    public boolean isDeep()
@@ -193,17 +165,8 @@
    }
 
    /**
-    * @param sessionId
     * @return
     */
-   public boolean isLockHolder(String sessionId)
-   {
-      return lockHolders.contains(sessionId) || SystemIdentity.SYSTEM.equals(sessionId);
-   }
-
-   /**
-    * @return
-    */
    public boolean isSessionScoped()
    {
       return sessionScoped;
@@ -218,15 +181,6 @@
    }
 
    /**
-    * @param sessionId
-    * @return
-    */
-   public boolean removeLockHolder(String sessionId)
-   {
-      return lockHolders.remove(sessionId);
-   }
-
-   /**
     * @param the
     *          live to set
     */
@@ -236,31 +190,6 @@
    }
 
    /**
-    * @param lockToken
-    */
-   public void setLockToken(String lockToken)
-   {
-      this.lockToken = lockToken;
-   }
-
-   /**
-    * @param nodeIdentifier
-    *          the nodeIdentifier to set
-    */
-   public void setNodeIdentifier(String nodeIdentifier)
-   {
-      this.nodeIdentifier = nodeIdentifier;
-   }
-
-   /**
-    * @param owner
-    */
-   public void setOwner(String owner)
-   {
-      this.owner = owner;
-   }
-
-   /**
     * @return
     */
    protected long getTimeOut()

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -38,27 +38,47 @@
 
    private SessionImpl session;
 
-   public LockImpl(SessionImpl session, LockData lockData)
+   // Token is not stored in lockData any more
+   private String token;
+
+   /**
+    * @param session
+    * @param lockData
+    */
+   public LockImpl(SessionImpl session, LockData lockData, String token)
    {
       this.lockData = lockData;
       this.session = session;
+      this.token = token;
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#getLockOwner()
+    */
    public String getLockOwner()
    {
       return lockData.getOwner();
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#getLockToken()
+    */
    public String getLockToken()
    {
-      return lockData.getLockToken(session.getId());
+      return token;
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#isLive()
+    */
    public boolean isLive()
    {
       return lockData.isLive();
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#refresh()
+    */
    public void refresh() throws LockException, RepositoryException
    {
       if (!isLive())
@@ -66,6 +86,9 @@
       lockData.refresh();
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#getNode()
+    */
    public Node getNode()
    {
       try
@@ -74,29 +97,49 @@
       }
       catch (RepositoryException e)
       {
-         e.printStackTrace();
       }
       return null;
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#isDeep()
+    */
    public boolean isDeep()
    {
 
       return lockData.isDeep();
    }
 
+   /**
+    * @see javax.jcr.lock.Lock#isSessionScoped()
+    */
    public boolean isSessionScoped()
    {
       return lockData.isSessionScoped();
    }
 
+   /**
+    * @see org.exoplatform.services.jcr.core.lock.ExtendedLock#getTimeToDeath()
+    */
    public long getTimeToDeath()
    {
       return lockData.getTimeToDeath();
    }
 
+   /**
+    * @see org.exoplatform.services.jcr.core.lock.ExtendedLock#getLockData()
+    */
+   public LockData getLockData()
+   {
+      return lockData;
+   }
+
+   /**
+    * @param timeOut
+    */
    protected void setTimeOut(long timeOut)
    {
       lockData.setTimeOut(timeOut);
    }
+
 }

Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-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$
- */
-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
-    */
-   public void addLockToken(String sessionId, String lt);
-
-   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.
-    * 
-    * @param node
-    *          node
-    * @return lock object
-    * @throws LockException
-    *           if this node is not locked
-    * @see javax.jcr.Node#getLock
-    */
-   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);
-
-}

Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core.lock;
-
-import org.exoplatform.management.annotations.Managed;
-import org.exoplatform.management.annotations.ManagedDescription;
-import org.exoplatform.management.jmx.annotations.NameTemplate;
-import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.access.SystemIdentity;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.core.ExtendedSession;
-import org.exoplatform.services.jcr.core.SessionLifecycleListener;
-import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
-import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
-import org.exoplatform.services.jcr.dataflow.DataManager;
-import org.exoplatform.services.jcr.dataflow.ItemState;
-import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
-import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
-import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.ItemData;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.datamodel.ValueData;
-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.dataflow.AbstractValueData;
-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.factories.annotations.NonVolatile;
-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.
- * 
- * @author <a href="mailto:gennady.azarenkov at exoplatform.com">Gennady Azarenkov</a>
- * @version $Id$
- */
- at Managed
- at NameTemplate(@Property(key = "service", value = "lockmanager"))
- at NonVolatile
-public class LockManagerImpl implements ItemsPersistenceListener, SessionLifecycleListener, LockManager, Startable
-{
-   /**
-    * Default lock time out. 30min
-    */
-   public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
-
-   // Search constants
-   /**
-    * The exact lock token.
-    */
-   private static final int SEARCH_EXECMATCH = 1;
-
-   /**
-    * Lock token of closed parent
-    */
-   private static final int SEARCH_CLOSEDPARENT = 2;
-
-   /**
-    * Lock token of closed child
-    */
-   private static final int SEARCH_CLOSEDCHILD = 4;
-
-   /**
-    * Logger
-    */
-   private final Log log = ExoLogger.getLogger("jcr.lock.LockManager");
-
-   /**
-    * Map NodeIdentifier -- lockData
-    * 
-    * TODO: changed from private to protected 
-    */
-   protected final Map<String, LockData> locks;
-
-   /**
-    * Data manager.
-    */
-   private final DataManager dataManager;
-
-   /**
-    * Map NodeIdentifier -- lockData
-    * 
-    * TODO: changed from private to protected
-    */
-   protected final Map<String, LockData> pendingLocks;
-
-   /**
-    * Map lockToken --lockData
-    */
-   private final Map<String, LockData> tokensMap;
-
-   /**
-    * Run time lock time out.
-    */
-   private long lockTimeOut;
-
-   /**
-    * Lock remover thread.
-    */
-   private LockRemover lockRemover;
-
-   /**
-    * Lock persister instance.
-    */
-   private final LockPersister persister;
-
-   /**
-    * Constructor for workspace without LockPersister
-    * 
-    * @param dataManager
-    * @param config
-    */
-   public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config)
-   {
-      this(dataManager, config, null);
-   }
-
-   public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config, LockPersister persister)
-   {
-
-      this.dataManager = dataManager;
-      this.persister = persister;
-      if (config.getLockManager() != null)
-      {
-         lockTimeOut =
-            config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
-      }
-      else
-         lockTimeOut = DEFAULT_LOCK_TIMEOUT;
-
-      locks = new HashMap<String, LockData>();
-      pendingLocks = new HashMap<String, LockData>();
-      tokensMap = new HashMap<String, LockData>();
-
-      dataManager.addItemPersistenceListener(this);
-   }
-
-   /*
-    * (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)
-   {
-      LockData currLock = tokensMap.get(lt);
-      if (currLock != null)
-      {
-         currLock.addLockHolder(sessionId);
-      }
-   }
-
-   /*
-    * (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
-   {
-      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();
-      lData =
-         new LockData(node.getInternalIdentifier(), lockToken, isDeep, isSessionScoped, node.getSession().getUserID(),
-            timeOut > 0 ? timeOut : lockTimeOut);
-
-      lData.addLockHolder(node.getSession().getId());
-      pendingLocks.put(node.getInternalIdentifier(), lData);
-      tokensMap.put(lockToken, lData);
-
-      LockImpl lock = new LockImpl(node.getSession(), lData);
-      return lock;
-   }
-
-   /*
-    * (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
-   {
-
-      LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
-      if (lData == null || (!node.getInternalIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
-      {
-         throw new LockException("Node not locked: " + node.getData().getQPath());
-
-      }
-      return new LockImpl(node.getSession(), lData);
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see org.exoplatform.services.jcr.impl.core.lock.LockManager#getLockTokens(java.lang.String)
-    */
-   public synchronized String[] getLockTokens(String sessionID)
-   {
-      List<String> retval = new ArrayList<String>();
-
-      for (LockData lockData : locks.values())
-      {
-         if (lockData.isLockHolder(sessionID))
-            retval.add(lockData.getLockToken(sessionID));
-
-      }
-      return retval.toArray(new String[retval.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
-   {
-      return getLockData(node, SEARCH_EXECMATCH) != null;
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.impl.core.lock.LockManager#isLocked(org.exoplatform.services.jcr
-    * .datamodel.NodeData)
-    */
-   public boolean isLocked(NodeData node)
-   {
-      LockData lData = getLockData(node, SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
-      if (lData == null || (!node.getIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
-      {
-         return false;
-      }
-      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 && lData.isLockHolder(node.getSession().getId());
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see
-    * org.exoplatform.services.jcr.core.SessionLifecycleListener#onCloseSession(org.exoplatform.services
-    * .jcr.core.ExtendedSession)
-    */
-   public synchronized void onCloseSession(ExtendedSession session)
-   {
-      // List<String> deadLocksList = new ArrayList<String>();
-      SessionImpl sessionImpl = (SessionImpl)session;
-      for (Iterator<Map.Entry<String, LockData>> entries = locks.entrySet().iterator(); entries.hasNext();)
-      {
-         Map.Entry<String, LockData> entry = entries.next();
-         LockData lockData = entry.getValue();
-         if (lockData.isLive())
-         {
-            if (lockData.isLockHolder(session.getId()))
-            {
-               if (lockData.isSessionScoped())
-               {
-                  // if no session currently holds lock except this
-                  try
-                  {
-                     // TODO it's possible to have next error
-                     // java.lang.NullPointerException
-                     // at
-                     // org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl.onCloseSession(LockManagerImpl.java:312)
-                     // at org.exoplatform.services.jcr.impl.core.SessionImpl.logout(SessionImpl.java:794)
-                     // at
-                     // org.exoplatform.services.jcr.impl.core.XASessionImpl.logout(XASessionImpl.java:254)
-                     // at
-                     // org.exoplatform.services.jcr.impl.core.SessionRegistry$SessionCleaner.callPeriodically(SessionRegistry.java:165)
-                     // at
-                     // org.exoplatform.services.jcr.impl.proccess.WorkerThread.run(WorkerThread.java:46)
-                     ((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
-               {
-                  lockData.removeLockHolder(session.getId());
-               }
-            }
-         }
-         else
-         {
-            entries.remove();
-         }
-      }
-   }
-
-   /*
-    * (non-Javadoc)
-    * @seeorg.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener#onSaveItems(org.
-    * exoplatform.services.jcr.dataflow.ItemStateChangesLog)
-    */
-   @Deprecated
-   public void onSaveItems(ItemStateChangesLog changesLog)
-   {
-      List<PlainChangesLog> chengesLogList = new ArrayList<PlainChangesLog>();
-      if (changesLog instanceof TransactionChangesLog)
-      {
-         ChangesLogIterator logIterator = ((TransactionChangesLog)changesLog).getLogIterator();
-
-         while (logIterator.hasNextLog())
-         {
-            chengesLogList.add(logIterator.nextLog());
-         }
-      }
-      else if (changesLog instanceof PlainChangesLog)
-      {
-         chengesLogList.add((PlainChangesLog)changesLog);
-      }
-      else if (changesLog instanceof CompositeChangesLog)
-      {
-         for (ChangesLogIterator iter = ((CompositeChangesLog)changesLog).getLogIterator(); iter.hasNextLog();)
-         {
-            chengesLogList.add(iter.nextLog());
-         }
-      }
-
-      for (PlainChangesLog currChangesLog : chengesLogList)
-      {
-         String nodeIdentifier;
-         try
-         {
-            switch (currChangesLog.getEventType())
-            {
-               case ExtendedEvent.LOCK :
-                  if (currChangesLog.getSize() < 2)
-                  {
-                     log.error("Incorrect changes log  of type ExtendedEvent.LOCK size=" + currChangesLog.getSize()
-                        + "<2 \n" + currChangesLog.dump());
-                     break;
-                  }
-                  nodeIdentifier = currChangesLog.getAllStates().get(0).getData().getParentIdentifier();
-
-                  if (pendingLocks.containsKey(nodeIdentifier))
-                  {
-                     internalLock(nodeIdentifier);
-                  }
-                  else
-                  {
-                     log.warn("No lock in pendingLocks for identifier " + nodeIdentifier
-                        + " Probably lock come from replication.");
-
-                     String lockToken = IdGenerator.generate();
-                     ItemState ownerState = getItemState(currChangesLog, Constants.JCR_LOCKOWNER);
-                     ItemState isDeepState = getItemState(currChangesLog, Constants.JCR_LOCKISDEEP);
-                     if (ownerState != null && isDeepState != null)
-                     {
-
-                        String owner =
-                           new String(((((TransientPropertyData)(ownerState.getData())).getValues()).get(0))
-                              .getAsByteArray(), Constants.DEFAULT_ENCODING);
-
-                        boolean isDeep =
-                           Boolean.valueOf(
-                              new String(((((TransientPropertyData)(isDeepState.getData())).getValues()).get(0))
-                                 .getAsByteArray(), Constants.DEFAULT_ENCODING)).booleanValue();
-
-                        createRemoteLock(currChangesLog.getSessionId(), nodeIdentifier, lockToken, isDeep, false, owner);
-                     }
-                  }
-                  break;
-               case ExtendedEvent.UNLOCK :
-                  if (currChangesLog.getSize() < 2)
-                  {
-                     log.error("Incorrect changes log  of type ExtendedEvent.UNLOCK size=" + currChangesLog.getSize()
-                        + "<2 \n" + currChangesLog.dump());
-                     break;
-                  }
-
-                  internalUnLock(currChangesLog.getSessionId(), currChangesLog.getAllStates().get(0).getData()
-                     .getParentIdentifier());
-                  break;
-               default :
-                  HashSet<String> removedLock = new HashSet<String>();
-                  for (ItemState itemState : currChangesLog.getAllStates())
-                  {
-                     // this is a node and node is locked
-                     if (itemState.getData().isNode() && locks.containsKey(itemState.getData().getIdentifier()))
-                     {
-                        nodeIdentifier = itemState.getData().getIdentifier();
-                        if (itemState.isDeleted())
-                        {
-                           removedLock.add(nodeIdentifier);
-                        }
-                        else if (itemState.isAdded() || itemState.isRenamed() || itemState.isUpdated())
-                        {
-                           removedLock.remove(nodeIdentifier);
-                        }
-                     }
-                  }
-                  for (String identifier : removedLock)
-                  {
-                     internalUnLock(currChangesLog.getSessionId(), identifier);
-                  }
-                  break;
-            }
-         }
-         catch (LockException e)
-         {
-            log.error(e.getLocalizedMessage(), e);
-         }
-         catch (UnsupportedEncodingException e)
-         {
-            log.error(e.getLocalizedMessage(), e);
-         }
-         catch (IllegalStateException e)
-         {
-            log.error(e.getLocalizedMessage(), e);
-         }
-         catch (IOException e)
-         {
-            log.error(e.getLocalizedMessage(), e);
-         }
-      }
-   }
-
-   /*
-    * (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)
-   {
-      LockData lData = tokensMap.get(lt);
-      if (lData != null && lData.isLockHolder(sessionId))
-      {
-         lData.removeLockHolder(sessionId);
-      }
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see org.picocontainer.Startable#start()
-    */
-   public void start()
-   {
-      lockRemover = new LockRemover(this);
-   }
-
-   // Quick method. We need to reconstruct
-   synchronized List<LockData> getLockList()
-   {
-      return new ArrayList<LockData>(locks.values());
-   }
-
-   /**
-    * Remove expired locks. Used from LockRemover.
-    */
-   synchronized void removeExpired()
-   {
-      final List<String> removeLockList = new ArrayList<String>();
-
-      for (LockData lock : locks.values())
-      {
-         if (!lock.isSessionScoped() && lock.getTimeToDeath() < 0)
-         {
-            removeLockList.add(lock.getNodeIdentifier());
-         }
-      }
-
-      for (String rLock : removeLockList)
-      {
-         removeLock(rLock);
-      }
-   }
-
-   /*
-    * (non-Javadoc)
-    * @see org.picocontainer.Startable#stop()
-    */
-   public void stop()
-   {
-      lockRemover.halt();
-      lockRemover.interrupt();
-      locks.clear();
-      pendingLocks.clear();
-      tokensMap.clear();
-   }
-
-   /**
-    * Copy <code>PropertyData prop<code> to new TransientItemData
-    * 
-    * @param prop
-    * @return
-    * @throws RepositoryException
-    */
-   private TransientItemData copyItemData(PropertyData prop) throws RepositoryException
-   {
-
-      if (prop == null)
-         return null;
-
-      // make a copy
-      TransientPropertyData newData =
-         new TransientPropertyData(prop.getQPath(), prop.getIdentifier(), prop.getPersistedVersion(), prop.getType(),
-            prop.getParentIdentifier(), prop.isMultiValued());
-
-      List<ValueData> values = null;
-      // null is possible for deleting items
-      if (prop.getValues() != null)
-      {
-         values = new ArrayList<ValueData>();
-         for (ValueData val : prop.getValues())
-         {
-            values.add(((AbstractValueData)val).createTransientCopy());
-         }
-      }
-      newData.setValues(values);
-      return newData;
-   }
-
-   /**
-    * Search item with name <code>itemName<code> in changesLog
-    * 
-    * @param changesLog
-    * @param itemName
-    * @return Item
-    */
-   private ItemState getItemState(PlainChangesLog changesLog, InternalQName itemName)
-   {
-      List<ItemState> allStates = changesLog.getAllStates();
-      for (int i = allStates.size() - 1; i >= 0; i--)
-      {
-         ItemState state = allStates.get(i);
-         if (state.getData().getQPath().getName().equals(itemName))
-            return state;
-      }
-      return null;
-   }
-
-   /**
-    * Search lock in maps.
-    * 
-    * @param data
-    * @param searchType
-    * @return
-    */
-   private LockData getLockData(NodeData data, int searchType)
-   {
-      if (data == null || locks.size() == 0)
-         return null;
-      LockData retval = null;
-      try
-      {
-         if ((searchType & SEARCH_EXECMATCH) != 0)
-         {
-            retval = locks.get(data.getIdentifier());
-         }
-         if (retval == null && (searchType & SEARCH_CLOSEDPARENT) != 0)
-         {
-
-            NodeData parentData = (NodeData)dataManager.getItemData(data.getParentIdentifier());
-            if (parentData != null)
-            {
-               retval = locks.get(parentData.getIdentifier());
-               // parent not found try to fo upper
-               if (retval == null)
-               {
-                  retval = getLockData(parentData, SEARCH_CLOSEDPARENT);
-               }
-            }
-         }
-         if (retval == null && (searchType & SEARCH_CLOSEDCHILD) != 0)
-         {
-
-            List<NodeData> childData = dataManager.getChildNodesData(data);
-            for (NodeData nodeData : childData)
-            {
-               retval = locks.get(nodeData.getIdentifier());
-               if (retval != null)
-                  break;
-            }
-            if (retval == null)
-            {
-               // child not found try to find diper
-               for (NodeData nodeData : childData)
-               {
-                  retval = getLockData(nodeData, SEARCH_CLOSEDCHILD);
-                  if (retval != null)
-                     break;
-               }
-            }
-         }
-      }
-      catch (RepositoryException e)
-      {
-         return null;
-      }
-
-      return retval;
-   }
-
-   /**
-    * Internal lock
-    * 
-    * @param nodeIdentifier
-    * @throws LockException
-    * 
-    * TODO: Changed from private to public. Need for LockCacheLoader.
-    */
-   public synchronized void internalLock(String nodeIdentifier) throws LockException
-   {
-      LockData ldata = pendingLocks.get(nodeIdentifier);
-      if (ldata != null)
-      {
-         locks.put(nodeIdentifier, ldata);
-
-         if (persister != null)
-         {
-            persister.add(ldata);
-         }
-         pendingLocks.remove(nodeIdentifier);
-      }
-      else
-      {
-         throw new LockException("No lock in pending locks");
-      }
-   }
-
-   /**
-    * Internal unlock.
-    * 
-    * @param sessionId
-    * @param nodeIdentifier
-    * @throws LockException
-    * 
-    * TODO: Changed from private to public. Need for LockCacheLoader.
-    */
-   public synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
-   {
-      LockData lData = locks.get(nodeIdentifier);
-
-      if (lData != null)
-      {
-         tokensMap.remove(lData.getLockToken(sessionId));
-         locks.remove(nodeIdentifier);
-
-         lData.setLive(false);
-         if (persister != null)
-         {
-            persister.remove(lData);
-         }
-         lData = null;
-      }
-   }
-
-   /**
-    * 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
-    * 
-    *  TODO: Changed from private to public. Need for LockCacheLoader.
-    */
-   public 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;
-   }
-
-   /**
-    * Remove lock, used by Lock remover.
-    * 
-    * @param nodeIdentifier String
-    */
-   protected void removeLock(String nodeIdentifier)
-   {
-      try
-      {
-         NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
-         PlainChangesLog changesLog =
-            new PlainChangesLogImpl(new ArrayList<ItemState>(), SystemIdentity.SYSTEM, ExtendedEvent.UNLOCK);
-
-         ItemData lockOwner =
-            copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
-
-         changesLog.add(ItemState.createDeletedState(lockOwner));
-
-         ItemData lockIsDeep =
-            copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKISDEEP, 1)));
-         changesLog.add(ItemState.createDeletedState(lockIsDeep));
-
-         // lock probably removed by other thread
-         if (lockOwner == null && lockIsDeep == null)
-            return;
-         dataManager.save(new TransactionChangesLog(changesLog));
-      }
-      catch (RepositoryException e)
-      {
-         log.error("Error occur during removing lock" + e.getLocalizedMessage());
-      }
-   }
-
-   @Managed
-   @ManagedDescription("The number of active locks")
-   public int getNumLocks()
-   {
-      return locks.size();
-   }
-
-   @Managed
-   @ManagedDescription("Remove the expired locks")
-   public void cleanExpiredLocks()
-   {
-      removeExpired();
-   }
-
-   /**
-    * TODO: Added. Need for LockCacheLoader..
-    */
-   public boolean hasPendingLocks(String nodeIdentifier)
-   {
-      return pendingLocks.containsKey(nodeIdentifier);
-   }
-
-   /**
-    * TODO: Added. Need for LockCacheLoader..
-    */
-   public boolean hasLockNode(String nodeIdentifier)
-   {
-      return locks.containsKey(nodeIdentifier);
-   }
-}

Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core.lock;
-
-import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
- * @version $Id$
- */
-public class LockRemover extends WorkerThread
-{
-
-   private final Log log = ExoLogger.getLogger("jcr.lock.LockRemover");
-
-   public static final long DEFAULT_THREAD_TIMEOUT = 30000; // 30
-
-   // sec
-
-   private final LockManagerImpl lockManagerImpl;
-
-   public LockRemover(LockManagerImpl lockManagerImpl)
-   {
-      this(lockManagerImpl, DEFAULT_THREAD_TIMEOUT);
-   }
-
-   private LockRemover(LockManagerImpl lockManagerImpl, long timeout)
-   {
-      super(timeout);
-      this.lockManagerImpl = lockManagerImpl;
-      setName("LockRemover " + getId());
-      setPriority(Thread.MIN_PRIORITY);
-      setDaemon(true);
-      start();
-      if (log.isDebugEnabled())
-         log.debug("LockRemover instantiated name= " + getName() + " timeout= " + timeout);
-   }
-
-   @Override
-   protected void callPeriodically() throws Exception
-   {
-      lockManagerImpl.removeExpired();
-   }
-}

Added: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.lock;
+
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.core.SessionLifecycleListener;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.LockPlainChangesLogImpl;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+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 java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+
+/**
+ * @author <a href="mailto:nikolazius at gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id$
+ *
+ */
+public class SessionLockManager implements SessionLifecycleListener
+{
+   /**
+    * Default lock time out. 30min
+    */
+   public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
+
+   /**
+    * Search lockData for given node  
+    */
+   private static final int SEARCH_EXACMATCH = 1;
+
+   /**
+    * Search lockData for parent's of given node
+    */
+   private static final int SEARCH_PARENT = 2;
+
+   /**
+    * Search lockData for children of given node
+    */
+   private static final int SEARCH_CHILD = 4;
+
+   /**
+    * Session through which this lock manager is created
+    */
+   private final SessionImpl session;
+
+   protected final Log log = ExoLogger.getLogger(this.getClass().getName());
+
+   /**
+    * Holds session's tokens and their hashes to avoid calculation every time.
+    * Token <--> Hash  
+    */
+   private Map<String, String> tokens;
+
+   /**
+    * Holds session's tokens and their hashes to avoid calculation every time.
+    * Hash <--> Token
+    * Added to speed up operations  
+    */
+   private Map<String, String> tokenHash;
+
+   /**
+    * Configured lock timeout
+    */
+   private long lockTimeOut;
+
+   /**
+    * @param session
+    * @param lockTimeOut
+    */
+   public SessionLockManager(SessionImpl session, long lockTimeOut)
+   {
+      this.session = session;
+      this.lockTimeOut = lockTimeOut;
+      // TODO: configured lock timeout should be acquired from WSconfig
+      /*      if (config.getLockManager() != null)
+      {
+         lockTimeOut =
+            config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
+      }
+      else
+         lockTimeOut = DEFAULT_LOCK_TIMEOUT;*/
+   }
+
+   /**
+    * Adds token to current session
+    * @param token
+    */
+   public void addLockToken(String token)
+   {
+      String hash = getHash(token);
+      tokens.put(token, hash);
+      tokenHash.put(hash, token);
+   }
+
+   /**
+    * Removes token from current session
+    * @param token
+    */
+   public void removeLockToken(String token)
+   {
+      String hash = getHash(token);
+      tokens.remove(token);
+      tokenHash.remove(hash);
+   }
+
+   /**
+    * Tries to get Lock for node. Is node is not a lockholder, then parent with deep lock is looked for. 
+    * 
+    * @param node
+    * @return
+    * @throws LockException
+    * @throws RepositoryException
+    */
+   public LockImpl getLock(NodeData node) throws LockException, RepositoryException
+   {
+      LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+
+      if (lockData == null || (!node.getIdentifier().equals(lockData.getNodeIdentifier()) && !lockData.isDeep()))
+      {
+         throw new LockException("Node not locked: " + node.getQPath());
+      }
+      // if session doesn't have token, null will be returned
+      return new LockImpl(session, lockData, tokenHash.get(lockData.getTokenHash()));
+   }
+
+   /**
+    * Returns the list of token that current session owns.
+    * @return
+    */
+   public String[] getLockTokens()
+   {
+      return tokens.keySet().toArray(new String[tokens.size()]);
+   }
+
+   /**
+    * Checks if node actually has a lock. 
+    * 
+    * @param node
+    * @return
+    * @throws RepositoryException
+    */
+   public boolean holdsLock(NodeData node) throws RepositoryException
+   {
+      return getLockData(node, SEARCH_EXACMATCH) != null;
+   }
+
+   /**
+    * Checks if current session has a token (access) for this node.
+    * 
+    * @param node
+    * @return
+    * @throws RepositoryException
+    */
+   public boolean isLockHolder(NodeData node) throws RepositoryException
+   {
+      LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+      return lockData != null && isLockHolder(lockData);
+   }
+
+   /**
+    * Checks if node is locked, or it's any parent has a deep lock. 
+    * 
+    * @param node
+    * @return
+    */
+   public boolean isLocked(NodeData node)
+   {
+      LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+
+      if (lockData == null || (!node.getIdentifier().equals(lockData.getNodeIdentifier()) && !lockData.isDeep()))
+      {
+         return false;
+      }
+      return true;
+   }
+
+   /**
+    * Actually locks the node, adding jcr:lockOwner and jcr:lockIsDeep properties to node and adds lock token
+    * to current session. 
+    * 
+    * @param node
+    * @param isDeep
+    * @param isSessionScoped
+    * @param timeOut
+    * @return
+    * @throws LockException
+    * @throws RepositoryException
+    */
+   public LockImpl lock(NodeData node, boolean isDeep, boolean isSessionScoped, long timeOut) throws LockException,
+      RepositoryException
+   {
+      // check child node is not locked
+      if (isDeep && getLockData(node, SEARCH_CHILD) != null)
+      {
+         throw new LockException("Can't place deep lock: some child node is locked.");
+      }
+
+      String token = IdGenerator.generate();
+      String hash = getHash(token);
+
+      LockData lockData =
+         new LockData(node.getIdentifier(), hash, isDeep, isSessionScoped, session.getUserID(), timeOut > 0 ? timeOut
+            : lockTimeOut);
+
+      tokens.put(token, hash);
+      tokenHash.put(hash, token);
+
+      // Create and pass changes log 
+      LockPlainChangesLogImpl changesLog =
+         new LockPlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+
+      changesLog.setLockData(lockData);
+
+      PropertyData propData =
+         TransientPropertyData.createPropertyData(node, Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
+            new TransientValueData(session.getUserID()));
+      changesLog.add(ItemState.createAddedState(propData));
+
+      propData =
+         TransientPropertyData.createPropertyData(node, Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
+            new TransientValueData(isDeep));
+      changesLog.add(ItemState.createAddedState(propData));
+
+      LockImpl newLock = new LockImpl(session, lockData, token);
+
+      session.getTransientNodesManager().getTransactManager().save(changesLog);
+      return newLock;
+   }
+
+   /**
+    * Actually unlock the node also removing jcr:lockOwner and jcr:lockIsDeep properties
+    * 
+    * @param node
+    * @throws RepositoryException
+    */
+   public void unlock(NodeData node) throws RepositoryException
+   {
+      PlainChangesLog changesLog =
+         new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.UNLOCK);
+
+      ItemData lockOwner =
+         session.getTransientNodesManager().getItemData(node, new QPathEntry(Constants.JCR_LOCKOWNER, 0));
+
+      changesLog.add(ItemState.createDeletedState(lockOwner));
+
+      ItemData lockIsDeep =
+         session.getTransientNodesManager().getItemData(node, new QPathEntry(Constants.JCR_LOCKISDEEP, 0));
+
+      changesLog.add(ItemState.createDeletedState(lockIsDeep));
+
+      session.getTransientNodesManager().getTransactManager().save(changesLog);
+   }
+
+   /**
+    * Calculates md5 hash of string.
+    * 
+    * @param token
+    * @return
+    */
+   private String getHash(String token)
+   {
+      String hash = "";
+      try
+      {
+         MessageDigest m = MessageDigest.getInstance("MD5");
+         m.update(token.getBytes(), 0, token.length());
+         hash = new BigInteger(1, m.digest()).toString(16);
+      }
+      catch (NoSuchAlgorithmException e)
+      {
+         log.error("Can't get instanse of MD5 MessageDigest!", e);
+      }
+      return hash;
+   }
+
+   /**
+    * Search lock with given search options:
+    *    * for only given node
+    *    * for any upper parent of given node
+    *    * for any deeper child of given node
+    * 
+    * @param data
+    * @param searchType
+    * @return
+    */
+   private LockData getLockData(NodeData data, int searchType)
+   {
+      if (data == null)
+         return null;
+      LockData retval = null;
+      try
+      {
+         if ((searchType & SEARCH_EXACMATCH) != 0)
+         {
+            retval = session.getTransientNodesManager().getLockData(data.getIdentifier());
+         }
+         if (retval == null && (searchType & SEARCH_PARENT) != 0)
+         {
+
+            NodeData parentData = (NodeData)session.getTransientNodesManager().getItemData(data.getParentIdentifier());
+            if (parentData != null)
+            {
+               retval = session.getTransientNodesManager().getLockData(parentData.getIdentifier());
+               // parent not found try to find upper
+               if (retval == null)
+               {
+                  retval = getLockData(parentData, SEARCH_PARENT);
+               }
+            }
+         }
+         if (retval == null && (searchType & SEARCH_CHILD) != 0)
+         {
+
+            List<NodeData> childData = session.getTransientNodesManager().getChildNodesData(data);
+            for (NodeData nodeData : childData)
+            {
+               retval = session.getTransientNodesManager().getLockData(nodeData.getIdentifier());
+               if (retval != null)
+                  break;
+            }
+            if (retval == null)
+            {
+               // child not found try to find deeper
+               for (NodeData nodeData : childData)
+               {
+                  retval = getLockData(nodeData, SEARCH_CHILD);
+                  if (retval != null)
+                     break;
+               }
+            }
+         }
+      }
+      catch (RepositoryException e)
+      {
+         return null;
+      }
+
+      return retval;
+   }
+
+   /**
+    * 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(session.getId()) || tokenHash.get(lockData.getTokenHash()) != null);
+   }
+
+   /**
+    * @see org.exoplatform.services.jcr.core.SessionLifecycleListener#onCloseSession(org.exoplatform.services.jcr.core.ExtendedSession)
+    */
+   public void onCloseSession(ExtendedSession session)
+   {
+      // TODO: remove session scoped locks
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2003-2009 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.storage.jbosscache;
-
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
-import org.exoplatform.services.jcr.util.IdGenerator;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Modification;
-import org.jboss.cache.Modification.ModificationType;
-import org.jboss.cache.factories.annotations.Inject;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a> 
- * @version $Id$
- */
-public class LockCacheLoader extends AbstractWriteOnlyCacheLoader
-{
-
-   /**
-    * Lock manager.
-    */
-   private LockManagerImpl lockManager;
-
-   /**
-    * Logger.
-    */
-   private final Log log = ExoLogger.getLogger("jcr.LockCacheLoader");
-
-   /**
-    * Injection dependencies.
-    *
-    * @param lockManager LockManagerImpl
-    */
-   @Inject
-   public void injectDependencies(LockManagerImpl lockManager) throws RepositoryConfigurationException
-   {
-      if (this.lockManager != null)
-      {
-         throw new RepositoryConfigurationException("Cannot set LockManagerImpl twice");
-      }
-
-      this.lockManager = lockManager;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public void put(List<Modification> modifications) throws Exception
-   {
-      String sessionId = null;
-      HashSet<String> removedLock = new HashSet<String>();
-      List<Modification> lockChanges = new ArrayList<Modification>();
-
-      for (Modification m : modifications)
-      {
-         if (m.getFqn().get(0).equals(JBossCacheStorage.SESSION))
-         {
-            switch (m.getType())
-            {
-               case PUT_DATA_ERASE :
-                  break;
-               case PUT_DATA :
-                  break;
-               case PUT_KEY_VALUE :
-                  // begin new changes log
-                  if (m.getKey().equals(JBossCacheStorage.SESSION_ID))
-                  {
-                     sessionId = (String)m.getValue();
-                  }
-                  break;
-               case REMOVE_DATA :
-                  // end changes log
-                  if (lockChanges.size() == 2)
-                  {
-                     if (lockChanges.get(0).getType() == ModificationType.PUT_KEY_VALUE
-                        && lockChanges.get(1).getType() == ModificationType.PUT_KEY_VALUE)
-                     {
-                        performLock(lockChanges, sessionId);
-                     }
-                     else if (lockChanges.get(0).getType() == ModificationType.REMOVE_KEY_VALUE
-                        && lockChanges.get(1).getType() == ModificationType.REMOVE_KEY_VALUE)
-                     {
-                        performUnLock(lockChanges, (String)lockChanges.get(0).getFqn().get(1), sessionId);
-                     }
-                     else
-                     {
-                        log.error("Incorrect changes log contains lock and unlock operation simultaneously");
-                     }
-                  }
-                  else if (lockChanges.size() != 0)
-                  {
-                     log.error("Incorrect changes log  size for lock or unlock operation");
-                  }
-
-                  for (String identifier : removedLock)
-                  {
-                     lockManager.internalUnLock(identifier, sessionId);
-                  }
-
-                  lockChanges = new ArrayList<Modification>();
-                  removedLock = new HashSet<String>();
-                  sessionId = null;
-                  break;
-               case REMOVE_KEY_VALUE :
-                  break;
-               case REMOVE_NODE :
-                  break;
-               case MOVE :
-                  break;
-               default :
-                  throw new CacheException("Unknown modification " + m.getType());
-            }
-         }
-         else if (m.getFqn().get(0).equals(JBossCacheStorage.PROPS))
-         {
-            switch (m.getType())
-            {
-               case PUT_DATA_ERASE :
-                  break;
-               case PUT_DATA :
-                  break;
-               case PUT_KEY_VALUE :
-                  // lock operation
-                  if (m.getKey().equals(JBossCacheStorage.ITEM_DATA))
-                  {
-                     InternalQName propName = ((PropertyData)m.getValue()).getQPath().getName();
-                     if (propName.equals(Constants.JCR_LOCKISDEEP) || propName.equals(Constants.JCR_LOCKOWNER))
-                     {
-                        lockChanges.add(m);
-                     }
-                  }
-                  break;
-               case REMOVE_DATA :
-                  break;
-               case REMOVE_KEY_VALUE :
-                  break;
-               case REMOVE_NODE :
-                  break;
-               case MOVE :
-                  break;
-               default :
-                  throw new CacheException("Unknown modification " + m.getType());
-            }
-         }
-         else if (m.getFqn().get(0).equals(JBossCacheStorage.NODES))
-         {
-            switch (m.getType())
-            {
-               case PUT_DATA_ERASE :
-                  break;
-               case PUT_DATA :
-                  if (m.getFqn().size() == 2)
-                  {
-                     String nodeIdentifier = (String)m.getFqn().get(1);
-                     if (lockManager.hasLockNode(nodeIdentifier))
-                     {
-                        removedLock.remove(nodeIdentifier);
-                     }
-                  }
-                  break;
-               case PUT_KEY_VALUE :
-                  break;
-               case REMOVE_DATA :
-                  break;
-               case REMOVE_KEY_VALUE :
-                  // unLock operation
-                  if (m.getKey().equals(Constants.JCR_LOCKISDEEP.getAsString())
-                     || m.getKey().equals(Constants.JCR_LOCKOWNER.getAsString()))
-                  {
-                     lockChanges.add(m);
-                  }
-                  break;
-               case REMOVE_NODE :
-                  if (m.getFqn().size() == 2)
-                  {
-                     String nodeIdentifier = (String)m.getFqn().get(1);
-                     if (lockManager.hasLockNode(nodeIdentifier))
-                     {
-                        removedLock.add(nodeIdentifier);
-                     }
-                  }
-                  break;
-               case MOVE :
-                  if (m.getFqn().size() == 2)
-                  {
-                     String nodeIdentifier = (String)m.getFqn().get(1);
-                     if (lockManager.hasLockNode(nodeIdentifier))
-                     {
-                        removedLock.remove(nodeIdentifier);
-                     }
-                  }
-                  break;
-               default :
-                  throw new CacheException("Unknown modification " + m.getType());
-            }
-         }
-      }
-   }
-
-   /**
-    * Perform lock operation.
-    *
-    * @param lockChanges
-    * @throws LockException
-    */
-   private void performLock(List<Modification> lockChanges, String sessionId)
-   {
-      String nodeIdentifier = ((PropertyData)lockChanges.get(0).getValue()).getParentIdentifier();
-
-      try
-      {
-         if (lockManager.hasPendingLocks(nodeIdentifier))
-         {
-            log.info("Perform lock operation nodeIdentifier=" + nodeIdentifier);
-            lockManager.internalLock(nodeIdentifier);
-         }
-         else
-         {
-            log.warn("No lock in pendingLocks for identifier " + nodeIdentifier
-               + " Probably lock come from replication.");
-
-            String lockToken = IdGenerator.generate();
-            Modification ownerModification = getModification(lockChanges, Constants.JCR_LOCKOWNER);
-            Modification isDeepModification = getModification(lockChanges, Constants.JCR_LOCKISDEEP);
-
-            if (ownerModification != null && isDeepModification != null)
-            {
-
-               String owner =
-                  new String(((((TransientPropertyData)(ownerModification.getValue())).getValues()).get(0))
-                     .getAsByteArray(), Constants.DEFAULT_ENCODING);
-
-               boolean isDeep =
-                  Boolean.valueOf(
-                     new String(((((TransientPropertyData)(isDeepModification.getValue())).getValues()).get(0))
-                        .getAsByteArray(), Constants.DEFAULT_ENCODING)).booleanValue();
-
-               lockManager.createRemoteLock(sessionId, nodeIdentifier, lockToken, isDeep, false, owner);
-            }
-         }
-      }
-      catch (LockException e)
-      {
-         log.error(e.getLocalizedMessage(), e);
-      }
-      catch (UnsupportedEncodingException e)
-      {
-         log.error(e.getLocalizedMessage(), e);
-      }
-      catch (IllegalStateException e)
-      {
-         log.error(e.getLocalizedMessage(), e);
-      }
-      catch (IOException e)
-      {
-         log.error(e.getLocalizedMessage(), e);
-      }
-   }
-
-   private void performUnLock(List<Modification> lockChanges, String nodeIdentifier, String sessionId)
-   {
-      try
-      {
-         log.info("Perform unlock operation nodeIdentifier=" + nodeIdentifier + " sessionId=" + sessionId);
-         lockManager.internalUnLock(nodeIdentifier, sessionId);
-      }
-      catch (LockException e)
-      {
-         log.error(e.getLocalizedMessage(), e);
-      }
-   }
-
-   /**
-    * Search item with name <code>itemName<code> in modification list
-    * 
-    * @param changes
-    * @param itemName
-    * @return Item
-    */
-   private Modification getModification(List<Modification> changes, InternalQName itemName)
-   {
-      for (Modification m : changes)
-      {
-         if (((PropertyData)changes.get(0).getValue()).getQPath().getName().equals(itemName))
-            return m;
-      }
-      return null;
-   }
-
-}

Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -32,11 +32,10 @@
 {
    private ExtendedNode lockedNode = null;
 
-   private LockManagerImpl service;
-
    private static final long LOCK_TIMEOUT = 5; // sec
 
-   private static final long LOCK_REMOVER_WAIT = LockRemover.DEFAULT_THREAD_TIMEOUT + (LOCK_TIMEOUT + 1) * 1000; // 15
+   //private static final long LOCK_REMOVER_WAIT = LockRemover.DEFAULT_THREAD_TIMEOUT + (LOCK_TIMEOUT + 1) * 1000; // 15
+   private static final long LOCK_REMOVER_WAIT = (LOCK_TIMEOUT + 30) * 1000; //
 
    // sec
 
@@ -45,8 +44,6 @@
 
       super.setUp();
 
-      service = (LockManagerImpl)container.getComponentInstanceOfType(LockManagerImpl.class);
-
       if (lockedNode == null)
          try
          {

Deleted: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2003-2009 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.storage.jbosscache;
-
-import org.exoplatform.services.idgenerator.impl.IDGeneratorServiceImpl;
-import org.exoplatform.services.jcr.config.ContainerEntry;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.SimpleParameterEntry;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.QPath;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockData;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
-import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.storage.value.StandaloneStoragePluginProvider;
-import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-import org.exoplatform.services.jcr.util.IdGenerator;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Modification;
-import org.jboss.cache.Node;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.PropertyType;
-import javax.naming.Context;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a> 
- * @version $Id$
- */
-public class LockCacheLoaderTest extends AbstractCacheLoaderTest
-{
-
-   private TesterLockManagerImpl lockManager;
-
-   private LockCacheLoader lockCacheLoader;
-
-   private final QPath testRoot = QPath.makeChildPath(Constants.ROOT_PATH, new InternalQName("", "testRoot"));
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      lockManager = new TesterLockManagerImpl();
-      lockCacheLoader = new LockCacheLoader();
-      lockCacheLoader.injectDependencies(lockManager);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   protected void tearDown() throws Exception
-   {
-
-      super.tearDown();
-   }
-
-   public void testLock() throws Exception
-   {
-      List<Modification> modifications = new ArrayList<Modification>();
-      String nodeIdentifier = "node1";
-      String sessionId = "session1";
-
-      TransientPropertyData lockIsDeepData =
-         new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKISDEEP), "prop1", 1,
-            PropertyType.BOOLEAN, nodeIdentifier, false);
-      TransientValueData lockIsDeepValue = new TransientValueData(false);
-      lockIsDeepData.setValue(lockIsDeepValue);
-
-      TransientPropertyData lockOwnerData =
-         new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKOWNER), "prop2", 1,
-            PropertyType.BOOLEAN, nodeIdentifier, false);
-      TransientValueData lockOwner = new TransientValueData("__system");
-      lockOwnerData.setValue(lockOwner);
-
-      lockManager.addPendingLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
-      modifications.addAll(addSessionInfo(sessionId, "userId"));
-      modifications.addAll(addProperty(lockIsDeepData));
-      modifications.addAll(addProperty(lockOwnerData));
-      modifications.addAll(removeSessionInfo());
-      lockCacheLoader.put(modifications);
-
-      assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
-   }
-
-   public void testUnLock() throws Exception
-   {
-      List<Modification> modifications = new ArrayList<Modification>();
-      String nodeIdentifier = "node1";
-      String sessionId = "session1";
-
-      TransientPropertyData lockIsDeepData =
-         new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKISDEEP), "prop1", 1,
-            PropertyType.BOOLEAN, nodeIdentifier, false);
-      TransientValueData lockIsDeepValue = new TransientValueData(false);
-      lockIsDeepData.setValue(lockIsDeepValue);
-
-      TransientPropertyData lockOwnerData =
-         new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKOWNER), "prop2", 1,
-            PropertyType.BOOLEAN, nodeIdentifier, false);
-      TransientValueData lockOwner = new TransientValueData("__system");
-      lockOwnerData.setValue(lockOwner);
-
-      modifications.addAll(addSessionInfo(sessionId, "userId"));
-      modifications.addAll(removeProperty(lockIsDeepData));
-      modifications.addAll(removeProperty(lockOwnerData));
-      modifications.addAll(removeSessionInfo());
-      lockCacheLoader.put(modifications);
-
-      assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
-      assertEquals(sessionId, lockManager.getSessionid());
-   }
-
-   public void testAddNodeLock() throws Exception
-   {
-      List<Modification> modifications = new ArrayList<Modification>();
-      String nodeIdentifier = "node1";
-      String sessionId = "session1";
-
-      TransientNodeData node =
-         new TransientNodeData(testRoot, nodeIdentifier, 0, null, null, 0, Constants.ROOT_UUID, null);
-
-      lockManager.addLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
-      modifications.addAll(addSessionInfo(sessionId, "userId"));
-      modifications.addAll(addNode(node));
-      modifications.addAll(removeSessionInfo());
-      lockCacheLoader.put(modifications);
-
-      assertNull(lockManager.getNodeIdentifier());
-      assertNull(lockManager.getSessionid());
-   }
-
-   public void testRemoveNodeLock() throws Exception
-   {
-      List<Modification> modifications = new ArrayList<Modification>();
-      String nodeIdentifier = "node1";
-      String sessionId = "session1";
-
-      TransientNodeData node =
-         new TransientNodeData(testRoot, nodeIdentifier, 0, null, null, 0, Constants.ROOT_UUID, null);
-
-      lockManager.addLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
-      modifications.addAll(addSessionInfo(sessionId, "userId"));
-      modifications.addAll(removeNode(node));
-      modifications.addAll(removeSessionInfo());
-      lockCacheLoader.put(modifications);
-
-      assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
-      assertEquals(sessionId, lockManager.getSessionid());
-   }
-}

Deleted: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java	2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java	2009-11-17 16:18:15 UTC (rev 723)
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2003-2009 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.storage.jbosscache;
-
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.lock.LockData;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.jboss.cache.factories.annotations.NonVolatile;
-
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a> 
- * @version $Id$
- */
- at NonVolatile
-public class TesterLockManagerImpl extends LockManagerImpl
-{
-
-   private String nodeIdentifier = null;
-
-   private String sessionId = null;
-
-   public TesterLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config)
-   {
-      super(dataManager, config);
-   }
-
-   public TesterLockManagerImpl()
-   {
-      this(new TesterWorkspacePersistedDataManager(null, null), new TesterWorkspaceEntry());
-   }
-
-   /**
-    * Internal lock
-    */
-   public synchronized void internalLock(String nodeIdentifier) throws LockException
-   {
-      if (this.nodeIdentifier != null)
-         throw new LockException("NodeIdentifier already exist!");
-
-      this.nodeIdentifier = nodeIdentifier;
-   }
-
-   /**
-   * Internal lock
-   */
-   public synchronized void internalUnLock(String nodeIdentifier, String sessionId) throws LockException
-   {
-      if (this.nodeIdentifier != null)
-         throw new LockException("NodeIdentifier already exist!");
-
-      if (this.sessionId != null)
-         throw new LockException("SessionId already exist!");
-
-      this.nodeIdentifier = nodeIdentifier;
-      this.sessionId = sessionId;
-   }
-
-   public String getNodeIdentifier()
-   {
-      return nodeIdentifier;
-   }
-
-   public String getSessionid()
-   {
-      return sessionId;
-   }
-
-   public void addPendingLock(String nodeIdentifier, LockData lData)
-   {
-      pendingLocks.put(nodeIdentifier, lData);
-   }
-
-   public void addLock(String nodeIdentifier, LockData lData)
-   {
-      locks.put(nodeIdentifier, lData);
-   }
-}



More information about the exo-jcr-commits mailing list