[exo-jcr-commits] exo-jcr SVN: r5075 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Oct 20 10:01:00 EDT 2011


Author: tolusha
Date: 2011-10-20 10:00:59 -0400 (Thu, 20 Oct 2011)
New Revision: 5075

Added:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java
Modified:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
Log:
EXOJCR-1590: support cache migration from 1.12.x to 1.14.x

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -17,6 +17,7 @@
 package org.exoplatform.services.jcr.impl.core.lock.cacheable;
 
 import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
 import org.exoplatform.management.annotations.Managed;
 import org.exoplatform.management.annotations.ManagedDescription;
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -128,6 +129,8 @@
     */
    protected TransactionManager tm;
 
+   public static final String LOCKS_FORCE_REMOVE = "org.exoplatform.jcr.locks.force.remove";
+
    /**
     * Logger
     */
@@ -524,6 +527,20 @@
    public void start()
    {
       lockRemover.start();
+
+      // Remove all locks records directly from DB. 
+      boolean deleteLocks = "true".equalsIgnoreCase(PrivilegedSystemHelper.getProperty(LOCKS_FORCE_REMOVE, "false"));
+
+      if (deleteLocks)
+      {
+         doClean();
+      }
+
+      // remove all locks at the start up time EXOJCR-1592
+      //      if (isCoordinator())
+      //      {
+      //         removeAll();
+      //      }
    }
 
    /**
@@ -774,11 +791,24 @@
    }
 
    /**
+    * Remove all locks.
+    */
+   protected void removeAll()
+   {
+      List<LockData> locks = getLockList();
+      for (LockData lockData : locks)
+      {
+         removeLock(lockData.getNodeIdentifier());
+         doRemove(lockData);
+      }
+   }
+
+   /**
     * {@inheritDoc}
     */
    public void clean() throws BackupException
    {
-      cleanCacheDirectly();
+      doClean();
    }
 
    /**
@@ -906,7 +936,7 @@
       public void clean() throws BackupException
       {
          actualLocks.addAll(getLockList());
-         cleanCacheDirectly();
+         doClean();
       }
 
       /**
@@ -916,7 +946,7 @@
       {
          for (LockData lockData : backupLocks)
          {
-            putDirectly(lockData);
+            doPut(lockData);
          }
       }
 
@@ -932,10 +962,10 @@
        */
       public void rollback() throws BackupException
       {
-         cleanCacheDirectly();
+         doClean();
          for (LockData lockData : actualLocks)
          {
-            putDirectly(lockData);
+            doPut(lockData);
          }
       }
 
@@ -950,16 +980,30 @@
    }
 
    /**
+    * Indicates if we are the only node in cluster.
+    */
+   protected abstract boolean isAloneInCluster();
+
+   /**
     * Puts lock data directly into cache.
     * 
     * @param lockData
     *          the lock data to put
+    * @return the old lock data previously added into cache         
     */
-   protected abstract void putDirectly(LockData lockData);
+   protected abstract LockData doPut(LockData lockData);
 
    /**
+    * Removes lock data directly from cache.
+    * 
+    * @param lockData
+    *          the lock data to remove
+    */
+   protected abstract void doRemove(LockData lockData);
+
+   /**
     * Clean cache directly.
     */
-   protected abstract void cleanCacheDirectly();
+   protected abstract void doClean();
 
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -31,9 +31,9 @@
  * @author <a href="mailto:gennady.azarenkov at exoplatform.com">Gennady Azarenkov</a>
  * @version $Id: LockData.java 787 2009-11-20 11:36:15Z nzamosenchuk $
  */
-
 public class LockData implements Externalizable
 {
+
    /**
     * The time of birth. From this time we start count the time of death. death = birthday+TIME_OUT;
     */
@@ -96,7 +96,7 @@
    {
       this(nodeIdentifier, lockTokenHash, deep, sessionScoped, owner, timeOut, System.currentTimeMillis());
    }
-   
+
    /**
     * @param nodeIdentifier
     * @param lockToken

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -39,6 +39,7 @@
 import org.exoplatform.services.naming.InitialContextInitializer;
 import org.exoplatform.services.transaction.TransactionService;
 import org.infinispan.Cache;
+import org.infinispan.config.Configuration.CacheMode;
 import org.infinispan.lifecycle.ComponentStatus;
 
 import java.io.Serializable;
@@ -366,7 +367,7 @@
          LockData lockData = session.getPendingLock(nodeIdentifier);
 
          // this will return null if success. And old data if something exists...
-         LockData oldLockData = (LockData)PrivilegedISPNCacheHelper.putIfAbsent(cache, nodeIdentifier, lockData);
+         LockData oldLockData = doPut(lockData);
 
          if (oldLockData != null)
          {
@@ -392,7 +393,7 @@
 
       if (lData != null)
       {
-         cache.remove(nodeIdentifier);
+         doRemove(lData);
 
          CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
          if (sessMgr != null)
@@ -403,23 +404,45 @@
    }
 
    /**
-   * {@inheritDoc}
-   */
+    * {@inheritDoc}
+    */
    @Override
-   protected void putDirectly(LockData lockData)
+   protected LockData doPut(LockData lockData)
    {
-      PrivilegedISPNCacheHelper.putIfAbsent(cache, lockData.getNodeIdentifier(), lockData);
+      return (LockData)PrivilegedISPNCacheHelper.putIfAbsent(cache, lockData.getNodeIdentifier(), lockData);
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
-   protected void cleanCacheDirectly()
+   protected void doRemove(LockData lockData)
    {
+      cache.remove(lockData.getNodeIdentifier());
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected boolean isAloneInCluster()
+   {
+      return cache.getConfiguration().getCacheMode() == CacheMode.LOCAL
+         || cache.getCacheManager().getMembers().size() == 1;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void doClean()
+   {
       if (cache.getStatus() == ComponentStatus.RUNNING)
       {
-         cache.clear();
+         for (LockData lockData : getLockList())
+         {
+            doRemove(lockData);
+         }
       }
    }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -46,6 +46,7 @@
 import org.jboss.cache.Node;
 import org.jboss.cache.config.CacheLoaderConfig;
 import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.jmx.JmxRegistrationManager;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.loader.CacheLoaderManager;
@@ -185,11 +186,11 @@
         
          Fqn<String> rootFqn = Fqn.fromElements(config.getUniqueName());
 
-         lockRoot = Fqn.fromRelativeElements(rootFqn, LOCKS);
-
          shareable =
             config.getLockManager().getParameterBoolean(JBOSSCACHE_SHAREABLE, JBOSSCACHE_SHAREABLE_DEFAULT)
                .booleanValue();
+         lockRoot = shareable ? Fqn.fromRelativeElements(rootFqn, LOCKS) : Fqn.fromElements(LOCKS);
+
          cache = ExoJBossCacheFactory.getUniqueInstance(CacheType.LOCK_CACHE, rootFqn, cache, shareable);
          this.jmxManager = ExoJBossCacheFactory.getJmxRegistrationManager(ctx, cache, CacheType.LOCK_CACHE);
          if (jmxManager != null)
@@ -491,8 +492,8 @@
    }
 
    /**
-   * {@inheritDoc}
-   */
+    * {@inheritDoc}
+    */
    @Override
    public void stop()
    {
@@ -529,13 +530,9 @@
       if (session != null && session.containsPendingLock(nodeIdentifier))
       {
          LockData lockData = session.getPendingLock(nodeIdentifier);
-         Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
 
-         // addChild will add if absent or return old if present
-         Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
-
          // this will return null if success. And old data if something exists...
-         LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
+         LockData oldLockData = doPut(lockData);
 
          if (oldLockData != null)
          {
@@ -561,7 +558,7 @@
 
       if (lData != null)
       {
-         cache.removeNode(makeLockFqn(nodeIdentifier));
+         doRemove(lData);
 
          CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
          if (sessMgr != null)
@@ -607,24 +604,47 @@
     * {@inheritDoc}
     */
    @Override
-   protected void putDirectly(LockData lockData)
+   protected LockData doPut(LockData lockData)
    {
       Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
 
+      // addChild will add if absent or return old if present
       Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
-      node.putIfAbsent(LOCK_DATA, lockData);
+
+      // this will return null if success. And old data if something exists...
+      return (LockData)node.putIfAbsent(LOCK_DATA, lockData);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
-   protected void cleanCacheDirectly()
+   protected void doRemove(LockData lockData)
    {
-      if (cache.getCacheStatus() != CacheStatus.STARTED)
+      cache.removeNode(makeLockFqn(lockData.getNodeIdentifier()));
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected boolean isAloneInCluster()
+   {
+      return cache.getConfiguration().getCacheMode() == CacheMode.LOCAL || cache.getMembers().size() == 1;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void doClean()
+   {
+      if (cache.getCacheStatus() == CacheStatus.STARTED)
       {
-         cache.removeNode(lockRoot);
-         createStructuredNode(lockRoot);
+         for (LockData lockData : getLockList())
+         {
+            doRemove(lockData);
+         }
       }
    }
 }

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.jbosscache;
+
+
+/**
+ * For backward compatibility between 1.12.x and 1.14.x
+ * 
+ * @author <a href="abazko at exoplatform.com">Anatoliy Bazko</a>
+ * @version $Id: LockData.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class LockData extends org.exoplatform.services.jcr.impl.core.lock.cacheable.LockData
+{
+   private static final long serialVersionUID = 920103551272363119L;
+
+}

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -1115,7 +1115,7 @@
                continue;
             }
             QPathEntryFilter nameFilter = (QPathEntryFilter)patternObject;
-            if (nameFilter.accept((ItemData)value))
+            if (nameFilter.accept(value))
             {
                cache.getInvocationContext().getOptionOverrides().setForceWriteLock(true);
                Object setObject = cache.get(patternFqn, listKey);
@@ -1230,7 +1230,7 @@
                continue;
             }
             QPathEntryFilter nameFilter = (QPathEntryFilter)patternObject;
-            if (nameFilter.accept((ItemData)value))
+            if (nameFilter.accept(value))
             {
                cache.getInvocationContext().getOptionOverrides().setForceWriteLock(true);
                Object setObject = cache.get(patternFqn, listKey);

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -2937,6 +2937,12 @@
 
    protected abstract int deleteReference(String propertyIdentifier) throws SQLException;
 
+   /**
+    * Deletes [http://www.jcp.org/jcr/1.0]lockOwner and [http://www.jcp.org/jcr/1.0]lockIsDeep
+    * properties directly from DB.
+    */
+   protected abstract void deleteLockProperties() throws SQLException;
+
    protected abstract ResultSet findReferences(String nodeIdentifier) throws SQLException;
 
    protected abstract int deleteItemByIdentifier(String identifier) throws SQLException;

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -21,6 +21,7 @@
 import org.exoplatform.commons.utils.PrivilegedFileHelper;
 import org.exoplatform.commons.utils.PrivilegedSystemHelper;
 import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.RepositoryEntry;
 import org.exoplatform.services.jcr.config.ValueStorageEntry;
@@ -44,6 +45,7 @@
 import org.exoplatform.services.jcr.impl.backup.rdbms.SybaseDBRestore;
 import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
 import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
 import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
 import org.exoplatform.services.jcr.impl.core.query.Reindexable;
 import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
@@ -369,8 +371,8 @@
          }
          catch (RepositoryConfigurationException e)
          {
-            sn = wsConfig.getContainer().getParameterValue("sourceName"); // TODO for backward comp,
-            // remove in rel.2.0
+            // for backward comp remove in rel.2.0
+            sn = wsConfig.getContainer().getParameterValue("sourceName");
          }
          this.dbSourceName = sn;
          if (dsProvider == null)
@@ -913,6 +915,37 @@
             }
          }
       }
+      
+      // Remove lock properties from DB. It is an issue of migration locks from 1.12.x to 1.14.x in case when we use
+      // shareable cache. The lock tables will be new but still remaining lock properties in JCR tables.
+      boolean deleteLocks =
+         "true".equalsIgnoreCase(PrivilegedSystemHelper.getProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE,
+            "false"));
+
+      try
+      {
+         if (deleteLocks)
+         {
+            JDBCStorageConnection conn = (JDBCStorageConnection)openConnection();
+            try
+            {
+               conn.deleteLockProperties();
+            }
+            finally
+            {
+               conn.close();
+            }
+         }
+      }
+      catch (SQLException e)
+      {
+         LOG.error(
+            "Can't remove lock properties because of " + ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
+      }
+      catch (RepositoryException e)
+      {
+         LOG.error("Can't remove lock properties because of " + e.getMessage(), e);
+      }
    }
 
    /**
@@ -920,27 +953,6 @@
     */
    public void stop()
    {
-
-      // TODO HSQLDB Stop (debug)
-      // if (dbDialect.equals(DB_DIALECT_GENERIC) ||
-      // dbDialect.equals(DB_DIALECT_HSQLDB)) {
-      // // shutdown in-process HSQLDB database
-      // System.out.println("Shutdown in-process HSQLDB database...");
-      // try {
-      // JDBCStorageConnection conn = (JDBCStorageConnection) openConnection();
-      // Connection jdbcConn = conn.getJdbcConnection();
-      // String dbUrl = jdbcConn.getMetaData().getURL();
-      // if (dbUrl.startsWith("jdbc:hsqldb:file") ||
-      // dbUrl.startsWith("jdbc:hsqldb:mem")) {
-      // // yeah, there is in-process hsqldb, shutdown it now
-      // jdbcConn.createStatement().execute("SHUTDOWN");
-      // System.out.println("Shutdown in-process HSQLDB database... done.");
-      // }
-      // } catch (Throwable e) {
-      // log.error("JDBC Data container stop error " + e);
-      // e.printStackTrace();
-      // }
-      // }
    }
 
    /**

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
@@ -551,4 +552,56 @@
       throw new UnsupportedOperationException(
          "The method findNodesAndProperties is not supported for this type of connection use the complex queries instead");
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void deleteLockProperties() throws SQLException
+   {
+      PreparedStatement removeValuesStatement = null;
+      PreparedStatement removeItemsStatement = null;
+
+      try
+      {
+         removeValuesStatement =
+            dbConnection
+               .prepareStatement("DELETE FROM JCR_MVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_MITEM WHERE NAME = ? OR NAME = ?)");
+         removeValuesStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+         removeValuesStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeItemsStatement = dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE NAME = ? OR NAME = ?");
+         removeItemsStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+         removeItemsStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeValuesStatement.executeUpdate();
+         removeItemsStatement.executeUpdate();
+      }
+      finally
+      {
+         if (removeValuesStatement != null)
+         {
+            try
+            {
+               removeValuesStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+
+         if (removeItemsStatement != null)
+         {
+            try
+            {
+               removeItemsStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+      }
+   }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -30,6 +30,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
@@ -573,4 +574,59 @@
       throw new UnsupportedOperationException(
          "The method findNodesAndProperties is not supported for this type of connection use the complex queries instead");
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void deleteLockProperties() throws SQLException
+   {
+      PreparedStatement removeValuesStatement = null;
+      PreparedStatement removeItemsStatement = null;
+
+      try
+      {
+         removeValuesStatement =
+            dbConnection
+               .prepareStatement("DELETE FROM JCR_SVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?))");
+         removeValuesStatement.setString(1, containerName);
+         removeValuesStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+         removeValuesStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?)");
+         removeItemsStatement.setString(1, containerName);
+         removeItemsStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+         removeItemsStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeValuesStatement.executeUpdate();
+         removeItemsStatement.executeUpdate();
+      }
+      finally
+      {
+         if (removeValuesStatement != null)
+         {
+            try
+            {
+               removeValuesStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+
+         if (removeItemsStatement != null)
+         {
+            try
+            {
+               removeItemsStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+      }
+   }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -33,6 +33,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
@@ -1028,4 +1029,56 @@
 
       return findACLHolders.executeQuery();
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void deleteLockProperties() throws SQLException
+   {
+      PreparedStatement removeValuesStatement = null;
+      PreparedStatement removeItemsStatement = null;
+
+      try
+      {
+         removeValuesStatement =
+            dbConnection
+               .prepareStatement("DELETE FROM JCR_MVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_MITEM WHERE NAME = ? OR NAME = ?)");
+         removeValuesStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+         removeValuesStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeItemsStatement = dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE NAME = ? OR NAME = ?");
+         removeItemsStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+         removeItemsStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeValuesStatement.executeUpdate();
+         removeItemsStatement.executeUpdate();
+      }
+      finally
+      {
+         if (removeValuesStatement != null)
+         {
+            try
+            {
+               removeValuesStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+
+         if (removeItemsStatement != null)
+         {
+            try
+            {
+               removeItemsStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+      }
+   }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -32,6 +32,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
@@ -946,4 +947,59 @@
 
       return findACLHolders.executeQuery();
    }   
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void deleteLockProperties() throws SQLException
+   {
+      PreparedStatement removeValuesStatement = null;
+      PreparedStatement removeItemsStatement = null;
+
+      try
+      {
+         removeValuesStatement =
+            dbConnection
+               .prepareStatement("DELETE FROM JCR_SVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?))");
+         removeValuesStatement.setString(1, containerName);
+         removeValuesStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+         removeValuesStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?)");
+         removeItemsStatement.setString(1, containerName);
+         removeItemsStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+         removeItemsStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+         removeValuesStatement.executeUpdate();
+         removeItemsStatement.executeUpdate();
+      }
+      finally
+      {
+         if (removeValuesStatement != null)
+         {
+            try
+            {
+               removeValuesStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+
+         if (removeItemsStatement != null)
+         {
+            try
+            {
+               removeItemsStatement.close();
+            }
+            catch (SQLException e)
+            {
+               LOG.error("Can't close statement", e);
+            }
+         }
+      }
+   }
 }

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java	2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java	2011-10-20 14:00:59 UTC (rev 5075)
@@ -21,7 +21,11 @@
 import org.exoplatform.services.jcr.JcrImplBaseTest;
 import org.exoplatform.services.jcr.core.ExtendedNode;
 import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
 
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 /**
@@ -109,4 +113,60 @@
       }
    }
 
+   public void testRemoveLockProperties() throws Exception
+   {
+      Node node = session.getRootNode().addNode("testLock");
+      node.addMixin("mix:lockable");
+      session.save();
+
+      node.lock(false, false);
+
+      assertTrue(node.isLocked());
+
+      // remove lock properties from JCR tables
+      JDBCWorkspaceDataContainer container =
+         (JDBCWorkspaceDataContainer)repository.getWorkspaceContainer("ws").getComponent(
+            JDBCWorkspaceDataContainer.class);
+
+      System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "true");
+      try
+      {
+         container.start();
+      }
+      finally
+      {
+         System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "false");
+      }
+
+      // node still locked, because there is lock data in lock tables
+      assertTrue(node.isLocked());
+
+      try
+      {
+         node.unlock();
+         fail("Exception should be thrown");
+      }
+      catch (JCRInvalidItemStateException e)
+      {
+      }
+
+      // remove locks from lock table
+      AbstractCacheableLockManager lockManager =
+         (AbstractCacheableLockManager)repository.getWorkspaceContainer("ws").getComponent(
+            AbstractCacheableLockManager.class);
+
+      System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "true");
+      try
+      {
+         lockManager.start();
+      }
+      finally
+      {
+         System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "false");
+      }
+
+      // node should not be locked after removing lock data from lock tables
+      assertFalse(node.isLocked());
+   }
+
 }



More information about the exo-jcr-commits mailing list