[exo-jcr-commits] exo-jcr SVN: r5707 - in jcr/branches/1.15.x: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock and 11 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Feb 29 02:24:54 EST 2012


Author: tolusha
Date: 2012-02-29 02:24:49 -0500 (Wed, 29 Feb 2012)
New Revision: 5707

Added:
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/checker/
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockTableHandler.java
Removed:
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionReport.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
Modified:
   jcr/branches/1.15.x/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
   jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TesterRepositoryCheckController.java
Log:
EXOJCR-1762: auto-repair for VS and Lock inconsistency

Deleted: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionReport.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionReport.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionReport.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1,172 +0,0 @@
-/*
- * 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;
-
-import org.exoplatform.commons.utils.SecurityHelper;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.security.PrivilegedExceptionAction;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * Text-based inspection log implementation.
- * 
- * @author <a href="mailto:skarpenko at exoplatform.com">Sergiy Karpenko</a>
- * @version $Id: InspectionReport.java 34360 6.10.2011 skarpenko $
- */
-public class InspectionReport
-{
-   private static final String COMMENT = "//";
-
-   private static final String DELIMITER = "\n";
-
-   private static final String WHITE_SPACE = " ";
-
-   private Writer writer;
-
-   private boolean reportHasInconsistency;
-
-   private String reportPath;
-
-   /**
-    * InspectionReport constructor.
-    */
-   public InspectionReport(String forRepository) throws IOException
-   {
-      final File reportFile =
-         new File("report-" + forRepository + "-" + new SimpleDateFormat("dd-MMM-yy-HH-mm").format(new Date()) + ".txt");
-
-      SecurityHelper.doPrivilegedIOExceptionAction(new PrivilegedExceptionAction<Void>()
-      {
-         public Void run() throws IOException
-         {
-            reportPath = reportFile.getAbsolutePath();
-            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(reportFile)));
-
-            return null;
-         }
-      });
-
-   }
-
-   /**
-    * Indicates if report has inconsistency info or not.
-    */
-   public boolean hasInconsistency()
-   {
-      return reportHasInconsistency;
-   }
-
-   /**
-    * Adds comment to log.
-    */
-   public void logComment(String message) throws IOException
-   {
-      writeLine(message);
-      writer.flush();
-   }
-
-   /**
-    * Adds description to log.
-    */
-   public void logDescription(String description) throws IOException
-   {
-      writeLine(description);
-      writer.flush();
-   }
-
-   /**
-    * Adds detailed event to log.
-    */
-   public void logBrokenObjectAndSetInconsistency(String brokenObjectDesc, String comment) throws IOException
-   {
-      setInconsistency();
-
-      writer.write(brokenObjectDesc);
-      writer.write(WHITE_SPACE);
-      writer.write(comment);
-      writer.write(DELIMITER);
-      writer.flush();
-   }
-
-   /**
-    * Adds exception with full stack trace.
-    */
-   public void logExceptionAndSetInconsistency(String message, Throwable e) throws IOException
-   {
-      setInconsistency();
-
-      writeLine(message);
-      writeStackTrace(e);
-      writer.flush();
-   }
-
-   /**
-    * Closes report and frees all allocated resources. 
-    */
-   public void close() throws IOException
-   {
-      writer.close();
-   }
-
-   /**
-    * Returns the absolute path to report file. 
-    */
-   public String getReportPath()
-   {
-      return reportPath;
-   }
-
-   private void setInconsistency()
-   {
-      reportHasInconsistency = true;
-   }
-
-   private void writeLine(String message) throws IOException
-   {
-      writer.write(COMMENT);
-      writer.write(message);
-      writer.write(DELIMITER);
-      writer.flush();
-   }
-
-   private void writeStackTrace(Throwable e) throws IOException
-   {
-      writeLine(e.getMessage());
-      writeLine(e.toString());
-      StackTraceElement[] trace = e.getStackTrace();
-      for (int i = 0; i < trace.length; i++)
-      {
-         writeLine("\tat " + trace[i]);
-      }
-
-      Throwable ourCause = e.getCause();
-      if (ourCause != null)
-      {
-         writeLine("Cause:");
-         writeStackTrace(ourCause);
-      }
-   }
-}

Deleted: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1,331 +0,0 @@
-/*
- * 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;
-
-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.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.core.ManageableRepository;
-import org.exoplatform.services.jcr.impl.core.query.SearchManager;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainerChecker;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.picocontainer.Startable;
-
-import java.io.IOException;
-
-import javax.jcr.RepositoryException;
-
-/**
- * Repository check controller allows check jcr repository consistency:
- * <ul>
- *  <li>Check DB consistency</li>
- *  <li>Check value storage</li>
- *  <li>Check index</li>
- * </ul>
- * 
- * @author <a href="mailto:skarpenko at exoplatform.com">Sergiy Karpenko</a>
- * @version $Id: RepositoryCheckController.java 34360 3.10.2011 skarpenko $
- */
- at Managed
- at NameTemplate(@Property(key = "service", value = "RepositoryCheckController"))
-public class RepositoryCheckController extends AbstractRepositorySuspender implements Startable
-{
-   /**
-    * Logger.
-    */
-   protected static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RepositoryCheckController");
-
-   public static final String REPORT_CONSISTENT_MESSAGE = "Repository data is consistent";
-
-   public static final String REPORT_NOT_CONSISTENT_MESSAGE = "Repository data is NOT consistent";
-
-   public static final String EXCEPTION_DURING_CHECKING_MESSAGE = "Exception occured during consistency checking";
-
-   /**
-    * The list of available storages for checking.
-    */
-   protected enum DataStorage {
-      DB, VALUE_STORAGE, LUCENE_INDEX
-   };
-
-   /**
-    * Store the results of last checking.
-    */
-   protected InspectionReport lastReport;
-
-   /**
-    * RepositoryCheckController constructor.
-    */
-   public RepositoryCheckController(ManageableRepository repository)
-   {
-      super(repository);
-   }
-
-   /**
-    * This method will make next steps:
-    * <ul>
-    *  <li>Suspend repository</li>
-    *  <li>Check DB consistency</li>
-    *  <li>Check value storage</li>
-    *  <li>Check index</li>
-    *  <li>Resume repository</li>
-    * </ul>
-    * 
-    * @return String check consistency report
-    */
-   @Managed
-   @ManagedDescription("Check repository data consistency. DB data, value storage and lucene index will be checked.")
-   public String checkRepositoryDataConsistency()
-   {
-      return checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
-         DataStorage.LUCENE_INDEX});
-   }
-
-   @Managed
-   @ManagedDescription("Check repository database consistency.")
-   public String checkRepositoryDataBaseConsistency()
-   {
-      return checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
-   }
-
-   @Managed
-   @ManagedDescription("Check repository value storage consistency.")
-   public String checkRepositoryValueStorageConsistency()
-   {
-      return checkRepositoryDataConsistency(new DataStorage[]{DataStorage.VALUE_STORAGE});
-   }
-
-   @Managed
-   @ManagedDescription("Check repository search index consistency.")
-   public String checkRepositorySearchIndexConsistency()
-   {
-      return checkRepositoryDataConsistency(new DataStorage[]{DataStorage.LUCENE_INDEX});
-   }
-
-   protected String checkRepositoryDataConsistency(DataStorage[] storages)
-
-   {
-      try
-      {
-         createNewReport();
-         suspendRepository();
-         
-         return doCheck(storages);
-      }
-      catch (IOException e)
-      {
-         return getExceptionDuringCheckingMessage(e);
-      }
-      catch (RepositoryException e)
-      {
-         return getExceptionDuringCheckingMessage(e);
-      }
-      finally
-      {
-         resumeRepository();
-         closeReport();
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   protected void resumeRepository()
-   {
-      try
-      {
-         super.resumeRepository();
-      }
-      catch (RepositoryException e)
-      {
-         LOG.error("Can not resume repository. Error: " + e.getMessage(), e);
-      }
-   }
-
-   private String doCheck(DataStorage[] storages)
-   {
-      try
-      {
-         for (DataStorage storage : storages)
-         {
-            switch (storage)
-            {
-               case DB :
-                  checkDataBase();
-                  break;
-
-               case VALUE_STORAGE :
-                  checkValueStorage();
-                  break;
-
-               case LUCENE_INDEX :
-                  checkLuceneIndex();
-                  break;
-            }
-         }
-
-         return logAndGetCheckingResultMessage();
-      }
-      catch (Throwable e)
-      {
-         return logAndGetExceptionDuringCheckingMessage(e);
-      }
-   }
-
-   private String logAndGetCheckingResultMessage()
-   {
-      if (lastReport.hasInconsistency())
-      {
-         logComment(REPORT_NOT_CONSISTENT_MESSAGE);
-         return REPORT_NOT_CONSISTENT_MESSAGE + getPathToReportMessage();
-      }
-      else
-      {
-         logComment(REPORT_CONSISTENT_MESSAGE);
-         return REPORT_CONSISTENT_MESSAGE + getPathToReportMessage();
-      }
-   }
-
-   private String logAndGetExceptionDuringCheckingMessage(Throwable e)
-   {
-      logExceptionAndSetInconsistency(EXCEPTION_DURING_CHECKING_MESSAGE, e);
-      return getExceptionDuringCheckingMessage(e) + getPathToReportMessage();
-   }
-
-   private String getExceptionDuringCheckingMessage(Throwable e)
-   {
-      return EXCEPTION_DURING_CHECKING_MESSAGE + ": " + e.getMessage();
-   }
-
-   private void logComment(String message)
-   {
-      try
-      {
-         lastReport.logComment(message);
-      }
-      catch (IOException e)
-      {
-         LOG.error(e.getMessage(), e);
-      }
-   }
-
-   private void logExceptionAndSetInconsistency(String message, Throwable e)
-   {
-      try
-      {
-         lastReport.logExceptionAndSetInconsistency(message, e);
-      }
-      catch (IOException e1)
-      {
-         LOG.error(e1.getMessage(), e1);
-      }
-   }
-
-   private void createNewReport() throws IOException
-   {
-      lastReport = new InspectionReport(repository.getConfiguration().getName());
-   }
-
-   private void closeReport()
-   {
-      try
-      {
-         lastReport.close();
-      }
-      catch (IOException e)
-      {
-         LOG.error(e.getMessage(), e);
-      }
-   }
-
-   private void checkDataBase() throws RepositoryException, IOException,
-      RepositoryConfigurationException
-   {
-      for (String wsName : repository.getWorkspaceNames())
-      {
-         logComment("Check DB consistency. Workspace " + wsName);
-
-         JDBCWorkspaceDataContainer dataContainer =
-            (JDBCWorkspaceDataContainer)getComponent(JDBCWorkspaceDataContainer.class, wsName);
-
-         JDBCWorkspaceDataContainerChecker.checkDataBase(dataContainer, lastReport);
-         JDBCWorkspaceDataContainerChecker.checkLocksInDataBase(dataContainer,
-            (WorkspaceEntry)getComponent(WorkspaceEntry.class, wsName), lastReport);
-      }
-   }
-
-   private void checkValueStorage() throws RepositoryException, IOException
-   {
-      for (String wsName : repository.getWorkspaceNames())
-      {
-         logComment("Check ValueStorage consistency. Workspace " + wsName);
-
-         JDBCWorkspaceDataContainer dataContainer =
-            (JDBCWorkspaceDataContainer)getComponent(JDBCWorkspaceDataContainer.class, wsName);
-         ValueStoragePluginProvider vsPlugin =
-            (ValueStoragePluginProvider)getComponent(ValueStoragePluginProvider.class, wsName);
-
-         JDBCWorkspaceDataContainerChecker.checkValueStorage(dataContainer, vsPlugin, lastReport);
-      }
-   }
-
-   private void checkLuceneIndex() throws RepositoryException, IOException
-   {
-      final String systemWS = repository.getConfiguration().getSystemWorkspaceName();
-
-      for (String wsName : repository.getWorkspaceNames())
-      {
-         logComment("Check SearchIndex consistency. Workspace " + wsName);
-
-         SearchManager searchManager = (SearchManager)getComponent(SearchManager.class, wsName);
-
-         searchManager.checkIndex(lastReport, systemWS.equals(wsName));
-      }
-   }
-
-   private Object getComponent(Class forClass, String wsName)
-   {
-      return repository.getWorkspaceContainer(wsName).getComponent(forClass);
-   }
-
-   private String getPathToReportMessage()
-   {
-      return ". See full report by path " + lastReport.getReportPath();
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void start()
-   {
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public void stop()
-   {
-   }
-}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -35,6 +35,7 @@
 import org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager;
 import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
 import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.checker.RepositoryCheckController;
 import org.exoplatform.services.jcr.impl.core.AddNamespacePluginHolder;
 import org.exoplatform.services.jcr.impl.core.LocationFactory;
 import org.exoplatform.services.jcr.impl.core.NamespaceDataPersister;

Added: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockTableHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockTableHandler.java	                        (rev 0)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractLockTableHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012 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.commons.utils.SecurityHelper;
+import org.exoplatform.services.database.utils.JDBCUtils;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.checker.InspectionQuery;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * @author <a href="abazko at exoplatform.com">Anatoliy Bazko</a>
+ * @version $Id: AbstractLockTableHandler.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public abstract class AbstractLockTableHandler implements LockTableHandler
+{
+
+   protected final WorkspaceEntry workspaceEntry;
+
+   protected final LockManagerEntry lockManagerEntry;
+
+   /**
+    * AbstractLockTableHandler constructor.
+    */
+   public AbstractLockTableHandler(WorkspaceEntry workspaceEntry)
+   {
+      this.workspaceEntry = workspaceEntry;
+      this.lockManagerEntry = workspaceEntry.getLockManager();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Set<String> getLockedNodesIds() throws SQLException
+   {
+      Set<String> lockedNodesIds = new HashSet<String>();
+
+      ResultSet resultSet = null;
+      PreparedStatement preparedStatement = null;
+
+      Connection jdbcConnection = openConnection();
+      try
+      {
+         InspectionQuery query = getSelectQuery();
+
+         preparedStatement = query.prepareStatement(jdbcConnection);
+         resultSet = preparedStatement.executeQuery();
+
+         while (resultSet.next())
+         {
+            String idColumn = query.getFieldNames()[0];
+            String idValue = resultSet.getString(idColumn);
+
+            lockedNodesIds.add(extractNodeId(idValue));
+         }
+      }
+      finally
+      {
+         JDBCUtils.freeResources(resultSet, preparedStatement, jdbcConnection);
+      }
+
+      return lockedNodesIds;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void removeLockedNode(String nodeId) throws SQLException
+   {
+      ResultSet resultSet = null;
+      PreparedStatement preparedStatement = null;
+
+      Connection jdbcConnection = openConnection();
+      try
+      {
+         InspectionQuery query = getDeleteQuery(nodeId);
+
+         preparedStatement = query.prepareStatement(jdbcConnection);
+         preparedStatement.executeUpdate();
+      }
+      finally
+      {
+         JDBCUtils.freeResources(resultSet, preparedStatement, jdbcConnection);
+      }
+   }
+
+   /**
+    * Opens connection to database.
+    */
+   protected Connection openConnection() throws SQLException
+   {
+      final DataSource ds;
+      try
+      {
+         ds = (DataSource)new InitialContext().lookup(getDataSourceName());
+      }
+      catch (NamingException e)
+      {
+         throw new SQLException(e);
+      }
+
+      return SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+      {
+         public Connection run() throws SQLException
+         {
+            return ds.getConnection();
+         }
+      });
+   }
+
+   /**
+    * Returns node identifier from ID column's value {@link DataSource}.
+    */
+   protected abstract String extractNodeId(String value);
+
+   /**
+    * Returns the name corresponding {@link DataSource}.
+    */
+   protected abstract String getDataSourceName() throws SQLException;
+
+   /**
+    * Returns {@link InspectionQuery} for removing row from LOCK table.
+    */
+   protected abstract InspectionQuery getDeleteQuery(String nodeId) throws SQLException;
+
+   /**
+    * Returns {@link InspectionQuery} for selecting all rows from LOCK table.
+    */
+   protected abstract InspectionQuery getSelectQuery() throws SQLException;
+
+}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -18,13 +18,9 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock;
 
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-
 import java.sql.SQLException;
 import java.util.Set;
 
-import javax.naming.NamingException;
-
 /**
  * Provides method for extraction of set of locked nodes' IDs from
  * {@link LockManager} persistant layer (database lock table),
@@ -38,9 +34,17 @@
     * Get a set of locked jcr nodes IDs contained in {@link LockManager} persistent layer (database table).
     * 
     * @return {@link Set} of node IDs
-    * @throws NamingException
-    * @throws RepositoryConfigurationException
     * @throws SQLException
     */
-   Set<String> getLockedNodesIds() throws NamingException, RepositoryConfigurationException, SQLException;
-}
\ No newline at end of file
+   Set<String> getLockedNodesIds() throws SQLException;
+
+   /**
+    * Removes locked node directly from database.
+    * 
+    * @param nodeId
+    *          node identifier
+    * @return {@link Set} of node IDs
+    * @throws SQLException
+    */
+   void removeLockedNode(String nodeId) throws SQLException;
+}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -83,10 +83,14 @@
 
    public static final String JBOSSCACHE_JDBC_CL_DATASOURCE = "jbosscache-cl-cache.jdbc.datasource";
 
-   public static final String JBOSSCACHE_JDBC_CL_NODE_COLUMN = "jbosscache-cl-cache.jdbc.node.type";
+   public static final String JBOSSCACHE_JDBC_CL_NODE_COLUMN_TYPE = "jbosscache-cl-cache.jdbc.node.type";
 
-   public static final String JBOSSCACHE_JDBC_CL_FQN_COLUMN = "jbosscache-cl-cache.jdbc.fqn.type";
+   public static final String JBOSSCACHE_JDBC_CL_FQN_COLUMN_TYPE = "jbosscache-cl-cache.jdbc.fqn.type";
 
+   public static final String JBOSSCACHE_JDBC_CL_FQN_COLUMN = "jbosscache-cl-cache.jdbc.fqn.column";
+
+   public static final String JBOSSCACHE_JDBC_CL_PARENT_COLUMN = "jbosscache-cl-cache.jdbc.parent.column";
+
    public static final String JBOSSCACHE_JDBC_TABLE_NAME = "jbosscache-cl-cache.jdbc.table.name";
 
    /**
@@ -426,16 +430,16 @@
          // will return JBOSSCACHE_JDBC_CL_AUTO. If parameter is present in configuration and 
          // equals to "auto", then it should be replaced 
          // with correct value for given database
-         if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN, JBOSSCACHE_JDBC_CL_AUTO)
+         if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN_TYPE, JBOSSCACHE_JDBC_CL_AUTO)
             .equalsIgnoreCase(JBOSSCACHE_JDBC_CL_AUTO))
          {
-            parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN, blobType);
+            parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_NODE_COLUMN_TYPE, blobType);
          }
 
-         if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN, JBOSSCACHE_JDBC_CL_AUTO).equalsIgnoreCase(
+         if (parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN_TYPE, JBOSSCACHE_JDBC_CL_AUTO).equalsIgnoreCase(
             JBOSSCACHE_JDBC_CL_AUTO))
          {
-            parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN, charType);
+            parameterEntry.putParameterValue(JBOSSCACHE_JDBC_CL_FQN_COLUMN_TYPE, charType);
          }
       }
       else

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -18,27 +18,15 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock.jbosscache;
 
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.config.LockManagerEntry;
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
-import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
+import org.exoplatform.services.jcr.impl.checker.InspectionQuery;
+import org.exoplatform.services.jcr.impl.core.lock.AbstractLockTableHandler;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 
-import java.security.PrivilegedExceptionAction;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
 
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-
 /**
  * Provides means for nodes' IDs extraction in case we use {@link CacheableLockManagerImpl}
  * as {@link LockManager} based on non shareable JBoss Cache instance.
@@ -47,109 +35,101 @@
  * @author <a href="mailto:dkuleshov at exoplatform.com">Dmitry Kuleshov</a>
  * @version $Id: JBCLockTableHandler.java 34360 2009-07-22 23:58:59Z dkuleshov $
  */
-public class JBCLockTableHandler implements LockTableHandler
+public class JBCLockTableHandler extends AbstractLockTableHandler
 {
    protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JBCLockTableHandler");
 
-   protected final WorkspaceEntry workspaceEntry;
-
-   protected final LockManagerEntry lockManagerEntry;
-
    /**
     * JBCLockTableHandler constructor.
     */
    public JBCLockTableHandler(final WorkspaceEntry workspaceEntry)
    {
-      this.workspaceEntry = workspaceEntry;
-      this.lockManagerEntry = workspaceEntry.getLockManager();
+      super(workspaceEntry);
    }
 
    /**
     * {@inheritDoc}
     */
-   public Set<String> getLockedNodesIds() throws NamingException, RepositoryConfigurationException, SQLException
+   protected InspectionQuery getSelectQuery() throws SQLException
    {
-      String fqnColumn = lockManagerEntry.getParameterValue("jbosscache-cl-cache.jdbc.fqn.column");
+      return new InspectionQuery("SELECT * FROM " + getTableName() + " WHERE " + getParentColumn() + "='/"
+         + CacheableLockManagerImpl.LOCKS + "'", new String[]{getIdColumn()}, "Locks table match");
+   }
 
-      Set<String> lockedNodesIds = new HashSet<String>();
+   /**
+    * {@inheritDoc}
+    */
+   protected InspectionQuery getDeleteQuery(String nodeId) throws SQLException
+   {
+      return new InspectionQuery("DELETE FROM " + getTableName() + " WHERE " + getIdColumn() + "='/"
+         + CacheableLockManagerImpl.LOCKS + "/" + nodeId + "'", new String[]{}, "");
+   }
 
-      ResultSet resultSet = null;
-      PreparedStatement preparedStatement = null;
-      
-      Connection jdbcConnection = openConnection();
+   /**
+    * Returns the column name which contain node identifier.
+    */
+   protected String getIdColumn() throws SQLException
+   {
       try
       {
-         InspectionQuery inspectionQuery = getQuery();
-
-         preparedStatement = inspectionQuery.prepareStatement(jdbcConnection);
-         resultSet = preparedStatement.executeQuery();
-
-         while (resultSet.next())
-         {
-            String fqn = resultSet.getString(fqnColumn);
-            
-            lockedNodesIds.add(fqn.substring(fqn.lastIndexOf("/") + 1));
-         }
+         return lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_FQN_COLUMN);
       }
-      finally
+      catch (RepositoryConfigurationException e)
       {
-         if (resultSet != null)
-         {
-            try
-            {
-               resultSet.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
-         if (preparedStatement != null)
-         {
-            try
-            {
-               preparedStatement.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
-         if (jdbcConnection != null)
-         {
-            try
-            {
-               jdbcConnection.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
+         throw new SQLException(e);
       }
-
-      return lockedNodesIds;
    }
 
-   protected InspectionQuery getQuery() throws RepositoryConfigurationException
+   /**
+    * Returns the name of parent column.
+    */
+   protected String getParentColumn() throws SQLException
    {
-      return new InspectionQuery("SELECT * FROM "
-         + lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME) + " WHERE PARENT='/"
-         + CacheableLockManagerImpl.LOCKS + "'", new String[]{}, "Locks table match");
+      try
+      {
+         return lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_PARENT_COLUMN);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         throw new SQLException(e);
+      }
    }
 
-   private Connection openConnection() throws NamingException, RepositoryConfigurationException, SQLException
+   /**
+    * Returns the name of LOCK table.
+    */
+   protected String getTableName() throws SQLException
    {
-      final DataSource ds =
-         (DataSource)new InitialContext().lookup(lockManagerEntry
-            .getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_DATASOURCE));
+      try
+      {
+         return lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         throw new SQLException(e);
+      }
+   }
 
-      return SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+   /**
+    * {@inheritDoc}
+    */
+   protected String getDataSourceName() throws SQLException
+   {
+      try
       {
-         public Connection run() throws SQLException
-         {
-            return ds.getConnection();
-         }
-      });
+         return lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_DATASOURCE);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         throw new SQLException(e);
+      }
    }
-}
\ No newline at end of file
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String extractNodeId(String value)
+   {
+      return value.substring(value.lastIndexOf("/") + 1);
+   }
+}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -16,11 +16,12 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock.jbosscache;
 
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.checker.InspectionQuery;
 import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
-import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
 
+import java.sql.SQLException;
+
 /**
  * Provides means for nodes' IDs extraction in case we use {@link CacheableLockManagerImpl}
  * as {@link LockManager} based on shareable JBoss Cache instance.
@@ -44,12 +45,18 @@
    /**
     * {@inheritDoc}
     */
-   protected InspectionQuery getQuery() throws RepositoryConfigurationException
+   protected InspectionQuery getSelectQuery() throws SQLException
    {
-      return new InspectionQuery("SELECT * FROM "
-         + lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME) + " WHERE PARENT='/"
-         + workspaceEntry.getUniqueName() + "/" + CacheableLockManagerImpl.LOCKS + "'", new String[]{},
+      return new InspectionQuery("SELECT * FROM " + getTableName() + " WHERE " + getParentColumn() + "='/"
+         + workspaceEntry.getUniqueName() + "/" + CacheableLockManagerImpl.LOCKS + "'", new String[]{getIdColumn()},
          "Locks table match");
    }
 
+   protected InspectionQuery getDeleteQuery(String nodeId) throws SQLException
+   {
+      return new InspectionQuery("DELETE FROM " + getTableName() + " WHERE " + getIdColumn() + "='/"
+         + workspaceEntry.getUniqueName() + "/" + CacheableLockManagerImpl.LOCKS + "/" + nodeId + "'", new String[]{},
+         "");
+   }
+
 }
\ No newline at end of file

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -20,7 +20,7 @@
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
 import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.InspectionReport;
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
 import org.exoplatform.services.jcr.impl.core.SessionDataManager;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
 import org.exoplatform.services.jcr.impl.core.query.lucene.ChangesHolder;

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -50,7 +50,6 @@
 import org.exoplatform.services.jcr.datamodel.QPath;
 import org.exoplatform.services.jcr.datamodel.ValueData;
 import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.InspectionReport;
 import org.exoplatform.services.jcr.impl.backup.BackupException;
 import org.exoplatform.services.jcr.impl.backup.Backupable;
 import org.exoplatform.services.jcr.impl.backup.DataRestore;
@@ -59,6 +58,7 @@
 import org.exoplatform.services.jcr.impl.backup.Suspendable;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DataRestoreContext;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestore;
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
 import org.exoplatform.services.jcr.impl.core.LocationFactory;
 import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
 import org.exoplatform.services.jcr.impl.core.SessionDataManager;

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -54,10 +54,10 @@
 import org.exoplatform.services.jcr.datamodel.PropertyData;
 import org.exoplatform.services.jcr.datamodel.QPath;
 import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.InspectionReport;
 import org.exoplatform.services.jcr.impl.backup.ResumeException;
 import org.exoplatform.services.jcr.impl.backup.SuspendException;
 import org.exoplatform.services.jcr.impl.backup.Suspendable;
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
 import org.exoplatform.services.jcr.impl.core.LocationFactory;
 import org.exoplatform.services.jcr.impl.core.SessionDataManager;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
@@ -908,12 +908,14 @@
                   if (docs.next())
                   {
                      //multiple entries
-                     report.logBrokenObjectAndSetInconsistency("ID=" + uuid, "Multiple entires.");
+                     report.logComment("Multiple entires.");
+                     report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
                   }
                }
                else
                {
-                  report.logBrokenObjectAndSetInconsistency("ID=" + uuid, "Not indexed.");
+                  report.logComment("Not indexed.");
+                  report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
                }
             }
             catch (IOException e)
@@ -971,7 +973,8 @@
             String uuid = d.get(FieldNames.UUID);
             if (!documentUUIDs.contains(uuid))
             {
-               report.logBrokenObjectAndSetInconsistency("ID=" + uuid, "Document corresponds to removed node.");
+               report.logComment("Document corresponds to removed node.");
+               report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
             }
          }
       }

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 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.storage.jdbc;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * @author <a href="mailto:aplotnikov at exoplatform.com">Andrey Plotnikov</a>
- * @version $Id: InspectionQuery.java 34360 16.02.2012 andrew.plotnikov $
- */
-public class InspectionQuery
-{
-   /**
-    * Data class, contains a combination of SQL states, description, field names and status  
-    */
-
-   /**
-    * SQL query that must be executed.
-    */
-   public String statement;
-
-   /**
-    * Inspection query description.
-    */
-   public String description;
-
-   /**
-    * Field names that must be showed in inspection log if something wrong.
-    */
-   public String[] fieldNames;
-
-   public InspectionQuery(String statement, String[] fieldNames, String headerMessage)
-   {
-      this.statement = statement;
-      this.description = headerMessage;
-      this.fieldNames = fieldNames;
-   }
-
-   public String getStatement()
-   {
-      return statement;
-   }
-
-   public String getDescription()
-   {
-      return description;
-   }
-
-   public String[] getFieldNames()
-   {
-      return fieldNames;
-   }
-
-   /**
-    * Creates a PreparedStatement object for sending parameterized SQL statements to the database. 
-    * 
-    * @param connection
-    *          connection to workspace storage
-    * @return
-    *          a new default PreparedStatement object containing the pre-compiled SQL statement 
-    * @throws SQLException
-    *           if a database access error occurs or this method is called on a closed connection
-    */
-   public PreparedStatement prepareStatement(Connection connection) throws SQLException
-   {
-      return connection.prepareStatement(statement);
-   }
-
-}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQueryFilteredMultivaluedProperties.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 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.storage.jdbc;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * @author <a href="mailto:aplotnikov at exoplatform.com">Andrey Plotnikov</a>
- * @version $Id: InspectionQueryFilteredMultivaluedProperties.java 34360 16.02.2012 andrew.plotnikov $
- */
-class InspectionQueryFilteredMultivaluedProperties extends InspectionQuery
-{
-
-   /**
-    * {@inheritDoc}
-    */
-   public InspectionQueryFilteredMultivaluedProperties(String statement, String[] fieldNames, String headerMessage)
-   {
-      super(statement, fieldNames, headerMessage);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public PreparedStatement prepareStatement(Connection connection) throws SQLException
-   {
-      PreparedStatement preparedStatement = super.prepareStatement(connection);
-      preparedStatement.setBoolean(1, false);
-
-      return preparedStatement;
-   }
-
-}

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -2727,6 +2727,12 @@
     */
    protected abstract void deleteLockProperties() throws SQLException;
 
+   /**
+    * Deletes [http://www.jcp.org/jcr/1.0]lockOwner and [http://www.jcp.org/jcr/1.0]lockIsDeep
+    * properties directly from DB for specific parent.
+    */
+   protected abstract void deleteLockProperties(String nodeIdentifier) throws SQLException;
+
    protected abstract ResultSet findReferences(String nodeIdentifier) throws SQLException;
 
    protected abstract int deleteItemByIdentifier(String identifier) throws SQLException;

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -19,21 +19,25 @@
 package org.exoplatform.services.jcr.impl.storage.jdbc;
 
 import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.database.utils.JDBCUtils;
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
 import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.InspectionReport;
+import org.exoplatform.services.jcr.impl.checker.InspectionQuery;
+import org.exoplatform.services.jcr.impl.checker.InspectionQueryFilteredMultivaluedProperties;
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
+import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
 import org.exoplatform.services.jcr.impl.core.lock.LockTableHandlerFactory;
 import org.exoplatform.services.jcr.impl.storage.value.ValueDataNotFoundException;
 import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 
 import java.io.IOException;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -53,138 +57,129 @@
 {
    protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JDBCWorkspaceDataContainerChecker");
 
+   protected final JDBCWorkspaceDataContainer jdbcDataContainer;
+
+   protected final ValueStoragePluginProvider vsPlugin;
+
+   protected final WorkspaceEntry workspaceEntry;
+
+   protected final InspectionReport report;
+
+   private InspectionQuery vsInspectionQuery;
+
+   private InspectionQuery lockInspectionQuery;
+
+   private LockTableHandler lockHandler;
+
    /**
+    * JDBCWorkspaceDataContainerChecker constructor.
+    */
+   public JDBCWorkspaceDataContainerChecker(JDBCWorkspaceDataContainer jdbcDataContainer,
+      ValueStoragePluginProvider vsPlugin, WorkspaceEntry workspaceEntry, InspectionReport report)
+   {
+      this.jdbcDataContainer = jdbcDataContainer;
+      this.vsPlugin = vsPlugin;
+      this.workspaceEntry = workspaceEntry;
+      this.report = report;
+      this.lockHandler = LockTableHandlerFactory.getHandler(workspaceEntry);
+
+      initInspectionQueries();
+   }
+
+   /**
     * Checks jcr locks for consistency. Defines if there is a node with lockIsDeep or lockOwner property 
     * (basically means that the node is to be locked)
-    * and has no corresponding record in LockManager persistant layer ( db table); 
+    * and has no corresponding record in LockManager persistent layer (db table); 
     * or the opposite.
     */
-   public static void checkLocksInDataBase(JDBCWorkspaceDataContainer jdbcDataContainer, WorkspaceEntry workspaceEntry,
-      InspectionReport report) throws RepositoryException, IOException
+   public void checkLocksInDataBase(boolean autoRepair) throws RepositoryException, IOException
    {
-      String multiDbQueryStatement =
-         "SELECT DISTINCT PARENT_ID from JCR_MITEM WHERE I_CLASS=2 "
-            + "AND (NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+      SecurityHelper.validateSecurityPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
 
-      String singleDbQueryStatement =
-         "SELECT DISTINCT PARENT_ID from JCR_SITEM WHERE CONTAINER_NAME='"
-            + jdbcDataContainer.containerName
-            + "' AND I_CLASS=2 and (NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
-
-      InspectionQuery itemTableQuery =
-         new InspectionQuery(jdbcDataContainer.multiDb ? multiDbQueryStatement : singleDbQueryStatement,
-            new String[]{DBConstants.COLUMN_PARENTID}, "Items which have jcr:lockOwner and jcr:lockIsDeep properties");
-
       ResultSet resultSet = null;
       PreparedStatement preparedStatement = null;
-
-      // using existing DataSource to get a JDBC Connection.
-      Connection jdbcConnection = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+      Connection jdbcConnection = null;
       try
       {
-         preparedStatement = itemTableQuery.prepareStatement(jdbcConnection);
+         jdbcConnection = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+         preparedStatement = lockInspectionQuery.prepareStatement(jdbcConnection);
          resultSet = preparedStatement.executeQuery();
 
-         Set<String> itemTableIds = new HashSet<String>();
+         Set<String> lockedInJCRITEM = new HashSet<String>();
          while (resultSet.next())
          {
-            itemTableIds.add(jdbcDataContainer.multiDb ? resultSet.getString(DBConstants.COLUMN_PARENTID) : resultSet
-               .getString(DBConstants.COLUMN_PARENTID).substring(workspaceEntry.getName().length()));
+            lockedInJCRITEM.add(removeWorkspacePrefix(resultSet.getString(DBConstants.COLUMN_PARENTID)));
          }
 
-         Set<String> lockTableIds = LockTableHandlerFactory.getHandler(workspaceEntry).getLockedNodesIds();
+         Set<String> lockedInJCRLOCK = lockHandler.getLockedNodesIds();
 
-         checkIdSetsConsistency(report, itemTableIds, lockTableIds);
+         checkConsistencyInJCRITEM(lockedInJCRITEM, lockedInJCRLOCK, autoRepair);
+         checkConsistencyInJCRLOCK(lockedInJCRITEM, lockedInJCRLOCK, autoRepair);
       }
       catch (SQLException e)
       {
-         report.logExceptionAndSetInconsistency("Exception during Lock DB inspection.", e);
+         report.logExceptionAndSetInconsistency("Unexpected exception during LOCK DB checking.", e);
       }
       catch (NamingException e)
       {
-         report.logExceptionAndSetInconsistency("Exception during Lock DB inspection.", e);
+         report.logExceptionAndSetInconsistency("Unexpected exception during LOCK DB checking.", e);
       }
       catch (RepositoryConfigurationException e)
       {
-         report.logExceptionAndSetInconsistency("Exception during Lock DB inspection.", e);
+         report.logExceptionAndSetInconsistency("Unexpected exception during LOCK DB checking.", e);
       }
       finally
       {
-         if (resultSet != null)
+         JDBCUtils.freeResources(resultSet, preparedStatement, jdbcConnection);
+      }
+   }
+
+   private void checkConsistencyInJCRITEM(Set<String> lockedInJCRITEM, Set<String> lockedInJCRLOCK,
+      boolean autoRepair) throws RepositoryException, SQLException
+   {
+      for (String nodeId : lockedInJCRITEM)
+      {
+         if (!lockedInJCRLOCK.contains(nodeId))
          {
-            try
+            logBrokenObjectAndSetInconsistency("Lock exists in ITEM table but not in LOCK table. Node UUID: "
+               + nodeId);
+            
+            if (autoRepair)
             {
-               resultSet.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
-         if (preparedStatement != null)
-         {
-            try
-            {
-               preparedStatement.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
+               WorkspaceStorageConnection conn = jdbcDataContainer.openConnection();
+               try
+               {
+                  if (conn instanceof JDBCStorageConnection)
+                  {
+                     ((JDBCStorageConnection)conn).deleteLockProperties(nodeId);
+                  }
 
-         if (jdbcConnection != null)
-         {
-            try
-            {
-               jdbcConnection.close();
+                  logComment("Lock has been removed form ITEM table. Node UUID: " + nodeId);
+               }
+               finally
+               {
+                  conn.close();
+               }
             }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
          }
       }
    }
 
-   private static void checkIdSetsConsistency(InspectionReport report,
-      Set<String> itemTableIds, Set<String> lockTableIds) throws IOException
+   private void checkConsistencyInJCRLOCK(Set<String> lockedInJCRITEM, Set<String> lockedInJCRLOCK, boolean autoRepair)
+      throws NamingException, RepositoryConfigurationException, SQLException
    {
-      // let us make a set to contain all the consistent node IDs
-      // which obviously is an interection of 
-      // itemTableIds set and lockTableIds set
-      Set<String> consistentIds = new HashSet<String>(itemTableIds);
-      consistentIds.retainAll(lockTableIds);
-
-      // simply remove consistent node IDs
-      // and we will have inconsistent nodes left
-      itemTableIds.removeAll(consistentIds);
-      lockTableIds.removeAll(consistentIds);
-
-      if (!itemTableIds.isEmpty())
+      for (String nodeId : lockedInJCRLOCK)
       {
-         StringBuffer record = new StringBuffer();
-
-         record.append("Items listed in JCR_XITEM table have lock inconsistency:\n");
-         for (String id : itemTableIds)
+         if (!lockedInJCRITEM.contains(nodeId))
          {
-            record.append("Node UUID: " + id + "\n");
-         }
+            logBrokenObjectAndSetInconsistency("Lock exists in LOCK table but not in ITEM table. Node UUID: " + nodeId);
 
-         report.logBrokenObjectAndSetInconsistency(record.toString(), "");
-      }
-
-      if (!lockTableIds.isEmpty())
-      {
-         StringBuffer record = new StringBuffer();
-
-         record.append("Items listed in LockManager's table have lock inconsistency:\n");
-         for (String id : lockTableIds)
-         {
-            record.append("Node UUID: " + id + "\n");
+            if (autoRepair)
+            {
+               lockHandler.removeLockedNode(nodeId);
+               logComment("Lock has been removed form LOCK table. Node UUID: " + nodeId);
+            }
          }
-
-         report.logBrokenObjectAndSetInconsistency(record.toString(), "");
       }
    }
 
@@ -199,9 +194,11 @@
     * @throws RepositoryException
     * @throws IOException
     */
-   public static void checkDataBase(JDBCWorkspaceDataContainer jdbcDataContainer, InspectionReport report)
+   public void checkDataBase()
       throws RepositoryException, IOException
    {
+      SecurityHelper.validateSecurityPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+      
       Set<InspectionQuery> queries = new HashSet<InspectionQuery>();
 
       // preload queries
@@ -349,36 +346,14 @@
                         record.append(' ');
                      }
 
-                     report.logBrokenObjectAndSetInconsistency(record.toString(), "");
+                     report.logBrokenObjectAndSetInconsistency(record.toString());
                   }
                   while (resultSet.next());
                }
             }
-            // safely free resources
             finally
             {
-               if (resultSet != null)
-               {
-                  try
-                  {
-                     resultSet.close();
-                  }
-                  catch (SQLException e)
-                  {
-                     LOG.error(e.getMessage(), e);
-                  }
-               }
-               if (st != null)
-               {
-                  try
-                  {
-                     st.close();
-                  }
-                  catch (SQLException e)
-                  {
-                     LOG.error(e.getMessage(), e);
-                  }
-               }
+               JDBCUtils.freeResources(resultSet, st, null);
             }
          }
       }
@@ -388,117 +363,57 @@
       }
       finally
       {
-         // safely close connection
-         if (jdbcConn != null)
-         {
-            try
-            {
-               jdbcConn.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
+         JDBCUtils.freeResources(null, null, jdbcConn);
       }
    }
 
    /**
-    * Inspect ValueStorage. 
+    * Inspect ValueStorage.
     * <p>
     * All ValueDatas that have storage description (that means, value data stored in value storage) will be inspected:
     * <ul>
     * <li> does value exists in value storage;</li>
-    * <li> is this value readable;</li>
     * <ul>
-    *
-    * 
-    * @param vsPlugin - value storages
-    * @param inspectionLog - log where inspection results will be placed
-    * @return resulting InspectionLog
-    * @throws RepositoryException
-    * @throws IOException
     */
-   public static void checkValueStorage(final JDBCWorkspaceDataContainer jdbcDataContainer,
-      ValueStoragePluginProvider vsPlugin, InspectionReport report) throws RepositoryException, IOException
+   public void checkValueStorage(boolean autoRepair)
    {
-      final String valueRecordFormat = "ValueData[PROPERTY_ID=%s ORDER_NUM=%d STORAGE_DESC=%s]";
+      SecurityHelper.validateSecurityPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
 
-      Connection connection = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+      Connection connection = null;
       PreparedStatement st = null;
       ResultSet resultSet = null;
       try
       {
-         st =
-            connection.prepareStatement(jdbcDataContainer.multiDb
-               ? "SELECT PROPERTY_ID, ORDER_NUM, STORAGE_DESC from JCR_MVALUE where STORAGE_DESC is not null"
-               : "SELECT V.PROPERTY_ID, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM I"
-                  + " where I.CONTAINER_NAME='" + jdbcDataContainer.containerName
-                  + "' and V.PROPERTY_ID = I.ID and STORAGE_DESC is not null");
+         connection = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+         st = vsInspectionQuery.prepareStatement(connection);
+         resultSet = st.executeQuery();
 
-         resultSet = st.executeQuery();
-         // traverse all values, written to value storage
          if (resultSet.next())
          {
-            ValueIOChannel channel = null;
             do
             {
-               final String propertyId = resultSet.getString(DBConstants.COLUMN_VPROPERTY_ID);
-               final int orderNumber = resultSet.getInt(DBConstants.COLUMN_VORDERNUM);
-               final String storageDesc = resultSet.getString(DBConstants.COLUMN_VSTORAGE_DESC);
+               String propertyId = removeWorkspacePrefix(resultSet.getString(DBConstants.COLUMN_VPROPERTY_ID));
+               int orderNumber = resultSet.getInt(DBConstants.COLUMN_VORDERNUM);
+               String storageDesc = resultSet.getString(DBConstants.COLUMN_VSTORAGE_DESC);
 
-               // don't acquire channel if it is already open 
-               if (channel == null || !channel.getStorageId().equals(storageDesc))
+               ValueIOChannel channel = null;
+               try
                {
-                  try
-                  {
-                     if (channel != null)
-                     {
-                        channel.close();
-                     }
-                     channel = vsPlugin.getChannel(storageDesc);
-                  }
-                  catch (ValueStorageNotFoundException e)
-                  {
-                     report.logBrokenObjectAndSetInconsistency("ValueStorage " + storageDesc + " not found. "
-                        + String.format(valueRecordFormat, propertyId, orderNumber, storageDesc), e.getMessage());
-                     continue;
-                  }
+                  channel = getIOChannel(storageDesc);
+                  doCheckAndRepairValueData(channel, resultSet, propertyId, orderNumber, autoRepair);
                }
-
-               try
+               catch (IOException e)
                {
-                  // check value data
-                  final ValueIOChannel vdChannel = channel;
-                  SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
-                  {
-                     public Object run() throws ValueDataNotFoundException, IOException
-                     {
-                        vdChannel.checkValueData(
-                           jdbcDataContainer.multiDb ? propertyId : propertyId
-                              .substring(jdbcDataContainer.containerName.length()), orderNumber);
-                        return null;
-                     }
-                  });
+                  logDescription("Unexpected exception during checking");
+                  logBrokenObjectAndSetInconsistency(getBrokenObject(resultSet, vsInspectionQuery.getFieldNames()));
+                  logExceptionAndSetInconsistency(e.getMessage(), e);
                }
-               // process exception thrown by checkValueData
-               catch (PrivilegedActionException e)
+               finally
                {
-                  Throwable ex = e.getCause();
-                  if (ex instanceof ValueDataNotFoundException)
+                  if (channel != null)
                   {
-                     report.logBrokenObjectAndSetInconsistency(
-                        String.format(valueRecordFormat, propertyId, orderNumber, storageDesc) + " not found.",
-                        ex.getMessage());
+                     channel.close();
                   }
-                  else if (ex instanceof IOException)
-                  {
-                     report.logExceptionAndSetInconsistency(ex.getMessage(), ex);
-                  }
-                  else
-                  {
-                     throw new RepositoryException(ex.getMessage(), ex);
-                  }
                }
             }
             while (resultSet.next());
@@ -506,47 +421,157 @@
       }
       catch (SQLException e)
       {
-         report.logExceptionAndSetInconsistency("Exception during ValueStorage inspection.", e);
+         logExceptionAndSetInconsistency("Unexpected exception during checking.", e);
       }
+      catch (RepositoryException e)
+      {
+         logExceptionAndSetInconsistency("Unexpected exception during checking.", e);
+      }
       finally
       {
-         // safely free resources
-         if (resultSet != null)
+         JDBCUtils.freeResources(resultSet, st, connection);
+      }
+   }
+
+   private ValueIOChannel getIOChannel(String storageDesc) throws IOException
+   {
+      ValueIOChannel channel = null;
+      try
+      {
+         channel = vsPlugin.getChannel(storageDesc);
+      }
+      catch (ValueStorageNotFoundException e)
+      {
+         logDescription("ValueStorage " + storageDesc + " not found");
+         logExceptionAndSetInconsistency(e.getMessage(), e);
+      }
+
+      return channel;
+   }
+
+   private void doCheckAndRepairValueData(ValueIOChannel channel, ResultSet resultSet, String propertyId,
+      int orderNumber, boolean autoRepair) throws IOException
+   {
+      try
+      {
+         channel.checkValueData(propertyId, orderNumber);
+      }
+      catch (ValueDataNotFoundException e)
+      {
+         String brokenObject = getBrokenObject(resultSet, vsInspectionQuery.getFieldNames());
+
+         logDescription("ValueData not found");
+         logBrokenObjectAndSetInconsistency(brokenObject);
+         logExceptionAndSetInconsistency(e.getMessage(), e);
+
+         if (autoRepair)
          {
-            try
-            {
-               resultSet.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
+            channel.repairValueData(propertyId, orderNumber);
+            logComment("ValueData corresponding to " + brokenObject + " has been repaired. New empty file is created.");
          }
+      }
+   }
 
-         if (st != null)
+   private String removeWorkspacePrefix(String str)
+   {
+      return jdbcDataContainer.multiDb ? str : str.substring(jdbcDataContainer.containerName.length());
+   }
+
+   private String getBrokenObject(ResultSet resultSet, String[] fieldNames)
+   {
+      StringBuilder record = new StringBuilder();
+      for (String fieldName : fieldNames)
+      {
+         record.append(fieldName);
+         record.append('=');
+
+         try
          {
-            try
-            {
-               st.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
+            record.append(resultSet.getString(fieldName));
          }
-
-         if (connection != null)
+         catch (SQLException e)
          {
-            try
-            {
-               connection.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
+            LOG.error(e.getMessage(), e);
          }
+         record.append(' ');
       }
+      
+      return record.toString();
    }
 
+   private void logBrokenObjectAndSetInconsistency(String brokenObject)
+   {
+      try
+      {
+         report.logBrokenObjectAndSetInconsistency(brokenObject);
+      }
+      catch (IOException e)
+      {
+         LOG.error(e.getMessage(), e);
+      }
+   }
+
+   private void logComment(String message)
+   {
+      try
+      {
+         report.logComment(message);
+      }
+      catch (IOException e1)
+      {
+         LOG.error(e1.getMessage(), e1);
+      }
+   }
+
+   private void logDescription(String description)
+   {
+      try
+      {
+         report.logDescription(description);
+      }
+      catch (IOException e1)
+      {
+         LOG.error(e1.getMessage(), e1);
+      }
+   }
+
+   private void logExceptionAndSetInconsistency(String message, Throwable e)
+   {
+      try
+      {
+         report.logExceptionAndSetInconsistency(message, e);
+      }
+      catch (IOException e1)
+      {
+         LOG.error(e1.getMessage(), e1);
+      }
+   }
+
+   private void initInspectionQueries()
+   {
+      String singleDbQuery =
+         "SELECT V.PROPERTY_ID, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM I"
+            + " where I.CONTAINER_NAME='" + jdbcDataContainer.containerName
+            + "' and V.PROPERTY_ID = I.ID and STORAGE_DESC is not null";
+      String multiDbQuery =
+         "SELECT PROPERTY_ID, ORDER_NUM, STORAGE_DESC from JCR_MVALUE where STORAGE_DESC is not null";
+
+      vsInspectionQuery =
+         new InspectionQuery(jdbcDataContainer.multiDb ? multiDbQuery : singleDbQuery, new String[]{
+            DBConstants.COLUMN_VPROPERTY_ID, DBConstants.COLUMN_VORDERNUM, DBConstants.COLUMN_VSTORAGE_DESC},
+            "Items with value data stored in value storage");
+
+      singleDbQuery =
+         "SELECT DISTINCT PARENT_ID from JCR_MITEM WHERE I_CLASS=2 "
+            + "AND (NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+
+      multiDbQuery =
+         "SELECT DISTINCT PARENT_ID from JCR_SITEM WHERE CONTAINER_NAME='"
+            + jdbcDataContainer.containerName
+            + "' AND I_CLASS=2 and (NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+
+      lockInspectionQuery =
+         new InspectionQuery(jdbcDataContainer.multiDb ? singleDbQuery : multiDbQuery,
+            new String[]{DBConstants.COLUMN_PARENTID}, "Items which have jcr:lockOwner and jcr:lockIsDeep properties");
+   }
 }

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -616,4 +616,60 @@
       }
       return findNodesCount.executeQuery();
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected void deleteLockProperties(String nodeIdentifier) 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 PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner'))");
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner')");
+
+         removeValuesStatement.setString(1, getInternalId(nodeIdentifier));
+         removeItemsStatement.setString(1, getInternalId(nodeIdentifier));
+
+         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/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -649,4 +649,59 @@
 
       return findNodesCount.executeQuery();
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected void deleteLockProperties(String nodeIdentifier) 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 PARENT_ID=? AND (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner'))");
+         removeValuesStatement.setString(1, containerName);
+         removeValuesStatement.setString(2, getInternalId(nodeIdentifier));
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner')");
+         removeItemsStatement.setString(1, containerName);
+         removeItemsStatement.setString(2, getInternalId(nodeIdentifier));
+
+         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/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1088,6 +1088,61 @@
    /**
     * {@inheritDoc}
     */
+   protected void deleteLockProperties(String nodeIdentifier) 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 PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner'))");
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner')");
+
+         removeValuesStatement.setString(1, getInternalId(nodeIdentifier));
+         removeItemsStatement.setString(1, getInternalId(nodeIdentifier));
+
+         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);
+            }
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
    @Override
    protected ResultSet findNodesCount() throws SQLException
    {

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -1028,4 +1028,59 @@
 
       return findNodesCount.executeQuery();
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected void deleteLockProperties(String nodeIdentifier) 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 PARENT_ID=? AND (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner'))");
+         removeValuesStatement.setString(1, containerName);
+         removeValuesStatement.setString(2, getInternalId(nodeIdentifier));
+
+         removeItemsStatement =
+            dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND PARENT_ID=? AND"
+               + " (NAME = '[http://www.jcp.org/jcr/1.0]lockIsDeep' OR"
+               + " NAME = '[http://www.jcp.org/jcr/1.0]lockOwner')");
+         removeItemsStatement.setString(1, containerName);
+         removeItemsStatement.setString(2, getInternalId(nodeIdentifier));
+
+         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/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -173,44 +173,23 @@
     */
    public void checkValueData(String propertyId, int orderNumber) throws ValueDataNotFoundException, IOException
    {
-      try
+      File f = getFile(propertyId, orderNumber);
+      if (!f.exists())
       {
-         //check that file exists
-         File f = getFile(propertyId, orderNumber);
-         if (!f.exists())
-         {
-            throw new ValueDataNotFoundException("Value data of property with [id=" + propertyId + ", ordernum="
-               + orderNumber + "] do not exists.");
-         }
-         else
-         {
-            //check readability
-            InputStream is = new FileInputStream(f);
-            try
-            {
-               is.read();
-            }
-            finally
-            {
-               try
-               {
-                  is.close();
-               }
-               catch (IOException e)
-               {
-                  if (LOG.isTraceEnabled())
-                  {
-                     LOG.trace("An exception occurred: " + e.getMessage());
-                  }
-               }
-            }
-         }
+         throw new ValueDataNotFoundException("Value data corresponding to property with [id=" + propertyId
+            + ", ordernum=" + orderNumber + "] does not exist.");
       }
-      catch (IOException e)
-      {
-         throw new ValueDataNotFoundException("Value data of property [id=" + propertyId + ", ordernum=" + orderNumber
-            + "] can not be read.");
+   }
 
+   /**
+    * {@inheritDoc}
+    */
+   public void repairValueData(String propertyId, int orderNumber) throws IOException
+   {
+      File f = getFile(propertyId, orderNumber);
+      if (!f.createNewFile())
+      {
+         throw new IOException("Can not create empty file " + f.getAbsolutePath());
       }
    }
 

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -47,16 +47,29 @@
    ValueData read(String propertyId, int orderNumber, int maxBufferSize) throws IOException;
 
    /**
-    * Check ValueData. Check that value storage contain this value and value is readable.
+    * Inspects whether corresponding file exists in value storage or not.
     * 
-    * @param propertyId - Property ID
-    * @param orderNumber - Property order number
-    * @throws ValueDataNotFoundException thrown if value data not exist or can not be read
-    * @throws IOException
+    * @param propertyId 
+    *          Property ID
+    * @param orderNumber 
+    *          Property order number
+    * @throws ValueDataNotFoundException is thrown if file not exist
+    * @throws IOException is thrown if another IO error is occurred
     */
    void checkValueData(String propertyId, int orderNumber) throws ValueDataNotFoundException, IOException;
 
    /**
+    * Repair value data by creation new corresponding empty file.
+    * 
+    * @param propertyId 
+    *          Property ID
+    * @param orderNumber 
+    *          Property order number
+    * @throws IOException is thrown if can not create new empty file
+    */
+   void repairValueData(String propertyId, int orderNumber) throws IOException;
+
+   /**
     * Add or update Property value.
     * 
     * @param propertyId

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -19,7 +19,7 @@
 import org.apache.lucene.search.Query;
 import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
 import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.InspectionReport;
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
 import org.exoplatform.services.jcr.impl.core.SessionDataManager;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
 import org.exoplatform.services.jcr.impl.core.query.AbstractQueryHandler;

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -20,6 +20,8 @@
 
 import junit.framework.TestCase;
 
+import org.exoplatform.services.jcr.impl.checker.InspectionReport;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -78,7 +80,7 @@
 
    public void testLogBrokenObjectInfo() throws Exception
    {
-      report.logBrokenObjectAndSetInconsistency("broken object descr", "message");
+      report.logBrokenObjectAndSetInconsistency("broken object descr");
 
       // read file;
       Reader reader = new FileReader(getFileFromReport());
@@ -86,7 +88,7 @@
       String s = br.readLine();
       br.close();
 
-      assertEquals("broken object descr message", s);
+      assertEquals("broken object descr", s);
       assertTrue(report.hasInconsistency());
    }
 

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -29,7 +29,8 @@
 import org.exoplatform.services.jcr.datamodel.InternalQName;
 import org.exoplatform.services.jcr.datamodel.NodeData;
 import org.exoplatform.services.jcr.datamodel.QPath;
-import org.exoplatform.services.jcr.impl.RepositoryCheckController.DataStorage;
+import org.exoplatform.services.jcr.impl.checker.RepositoryCheckController;
+import org.exoplatform.services.jcr.impl.checker.RepositoryCheckController.DataStorage;
 import org.exoplatform.services.jcr.impl.core.NodeImpl;
 import org.exoplatform.services.jcr.impl.core.PropertyImpl;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
@@ -63,9 +64,6 @@
  */
 public class TestRepositoryCheckController extends BaseStandaloneTest
 {
-
-   private TesterRepositoryCheckController checkController;
-
    private static boolean SHARED_CACHE = true;
 
    private static boolean NOT_SHARED_CACHE = false;
@@ -95,16 +93,25 @@
 
    }
 
-   public void setUp() throws Exception
+   public void tearDown() throws Exception
    {
-      super.setUp();
+      for (File file : new File(".").listFiles())
+      {
+         if (file.getName().startsWith("report"))
+         {
+            file.delete();
+         }
+      }
+
+      super.tearDown();
    }
 
    public void testDB() throws Exception
    {
-      checkController = new TesterRepositoryCheckController(repositoryService.getRepository("db1"));
+      TesterRepositoryCheckController checkController =
+         new TesterRepositoryCheckController(repositoryService.getRepository("db1"));
 
-      String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
+      String result = checkController.checkAndRepair(new DataStorage[]{DataStorage.DB}, false);
       assertNotNull(result);
       assertTrue("Repository data is not consistent, result: " + result,
          result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
@@ -133,13 +140,12 @@
       session.save();
       node.lock(false, false);
 
-      checkController = new TesterRepositoryCheckController(repository);
-      String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      String result = checkController.checkAndRepair(new DataStorage[]{DataStorage.DB}, false);
       assertNotNull(result);
 
       assertTrue("Repository data is not consistent, result: " + result,
          result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
    }
 
    public void testInconsistentLocksInDataBase() throws Exception
@@ -170,6 +176,8 @@
       session.save();
       node.lock(false, false);
 
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+
       WorkspaceEntry workspaceEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       String sourceName = workspaceEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
 
@@ -209,12 +217,10 @@
       conn.commit();
       conn.close();
 
-      checkController = new TesterRepositoryCheckController(repository);
-      String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
-      assertNotNull(result);
-      assertTrue("Repository data is consistent, result: " + result,
-         result.startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+      assertTrue(checkController.checkDataBase().startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
+
+      checkController.repairDataBase("yes");
+      assertTrue(checkController.checkValueStorage().startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
    }
 
    private void checkInconsistentLocksInLockTable(boolean cacheShared, boolean isMultiDb) throws Exception
@@ -266,17 +272,17 @@
       conn.commit();
       conn.close();
 
-      checkController = new TesterRepositoryCheckController(repository);
-      String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      String result = checkController.checkAndRepair(new DataStorage[]{DataStorage.DB}, false);
       assertNotNull(result);
       assertTrue("Repository data is consistent, result: " + result,
          result.startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    public void testValueStorage() throws Exception
    {
-      checkController = new TesterRepositoryCheckController(repositoryService.getRepository("db1"));
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
 
       File f = this.createBLOBTempFile(20);
       InputStream is = new FileInputStream(f);
@@ -287,7 +293,7 @@
 
          root.save();
 
-         String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.VALUE_STORAGE});
+         String result = checkController.checkAndRepair(new DataStorage[]{DataStorage.VALUE_STORAGE}, false);
          assertNotNull(result);
          assertTrue("Repository data is not consistent, result: " + result,
             result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
@@ -301,9 +307,9 @@
 
    public void testSearchIndex() throws Exception
    {
-      checkController = new TesterRepositoryCheckController(repositoryService.getRepository("db1"));
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
 
-      String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.LUCENE_INDEX});
+      String result = checkController.checkAndRepair(new DataStorage[]{DataStorage.LUCENE_INDEX}, false);
       assertNotNull(result);
       assertTrue("Repository data is not consistent, result: " + result,
          result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
@@ -311,13 +317,13 @@
 
    public void testAll() throws Exception
    {
-      checkController = new TesterRepositoryCheckController(repositoryService.getRepository("db1"));
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
 
       String result =
-         checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
-            DataStorage.LUCENE_INDEX});
-      checkController.getLastLogFile().delete();
+         checkController.checkAndRepair(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
+            DataStorage.LUCENE_INDEX}, false);
 
+
       assertNotNull(result);
       assertTrue("Repository data is not consistent, result: " + result,
          result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
@@ -338,11 +344,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -362,9 +368,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -383,11 +389,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -424,9 +430,9 @@
       sm.onSaveItems(log);
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -445,11 +451,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -486,9 +492,9 @@
       sm.onSaveItems(log);
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositorySearchIndexConsistency().startsWith(
+      assertTrue(checkController.checkIndex().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -518,11 +524,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -541,9 +547,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -573,11 +579,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -610,9 +616,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -642,11 +648,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -666,9 +672,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -699,11 +705,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -719,9 +725,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    private void checkDBUsecasesIncorrectValueRecords2(ManageableRepository repository) throws Exception
@@ -734,11 +740,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -754,9 +760,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -785,11 +791,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -808,9 +814,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -841,11 +847,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -861,9 +867,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    private void checkDBUsecasesPropertiesHasEmptyMultiValueRecord(ManageableRepository repository) throws Exception
@@ -876,10 +882,10 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -912,11 +918,11 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -932,9 +938,9 @@
       conn.close();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+
    }
 
    /**
@@ -966,11 +972,11 @@
       PropertyIterator iter = node.getProperties();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -998,9 +1004,8 @@
       session.logout();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
    }
 
    private void checkDBUsecasesNodeHasPrimaryTypeProperties(ManageableRepository repository) throws Exception
@@ -1014,11 +1019,11 @@
       PropertyIterator iter = node.getProperties();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
+
       WorkspaceEntry wsEntry = repository.getConfiguration().getWorkspaceEntries().get(0);
       boolean isMultiDb = wsEntry.getContainer().getParameterBoolean(JDBCWorkspaceDataContainer.MULTIDB);
 
@@ -1050,9 +1055,8 @@
       session.logout();
 
       // repository is inconsistent
-      assertTrue(checkController.checkRepositoryDataBaseConsistency().startsWith(
+      assertTrue(checkController.checkDataBase().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
    }
 
    /**
@@ -1084,10 +1088,9 @@
       session.logout();
 
       // repository is consistent
-      checkController = new TesterRepositoryCheckController(repository);
-      assertTrue(checkController.checkRepositoryValueStorageConsistency().startsWith(
+      TesterRepositoryCheckController checkController = new TesterRepositoryCheckController(repository);
+      assertTrue(checkController.checkValueStorage().startsWith(
          RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
 
       // remove the file from the value storage
       String vsPath =
@@ -1098,9 +1101,10 @@
       assertTrue(vsFile.exists());
       assertTrue(vsFile.delete());
 
-      // repository is inconsistent
-      assertTrue(checkController.checkRepositoryValueStorageConsistency().startsWith(
-         RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
-      checkController.getLastLogFile().delete();
+      assertTrue(checkController.checkValueStorage()
+         .startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
+
+      checkController.repairValueStorage("yes");
+      assertTrue(checkController.checkValueStorage().startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
    }
 }

Modified: jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TesterRepositoryCheckController.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TesterRepositoryCheckController.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TesterRepositoryCheckController.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -19,6 +19,7 @@
 package org.exoplatform.services.jcr.impl;
 
 import org.exoplatform.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.jcr.impl.checker.RepositoryCheckController;
 
 import java.io.File;
 

Modified: jcr/branches/1.15.x/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java
===================================================================
--- jcr/branches/1.15.x/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java	2012-02-29 06:57:09 UTC (rev 5706)
+++ jcr/branches/1.15.x/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java	2012-02-29 07:24:49 UTC (rev 5707)
@@ -18,27 +18,15 @@
  */
 package org.exoplatform.services.jcr.impl.core.lock.infinispan;
 
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.config.LockManagerEntry;
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
-import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
+import org.exoplatform.services.jcr.impl.checker.InspectionQuery;
+import org.exoplatform.services.jcr.impl.core.lock.AbstractLockTableHandler;
 import org.exoplatform.services.log.ExoLogger;
 import org.exoplatform.services.log.Log;
 
-import java.security.PrivilegedExceptionAction;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
 
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-
 /**
  * Provides means for nodes' IDs extraction in case we use {@link ISPNCacheableLockManagerImpl}
  * as {@link LockManager} based on ISPN Cache instance.
@@ -47,110 +35,88 @@
  * @version $Id: ISPNLockTableHandler.java 34360 27.02.2012 12:41:39 dkuleshov $
  *
  */
-public class ISPNLockTableHandler implements LockTableHandler
+public class ISPNLockTableHandler extends AbstractLockTableHandler
 {
 
    protected static final Log LOG = ExoLogger
       .getLogger("exo.jcr.component.core.impl.infinispan.v5.ISPNLockTableHandler");
 
-   protected final WorkspaceEntry workspaceEntry;
-
-   protected final LockManagerEntry lockManagerEntry;
-
+   /**
+    * ISPNLockTableHandler constructor.
+    */
    public ISPNLockTableHandler(WorkspaceEntry workspaceEntry)
    {
-      this.workspaceEntry = workspaceEntry;
-      this.lockManagerEntry = workspaceEntry.getLockManager();
+      super(workspaceEntry);
    }
 
    /**
     * {@inheritDoc}
     */
-   public Set<String> getLockedNodesIds() throws RepositoryConfigurationException, SQLException, NamingException
+   protected InspectionQuery getSelectQuery() throws SQLException
    {
-      Set<String> lockedNodesIds = new HashSet<String>();
+      return new InspectionQuery("SELECT * FROM " + getTableName(), new String[]{getIdColumn()}, "Locks table match");
+   }
 
-      ResultSet resultSet = null;
-      PreparedStatement preparedStatement = null;
+   /**
+    * {@inheritDoc}
+    */
+   public InspectionQuery getDeleteQuery(String nodeId) throws SQLException
+   {
+      return new InspectionQuery("DELETE FROM " + getTableName() + " WHERE " + getIdColumn() + "='" + nodeId + "'",
+         new String[]{}, "");
+   }
 
-      Connection jdbcConnection = openConnection();
+   /**
+    * Returns the column name which contain node identifier.
+    */
+   private String getIdColumn() throws SQLException
+   {
       try
       {
-         InspectionQuery inspectionQuery = getQuery();
-
-         preparedStatement = inspectionQuery.prepareStatement(jdbcConnection);
-         resultSet = preparedStatement.executeQuery();
-
-         String idColumn =
-            lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_ID_COLUMN_NAME);
-
-         while (resultSet.next())
-         {
-            lockedNodesIds.add(resultSet.getString(idColumn));
-         }
+         return lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_ID_COLUMN_NAME);
       }
-      finally
+      catch (RepositoryConfigurationException e)
       {
-         if (resultSet != null)
-         {
-            try
-            {
-               resultSet.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
-         if (preparedStatement != null)
-         {
-            try
-            {
-               preparedStatement.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
-         if (jdbcConnection != null)
-         {
-            try
-            {
-               jdbcConnection.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error(e.getMessage(), e);
-            }
-         }
+         throw new SQLException(e);
       }
-
-      return lockedNodesIds;
    }
 
-   protected InspectionQuery getQuery() throws RepositoryConfigurationException
+   /**
+    * Returns the name of LOCK table.
+    */
+   private String getTableName() throws SQLException
    {
-      String tableName =
-         lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_TABLE_NAME) + "_" + "L"
+      try
+      {
+         return lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_TABLE_NAME) + "_" + "L"
             + workspaceEntry.getUniqueName().replace("_", "").replace("-", "_");
-
-      return new InspectionQuery("SELECT * FROM " + tableName, new String[]{}, "Locks table match");
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         throw new SQLException(e);
+      }
    }
-
-   private Connection openConnection() throws NamingException, RepositoryConfigurationException, SQLException
+   
+   /**
+    * {@inheritDoc}
+    */
+   protected String getDataSourceName() throws SQLException
    {
-      final DataSource ds =
-         (DataSource)new InitialContext().lookup(lockManagerEntry
-            .getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_DATASOURCE));
-
-      return SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+      try
       {
-         public Connection run() throws SQLException
-         {
-            return ds.getConnection();
-         }
-      });
+         return lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_DATASOURCE);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         throw new SQLException(e);
+      }
    }
 
+   /**
+    * {@inheritDoc}
+    */
+   protected String extractNodeId(String value)
+   {
+      return value;
+   }
 }
\ No newline at end of file



More information about the exo-jcr-commits mailing list