exo-jcr SVN: r5076 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-20 10:02:26 -0400 (Thu, 20 Oct 2011)
New Revision: 5076
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
Log:
EXOJCR-1590: support cache migration from 1.12.x to 1.14.x
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-10-20 14:00:59 UTC (rev 5075)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-10-20 14:02:26 UTC (rev 5076)
@@ -799,7 +799,6 @@
for (LockData lockData : locks)
{
removeLock(lockData.getNodeIdentifier());
- doRemove(lockData);
}
}
14 years, 6 months
exo-jcr SVN: r5075 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan and 6 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-10-20 10:00:59 -0400 (Thu, 20 Oct 2011)
New Revision: 5075
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
Log:
EXOJCR-1590: support cache migration from 1.12.x to 1.14.x
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -17,6 +17,7 @@
package org.exoplatform.services.jcr.impl.core.lock.cacheable;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -128,6 +129,8 @@
*/
protected TransactionManager tm;
+ public static final String LOCKS_FORCE_REMOVE = "org.exoplatform.jcr.locks.force.remove";
+
/**
* Logger
*/
@@ -524,6 +527,20 @@
public void start()
{
lockRemover.start();
+
+ // Remove all locks records directly from DB.
+ boolean deleteLocks = "true".equalsIgnoreCase(PrivilegedSystemHelper.getProperty(LOCKS_FORCE_REMOVE, "false"));
+
+ if (deleteLocks)
+ {
+ doClean();
+ }
+
+ // remove all locks at the start up time EXOJCR-1592
+ // if (isCoordinator())
+ // {
+ // removeAll();
+ // }
}
/**
@@ -774,11 +791,24 @@
}
/**
+ * Remove all locks.
+ */
+ protected void removeAll()
+ {
+ List<LockData> locks = getLockList();
+ for (LockData lockData : locks)
+ {
+ removeLock(lockData.getNodeIdentifier());
+ doRemove(lockData);
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
public void clean() throws BackupException
{
- cleanCacheDirectly();
+ doClean();
}
/**
@@ -906,7 +936,7 @@
public void clean() throws BackupException
{
actualLocks.addAll(getLockList());
- cleanCacheDirectly();
+ doClean();
}
/**
@@ -916,7 +946,7 @@
{
for (LockData lockData : backupLocks)
{
- putDirectly(lockData);
+ doPut(lockData);
}
}
@@ -932,10 +962,10 @@
*/
public void rollback() throws BackupException
{
- cleanCacheDirectly();
+ doClean();
for (LockData lockData : actualLocks)
{
- putDirectly(lockData);
+ doPut(lockData);
}
}
@@ -950,16 +980,30 @@
}
/**
+ * Indicates if we are the only node in cluster.
+ */
+ protected abstract boolean isAloneInCluster();
+
+ /**
* Puts lock data directly into cache.
*
* @param lockData
* the lock data to put
+ * @return the old lock data previously added into cache
*/
- protected abstract void putDirectly(LockData lockData);
+ protected abstract LockData doPut(LockData lockData);
/**
+ * Removes lock data directly from cache.
+ *
+ * @param lockData
+ * the lock data to remove
+ */
+ protected abstract void doRemove(LockData lockData);
+
+ /**
* Clean cache directly.
*/
- protected abstract void cleanCacheDirectly();
+ protected abstract void doClean();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/LockData.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -31,9 +31,9 @@
* @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
* @version $Id: LockData.java 787 2009-11-20 11:36:15Z nzamosenchuk $
*/
-
public class LockData implements Externalizable
{
+
/**
* The time of birth. From this time we start count the time of death. death = birthday+TIME_OUT;
*/
@@ -96,7 +96,7 @@
{
this(nodeIdentifier, lockTokenHash, deep, sessionScoped, owner, timeOut, System.currentTimeMillis());
}
-
+
/**
* @param nodeIdentifier
* @param lockToken
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -39,6 +39,7 @@
import org.exoplatform.services.naming.InitialContextInitializer;
import org.exoplatform.services.transaction.TransactionService;
import org.infinispan.Cache;
+import org.infinispan.config.Configuration.CacheMode;
import org.infinispan.lifecycle.ComponentStatus;
import java.io.Serializable;
@@ -366,7 +367,7 @@
LockData lockData = session.getPendingLock(nodeIdentifier);
// this will return null if success. And old data if something exists...
- LockData oldLockData = (LockData)PrivilegedISPNCacheHelper.putIfAbsent(cache, nodeIdentifier, lockData);
+ LockData oldLockData = doPut(lockData);
if (oldLockData != null)
{
@@ -392,7 +393,7 @@
if (lData != null)
{
- cache.remove(nodeIdentifier);
+ doRemove(lData);
CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
if (sessMgr != null)
@@ -403,23 +404,45 @@
}
/**
- * {@inheritDoc}
- */
+ * {@inheritDoc}
+ */
@Override
- protected void putDirectly(LockData lockData)
+ protected LockData doPut(LockData lockData)
{
- PrivilegedISPNCacheHelper.putIfAbsent(cache, lockData.getNodeIdentifier(), lockData);
+ return (LockData)PrivilegedISPNCacheHelper.putIfAbsent(cache, lockData.getNodeIdentifier(), lockData);
}
/**
* {@inheritDoc}
*/
@Override
- protected void cleanCacheDirectly()
+ protected void doRemove(LockData lockData)
{
+ cache.remove(lockData.getNodeIdentifier());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isAloneInCluster()
+ {
+ return cache.getConfiguration().getCacheMode() == CacheMode.LOCAL
+ || cache.getCacheManager().getMembers().size() == 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doClean()
+ {
if (cache.getStatus() == ComponentStatus.RUNNING)
{
- cache.clear();
+ for (LockData lockData : getLockList())
+ {
+ doRemove(lockData);
+ }
}
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -46,6 +46,7 @@
import org.jboss.cache.Node;
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.jmx.JmxRegistrationManager;
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.loader.CacheLoaderManager;
@@ -185,11 +186,11 @@
Fqn<String> rootFqn = Fqn.fromElements(config.getUniqueName());
- lockRoot = Fqn.fromRelativeElements(rootFqn, LOCKS);
-
shareable =
config.getLockManager().getParameterBoolean(JBOSSCACHE_SHAREABLE, JBOSSCACHE_SHAREABLE_DEFAULT)
.booleanValue();
+ lockRoot = shareable ? Fqn.fromRelativeElements(rootFqn, LOCKS) : Fqn.fromElements(LOCKS);
+
cache = ExoJBossCacheFactory.getUniqueInstance(CacheType.LOCK_CACHE, rootFqn, cache, shareable);
this.jmxManager = ExoJBossCacheFactory.getJmxRegistrationManager(ctx, cache, CacheType.LOCK_CACHE);
if (jmxManager != null)
@@ -491,8 +492,8 @@
}
/**
- * {@inheritDoc}
- */
+ * {@inheritDoc}
+ */
@Override
public void stop()
{
@@ -529,13 +530,9 @@
if (session != null && session.containsPendingLock(nodeIdentifier))
{
LockData lockData = session.getPendingLock(nodeIdentifier);
- Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
- // addChild will add if absent or return old if present
- Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
-
// this will return null if success. And old data if something exists...
- LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
+ LockData oldLockData = doPut(lockData);
if (oldLockData != null)
{
@@ -561,7 +558,7 @@
if (lData != null)
{
- cache.removeNode(makeLockFqn(nodeIdentifier));
+ doRemove(lData);
CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
if (sessMgr != null)
@@ -607,24 +604,47 @@
* {@inheritDoc}
*/
@Override
- protected void putDirectly(LockData lockData)
+ protected LockData doPut(LockData lockData)
{
Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
+ // addChild will add if absent or return old if present
Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
- node.putIfAbsent(LOCK_DATA, lockData);
+
+ // this will return null if success. And old data if something exists...
+ return (LockData)node.putIfAbsent(LOCK_DATA, lockData);
}
/**
* {@inheritDoc}
*/
@Override
- protected void cleanCacheDirectly()
+ protected void doRemove(LockData lockData)
{
- if (cache.getCacheStatus() != CacheStatus.STARTED)
+ cache.removeNode(makeLockFqn(lockData.getNodeIdentifier()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isAloneInCluster()
+ {
+ return cache.getConfiguration().getCacheMode() == CacheMode.LOCAL || cache.getMembers().size() == 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doClean()
+ {
+ if (cache.getCacheStatus() == CacheStatus.STARTED)
{
- cache.removeNode(lockRoot);
- createStructuredNode(lockRoot);
+ for (LockData lockData : getLockList())
+ {
+ doRemove(lockData);
+ }
}
}
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/LockData.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.lock.jbosscache;
+
+
+/**
+ * For backward compatibility between 1.12.x and 1.14.x
+ *
+ * @author <a href="abazko(a)exoplatform.com">Anatoliy Bazko</a>
+ * @version $Id: LockData.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class LockData extends org.exoplatform.services.jcr.impl.core.lock.cacheable.LockData
+{
+ private static final long serialVersionUID = 920103551272363119L;
+
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -1115,7 +1115,7 @@
continue;
}
QPathEntryFilter nameFilter = (QPathEntryFilter)patternObject;
- if (nameFilter.accept((ItemData)value))
+ if (nameFilter.accept(value))
{
cache.getInvocationContext().getOptionOverrides().setForceWriteLock(true);
Object setObject = cache.get(patternFqn, listKey);
@@ -1230,7 +1230,7 @@
continue;
}
QPathEntryFilter nameFilter = (QPathEntryFilter)patternObject;
- if (nameFilter.accept((ItemData)value))
+ if (nameFilter.accept(value))
{
cache.getInvocationContext().getOptionOverrides().setForceWriteLock(true);
Object setObject = cache.get(patternFqn, listKey);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -2937,6 +2937,12 @@
protected abstract int deleteReference(String propertyIdentifier) throws SQLException;
+ /**
+ * Deletes [http://www.jcp.org/jcr/1.0]lockOwner and [http://www.jcp.org/jcr/1.0]lockIsDeep
+ * properties directly from DB.
+ */
+ protected abstract void deleteLockProperties() throws SQLException;
+
protected abstract ResultSet findReferences(String nodeIdentifier) throws SQLException;
protected abstract int deleteItemByIdentifier(String identifier) throws SQLException;
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -21,6 +21,7 @@
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.commons.utils.PrivilegedSystemHelper;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.ValueStorageEntry;
@@ -44,6 +45,7 @@
import org.exoplatform.services.jcr.impl.backup.rdbms.SybaseDBRestore;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.core.query.Reindexable;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
@@ -369,8 +371,8 @@
}
catch (RepositoryConfigurationException e)
{
- sn = wsConfig.getContainer().getParameterValue("sourceName"); // TODO for backward comp,
- // remove in rel.2.0
+ // for backward comp remove in rel.2.0
+ sn = wsConfig.getContainer().getParameterValue("sourceName");
}
this.dbSourceName = sn;
if (dsProvider == null)
@@ -913,6 +915,37 @@
}
}
}
+
+ // Remove lock properties from DB. It is an issue of migration locks from 1.12.x to 1.14.x in case when we use
+ // shareable cache. The lock tables will be new but still remaining lock properties in JCR tables.
+ boolean deleteLocks =
+ "true".equalsIgnoreCase(PrivilegedSystemHelper.getProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE,
+ "false"));
+
+ try
+ {
+ if (deleteLocks)
+ {
+ JDBCStorageConnection conn = (JDBCStorageConnection)openConnection();
+ try
+ {
+ conn.deleteLockProperties();
+ }
+ finally
+ {
+ conn.close();
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ LOG.error(
+ "Can't remove lock properties because of " + ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Can't remove lock properties because of " + e.getMessage(), e);
+ }
}
/**
@@ -920,27 +953,6 @@
*/
public void stop()
{
-
- // TODO HSQLDB Stop (debug)
- // if (dbDialect.equals(DB_DIALECT_GENERIC) ||
- // dbDialect.equals(DB_DIALECT_HSQLDB)) {
- // // shutdown in-process HSQLDB database
- // System.out.println("Shutdown in-process HSQLDB database...");
- // try {
- // JDBCStorageConnection conn = (JDBCStorageConnection) openConnection();
- // Connection jdbcConn = conn.getJdbcConnection();
- // String dbUrl = jdbcConn.getMetaData().getURL();
- // if (dbUrl.startsWith("jdbc:hsqldb:file") ||
- // dbUrl.startsWith("jdbc:hsqldb:mem")) {
- // // yeah, there is in-process hsqldb, shutdown it now
- // jdbcConn.createStatement().execute("SHUTDOWN");
- // System.out.println("Shutdown in-process HSQLDB database... done.");
- // }
- // } catch (Throwable e) {
- // log.error("JDBC Data container stop error " + e);
- // e.printStackTrace();
- // }
- // }
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -31,6 +31,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@@ -551,4 +552,56 @@
throw new UnsupportedOperationException(
"The method findNodesAndProperties is not supported for this type of connection use the complex queries instead");
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void deleteLockProperties() throws SQLException
+ {
+ PreparedStatement removeValuesStatement = null;
+ PreparedStatement removeItemsStatement = null;
+
+ try
+ {
+ removeValuesStatement =
+ dbConnection
+ .prepareStatement("DELETE FROM JCR_MVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_MITEM WHERE NAME = ? OR NAME = ?)");
+ removeValuesStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+ removeValuesStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeItemsStatement = dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE NAME = ? OR NAME = ?");
+ removeItemsStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+ removeItemsStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeValuesStatement.executeUpdate();
+ removeItemsStatement.executeUpdate();
+ }
+ finally
+ {
+ if (removeValuesStatement != null)
+ {
+ try
+ {
+ removeValuesStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+
+ if (removeItemsStatement != null)
+ {
+ try
+ {
+ removeItemsStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -30,6 +30,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@@ -573,4 +574,59 @@
throw new UnsupportedOperationException(
"The method findNodesAndProperties is not supported for this type of connection use the complex queries instead");
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void deleteLockProperties() throws SQLException
+ {
+ PreparedStatement removeValuesStatement = null;
+ PreparedStatement removeItemsStatement = null;
+
+ try
+ {
+ removeValuesStatement =
+ dbConnection
+ .prepareStatement("DELETE FROM JCR_SVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?))");
+ removeValuesStatement.setString(1, containerName);
+ removeValuesStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+ removeValuesStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeItemsStatement =
+ dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?)");
+ removeItemsStatement.setString(1, containerName);
+ removeItemsStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+ removeItemsStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeValuesStatement.executeUpdate();
+ removeItemsStatement.executeUpdate();
+ }
+ finally
+ {
+ if (removeValuesStatement != null)
+ {
+ try
+ {
+ removeValuesStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+
+ if (removeItemsStatement != null)
+ {
+ try
+ {
+ removeItemsStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -33,6 +33,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@@ -1028,4 +1029,56 @@
return findACLHolders.executeQuery();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void deleteLockProperties() throws SQLException
+ {
+ PreparedStatement removeValuesStatement = null;
+ PreparedStatement removeItemsStatement = null;
+
+ try
+ {
+ removeValuesStatement =
+ dbConnection
+ .prepareStatement("DELETE FROM JCR_MVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_MITEM WHERE NAME = ? OR NAME = ?)");
+ removeValuesStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+ removeValuesStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeItemsStatement = dbConnection.prepareStatement("DELETE FROM JCR_MITEM WHERE NAME = ? OR NAME = ?");
+ removeItemsStatement.setString(1, Constants.JCR_LOCKISDEEP.getAsString());
+ removeItemsStatement.setString(2, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeValuesStatement.executeUpdate();
+ removeItemsStatement.executeUpdate();
+ }
+ finally
+ {
+ if (removeValuesStatement != null)
+ {
+ try
+ {
+ removeValuesStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+
+ if (removeItemsStatement != null)
+ {
+ try
+ {
+ removeItemsStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -32,6 +32,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@@ -946,4 +947,59 @@
return findACLHolders.executeQuery();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void deleteLockProperties() throws SQLException
+ {
+ PreparedStatement removeValuesStatement = null;
+ PreparedStatement removeItemsStatement = null;
+
+ try
+ {
+ removeValuesStatement =
+ dbConnection
+ .prepareStatement("DELETE FROM JCR_SVALUE WHERE PROPERTY_ID IN (SELECT ID FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?))");
+ removeValuesStatement.setString(1, containerName);
+ removeValuesStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+ removeValuesStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeItemsStatement =
+ dbConnection.prepareStatement("DELETE FROM JCR_SITEM WHERE CONTAINER_NAME = ? AND (NAME = ? OR NAME = ?)");
+ removeItemsStatement.setString(1, containerName);
+ removeItemsStatement.setString(2, Constants.JCR_LOCKISDEEP.getAsString());
+ removeItemsStatement.setString(3, Constants.JCR_LOCKOWNER.getAsString());
+
+ removeValuesStatement.executeUpdate();
+ removeItemsStatement.executeUpdate();
+ }
+ finally
+ {
+ if (removeValuesStatement != null)
+ {
+ try
+ {
+ removeValuesStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+
+ if (removeItemsStatement != null)
+ {
+ try
+ {
+ removeItemsStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close statement", e);
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java 2011-10-20 12:10:12 UTC (rev 5074)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java 2011-10-20 14:00:59 UTC (rev 5075)
@@ -21,7 +21,11 @@
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.core.ExtendedNode;
import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+import javax.jcr.Node;
import javax.jcr.RepositoryException;
/**
@@ -109,4 +113,60 @@
}
}
+ public void testRemoveLockProperties() throws Exception
+ {
+ Node node = session.getRootNode().addNode("testLock");
+ node.addMixin("mix:lockable");
+ session.save();
+
+ node.lock(false, false);
+
+ assertTrue(node.isLocked());
+
+ // remove lock properties from JCR tables
+ JDBCWorkspaceDataContainer container =
+ (JDBCWorkspaceDataContainer)repository.getWorkspaceContainer("ws").getComponent(
+ JDBCWorkspaceDataContainer.class);
+
+ System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "true");
+ try
+ {
+ container.start();
+ }
+ finally
+ {
+ System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "false");
+ }
+
+ // node still locked, because there is lock data in lock tables
+ assertTrue(node.isLocked());
+
+ try
+ {
+ node.unlock();
+ fail("Exception should be thrown");
+ }
+ catch (JCRInvalidItemStateException e)
+ {
+ }
+
+ // remove locks from lock table
+ AbstractCacheableLockManager lockManager =
+ (AbstractCacheableLockManager)repository.getWorkspaceContainer("ws").getComponent(
+ AbstractCacheableLockManager.class);
+
+ System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "true");
+ try
+ {
+ lockManager.start();
+ }
+ finally
+ {
+ System.setProperty(AbstractCacheableLockManager.LOCKS_FORCE_REMOVE, "false");
+ }
+
+ // node should not be locked after removing lock data from lock tables
+ assertFalse(node.isLocked());
+ }
+
}
14 years, 6 months
exo-jcr SVN: r5074 - in jcr/branches/1.12.x: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core and 7 other directories.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-10-20 08:10:12 -0400 (Thu, 20 Oct 2011)
New Revision: 5074
Added:
jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1661/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/ItemAutocreator.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestMultipleListenersNotifying.java
Log:
JCR-1661: TESTING: Regression during daily testing
Fix description
* For WorkspaceMoveTest and WorkspaceNodeUpdateTest: fixed by avoiding extra cache cleaning while running in cluster environment but with single node.
* For other tests: fixed by avoiding extra putting NullItemData instances to cache.
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -70,6 +70,24 @@
ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType) throws RepositoryException;
/**
+ * Find Item by parent (id) and name (with path index) of defined type and create
+ * or not (defined by createNullItemData) null item data.
+ *
+ * @param parent
+ * NodeData
+ * @param name
+ * item name
+ * @param itemType
+ * itemType
+ * @param createNullItemData
+ * defines if NullItemData should be created
+ * @return ItemData, data by parent and name
+ * @throws RepositoryException
+ */
+ ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException;
+
+ /**
* Find Item by identifier.
*
* @param String identifier
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -419,7 +419,8 @@
PropertyImpl prevProp;
PropertyDefinitionDatas defs;
ItemImpl prevItem =
- dataManager.getItem(parentNode.nodeData(), new QPathEntry(propertyName, 0), true, ItemType.PROPERTY);
+ dataManager.getItem(parentNode.nodeData(), new QPathEntry(propertyName, 0), true, ItemType.PROPERTY, true,
+ false);
NodeTypeDataManager ntm = session.getWorkspace().getNodeTypesHolder();
NodeData parentData = (NodeData)parentNode.getData();
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -576,7 +576,7 @@
PropertyData prop =
(PropertyData)dataManager.getItemData(((NodeData)getData()), new QPathEntry(Constants.JCR_MIXINTYPES, 0),
- ItemType.PROPERTY);
+ ItemType.PROPERTY, false);
ItemState state;
if (prop != null)
@@ -1773,7 +1773,7 @@
for (PropertyDefinitionData pd : ntmanager.getAllPropertyDefinitions(removedName))
{
- ItemData p = dataManager.getItemData(nodeData(), new QPathEntry(pd.getName(), 1), ItemType.PROPERTY);
+ ItemData p = dataManager.getItemData(nodeData(), new QPathEntry(pd.getName(), 1), ItemType.PROPERTY, false);
if (p != null && !p.isNode())
// remove it
dataManager.delete(p, ancestorToSave);
@@ -2850,13 +2850,15 @@
int ind = 1;
- NodeData sibling = (NodeData)dataManager.getItemData(parentNode, new QPathEntry(nameToAdd, ind), ItemType.NODE);
+ NodeData sibling =
+ (NodeData)dataManager.getItemData(parentNode, new QPathEntry(nameToAdd, ind), ItemType.NODE, false);
while (sibling != null)
{
if (allowSns)
{
ind++;
- sibling = (NodeData)dataManager.getItemData(parentNode, new QPathEntry(nameToAdd, ind), ItemType.NODE);
+ sibling =
+ (NodeData)dataManager.getItemData(parentNode, new QPathEntry(nameToAdd, ind), ItemType.NODE, false);
}
else
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -224,6 +224,12 @@
*/
public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType) throws RepositoryException
{
+ return getItemData(parent, name, itemType, true);
+ }
+
+ public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
if (name.getName().equals(JCRPath.PARENT_RELPATH) && name.getNamespace().equals(Constants.NS_DEFAULT_URI))
{
if (parent.getIdentifier().equals(Constants.ROOT_UUID))
@@ -249,7 +255,7 @@
return null;
}
// 2. Try from txdatamanager
- data = transactionableManager.getItemData(parent, name, itemType);
+ data = transactionableManager.getItemData(parent, name, itemType, createNullItemData);
}
else if (!state.isDeleted())
{
@@ -328,6 +334,31 @@
public ItemImpl getItem(NodeData parent, QPathEntry name, boolean pool, ItemType itemType, boolean apiRead)
throws RepositoryException
{
+ return getItem(parent, name, pool, itemType, apiRead, true);
+ }
+
+ /**
+ * For internal use. Return Item by parent NodeDada and the name of searched item.
+ *
+ * @param parent
+ * - parent of the searched item
+ * @param name
+ * - item name
+ * @param itemType
+ * - item type
+ * @param pool
+ * - indicates does the item fall in pool
+ * @param apiRead
+ * - if true will call postRead Action and check permissions
+ * @param createNullItemData
+ * - defines if there is a need to create NullItemData
+ *
+ * @return existed item or null if not found
+ * @throws RepositoryException
+ */
+ public ItemImpl getItem(NodeData parent, QPathEntry name, boolean pool, ItemType itemType, boolean apiRead,
+ boolean createNullItemData) throws RepositoryException
+ {
long start = System.currentTimeMillis();
if (log.isDebugEnabled())
{
@@ -337,7 +368,7 @@
ItemImpl item = null;
try
{
- return item = readItem(getItemData(parent, name, itemType), parent, pool, apiRead);
+ return item = readItem(getItemData(parent, name, itemType, createNullItemData), parent, pool, apiRead);
}
finally
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/ItemAutocreator.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/ItemAutocreator.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/ItemAutocreator.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -118,7 +118,7 @@
{
final ItemData pdata =
avoidCheckExistedChildItems ? null : targetDataManager.getItemData(parent, new QPathEntry(
- ndef.getName(), 0), ItemType.NODE);
+ ndef.getName(), 0), ItemType.NODE, false);
if (pdata == null && !addedNodes.contains(ndef.getName()) || pdata != null && !pdata.isNode())
{
@@ -163,7 +163,7 @@
final ItemData pdata =
avoidCheckExistedChildItems ? null : targetDataManager.getItemData(parent, new QPathEntry(
- pdef.getName(), 0), ItemType.PROPERTY);
+ pdef.getName(), 0), ItemType.PROPERTY, false);
if (pdata == null && !addedProperties.contains(pdef.getName()) || pdata != null && pdata.isNode())
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -182,9 +182,19 @@
/**
* {@inheritDoc}
*/
- public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType) throws RepositoryException
+ public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType)
+ throws RepositoryException
{
- final ItemData item = persistentManager.getItemData(parent, name, itemType);
+ return getItemData(parent, name, itemType, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
+ final ItemData item = persistentManager.getItemData(parent, name, itemType, createNullItemData);
return item != null && item.isNode() ? initACL(parent, (NodeData)item) : item;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -402,7 +402,16 @@
@Override
public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType) throws RepositoryException
{
+ return getItemData(parentData, name, itemType, true);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
+
// 1. Try from cache
ItemData data = getCachedItemData(parentData, name, itemType);
@@ -419,7 +428,7 @@
data = getCachedItemData(parentData, name, itemType);
if (data == null)
{
- data = getPersistedItemData(parentData, name, itemType);
+ data = getPersistedItemData(parentData, name, itemType, createNullItemData);
}
}
finally
@@ -755,11 +764,36 @@
protected ItemData getPersistedItemData(NodeData parentData, QPathEntry name, ItemType itemType)
throws RepositoryException
{
+ return getPersistedItemData(parentData, name, itemType, true);
+ }
+
+ /**
+ * Get persisted ItemData.
+ *
+ * @param parentData
+ * parent
+ * @param name
+ * Item name
+ * @param itemType
+ * item type
+ * @param createNullItemData
+ * indicates if we need to create NullItemData
+ * @return ItemData
+ * @throws RepositoryException
+ * error
+ */
+ protected ItemData getPersistedItemData(NodeData parentData, QPathEntry name, ItemType itemType,
+ boolean createNullItemData) throws RepositoryException
+ {
ItemData data = super.getItemData(parentData, name, itemType);
if (cache.isEnabled())
{
- if (data == null)
+ if (data != null)
{
+ cache.put(data);
+ }
+ else if (createNullItemData)
+ {
if (itemType == ItemType.NODE || itemType == ItemType.UNKNOWN)
{
cache.put(new NullNodeData(parentData, name));
@@ -769,10 +803,6 @@
cache.put(new NullPropertyData(parentData, name));
}
}
- else
- {
- cache.put(data);
- }
}
return data;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -139,15 +139,24 @@
@Override
public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType) throws RepositoryException
{
+ return getItemData(parentData, name, itemType, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
if (parentData != null)
{
final QPath ipath = QPath.makeChildPath(parentData.getQPath(), name);
if (isSystemDescendant(ipath) && !this.equals(versionDataManager))
{
- return versionDataManager.getItemData(parentData, name, itemType);
+ return versionDataManager.getItemData(parentData, name, itemType, createNullItemData);
}
}
- return super.getItemData(parentData, name, itemType);
+ return super.getItemData(parentData, name, itemType, createNullItemData);
}
/**
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -994,7 +994,8 @@
LOG.error("Unexpected object found by FQN:" + getFqn() + " and key:" + key + ". Expected Set, but found:"
+ existingObject.getClass().getName());
}
- else if (!localMode && cache.getConfiguration().getCacheMode() != CacheMode.LOCAL)
+ else if (!localMode && cache.getConfiguration().getCacheMode() != CacheMode.LOCAL
+ && cache.getMembers().size() > 1)
{
// to prevent consistency issue since we don't have the list in the local cache, we are in cluster env
// and we are in a non local mode, we clear the list in order to enforce other cluster nodes to reload it from the db
@@ -1029,7 +1030,7 @@
@Override
public void apply()
{
- if (!localMode && cache.getConfiguration().getCacheMode() != CacheMode.LOCAL)
+ if (!localMode && cache.getConfiguration().getCacheMode() != CacheMode.LOCAL && cache.getMembers().size() > 1)
{
// to prevent consistency issue since we don't have the list in the local cache, we are in cluster env
// and we are in a non local mode, we remove all the patterns in order to enforce other cluster nodes to reload them from the db
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -119,6 +119,15 @@
/**
* {@inheritDoc}
*/
+ public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
+ return copyItemData(storageDataManager.getItemData(parentData, name, itemType, createNullItemData));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public ItemData getItemData(String identifier) throws RepositoryException
{
return copyItemData(storageDataManager.getItemData(identifier));
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -254,6 +254,15 @@
*/
public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType) throws RepositoryException
{
+ return getItemData(parentData, name, itemType, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ItemData getItemData(NodeData parentData, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
ItemData data = null;
if (txStarted())
{
@@ -269,7 +278,7 @@
}
else
{
- return storageDataManager.getItemData(parentData, name, itemType);
+ return storageDataManager.getItemData(parentData, name, itemType, createNullItemData);
}
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/xml/importing/BaseXmlImporter.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -229,7 +229,7 @@
ItemData sameNameNode = null;
try
{
- sameNameNode = dataConsumer.getItemData(parentData, new QPathEntry(name, 0), ItemType.NODE);
+ sameNameNode = dataConsumer.getItemData(parentData, new QPathEntry(name, 0), ItemType.NODE, false);
}
catch (PathNotFoundException e)
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestMultipleListenersNotifying.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestMultipleListenersNotifying.java 2011-10-20 07:29:45 UTC (rev 5073)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestMultipleListenersNotifying.java 2011-10-20 12:10:12 UTC (rev 5074)
@@ -20,8 +20,14 @@
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.ItemType;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS.
*
@@ -39,6 +45,12 @@
{
super(null, new SystemDataContainerHolder(null));
}
+
+ public ItemData getItemData(NodeData parent, QPathEntry name, ItemType itemType, boolean createNullItemData)
+ throws RepositoryException
+ {
+ return null;
+ }
}
class Counter
Added: jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1661/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1661/readme.txt (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1661/readme.txt 2011-10-20 12:10:12 UTC (rev 5074)
@@ -0,0 +1,68 @@
+Summary
+
+ * Status: TESTING: Regression during daily testing
+ * CCP Issue: N/A. Product Jira Issue: JCR-1661.
+ * Complexity: low
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+During daily testing we have regressions on some of tests, detail: http://tests.exoplatform.org/JCR/1.12.10-GA/rev.4778/daily-performance-te...
+
+Fix description
+
+How is the problem fixed?
+ * For WorkspaceMoveTest and WorkspaceNodeUpdateTest: fixed by avoiding extra cache cleaning while running in cluster environment but with single node.
+ * For other tests: fixed by avoiding extra putting NullItemData instances to cache.
+
+Patch file: JCR-1661.patch
+
+Tests to perform
+
+Reproduction test
+
+ * Daily testing
+
+Tests performed at DevLevel
+
+ * Functional testing, daily testing
+
+Tests performed at QA/Support Level
+*
+Documentation changes
+
+Documentation changes:
+
+ * None
+
+Configuration changes
+
+Configuration changes:
+
+ * None
+
+Will previous configuration continue to work?
+
+ * Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+
+ * No
+
+Is there a performance risk/cost?
+
+ * No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch approved.
+
+Support Comment
+* Validated on behalf of Support.
+
+QA Feedbacks
+*
14 years, 6 months
exo-jcr SVN: r5073 - jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/cluster/functional.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-10-20 03:29:45 -0400 (Thu, 20 Oct 2011)
New Revision: 5073
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/cluster/functional/WebdavQueryTest.java
Log:
EXOJCR-1538 : fix message output
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/cluster/functional/WebdavQueryTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/cluster/functional/WebdavQueryTest.java 2011-10-19 14:24:18 UTC (rev 5072)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/cluster/functional/WebdavQueryTest.java 2011-10-20 07:29:45 UTC (rev 5073)
@@ -249,7 +249,7 @@
List<String> found;
assertEquals(207, response.getStatusCode());
found = parseNodeNames(response.getData());
- assertTrue("Lists are not equals:\n*found:\t" + found + "\n*expected:\t" + entry.getValue(),
+ assertTrue("Lists are not equals:\n*found:\t" + found + "\n*expected:\t" + Arrays.asList(entry.getValue()),
compareLists(Arrays.asList(entry.getValue()), found));
}
}
14 years, 6 months
exo-jcr SVN: r5072 - in jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules: jcr and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-10-19 10:24:18 -0400 (Wed, 19 Oct 2011)
New Revision: 5072
Added:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/repository-check-controller.xml
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml
Log:
EXOJCR-1471 : committing doc patch
Added: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/repository-check-controller.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/repository-check-controller.xml (rev 0)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/repository-check-controller.xml 2011-10-19 14:24:18 UTC (rev 5072)
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.RepositoryCheckController">
+ <?dbhtml filename="ch-repo-check-controller.html"?>
+
+ <title>Checking repository integrity and consistency</title>
+
+ <section>
+ <title>JMX-based consistency tool</title>
+
+ <para>Production and any other system may have faults some day. They may
+ be caused by hardware problems, human faults, software errors during
+ updates and many other circumstances. It is important to check integrity
+ and consistency of the system if there is no backup or it is stale, or
+ recovery process takes much. Exo JCR implementation offers an innovative
+ JMX-based complex checking tool. Running inspection, tool check every
+ major JCR component, such as persistent data layer and index. Persistent
+ layer includes JDBC Data Container and Value-Storages if they are
+ configured. Database verified using the set of complex specialized
+ domain-specific queries. Value Storage tool checks existence and access to
+ each file. Index verification contains two-way pass cycle, existence of
+ each node in index checks on persistent layer along with opposite
+ direction, when each node from Data Container validated in index. Access
+ to check tool is exposed via JMX interface, with the following operation
+ available: </para>
+
+ <table>
+ <title>Available methods</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>checkRepositoryDataConsistency()</entry>
+
+ <entry>Inspect full repository data (db, value storage and search
+ index)</entry>
+ </row>
+
+ <row>
+ <entry>checkRepositoryDataBaseConsistency()</entry>
+
+ <entry>Inspect only DB</entry>
+ </row>
+
+ <row>
+ <entry>checkRepositoryValueStorageConsistency()</entry>
+
+ <entry>Inspect only ValueStorage</entry>
+ </row>
+
+ <row>
+ <entry>checkRepositorySearchIndexConsistency()</entry>
+
+ <entry>Inspect only SearchIndex</entry>
+ </row>
+
+ <row>
+ <entry>getStatus()</entry>
+
+ <entry>Get inspection process status. If process is finished, it
+ will return inspection result.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Operations are launched in a separate thread without blocking JMX
+ connection and the status of background job can be accessed by getStatus()
+ operation. All inspection activities and corrupted data identifier are
+ stored in file, which can be found in app directory by name
+ <code>report-<repository name>-dd-MMM-yy-HH-mm.txt</code>. Path to
+ file will be returned in result message also. Please, take in account
+ thare is three types of inconsistency and two of them are critical. They
+ are Errors and Index faults. Index faults are marked as "Reindex" and can
+ be fixed by reindexing the workspace, but the Errors can only be fixed
+ manually. Warnings found by tool can be a normal situation in some cases
+ and usually production system will still remain fully functional.</para>
+ </section>
+</chapter>
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml 2011-10-19 11:29:06 UTC (rev 5071)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml 2011-10-19 14:24:18 UTC (rev 5072)
@@ -133,6 +133,11 @@
<xi:include href="jcr/statistics.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="jcr/repository-check-controller.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+
<xi:include href="jcr/jta.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
14 years, 6 months
exo-jcr SVN: r5071 - jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-10-19 07:29:06 -0400 (Wed, 19 Oct 2011)
New Revision: 5071
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
Log:
EXOJCR-1471 : fix test.
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java 2011-10-19 09:10:57 UTC (rev 5070)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java 2011-10-19 11:29:06 UTC (rev 5071)
@@ -73,7 +73,6 @@
public void testDB()
{
String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
- System.out.println("\n\n\n\n\n\n"+result+"\n\n\n\n\n\n");
assertEquals("Repository data is consistent. See full report by path "
+ checkController.getLastLogFile().getAbsolutePath(), result);
}
@@ -112,7 +111,6 @@
String result =
checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
DataStorage.LUCENE_INDEX});
- System.out.println("\n\n\n\n\n\n"+result+"\n\n\n\n\n\n");
assertEquals("Repository data is consistent. See full report by path "
+ checkController.getLastLogFile().getAbsolutePath(), result);
}
14 years, 6 months
exo-jcr SVN: r5070 - in jcr/branches/1.12.x: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/ext/action and 1 other directories.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-10-19 05:10:57 -0400 (Wed, 19 Oct 2011)
New Revision: 5070
Added:
jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1677/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/ext/action/SessionActionInterceptor.java
Log:
JCR-1677: Could not intercept any jcr action listener only in the trunk of a predefined workspace
Fix description
* Workspace name wasn't handled when generating condition list. That's why this condition was skipped when broadcasting events, so Listeners registered on one workspace, received events from another one.
* Pass the workspace name to SessionActionInterceptor via constructor argument and set it into condition's map.
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-10-19 09:10:57 UTC (rev 5070)
@@ -197,7 +197,7 @@
SessionActionCatalog catalog =
(SessionActionCatalog)container.getComponentInstanceOfType(SessionActionCatalog.class);
- actionHandler = new SessionActionInterceptor(catalog, container);
+ actionHandler = new SessionActionInterceptor(catalog, container, workspaceName);
sessionRegistry = (SessionRegistry)container.getComponentInstanceOfType(SessionRegistry.class);
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/ext/action/SessionActionInterceptor.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/ext/action/SessionActionInterceptor.java 2011-10-19 08:55:25 UTC (rev 5069)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/ext/action/SessionActionInterceptor.java 2011-10-19 09:10:57 UTC (rev 5070)
@@ -52,17 +52,21 @@
private final ExoContainer container;
+ private final String workspaceName;
+
private static Log log = ExoLogger.getLogger("exo.jcr.component.core.SessionActionInterceptor");
/**
* SessionActionInterceptor is per session, and only one action per session/time can be active.
*/
private ItemImpl activeItem = null;
+
- public SessionActionInterceptor(ActionCatalog catalog, ExoContainer container)
+ public SessionActionInterceptor(ActionCatalog catalog, ExoContainer container, String workspaceName)
{
this.catalog = catalog;
this.container = container;
+ this.workspaceName = workspaceName;
}
/**
@@ -88,7 +92,8 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.ADD_MIXIN);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, new InternalQName[]{mixinType});
-
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
+
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
ctx.put(InvocationContext.EVENT, ExtendedEvent.ADD_MIXIN);
@@ -117,6 +122,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.NODE_ADDED);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)node.getData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
@@ -146,6 +152,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.CHECKIN);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)node.getData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
@@ -175,6 +182,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.CHECKOUT);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)node.getData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
@@ -204,6 +212,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.LOCK);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)node.getData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
@@ -232,6 +241,7 @@
Condition conditions = new Condition();
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.READ);
conditions.put(SessionEventMatcher.PATH_KEY, item.getInternalPath());
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
if (item.isNode())
{
@@ -286,6 +296,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, event);
conditions.put(SessionEventMatcher.PATH_KEY, property.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames(property.parentData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, property);
@@ -315,6 +326,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.UNLOCK);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)node.getData()));
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
@@ -344,6 +356,7 @@
int event = item.isNode() ? ExtendedEvent.NODE_REMOVED : ExtendedEvent.PROPERTY_REMOVED;
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, event);
conditions.put(SessionEventMatcher.PATH_KEY, item.getInternalPath());
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
if (item.isNode())
{
conditions.put(SessionEventMatcher.NODETYPES_KEY, readNodeTypeNames((NodeData)item.getData()));
@@ -381,6 +394,7 @@
conditions.put(SessionEventMatcher.EVENTTYPE_KEY, ExtendedEvent.REMOVE_MIXIN);
conditions.put(SessionEventMatcher.PATH_KEY, node.getInternalPath());
conditions.put(SessionEventMatcher.NODETYPES_KEY, new InternalQName[]{mixinType});
+ conditions.put(SessionEventMatcher.WORKSPACE_KEY, workspaceName);
InvocationContext ctx = new InvocationContext();
ctx.put(InvocationContext.CURRENT_ITEM, node);
Added: jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1677/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1677/readme.txt (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1677/readme.txt 2011-10-19 09:10:57 UTC (rev 5070)
@@ -0,0 +1,69 @@
+Summary
+
+ * Status: Could not intercept any jcr action listener only in the trunk of a predefined workspace
+ * CCP Issue: CCP-1120, Product Jira Issue: JCR-1677.
+ * Complexity: N/A
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+* When removing a node using the File Explorer contextual menu, the component org.exoplatform.ecm.webui.component.explorer.rightclick.manager.DeleteManageComponent would be executed to remove a node or to move it to Trash if it's in the same workspace. Removing nodes from "collaboration" workspace using UI does not execute a JCR node remove event, but it just moves the node to Trash folder, that means it changes the Path of the node to collaboration:/Trash folder.
+* However, if i configure my listener to be triggered on the workspace collaboration, and i delete a document from another workspace, the listner will be triggered.
+
+Fix description
+Problem analysis
+ * Workspace name wasn't handled when generating condition list. That's why this condition was skipped when broadcasting events, so Listeners registered on one workspace, received events from another one.
+
+How is the problem fixed?
+ * Pass the workspace name to SessionActionInterceptor via constructor argument and set it into condition's map.
+
+Patch file: JCR-1677.patch
+
+Tests to perform
+
+Reproduction test
+ * Manual, given in issue description.
+
+Tests performed at DevLevel
+
+ * Manual testing, mentioned in the description of the issue.
+
+Tests performed at QA/Support Level
+*
+Documentation changes
+
+Documentation changes:
+
+ * none
+
+Configuration changes
+
+Configuration changes:
+
+ * none
+
+Will previous configuration continue to work?
+
+ * yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+
+ * The signature of SessionActionInterceptor's constructor changed: new argument added. Doesn't influence on compatibly with other projects because SessionActionInterceptor is an internal component and not the part of public API. But fix in general may influence some projects because condition for workspace name is now properly handled and events with non-matching names won't be broadcasted.
+
+Is there a performance risk/cost?
+* No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch validated
+
+Support Comment
+* Patch validated
+
+QA Feedbacks
+*
+
14 years, 6 months
exo-jcr SVN: r5069 - in core/trunk: exo.core.component.database/src/main/java/org/exoplatform/services/database/impl and 4 other directories.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-10-19 04:55:25 -0400 (Wed, 19 Oct 2011)
New Revision: 5069
Added:
core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeEventListener.java
Modified:
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/HibernateService.java
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/impl/HibernateServiceImpl.java
core/trunk/exo.core.component.organization.jdbc/pom.xml
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/GroupDAOImpl.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/HibernateListAccess.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipDAOImpl.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipTypeDAOImpl.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/OrganizationServiceImpl.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserDAOImpl.java
core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserProfileDAOImpl.java
core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-hibernate.xml
core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-jdbc.xml
core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestGroupHandler.java
core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeHandler.java
core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestUserHandler.java
Log:
EXOJCR-1588: Were made some adpotion of hibernate org service for TCK test:
- implemented some unsupported methods
- fixed exception handling in cases where they should be thrown
- fixed configuration files
- fixed and reorganized TCK tests
Modified: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/HibernateService.java
===================================================================
--- core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/HibernateService.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/HibernateService.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -23,6 +23,7 @@
import org.hibernate.cfg.Configuration;
import java.io.Serializable;
+import java.util.Collection;
/**
* Created by The eXo Platform SAS . Author : Tuan Nguyen
@@ -45,6 +46,8 @@
public Object findOne(Session session, String query, String id) throws Exception;
+ public Collection findAll(Session session, String query) throws Exception;
+
public Object findExactOne(Session session, String query, String id) throws Exception;
public Object findOne(Class clazz, java.io.Serializable id) throws Exception;
Modified: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/impl/HibernateServiceImpl.java
===================================================================
--- core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/impl/HibernateServiceImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/impl/HibernateServiceImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -380,6 +380,19 @@
}
}
+ public Collection findAll(Session session, String query) throws Exception
+ {
+ List l = session.createQuery(query).list();
+ if (l.size() == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return l;
+ }
+ }
+
public Object findOne(Class clazz, Serializable id) throws Exception
{
Session session = openSession();
Modified: core/trunk/exo.core.component.organization.jdbc/pom.xml
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/pom.xml 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/pom.xml 2011-10-19 08:55:25 UTC (rev 5069)
@@ -163,35 +163,6 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
- <systemProperties>
- <!--
- This property defines TCK tests configuration file location
- -->
- <property>
- <name>orgservice.test.configuration.file</name>
- <value>${orgservice.test.configuration.file}</value>
- </property>
- </systemProperties>
- <includes>
- <include>org/exoplatform/services/tck/organization/Test*.java</include>
- </includes>
- <excludes>
- <!--
- Temporary excluded, to investigate cause of failures and errors.
- -->
- <exclude>org/exoplatform/services/tck/organization/Test*.java</exclude>
- <!--
- Excluded as this class has no tests to be run
- -->
- <exclude>**/AbstractOrganizationServiceTest.java</exclude>
- </excludes>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
@@ -236,6 +207,42 @@
<properties>
<orgservice.test.configuration.file>/conf/standalone/test-configuration-hibernate.xml</orgservice.test.configuration.file>
</properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <systemProperties>
+ <!--
+ This property defines TCK tests configuration file location
+ -->
+ <property>
+ <name>orgservice.test.configuration.file</name>
+ <value>${orgservice.test.configuration.file}</value>
+ </property>
+ </systemProperties>
+ <includes>
+ <include>org/exoplatform/services/tck/organization/Test*.java</include>
+ </includes>
+ <excludes>
+ <!--
+ Excluded as there some hibernate cache issues on pre-, postoperations
+ (e.g. preDelete, postDelete, etc.)
+ -->
+
+ <exclude>org/exoplatform/services/tck/organization/TestMembershipTypeEventListener.java</exclude>
+
+ <!--
+ Excluded as this class has no tests to be run
+ -->
+ <exclude>**/AbstractOrganizationServiceTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</profile>
<profile>
<id>jdbc</id>
@@ -245,6 +252,40 @@
<properties>
<orgservice.test.configuration.file>/conf/standalone/test-configuration-jdbc.xml</orgservice.test.configuration.file>
</properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <systemProperties>
+ <!--
+ This property defines TCK tests configuration file location
+ -->
+ <property>
+ <name>orgservice.test.configuration.file</name>
+ <value>${orgservice.test.configuration.file}</value>
+ </property>
+ </systemProperties>
+ <includes>
+ <include>org/exoplatform/services/tck/organization/Test*.java</include>
+ </includes>
+ <excludes>
+ <!--
+ Temporary excluded, to investigate cause of failures and errors.
+ -->
+
+ <exclude>org/exoplatform/services/tck/organization/Test*.java</exclude>
+ <!--
+ Excluded as this class has no tests to be run
+ -->
+ <exclude>**/AbstractOrganizationServiceTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</profile>
</profiles>
</project>
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/GroupDAOImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/GroupDAOImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/GroupDAOImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -33,6 +33,8 @@
import java.util.Collections;
import java.util.List;
+import javax.naming.InvalidNameException;
+
/**
* Created by The eXo Platform SAS Author : Mestrallet Benjamin
* benjmestrallet(a)users.sourceforge.net Author : Tuan Nguyen
@@ -150,6 +152,13 @@
if (broadcast)
preDelete(group);
Session session = service_.openSession();
+
+ if (session.get(group.getClass(), group.getId()) == null)
+ {
+ throw new InvalidNameException("Can not remove group " + group.getGroupName()
+ + "record, because group does not exist.");
+ }
+
session.delete(group);
List entries = session.createQuery(queryFindGroupByParent).setString(0, group.getId()).list();
for (int i = 0; i < entries.size(); i++)
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/HibernateListAccess.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/HibernateListAccess.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/HibernateListAccess.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -44,8 +44,8 @@
import org.hibernate.Query;
import org.hibernate.Session;
+import java.lang.reflect.Array;
import java.security.PrivilegedAction;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -163,8 +163,6 @@
throw new IllegalArgumentException("Illegal length: length must be a positive number");
}
- List<E> entities = new ArrayList<E>(length);
-
Query query = SecurityHelper.doPrivilegedAction(new PrivilegedAction<Query>()
{
public Query run()
@@ -174,7 +172,11 @@
});
bindFields(query);
- Iterator<Object> results = query.iterate();
+ // here we're creating an array of elements of class E
+ // this looks complicated because we use generic class
+ E[] entities = (E[])Array.newInstance(query.getReturnTypes()[0].getReturnedClass(), length);
+ Iterator<E> results = query.iterate();
+
for (int p = 0, counter = 0; counter < length; p++)
{
if (!results.hasNext())
@@ -183,16 +185,15 @@
"Illegal index or length: sum of the index and the length cannot be greater than the list size");
}
- Object result = results.next();
+ E result = results.next();
if (p >= index)
{
- entities.add((E)result);
- counter++;
+ entities[counter++] = result;
}
}
- return (E[])entities.toArray();
+ return entities;
}
/**
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipDAOImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipDAOImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipDAOImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -51,6 +51,9 @@
"from m in class org.exoplatform.services.organization.impl.MembershipImpl " + "where m.userName = ? "
+ " and m.groupId = ? " + " and m.membershipType = ? ";
+ private static final String queryFindMembershipByType =
+ "from m in class org.exoplatform.services.organization.impl.MembershipImpl " + "where m.membershipType = ? ";
+
private static final String queryFindMembershipsByUserAndGroup =
"from m in class org.exoplatform.services.organization.impl.MembershipImpl " + "where m.userName = ? "
+ " and m.groupId = ? ";
@@ -111,10 +114,22 @@
{
if (orgService.getMembershipTypeHandler().findMembershipType(m.getMembershipType()) == null)
{
- throw new InvalidNameException("Can not create membership record " + m.getId()
- + " because membership type " + m.getMembershipType() + " is not exists.");
+ throw new InvalidNameException("Can not create membership record " + m.getId() + ", because membership"
+ + "type " + m.getMembershipType() + " does not exist.");
}
+
+ if (orgService.getGroupHandler().findGroupById(m.getGroupId()) == null)
+ {
+ throw new InvalidNameException("Can not create membership record " + m.getId() + ", because group "
+ + m.getGroupId() + " does not exist.");
+ }
+ if (orgService.getUserHandler().findUserByName(m.getUserName()) == null)
+ {
+ throw new InvalidNameException("Can not create membership record " + m.getId() + ", because user "
+ + m.getGroupId() + " does not exist.");
+ }
+
// check if we already have membership record
if (findMembershipByUserGroupAndType(m.getUserName(), m.getGroupId(), m.getMembershipType()) != null)
{
@@ -289,6 +304,15 @@
session.delete(entries.get(i));
}
+ static void removeMembershipEntriesOfMembershipType(MembershipType mt, Session session) throws Exception
+ {
+ List<?> entries = session.createQuery(queryFindMembershipByType).setString(0, mt.getName()).list();
+ for (int i = 0; i < entries.size(); i++)
+ {
+ session.delete(entries.get(i));
+ }
+ }
+
Collection findMembershipsByUser(String userName, Session session) throws Exception
{
return session.createQuery(queryFindMembershipsByUser).setString(0, userName).list();
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipTypeDAOImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipTypeDAOImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/MembershipTypeDAOImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -32,6 +32,8 @@
import java.util.Date;
import java.util.List;
+import javax.naming.InvalidNameException;
+
/**
* Created by The eXo Platform SAS Author : Mestrallet Benjamin
* benjmestrallet(a)users.sourceforge.net Author : Tuan Nguyen
@@ -117,38 +119,29 @@
public MembershipType removeMembershipType(String name, boolean broadcast) throws Exception
{
Session session = service_.openSession();
- MembershipTypeImpl m = (MembershipTypeImpl)session.get(MembershipTypeImpl.class, name);
+ MembershipTypeImpl mt = (MembershipTypeImpl)session.get(MembershipTypeImpl.class, name);
- try
+ if (mt == null)
{
- List entries =
- session.createQuery(
- "from m in class " + " org.exoplatform.services.organization.impl.MembershipImpl "
- + "where m.membershipType = '" + name + "'").list();
- for (int i = 0; i < entries.size(); i++)
- session.delete(entries.get(i));
+ throw new InvalidNameException("Can not remove membership type" + name
+ + "record, because membership type does not exist.");
}
- catch (Exception exp)
- {
- }
if (broadcast)
{
- preDelete(m);
+ preDelete(mt);
}
- if (m != null)
- {
- session.delete(m);
- session.flush();
- }
+ session.delete(mt);
+ MembershipDAOImpl.removeMembershipEntriesOfMembershipType(mt, session);
+ session.flush();
if (broadcast)
{
- postDelete(m);
+ postDelete(mt);
}
- return m;
+ return mt;
}
public Collection findMembershipTypes() throws Exception
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/OrganizationServiceImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/OrganizationServiceImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/OrganizationServiceImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -33,7 +33,7 @@
public OrganizationServiceImpl(HibernateService hservice, CacheService cservice) throws Exception
{
- userDAO_ = new UserDAOImpl(hservice, cservice);
+ userDAO_ = new UserDAOImpl(hservice, cservice, this);
userProfileDAO_ = new UserProfileDAOImpl(hservice, cservice);
groupDAO_ = new GroupDAOImpl(hservice);
membershipTypeDAO_ = new MembershipTypeDAOImpl(hservice);
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserDAOImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserDAOImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserDAOImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -26,6 +26,7 @@
import org.exoplatform.services.database.HibernateService;
import org.exoplatform.services.database.ObjectQuery;
import org.exoplatform.services.organization.ExtendedUserHandler;
+import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.Query;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.UserEventListener;
@@ -58,10 +59,13 @@
private List<UserEventListener> listeners_ = new ArrayList<UserEventListener>(3);
- public UserDAOImpl(HibernateService service, CacheService cservice) throws Exception
+ private OrganizationService orgService;
+
+ public UserDAOImpl(HibernateService service, CacheService cservice, OrganizationService orgService) throws Exception
{
service_ = service;
cache_ = cservice.getCacheInstance(UserImpl.class.getName());
+ this.orgService = orgService;
}
final public List getUserEventListeners()
@@ -139,6 +143,7 @@
{
Session session = service_.openSession();
User foundUser = findUserByName(userName, session);
+
if (foundUser == null)
return null;
@@ -146,6 +151,8 @@
preDelete(foundUser);
session = service_.openSession();
session.delete(foundUser);
+ ((UserProfileDAOImpl)orgService.getUserProfileHandler()).removeUserProfileEntry(userName, session);
+ MembershipDAOImpl.removeMembershipEntriesOfUser(userName, session);
if (broadcast)
postDelete(foundUser);
session.flush();
@@ -226,7 +233,7 @@
ObjectQuery oq = new ObjectQuery(UserImpl.class);
if (q.getUserName() != null)
{
- oq.addLIKE("UPPER(userName)", q.getUserName().toUpperCase());
+ oq.addLIKE("UPPER(userName)", addAsterisk(q.getUserName().toUpperCase()));
}
if (q.getFirstName() != null)
{
@@ -301,6 +308,22 @@
listener.postDelete(user);
}
+ private String addAsterisk(String s)
+ {
+ StringBuffer sb = new StringBuffer(s);
+ if (!s.startsWith("*"))
+ {
+ sb.insert(0, "*");
+ }
+ if (!s.endsWith("*"))
+ {
+ sb.append("*");
+ }
+
+ return sb.toString();
+
+ }
+
/**
* {@inheritDoc}
*/
Modified: core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserProfileDAOImpl.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserProfileDAOImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/main/java/org/exoplatform/services/organization/hibernate/UserProfileDAOImpl.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -46,6 +46,9 @@
private static final String queryFindUserProfileByName =
"from u in class org.exoplatform.services.organization.impl.UserProfileData " + "where u.userName = ?";
+ private static final String queryFindUserProfiles =
+ "from u in class org.exoplatform.services.organization.impl.UserProfileData";
+
private HibernateService service_;
private ExoCache cache_;
@@ -176,16 +179,20 @@
return null;
}
- static void removeUserProfileEntry(String userName, Session session) throws Exception
+ void removeUserProfileEntry(String userName, Session session) throws Exception
{
Object user = session.createQuery(queryFindUserProfileByName).setString(0, userName).uniqueResult();
if (user != null)
+ {
session.delete(user);
+ cache_.remove(userName);
+ }
}
public Collection findUserProfiles() throws Exception
{
- return null;
+ Session session = service_.openSession();
+ return service_.findAll(session, queryFindUserProfiles);
}
private void preSave(UserProfile profile, boolean isNew) throws Exception
Modified: core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-hibernate.xml
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-hibernate.xml 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-hibernate.xml 2011-10-19 08:55:25 UTC (rev 5069)
@@ -46,7 +46,7 @@
<description>Default Hibernate Service</description>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
- <property name="hibernate.connection.url" value="jdbc:hsqldb:file:../temp/data/exodb"/>
+ <property name="hibernate.connection.url" value="jdbc:hsqldb:file:target/temp/data/exodb"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.autocommit" value="true"/>
<property name="hibernate.connection.username" value="sa"/>
@@ -82,6 +82,16 @@
</values-param>
</init-params>
</component-plugin>
+ </external-component-plugins>
+
+ <external-component-plugins>
+ <target-component>org.exoplatform.services.organization.OrganizationService</target-component>
+ <component-plugin>
+ <name>tester.membership.type.listener</name>
+ <set-method>addListenerPlugin</set-method>
+ <type>org.exoplatform.services.organization.MembershipTypeEventListener</type>
+ <description>Membership type listerner for testing purpose</description>
+ </component-plugin>
</external-component-plugins>
<!-- org service initializer, copied from ECM portal.war -->
Modified: core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-jdbc.xml
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-jdbc.xml 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.jdbc/src/test/resources/conf/standalone/test-configuration-jdbc.xml 2011-10-19 08:55:25 UTC (rev 5069)
@@ -76,7 +76,7 @@
<name>connection.config</name>
<description>Connection configuration</description>
<property name='connection.driver' value='org.hsqldb.jdbcDriver' />
- <property name='connection.url' value='jdbc:hsqldb:file:target/temp' />
+ <property name='connection.url' value='jdbc:hsqldb:file:target/temp/data/exodb' />
<property name='connection.login' value='sa' />
<property name='connection.password' value='' />
<property name='connection.min-size' value='3' />
Modified: core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestGroupHandler.java
===================================================================
--- core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestGroupHandler.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestGroupHandler.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -86,13 +86,22 @@
*/
public void testRemoveGroup() throws Exception
{
+ createUser(userName);
createGroup("/organization", groupName1, "label", "desc");
createGroup("/organization/" + groupName1, groupName1, "label", "desc");
+
+ createMembership(newUserName, groupName2, membershipType);
+ assertEquals("We expect to find single membership for user " + newUserName, 1,
+ mHandler.findMembershipsByUser(newUserName).size());
Group group = gHandler.removeGroup(gHandler.findGroupById("/organization/group1"), true);
assertNull(gHandler.findGroupById("/organization/group1"));
assertNull(gHandler.findGroupById("/organization/group1/group2"));
+ gHandler.removeGroup(gHandler.findGroupById("/" + groupName2), true);
+ assertEquals("We expect to find no membership for user " + newUserName, 0,
+ mHandler.findMembershipsByUser(newUserName).size());
+
// try to remove not exited group. Exception should be thrown
try
{
Added: core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeEventListener.java
===================================================================
--- core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeEventListener.java (rev 0)
+++ core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeEventListener.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -0,0 +1,163 @@
+/**
+ *
+ */
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.tck.organization;
+
+import org.exoplatform.services.organization.MembershipType;
+import org.exoplatform.services.organization.MembershipTypeEventListener;
+import org.exoplatform.services.organization.MembershipTypeEventListenerHandler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="dmitry.kuleshov(a)exoplatform.com">Dmitry Kuleshov</a>
+ * @version $Id: TestMembershipTypeHandlerImpl.java 111 2008-11-11 11:11:11Z $
+ */
+public class TestMembershipTypeEventListener extends AbstractOrganizationServiceTest
+{
+
+ /**
+ * Test get listeners.
+ */
+ public void testGetListeners() throws Exception
+ {
+ if (mtHandler instanceof MembershipTypeEventListenerHandler)
+ {
+ List<MembershipTypeEventListener> list =
+ ((MembershipTypeEventListenerHandler)mtHandler).getMembershipTypeListeners();
+
+ assertEquals(1, list.size());
+ try
+ {
+ list.clear();
+ fail("We are not supposed to change list of listeners");
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Test events.
+ */
+ public void testMembershipTypeEventListener() throws Exception
+ {
+ TesterMembershipTypeEventListener testListener = new TesterMembershipTypeEventListener();
+ mtHandler.addMembershipTypeEventListener(testListener);
+
+ if (mtHandler instanceof MembershipTypeEventListenerHandler)
+ {
+ List<MembershipTypeEventListener> list =
+ ((MembershipTypeEventListenerHandler)mtHandler).getMembershipTypeListeners();
+
+ assertEquals(2, list.size());
+ }
+
+ // Create new membership type. In preSave event there is not recored in db.
+ createMembershipType(membershipType, "desc");
+
+ assertEquals(2, testListener.mtInEvent.size());
+ assertEquals(2, testListener.mtInStorage.size());
+
+ // preSave Event
+ assertEquals(membershipType, testListener.mtInEvent.get(0).getName());
+ assertNull(testListener.mtInStorage.get(0));
+
+ // postSave Event
+ assertEquals(membershipType, testListener.mtInEvent.get(1).getName());
+ assertNotNull(testListener.mtInStorage.get(1));
+ assertEquals(membershipType, testListener.mtInStorage.get(1).getName());
+
+ testListener.mtInEvent.clear();
+ testListener.mtInStorage.clear();
+
+ // Modify membership type. In preSave event there is old record in storage.
+ MembershipType mt = mtHandler.findMembershipType(membershipType);
+ mt.setDescription("newDesc");
+
+ mtHandler.saveMembershipType(mt, true);
+
+ // preSave Event
+ assertEquals(2, testListener.mtInEvent.size());
+ assertEquals(2, testListener.mtInStorage.size());
+
+ assertEquals("newDesc", testListener.mtInEvent.get(0).getDescription());
+ assertEquals("desc", testListener.mtInStorage.get(0).getDescription());
+
+ // postSave Event
+ assertEquals("newDesc", testListener.mtInEvent.get(1).getDescription());
+ assertEquals("newDesc", testListener.mtInStorage.get(1).getDescription());
+
+ testListener.mtInEvent.clear();
+ testListener.mtInStorage.clear();
+
+ // Remove membership type. In preDelete Event there is still record in storage
+ mtHandler.removeMembershipType(membershipType, true);
+
+ assertEquals(2, testListener.mtInEvent.size());
+ assertEquals(2, testListener.mtInStorage.size());
+
+ // preDelete Event
+ assertEquals(membershipType, testListener.mtInEvent.get(0).getName());
+ assertNotNull(testListener.mtInStorage.get(0));
+
+ // postDelete Event
+ assertEquals(membershipType, testListener.mtInEvent.get(1).getName());
+ assertNull(testListener.mtInStorage.get(1));
+
+ testListener.mtInEvent.clear();
+ testListener.mtInStorage.clear();
+
+ }
+
+ private class TesterMembershipTypeEventListener extends MembershipTypeEventListener
+ {
+ List<MembershipType> mtInEvent = new ArrayList<MembershipType>();
+
+ List<MembershipType> mtInStorage = new ArrayList<MembershipType>();
+
+ public void preSave(MembershipType type, boolean isNew) throws Exception
+ {
+ mtInEvent.add(type);
+ mtInStorage.add(mtHandler.findMembershipType(type.getName()));
+ }
+
+ public void postSave(MembershipType type, boolean isNew) throws Exception
+ {
+ mtInEvent.add(type);
+ mtInStorage.add(mtHandler.findMembershipType(type.getName()));
+ }
+
+ public void preDelete(MembershipType type) throws Exception
+ {
+ mtInEvent.add(type);
+ mtInStorage.add(mtHandler.findMembershipType(type.getName()));
+ }
+
+ public void postDelete(MembershipType type) throws Exception
+ {
+ mtInEvent.add(type);
+ mtInStorage.add(mtHandler.findMembershipType(type.getName()));
+ }
+ }
+}
Modified: core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeHandler.java
===================================================================
--- core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeHandler.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestMembershipTypeHandler.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -20,12 +20,7 @@
package org.exoplatform.services.tck.organization;
import org.exoplatform.services.organization.MembershipType;
-import org.exoplatform.services.organization.MembershipTypeEventListener;
-import org.exoplatform.services.organization.MembershipTypeEventListenerHandler;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Created by The eXo Platform SAS.
*
@@ -62,20 +57,24 @@
*/
public void testRemoveMembershipType() throws Exception
{
- createMembershipType(membershipType, "desc");
+ createMembership(userName, groupName1, membershipType);
+ assertEquals("We expect to find single membership for user " + userName, 1,
+ mHandler.findMembershipsByUser(userName).size());
MembershipType mt = mtHandler.removeMembershipType("type", true);
assertEquals(mt.getName(), membershipType);
assertNull(mtHandler.findMembershipType("type"));
+ assertEquals("We expect to find no membership for user " + userName, 0, mHandler.findMembershipsByUser(userName)
+ .size());
// try to remove not existed membership type. We are supposed to get "null" instead of Exception
try
{
assertNull(mtHandler.removeMembershipType("not-existed-mt", true));
+ fail("Exception should be thrown");
}
catch (Exception e)
{
- fail("Exception should not be thrown");
}
}
@@ -95,129 +94,4 @@
assertEquals(mt.getDescription(), "newDesc");
}
- /**
- * Test get listeners.
- */
- public void testGetListeners() throws Exception
- {
- if (mtHandler instanceof MembershipTypeEventListenerHandler)
- {
- List<MembershipTypeEventListener> list =
- ((MembershipTypeEventListenerHandler)mtHandler).getMembershipTypeListeners();
-
- assertEquals(1, list.size());
- try
- {
- list.clear();
- fail("We are not supposed to change list of listeners");
- }
- catch (Exception e)
- {
- }
- }
- }
-
- /**
- * Test events.
- */
- public void testMembershipTypeEventListener() throws Exception
- {
- TesterMembershipTypeEventListener testListener = new TesterMembershipTypeEventListener();
- mtHandler.addMembershipTypeEventListener(testListener);
-
- if (mtHandler instanceof MembershipTypeEventListenerHandler)
- {
- List<MembershipTypeEventListener> list =
- ((MembershipTypeEventListenerHandler)mtHandler).getMembershipTypeListeners();
-
- assertEquals(2, list.size());
- }
-
- // Create new membership type. In preSave event there is not recored in db.
- createMembershipType(membershipType, "desc");
-
- assertEquals(2, testListener.mtInEvent.size());
- assertEquals(2, testListener.mtInStorage.size());
-
- // preSave Event
- assertEquals(membershipType, testListener.mtInEvent.get(0).getName());
- assertNull(testListener.mtInStorage.get(0));
-
- // postSave Event
- assertEquals(membershipType, testListener.mtInEvent.get(1).getName());
- assertNotNull(testListener.mtInStorage.get(1));
- assertEquals(membershipType, testListener.mtInStorage.get(1).getName());
-
- testListener.mtInEvent.clear();
- testListener.mtInStorage.clear();
-
- // Modify membership type. In preSave event there is old record in storage.
- MembershipType mt = mtHandler.findMembershipType(membershipType);
- mt.setDescription("newDesc");
-
- mtHandler.saveMembershipType(mt, true);
-
- // preSave Event
- assertEquals(2, testListener.mtInEvent.size());
- assertEquals(2, testListener.mtInStorage.size());
-
- assertEquals("newDesc", testListener.mtInEvent.get(0).getDescription());
- assertEquals("desc", testListener.mtInStorage.get(0).getDescription());
-
- // postSave Event
- assertEquals("newDesc", testListener.mtInEvent.get(1).getDescription());
- assertEquals("newDesc", testListener.mtInStorage.get(1).getDescription());
-
- testListener.mtInEvent.clear();
- testListener.mtInStorage.clear();
-
- // Remove membership type. In preDelete Event there is still record in storage
- mtHandler.removeMembershipType(membershipType, true);
-
- assertEquals(2, testListener.mtInEvent.size());
- assertEquals(2, testListener.mtInStorage.size());
-
- // preDelete Event
- assertEquals(membershipType, testListener.mtInEvent.get(0).getName());
- assertNotNull(testListener.mtInStorage.get(0));
-
- // postDelete Event
- assertEquals(membershipType, testListener.mtInEvent.get(1).getName());
- assertNull(testListener.mtInStorage.get(1));
-
- testListener.mtInEvent.clear();
- testListener.mtInStorage.clear();
-
- }
-
- private class TesterMembershipTypeEventListener extends MembershipTypeEventListener
- {
- List<MembershipType> mtInEvent = new ArrayList<MembershipType>();
-
- List<MembershipType> mtInStorage = new ArrayList<MembershipType>();
-
- public void preSave(MembershipType type, boolean isNew) throws Exception
- {
- mtInEvent.add(type);
- mtInStorage.add(mtHandler.findMembershipType(type.getName()));
- }
-
- public void postSave(MembershipType type, boolean isNew) throws Exception
- {
- mtInEvent.add(type);
- mtInStorage.add(mtHandler.findMembershipType(type.getName()));
- }
-
- public void preDelete(MembershipType type) throws Exception
- {
- mtInEvent.add(type);
- mtInStorage.add(mtHandler.findMembershipType(type.getName()));
- }
-
- public void postDelete(MembershipType type) throws Exception
- {
- mtInEvent.add(type);
- mtInStorage.add(mtHandler.findMembershipType(type.getName()));
- }
- }
}
Modified: core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestUserHandler.java
===================================================================
--- core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestUserHandler.java 2011-10-19 08:09:57 UTC (rev 5068)
+++ core/trunk/exo.core.component.organization.tests/src/main/java/org/exoplatform/services/tck/organization/TestUserHandler.java 2011-10-19 08:55:25 UTC (rev 5069)
@@ -129,6 +129,7 @@
query = new Query();
query.setFromLoginDate(calc.getTime());
+ query.setUserName("tolik");
assertEquals(uHandler.findUsersByQuery(query).getSize(), 1);
calc = Calendar.getInstance();
@@ -150,6 +151,7 @@
query = new Query();
query.setToLoginDate(calc.getTime());
+ query.setUserName("tolik");
assertEquals(uHandler.findUsersByQuery(query).getSize(), 1);
}
@@ -208,6 +210,7 @@
query = new Query();
query.setFromLoginDate(calc.getTime());
+ query.setUserName("tolik");
assertEquals(uHandler.findUsersByQuery(query).getSize(), 1);
calc = Calendar.getInstance();
@@ -229,6 +232,7 @@
query = new Query();
query.setToLoginDate(calc.getTime());
+ query.setUserName("tolik");
assertEquals(uHandler.findUsersByQuery(query).getSize(), 1);
}
@@ -253,9 +257,17 @@
*/
public void testRemoveUser() throws Exception
{
- createUser(userName);
+ createMembership(userName, groupName2, membershipType);
+
+ assertEquals("We expect to find single membership for user " + userName, 1,
+ mHandler.findMembershipsByUser(userName).size());
+
assertNotNull(uHandler.removeUser(userName, true));
+ assertNull(upHandler.findUserProfileByName(userName));
+ assertEquals("We expect to find no membership for user " + userName, 0, mHandler.findMembershipsByUser(userName)
+ .size());
+
// try to find user after remove. We are supposed to get "null" instead of exception
try
{
@@ -283,14 +295,6 @@
uHandler.saveUser(u, true);
assertEquals(newEmail, uHandler.findUserByName(userName).getEmail());
- // change name
- u = uHandler.findUserByName(userName);
- u.setUserName(newUserName);
- uHandler.saveUser(u, true);
-
- // we should to find user with new name but not with old one
- assertNotNull(uHandler.findUserByName(newUserName));
- assertNull(uHandler.findUserByName(userName));
}
/**
14 years, 6 months
exo-jcr SVN: r5068 - in jcr/branches/1.12.x: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow and 12 other directories.
by do-not-reply@jboss.org
Author: trang_vu
Date: 2011-10-19 04:09:57 -0400 (Wed, 19 Oct 2011)
New Revision: 5068
Added:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/DummySession.java
jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1671/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedWorkspace.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLog.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLogImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/WorkspaceImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/FileSystemLockPersister.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataMergeVisitor.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/observation/TestSessionsObservation.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestItemDataChangesLog.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLogTest.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/fs/TestJCRVSReadWrite.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/version/BaseVersionImplTest.java
Log:
JCR-1671: Problem of EventListener not triggered when renaming a document
Fix description
* Inject a Session instance to PlainChangesLogImpl class, that is invoked in dataflow. Mentioned Session instance is retrieved from log when preparing the events to broadcast.
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedWorkspace.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedWorkspace.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedWorkspace.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.jcr.core;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -58,4 +60,12 @@
throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException,
InvalidSerializedDataException, RepositoryException;
+ /**
+ * Returns {@link NodeTypeDataManager} instance
+ *
+ * @return NodeTypeDataManager
+ * @throws RepositoryException
+ */
+ NodeTypeDataManager getNodeTypesHolder() throws RepositoryException;
+
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLog.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLog.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLog.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.dataflow;
+import org.exoplatform.services.jcr.core.ExtendedSession;
import org.exoplatform.services.jcr.observation.ExtendedEventType;
import java.util.List;
@@ -38,7 +39,7 @@
* @return sessionId of a session produced this changes log
*/
String getSessionId();
-
+
/**
* Return pair Id of system and non-system logs.
*
@@ -67,4 +68,10 @@
* @param states List of ItemState
*/
PlainChangesLog addAll(List<ItemState> states);
+
+ /**
+ * Returns session instance is present
+ * @return session instance
+ */
+ ExtendedSession getSession();
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLogImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLogImpl.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/PlainChangesLogImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.dataflow;
+import org.exoplatform.services.jcr.core.ExtendedSession;
import org.exoplatform.services.jcr.impl.Constants;
import java.io.Externalizable;
@@ -37,7 +38,7 @@
public class PlainChangesLogImpl implements Externalizable, PlainChangesLog
{
private static final int NULL_VALUE = -1;
-
+
private static final int NOT_NULL_VALUE = 1;
private static final long serialVersionUID = 5624550860372364084L;
@@ -48,25 +49,23 @@
protected int eventType;
+ protected ExtendedSession session;
+
/**
* Identifier of system and non-system logs pair. Null if no pair found.
*/
- protected String pairId = null;
+ protected String pairId;
/**
- * Full qualified constructor.
+ * Constructor.
*
* @param items List of ItemState
- * @param sessionId String
+ * @param session Session
* @param eventType int
- * @param pairId String
*/
- public PlainChangesLogImpl(List<ItemState> items, String sessionId, int eventType, String pairId)
+ public PlainChangesLogImpl(List<ItemState> items, ExtendedSession session, int eventType)
{
- this.items = items;
- this.sessionId = sessionId;
- this.eventType = eventType;
- this.pairId = pairId;
+ this(items, session.getId(), eventType, null, session);
}
/**
@@ -78,30 +77,38 @@
*/
public PlainChangesLogImpl(List<ItemState> items, String sessionId, int eventType)
{
- this.items = items;
- this.sessionId = sessionId;
- this.eventType = eventType;
+ this(items, sessionId, eventType, null, null);
}
/**
* Constructor with undefined event type.
*
* @param items List of ItemState
- * @param sessionId String
+ * @param session Session
*/
- public PlainChangesLogImpl(List<ItemState> items, String sessionId)
+ public PlainChangesLogImpl(List<ItemState> items, ExtendedSession session)
{
- this(items, sessionId, -1);
+ this(items, session, -1);
}
/**
* An empty log.
*
+ * @param session Session
+ */
+ public PlainChangesLogImpl(ExtendedSession session)
+ {
+ this(new ArrayList<ItemState>(), session);
+ }
+
+ /**
+ * An empty log.
+ *
* @param sessionId String
*/
public PlainChangesLogImpl(String sessionId)
{
- this(new ArrayList<ItemState>(), sessionId);
+ this(new ArrayList<ItemState>(), sessionId, -1);
}
/**
@@ -109,7 +116,7 @@
*/
public PlainChangesLogImpl()
{
- this(new ArrayList<ItemState>(), null);
+ this(new ArrayList<ItemState>(), (String)null, -1);
}
/*
@@ -152,6 +159,14 @@
return sessionId;
}
+ /**
+ * {@inheritDoc}
+ */
+ public ExtendedSession getSession()
+ {
+ return session;
+ }
+
/*
* (non-Javadoc)
*
@@ -200,15 +215,66 @@
{
String str = "ChangesLog: \n";
for (int i = 0; i < items.size(); i++)
+ {
str +=
" " + ItemState.nameFromValue(items.get(i).getState()) + "\t" + items.get(i).getData().getIdentifier()
+ "\t" + "isPersisted=" + items.get(i).isPersisted() + "\t" + "isEventFire="
+ items.get(i).isEventFire() + "\t" + "isInternallyCreated=" + items.get(i).isInternallyCreated() + "\t"
+ items.get(i).getData().getQPath().getAsString() + "\n";
+ }
return str;
}
+ /**
+ * Full qualified constructor.
+ *
+ * @param items List of ItemState
+ * @param sessionId String
+ * @param eventType int
+ * @param pairId String
+ */
+ protected PlainChangesLogImpl(List<ItemState> items, String sessionId, int eventType, String pairId,
+ ExtendedSession session)
+ {
+ this.items = items;
+ this.session = session;
+ this.sessionId = sessionId;
+ this.eventType = eventType;
+ this.pairId = pairId;
+ }
+
+ /**
+ * Creates a new instance of {@link PlainChangesLogImpl} by copying metadata from originalLog
+ * instance with Items provided.
+ *
+ * @param items
+ * @param originalLog
+ * @return
+ */
+ public static PlainChangesLogImpl createCopy(List<ItemState> items, PlainChangesLog originalLog)
+ {
+ return createCopy(items, originalLog.getPairId(), originalLog);
+ }
+
+ /**
+ * Creates a new instance of {@link PlainChangesLogImpl} by copying metadata from originalLog
+ * instance with Items and PairID provided. Metadata will be copied excluding PairID.
+ *
+ * @param items
+ * @param originalLog
+ * @return
+ */
+ public static PlainChangesLogImpl createCopy(List<ItemState> items, String pairId, PlainChangesLog originalLog)
+ {
+ if (originalLog.getSession() != null)
+ {
+ return new PlainChangesLogImpl(items, originalLog.getSession().getId(), originalLog.getEventType(), pairId,
+ originalLog.getSession());
+ }
+ return new PlainChangesLogImpl(items, originalLog.getSessionId(), originalLog.getEventType(), pairId, null);
+ }
+
// Need for Externalizable
// ------------------ [ BEGIN ] ------------------
@@ -227,7 +293,7 @@
out.writeObject(items.get(i));
}
- if (pairId != null)
+ if (pairId != null)
{
out.writeInt(NOT_NULL_VALUE);
buff = pairId.getBytes(Constants.DEFAULT_ENCODING);
@@ -253,7 +319,7 @@
{
add((ItemState)in.readObject());
}
-
+
if (in.readInt() == NOT_NULL_VALUE)
{
buf = new byte[in.readInt()];
@@ -261,5 +327,7 @@
pairId = new String(buf, Constants.DEFAULT_ENCODING);
}
}
+
// ------------------ [ END ] ------------------
+
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/BackupWorkspaceInitializer.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -270,7 +270,7 @@
normalized.add(change);
}
- PlainChangesLog plog = new PlainChangesLogImpl(normalized, next.getSessionId(), next.getEventType());
+ PlainChangesLog plog = PlainChangesLogImpl.createCopy(normalized,next);
result.addLog(plog);
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -363,7 +363,7 @@
checkValid();
- PlainChangesLog changesLog = new PlainChangesLogImpl(session.getId());
+ PlainChangesLog changesLog = new PlainChangesLogImpl(session);
removeMergeFailed(version, changesLog);
@@ -439,7 +439,7 @@
// the new version identifier
String verIdentifier = IdGenerator.generate();
- SessionChangesLog changesLog = new SessionChangesLog(session.getId());
+ SessionChangesLog changesLog = new SessionChangesLog(session);
VersionHistoryImpl vh = versionHistory(false);
vh.addVersion(this.nodeData(), verIdentifier, changesLog);
@@ -486,7 +486,7 @@
if (checkedOut())
return;
- SessionChangesLog changesLog = new SessionChangesLog(session.getId());
+ SessionChangesLog changesLog = new SessionChangesLog(session);
changesLog.add(ItemState.createUpdatedState(updatePropertyData(Constants.JCR_ISCHECKEDOUT,
new TransientValueData(true))));
@@ -643,7 +643,7 @@
+ session.getUserID() + " item owner " + getACL().getOwner());
}
- PlainChangesLog changesLog = new PlainChangesLogImpl(session.getId());
+ PlainChangesLog changesLog = new PlainChangesLogImpl(session);
VersionImpl base = (VersionImpl)getBaseVersion();
base.addPredecessor(version.getUUID(), changesLog);
@@ -1563,8 +1563,7 @@
Lock newLock = session.getLockManager().addLock(this, isDeep, isSessionScoped, -1);
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+ PlainChangesLog changesLog = new PlainChangesLogImpl(new ArrayList<ItemState>(), session, ExtendedEvent.LOCK);
PropertyData propData =
TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
@@ -1608,8 +1607,7 @@
Lock newLock = session.getLockManager().addLock(this, isDeep, false, timeOut);
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+ PlainChangesLog changesLog = new PlainChangesLogImpl(new ArrayList<ItemState>(), session, ExtendedEvent.LOCK);
PropertyData propData =
TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
@@ -2318,7 +2316,7 @@
if (!checkLocking())
throw new LockException("Node " + getPath() + " is locked ");
- SessionChangesLog changes = new SessionChangesLog(session.getId());
+ SessionChangesLog changes = new SessionChangesLog(session);
String srcPath;
try
@@ -2634,8 +2632,7 @@
protected void doUnlock() throws RepositoryException
{
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.UNLOCK);
+ PlainChangesLog changesLog = new PlainChangesLogImpl(new ArrayList<ItemState>(), session, ExtendedEvent.UNLOCK);
ItemData lockOwner =
dataManager.getItemData(nodeData(), new QPathEntry(Constants.JCR_LOCKOWNER, 0), ItemType.PROPERTY);
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -104,7 +104,7 @@
public SessionDataManager(SessionImpl session, LocalWorkspaceDataManagerStub dataManager) throws RepositoryException
{
this.session = session;
- this.changesLog = new SessionChangesLog(session.getId());
+ this.changesLog = new SessionChangesLog(session);
this.itemsPool = new ItemReferencePool();
this.itemFactory = new SessionItemFactory();
this.accessManager = session.getAccessManager();
@@ -1703,7 +1703,7 @@
// remove from changes log (Session pending changes)
PlainChangesLog slog = changesLog.pushLog(item.getQPath());
- SessionChangesLog changes = new SessionChangesLog(slog.getAllStates(), session.getId());
+ SessionChangesLog changes = new SessionChangesLog(slog.getAllStates(), session);
String exceptions = "";
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/WorkspaceImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/WorkspaceImpl.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/WorkspaceImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -110,9 +110,13 @@
QueryManagerFactory qf = (QueryManagerFactory)container.getComponentInstanceOfType(QueryManagerFactory.class);
if (qf == null)
+ {
this.queryManager = null;
+ }
else
+ {
this.queryManager = qf.getQueryManager(session);
+ }
}
/**
@@ -123,7 +127,7 @@
PathNotFoundException, ItemExistsException, RepositoryException
{
- SessionChangesLog changes = new SessionChangesLog(session.getId());
+ SessionChangesLog changes = new SessionChangesLog(session);
clone(srcWorkspace, srcAbsPath, destAbsPath, removeExisting, changes);
@@ -162,8 +166,10 @@
// get destination node
JCRPath destNodePath = session.getLocationFactory().parseAbsPath(destAbsPath);
if (destNodePath.isIndexSetExplicitly())
+ {
throw new RepositoryException("The path provided must not have an index on its final element. "
+ destNodePath.getAsString(false));
+ }
// get source node
JCRPath srcNodePath = srcSession.getLocationFactory().parseAbsPath(srcAbsPath);
@@ -208,7 +214,7 @@
srcNode.getData().accept(initializer);
- PlainChangesLogImpl changesLog = new PlainChangesLogImpl(initializer.getItemAddStates(), session.getId());
+ PlainChangesLogImpl changesLog = new PlainChangesLogImpl(initializer.getItemAddStates(), session);
session.getTransientNodesManager().getTransactManager().save(changesLog);
}
@@ -296,7 +302,9 @@
public QueryManager getQueryManager() throws RepositoryException
{
if (queryManager == null)
+ {
throw new RepositoryException("Query Manager Factory not found. Check configuration.");
+ }
return queryManager;
}
@@ -382,8 +390,10 @@
// get destination node
JCRPath destNodePath = session.getLocationFactory().parseAbsPath(destAbsPath);
if (destNodePath.isIndexSetExplicitly())
+ {
throw new RepositoryException("The path provided must not have an index on its final element. "
+ destNodePath.getAsString(false));
+ }
// get source node
JCRPath srcNodePath = session.getLocationFactory().parseAbsPath(srcAbsPath);
@@ -427,19 +437,22 @@
// Check if versionable ancestor is not checked-in
if (!srcNode.checkedOut())
+ {
throw new VersionException("Source parent node " + srcNode.getPath()
+ " or its nearest ancestor is checked-in");
+ }
// Check locking
if (!srcNode.checkLocking())
+ {
throw new LockException("Source parent node " + srcNode.getPath() + " is locked ");
+ }
ItemDataMoveVisitor initializer =
new ItemDataMoveVisitor((NodeData)destParentNode.getData(), destNodePath.getName().getInternalName(),
nodeTypeManager, session.getTransientNodesManager(), true);
srcNode.getData().accept(initializer);
- PlainChangesLog changes = new PlainChangesLogImpl(session.getId());
- changes.addAll(initializer.getAllStates());
+ PlainChangesLog changes = new PlainChangesLogImpl(initializer.getAllStates(), session);
session.getTransientNodesManager().getTransactManager().save(changes);
}
@@ -460,13 +473,17 @@
{
if (srcWorkspace.equals(getName()))
+ {
throw new RepositoryException("Source and destination workspace are equals " + name);
+ }
// make dest node path
JCRPath destNodePath = session.getLocationFactory().parseAbsPath(destAbsPath);
if (destNodePath.isIndexSetExplicitly())
+ {
throw new RepositoryException("DestPath should not contain an index " + destAbsPath);
+ }
// find src node
SessionImpl srcSession = repository().internalLogin(session.getUserState(), srcWorkspace);
@@ -540,7 +557,9 @@
{
if (session.hasPendingChanges())
+ {
throw new InvalidItemStateException("Session has pending changes ");
+ }
// for restore operation
List<String> existedIdentifiers = new ArrayList<String>(); // InWorkspace
@@ -575,9 +594,13 @@
((SessionImpl)v.getSession()).getTransientNodesManager().getTransactManager();
corrNode = (NodeData)vDataManager.getItemData(versionableIdentifier);
if (corrNode != null)
+ {
versionableParentIdentifier = corrNode.getParentIdentifier();
+ }
else
+ {
log.warn("Workspace.restore(). Correspondent node is not found " + versionableIdentifier);
+ }
}
if (versionableParentIdentifier != null && existedIdentifiers.contains(versionableParentIdentifier))
{
@@ -592,7 +615,7 @@
}
}
- SessionChangesLog changesLog = new SessionChangesLog(session.getId());
+ SessionChangesLog changesLog = new SessionChangesLog(session);
for (VersionImpl v : existedVersions.keySet())
{
@@ -605,7 +628,7 @@
// parent
// it's a VH
VersionHistoryDataHelper historyHelper =
- new VersionHistoryDataHelper((NodeData)vh, dataManager, nodeTypeManager);
+ new VersionHistoryDataHelper(vh, dataManager, nodeTypeManager);
changesLog.addAll(v.restoreLog(destParent, node.getQPath().getName(), historyHelper, session,
removeExisting, changesLog).getAllStates());
@@ -643,7 +666,7 @@
// version parent it's a VH
NodeData vh = (NodeData)dataManager.getItemData(v.getParentIdentifier());
VersionHistoryDataHelper historyHelper =
- new VersionHistoryDataHelper((NodeData)vh, dataManager, nodeTypeManager);
+ new VersionHistoryDataHelper(vh, dataManager, nodeTypeManager);
changesLog.addAll(v.restoreLog(destParent, node.getQPath().getName(), historyHelper, session,
removeExisting, changesLog).getAllStates());
@@ -675,6 +698,9 @@
return (RepositoryImpl)session.getRepository();
}
+ /**
+ * {@inheritDoc}
+ */
public NodeTypeDataManager getNodeTypesHolder() throws RepositoryException
{
return nodeTypeManager;
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/FileSystemLockPersister.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/FileSystemLockPersister.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/FileSystemLockPersister.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -152,7 +152,9 @@
return;
}
if (!lockFile.delete())
+ {
throw new LockException("Fail to remove lock information");
+ }
}
@@ -197,9 +199,11 @@
(PropertyData)dataManager.getItemData(lockedNodeData, new QPathEntry(Constants.JCR_LOCKOWNER, 0),
ItemType.PROPERTY);
if (dataLockOwner != null)
+ {
plainChangesLog.add(ItemState.createDeletedState(new TransientPropertyData(QPath.makeChildPath(
lockedNodeData.getQPath(), Constants.JCR_LOCKOWNER), dataLockOwner.getIdentifier(), 0,
dataLockOwner.getType(), dataLockOwner.getParentIdentifier(), dataLockOwner.isMultiValued())));
+ }
if (plainChangesLog.getSize() > 0)
{
@@ -222,7 +226,9 @@
log.warn("Persistent lock information for node id " + list[i] + " doesn't exists");
}
if (!lockFile.delete())
+ {
throw new LockException("Fail to remove lock information");
+ }
}
}
catch (RepositoryException e)
@@ -288,8 +294,10 @@
String root = config.getParameterValue(PARAM_ROOT_DIR);
if (root == null)
+ {
throw new RepositoryConfigurationException("Repository service configuration." + " Source name ("
+ PARAM_ROOT_DIR + ") is expected");
+ }
rootDir = new File(root);
if (rootDir.exists())
{
@@ -301,7 +309,9 @@
else
{
if (!rootDir.mkdirs())
+ {
throw new RepositoryException("Can't create dir" + root);
+ }
}
}
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/observation/ActionLauncher.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.jcr.impl.core.observation;
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.core.ExtendedWorkspace;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
@@ -31,7 +33,6 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
-import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.jcr.impl.util.EntityCollection;
@@ -92,9 +93,19 @@
PlainChangesLog subLog = logIterator.nextLog();
String sessionId = subLog.getSessionId();
- SessionImpl userSession = sessionRegistry.getSession(sessionId);
+ ExtendedSession userSession;
+ if (subLog.getSession() != null)
+ {
+ userSession = subLog.getSession();
+ }
+ else
+ {
+ userSession = sessionRegistry.getSession(sessionId);
+ }
+
if (userSession != null)
+ {
for (ItemState itemState : subLog.getAllStates())
{
if (itemState.isEventFire())
@@ -123,6 +134,7 @@
}
}
}
+ }
}
if (events.getSize() > 0)
{
@@ -141,15 +153,15 @@
private boolean isSessionMatch(ListenerCriteria criteria, String sessionId)
{
- if (criteria.getNoLocal() && criteria.getSessionId().equals(sessionId))
- return false;
- return true;
+ return !(criteria.getNoLocal() && criteria.getSessionId().equals(sessionId));
}
- private boolean isPathMatch(ListenerCriteria criteria, ItemData item, SessionImpl userSession)
+ private boolean isPathMatch(ListenerCriteria criteria, ItemData item, ExtendedSession userSession)
{
if (criteria.getAbsPath() == null)
+ {
return true;
+ }
try
{
QPath cLoc = userSession.getLocationFactory().parseAbsPath(criteria.getAbsPath()).getInternalPath();
@@ -171,25 +183,33 @@
{
if (criteria.getIdentifier() == null)
+ {
return true;
+ }
// assotiated parent is node itself for node and parent for property ????
for (int i = 0; i < criteria.getIdentifier().length; i++)
{
if (item.isNode() && criteria.getIdentifier()[i].equals(item.getIdentifier()))
+ {
return true;
+ }
else if (!item.isNode() && criteria.getIdentifier()[i].equals(item.getParentIdentifier()))
+ {
return true;
+ }
}
return false;
}
- private boolean isNodeTypeMatch(ListenerCriteria criteria, ItemData item, SessionImpl userSession,
+ private boolean isNodeTypeMatch(ListenerCriteria criteria, ItemData item, ExtendedSession userSession,
PlainChangesLog changesLog) throws RepositoryException
{
if (criteria.getNodeTypeName() == null)
+ {
return true;
+ }
NodeData node = (NodeData)workspaceDataManager.getItemData(item.getParentIdentifier());
if (node == null)
@@ -214,7 +234,7 @@
}
}
- NodeTypeDataManager ntManager = userSession.getWorkspace().getNodeTypesHolder();
+ NodeTypeDataManager ntManager = ((ExtendedWorkspace)userSession.getWorkspace()).getNodeTypesHolder();
LocationFactory locationFactory = userSession.getLocationFactory();
for (int i = 0; i < criteria.getNodeTypeName().length; i++)
{
@@ -231,7 +251,9 @@
testQNames[0] = node.getPrimaryTypeName();
}
if (ntManager.isNodeType(criteriaNT.getName(), testQNames))
+ {
return true;
+ }
}
return false;
}
@@ -242,24 +264,40 @@
if (state.getData().isNode())
{
if (state.isAdded() || state.isRenamed() || state.isUpdated())
+ {
return Event.NODE_ADDED;
+ }
else if (state.isDeleted())
+ {
return Event.NODE_REMOVED;
+ }
else if (state.isUpdated())
+ {
return SKIP_EVENT;
+ }
else if (state.isUnchanged())
+ {
return SKIP_EVENT;
+ }
}
else
{ // property
if (state.isAdded())
+ {
return Event.PROPERTY_ADDED;
+ }
else if (state.isDeleted())
+ {
return Event.PROPERTY_REMOVED;
+ }
else if (state.isUpdated())
+ {
return Event.PROPERTY_CHANGED;
+ }
else if (state.isUnchanged())
+ {
return SKIP_EVENT;
+ }
}
throw new RepositoryException("Unexpected ItemState for Node " + ItemState.nameFromValue(state.getState()) + " "
+ state.getData().getQPath().getAsString());
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataMergeVisitor.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataMergeVisitor.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataMergeVisitor.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -174,7 +174,7 @@
this.bestEffort = bestEffort;
this.failed = failed;
- this.changes = new SessionChangesLog(mergeSession.getId());
+ this.changes = new SessionChangesLog(mergeSession);
}
@Override
@@ -530,6 +530,7 @@
ItemType.PROPERTY);
if (predecessorsProperty != null)
+ {
for (ValueData pv : predecessorsProperty.getValues())
{
try
@@ -537,7 +538,9 @@
String pidentifier = new String(pv.getAsByteArray());
if (pidentifier.equals(corrVersion.getIdentifier()))
+ {
return true; // got it
+ }
// search in predecessors of the predecessor
NodeData predecessor = (NodeData)mergeDataManager.getItemData(pidentifier);
@@ -560,6 +563,7 @@
}
}
// else it's a root version
+ }
return false;
}
@@ -576,6 +580,7 @@
ItemType.PROPERTY);
if (successorsProperty != null)
+ {
for (ValueData sv : successorsProperty.getValues())
{
try
@@ -583,7 +588,9 @@
String sidentifier = new String(sv.getAsByteArray());
if (sidentifier.equals(corrVersion.getIdentifier()))
+ {
return true; // got it
+ }
// search in successors of the successor
NodeData successor = (NodeData)mergeDataManager.getItemData(sidentifier);
@@ -606,6 +613,7 @@
}
}
// else it's a end of version graph node
+ }
return false;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -150,7 +150,7 @@
super(userSession.getTransientNodesManager().getTransactManager());
this.userSession = userSession;
- this.changes = new SessionChangesLog(userSession.getId());
+ this.changes = new SessionChangesLog(userSession);
this.context = context;
this.destName = destName;
this.history = history;
@@ -177,7 +177,9 @@
for (ItemState state : delegatedChanges.getAllStates())
{
if (state.getData().getIdentifier().equals(identifier))
+ {
return state.getData();
+ }
}
}
@@ -191,7 +193,9 @@
for (ItemState state : delegatedChanges.getAllStates())
{
if (state.getData().getQPath().equals(path))
+ {
return state.getData();
+ }
}
}
@@ -206,7 +210,9 @@
for (ItemState state : delegatedChanges.getAllStates())
{
if (state.getData().getQPath().equals(path) || state.getData().getQPath().isDescendantOf(path))
+ {
removed.add(state);
+ }
}
for (ItemState state : removed)
@@ -223,7 +229,9 @@
QPath nodePath = QPath.makeChildPath(parentData.getQPath(), name);
if (log.isDebugEnabled())
+ {
log.debug("Restore: " + nodePath.getAsString() + ", removeExisting=" + removeExisting);
+ }
PropertyData frozenIdentifier =
(PropertyData)dataManager.getItemData(frozen, new QPathEntry(Constants.JCR_FROZENUUID, 1), ItemType.PROPERTY);
@@ -254,8 +262,10 @@
// name
if (sameIdentifierPath.getIndex() != nodePath.getIndex())
+ {
// but different index, see below... fix it
nodePath = QPath.makeChildPath(parentData.getQPath(), name, sameIdentifierPath.getIndex());
+ }
// if it's a target node
existing = sameIdentifierNode;
@@ -466,7 +476,9 @@
NodeData cHistory = null;
if ((cHistory = (NodeData)dataManager.getItemData(vhIdentifier)) == null)
+ {
throw new RepositoryException("Version history is not found with uuid " + vhIdentifier);
+ }
childHistory = new VersionHistoryDataHelper(cHistory, dataManager, nodeTypeDataManager);
}
@@ -687,6 +699,7 @@
InternalQName qname = property.getQPath().getName();
if (nodeTypeDataManager.isNodeType(Constants.NT_FROZENNODE, frozenParent.getPrimaryTypeName()))
+ {
if (qname.equals(Constants.JCR_FROZENPRIMARYTYPE))
{
qname = Constants.JCR_PRIMARYTYPE;
@@ -705,6 +718,7 @@
// skip these props, as they are a nt:frozenNode special props
return;
}
+ }
int action =
nodeTypeDataManager.getPropertyDefinitions(qname, currentNode().getPrimaryTypeName(),
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -328,7 +328,7 @@
throw new ReferentialIntegrityException("There are Reference property pointed to this Version "
+ refs.get(0).getQPath().getAsString());
- PlainChangesLog changes = new PlainChangesLogImpl(session.getId());
+ PlainChangesLog changes = new PlainChangesLogImpl(session);
// remove labels first
try
@@ -506,7 +506,7 @@
NodeData versionData = getVersionData(versionName);
- SessionChangesLog changesLog = new SessionChangesLog(session.getId());
+ SessionChangesLog changesLog = new SessionChangesLog(session);
PropertyData labelData =
TransientPropertyData.createPropertyData(labels, labelQName, PropertyType.REFERENCE, false,
@@ -532,7 +532,7 @@
if (vldata != null)
{
- PlainChangesLog changes = new PlainChangesLogImpl(session.getId());
+ PlainChangesLog changes = new PlainChangesLogImpl(session);
changes.add(ItemState.createDeletedState(vldata));
dataManager.getTransactManager().save(changes);
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -219,19 +219,18 @@
// we have pair of logs for system and non-system (this) workspaces
final String pairId = IdGenerator.generate();
- versionLogs.addLog(new PlainChangesLogImpl(vstates, changes.getSessionId(), changes.getEventType(),
- pairId));
- nonVersionLogs.addLog(new PlainChangesLogImpl(nvstates, changes.getSessionId(), changes.getEventType(),
- pairId));
+ versionLogs.addLog(PlainChangesLogImpl.createCopy(vstates, pairId, changes));
+ nonVersionLogs.addLog(PlainChangesLogImpl.createCopy(nvstates, pairId, changes));
}
else
{
- versionLogs.addLog(new PlainChangesLogImpl(vstates, changes.getSessionId(), changes.getEventType()));
+ versionLogs.addLog(PlainChangesLogImpl.createCopy(vstates, changes));
+ nonVersionLogs.addLog(PlainChangesLogImpl.createCopy(nvstates, changes));
}
}
else if (nvstates.size() > 0)
{
- nonVersionLogs.addLog(new PlainChangesLogImpl(nvstates, changes.getSessionId(), changes.getEventType()));
+ nonVersionLogs.addLog(PlainChangesLogImpl.createCopy(nvstates, changes));
}
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -270,9 +270,7 @@
RepositoryException, IOException
{
// copy state
- PlainChangesLogImpl newLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), changesLog.getSessionId(), changesLog.getEventType(),
- changesLog.getPairId());
+ PlainChangesLogImpl newLog = PlainChangesLogImpl.createCopy(new ArrayList<ItemState>(), changesLog);
for (Iterator<ItemState> iter = changesLog.getAllStates().iterator(); iter.hasNext();)
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -94,7 +94,7 @@
.getAncestorToSave(), change.isInternallyCreated(), change.isPersisted()));
}
- newLog.addLog(new PlainChangesLogImpl(states, changes.getSessionId(), changes.getEventType()));
+ newLog.addLog(PlainChangesLogImpl.createCopy(states, changes));
}
storageDataManager.save(newLog);
@@ -139,7 +139,7 @@
{
return storageDataManager.getLastOrderNumber(parent);
}
-
+
/**
* {@inheritDoc}
*/
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLog.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.session;
+import org.exoplatform.services.jcr.core.ExtendedSession;
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
@@ -84,9 +85,9 @@
*
* @param sessionId
*/
- public SessionChangesLog(String sessionId)
+ public SessionChangesLog(ExtendedSession session)
{
- super(sessionId);
+ super(session);
}
/**
@@ -95,14 +96,14 @@
* @param items
* @param sessionId
*/
- public SessionChangesLog(List<ItemState> items, String sessionId)
+ public SessionChangesLog(List<ItemState> items, ExtendedSession session)
{
- super(items, sessionId);
+ super(items, session);
for (int i = 0, length = items.size(); i < length; i++)
{
ItemState change = items.get(i);
addItem(change);
- }
+ }
}
/**
@@ -192,13 +193,17 @@
{
Map<String, ItemState> children = lastChildNodeStates.get(item.getData().getParentIdentifier());
if (children != null)
+ {
children.remove(item.getData().getIdentifier());
+ }
}
else
{
Map<String, ItemState> children = lastChildPropertyStates.get(item.getData().getParentIdentifier());
if (children != null)
+ {
children.remove(item.getData().getIdentifier());
+ }
}
}
}
@@ -324,7 +329,8 @@
*/
public PlainChangesLog pushLog(QPath rootPath)
{
- PlainChangesLog cLog = new PlainChangesLogImpl(sessionId);
+ // session instance is always present in SessionChangesLog
+ PlainChangesLog cLog = new PlainChangesLogImpl(session);
if (rootPath.equals(Constants.ROOT_PATH))
{
@@ -422,7 +428,9 @@
{
ItemData item = items.get(i).getData();
if (item.getParentIdentifier().equals(rootIdentifier) || item.getIdentifier().equals(rootIdentifier))
+ {
list.add(items.get(i));
+ }
}
return list;
}
@@ -478,11 +486,15 @@
{
// the node
if (items.get(i).isAdded())
+ {
// if a new item - no modify changes can be
return new ArrayList<ItemState>();
+ }
if (!items.get(i).isDeleted())
+ {
changes.put(item.getIdentifier(), items.get(i));
+ }
}
else if (item.getParentIdentifier().equals(rootData.getIdentifier()))
{
@@ -538,7 +550,9 @@
rename = state;
delete = allStates.get(i - 1); // try the fresh delete state
if (delete.getData().getIdentifier().equals(rename.getData().getIdentifier()))
+ {
return new ItemState[]{delete, rename}; // 3. ok, got it
+ }
}
}
@@ -594,7 +608,9 @@
}
}
else
+ {
byState = true;
+ }
if (byState
&& (isPersisted != null ? istate.isPersisted() == isPersisted : true)
&& ((orAncestor != null && orAncestor ? rootPath.isDescendantOf(istate.getData().getQPath()) : true) || rootPath
@@ -641,7 +657,9 @@
}
}
else
+ {
byState = true;
+ }
if (byState && (isPersisted != null ? istate.isPersisted() == isPersisted : true)
&& istate.getData().getIdentifier().equals(id))
{
@@ -757,22 +775,34 @@
public boolean equals(Object obj)
{
if (this == obj)
+ {
return true;
+ }
if (obj == null)
+ {
return false;
+ }
if (getClass() != obj.getClass())
+ {
return false;
+ }
IDStateBasedKey other = (IDStateBasedKey)obj;
if (identifier == null)
{
if (other.identifier != null)
+ {
return false;
+ }
}
else if (!identifier.equals(other.identifier))
+ {
return false;
+ }
if (state != other.state)
+ {
return false;
+ }
return true;
}
}
@@ -846,37 +876,55 @@
public boolean equals(Object obj)
{
if (this == obj)
+ {
return true;
+ }
if (obj == null)
+ {
return false;
+ }
if (getClass() != obj.getClass())
+ {
return false;
+ }
ParentIDQPathBasedKey other = (ParentIDQPathBasedKey)obj;
if (name == null)
{
if (other.name != null)
+ {
return false;
+ }
}
else if (!name.getName().equals(other.name.getName())
|| !name.getNamespace().equals(other.name.getNamespace()) || name.getIndex() != other.name.getIndex())
+ {
return false;
+ }
if (parentIdentifier == null)
{
if (other.parentIdentifier != null)
+ {
return false;
+ }
}
else if (!parentIdentifier.equals(other.parentIdentifier))
+ {
return false;
+ }
if (itemType == null)
{
if (other.itemType != null)
+ {
return false;
+ }
}
else if (!itemType.equals(other.itemType))
+ {
return false;
+ }
return true;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/observation/TestSessionsObservation.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/observation/TestSessionsObservation.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/observation/TestSessionsObservation.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -23,6 +23,7 @@
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.jcr.observation.Event;
public class TestSessionsObservation extends JcrAPIBaseTest
@@ -258,4 +259,26 @@
sessionWs1.getWorkspace().getObservationManager().removeEventListener(listener2);
}
}
+
+ public void testMoveOnClosedSession() throws Exception
+ {
+
+ testRootWs1.addNode("newNode");
+ sessionWs1.save();
+
+ int counter = 0;
+
+ SimpleListener listener = new SimpleListener("testSessionOpen", log, counter);
+
+ Session sessionWs1ForListener = repository.login(credentials, "ws1");
+
+ sessionWs1ForListener.getWorkspace().getObservationManager().addEventListener(listener,
+ Event.NODE_ADDED | Event.NODE_REMOVED, testRootWs1.getPath() + "/", false, null, null, false);
+
+ sessionWs1ForListener.logout();
+
+ sessionWs1.logout();
+ sessionWs1.getWorkspace().move(testRootWs1.getPath() + "/newNode", testRootWs1.getPath() + "/newNode2");
+ assertEquals(2, listener.getCounter());
+ }
}
Added: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/DummySession.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/DummySession.java (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/DummySession.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core;
+
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.core.SessionLifecycleListener;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.AccessControlException;
+import java.util.Map;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.LoginException;
+import javax.jcr.NamespaceException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.VersionException;
+import javax.transaction.xa.XAResource;
+
+/**
+* @author Nikolay Zamosenchuk
+* @version $Id: DummySession.xml 34360 2009-07-22 23:58:59Z nzamosenchuk $
+*
+*/
+public class DummySession implements ExtendedSession
+{
+ private String sessionId;
+
+ public DummySession(String sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ public String getId()
+ {
+ return sessionId;
+ }
+
+ // do nothing
+ public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse,
+ boolean exportChildVersionHisotry) throws IOException, PathNotFoundException, RepositoryException
+ {
+ }
+
+ public LocationFactory getLocationFactory()
+ {
+ return null;
+ }
+
+ public Node getNodeByIdentifier(String identifier) throws ItemNotFoundException, RepositoryException
+ {
+ return null;
+ }
+
+ public long getTimeout()
+ {
+ return 0;
+ }
+
+ public XAResource getXAResource()
+ {
+ return null;
+ }
+
+ public boolean hasExpired()
+ {
+ return false;
+ }
+
+ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior, Map<String, Object> context)
+ throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException,
+ InvalidSerializedDataException, RepositoryException
+ {
+ }
+
+ public void registerLifecycleListener(SessionLifecycleListener listener)
+ {
+ }
+
+ public void setTimeout(long timeout)
+ {
+ }
+
+ public void addLockToken(String lt)
+ {
+ }
+
+ public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException
+ {
+ }
+
+ public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+ throws PathNotFoundException, SAXException, RepositoryException
+ {
+ }
+
+ public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+ throws IOException, PathNotFoundException, RepositoryException
+ {
+ }
+
+ public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+ throws PathNotFoundException, SAXException, RepositoryException
+ {
+ }
+
+ public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+ throws IOException, PathNotFoundException, RepositoryException
+ {
+ }
+
+ public Object getAttribute(String name)
+ {
+ return null;
+ }
+
+ public String[] getAttributeNames()
+ {
+ return null;
+ }
+
+ public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException,
+ ConstraintViolationException, VersionException, LockException, RepositoryException
+ {
+ return null;
+ }
+
+ public Item getItem(String absPath) throws PathNotFoundException, RepositoryException
+ {
+ return null;
+ }
+
+ public String[] getLockTokens()
+ {
+ return null;
+ }
+
+ public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException
+ {
+ return null;
+ }
+
+ public String[] getNamespacePrefixes() throws RepositoryException
+ {
+ return null;
+ }
+
+ public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException
+ {
+ return null;
+ }
+
+ public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException
+ {
+ return null;
+ }
+
+ public Repository getRepository()
+ {
+ return null;
+ }
+
+ public Node getRootNode() throws RepositoryException
+ {
+ return null;
+ }
+
+ public String getUserID()
+ {
+ return null;
+ }
+
+ public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException
+ {
+ return null;
+ }
+
+ public Workspace getWorkspace()
+ {
+ return null;
+ }
+
+ public boolean hasPendingChanges() throws RepositoryException
+ {
+ return false;
+ }
+
+ public Session impersonate(Credentials credentials) throws LoginException, RepositoryException
+ {
+ return null;
+ }
+
+ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException,
+ PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException,
+ InvalidSerializedDataException, LockException, RepositoryException
+ {
+ }
+
+ public boolean isLive()
+ {
+ return false;
+ }
+
+ public boolean itemExists(String absPath) throws RepositoryException
+ {
+ return false;
+ }
+
+ public void logout()
+ {
+ }
+
+ public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException,
+ VersionException, ConstraintViolationException, LockException, RepositoryException
+ {
+ }
+
+ public void refresh(boolean keepChanges) throws RepositoryException
+ {
+ }
+
+ public void removeLockToken(String lt)
+ {
+ }
+
+ public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException,
+ InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException
+ {
+ }
+
+ public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException
+ {
+ }
+}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestItemDataChangesLog.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestItemDataChangesLog.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestItemDataChangesLog.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -70,7 +70,7 @@
public void testBasicOperations() throws Exception
{
- SessionChangesLog cLog = new SessionChangesLog("s1");
+ SessionChangesLog cLog = new SessionChangesLog(new DummySession("s1"));
cLog.add(ItemState.createAddedState(data1));
cLog.add(ItemState.createAddedState(data2));
cLog.add(ItemState.createDeletedState(data2));
@@ -92,7 +92,7 @@
public void testSessionOperations() throws Exception
{
- SessionChangesLog cLog = new SessionChangesLog("s1");
+ SessionChangesLog cLog = new SessionChangesLog(new DummySession("s1"));
TransientNodeData d1 =
TransientNodeData.createNodeData(data1, new InternalQName(null, "testSessionOperations"), new InternalQName(
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLogTest.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLogTest.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/session/SessionChangesLogTest.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -20,10 +20,10 @@
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.dataflow.ItemState;
-import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.DummySession;
import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
@@ -120,7 +120,7 @@
try
{
userSession = (SessionImpl)frepository.login(fcredentials, "ws");
- chlog[0] = new SessionChangesLogInfo(new SessionChangesLog(userSession.getId()), userSession.getId());
+ chlog[0] = new SessionChangesLogInfo(new SessionChangesLog(userSession), userSession.getId());
}
catch (RepositoryException e)
{
@@ -148,7 +148,7 @@
public void testSameSession()
{
- SessionChangesLog chlog = new SessionChangesLog(session.getId());
+ SessionChangesLog chlog = new SessionChangesLog(session);
assertEquals("Session must be same as given id owns", session, getRegisteredSession(chlog.getSessionId()));
}
@@ -156,7 +156,7 @@
{
String id = IdGenerator.generate();
- SessionChangesLog chlog = new SessionChangesLog(id);
+ SessionChangesLog chlog = new SessionChangesLog(new DummySession(id));
assertNull("No session should be linked to the log", getRegisteredSession(chlog.getSessionId()));
}
@@ -248,7 +248,7 @@
public void testAddRootChanges() throws Exception
{
- SessionChangesLog changesLog = new SessionChangesLog(session.getId());
+ SessionChangesLog changesLog = new SessionChangesLog(session);
try
{
changesLog.add(new ItemState(new TransientPropertyData(Constants.ROOT_PATH, Constants.ROOT_UUID, 0,
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/fs/TestJCRVSReadWrite.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/fs/TestJCRVSReadWrite.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/fs/TestJCRVSReadWrite.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -147,7 +147,9 @@
path = resource.setProperty("jcr:data", vals).getPath();
}
else
+ {
path = resource.setProperty("jcr:data", fBLOB1).getPath();
+ }
resource.setProperty("jcr:mimeType", "application/x-octet-stream");
resource.setProperty("jcr:lastModified", Calendar.getInstance());
testRoot.save();
@@ -191,7 +193,7 @@
{
try
{
- SessionChangesLog changes = new SessionChangesLog(((NodeImpl)testRoot).getSession().getId());
+ SessionChangesLog changes = new SessionChangesLog(((NodeImpl)testRoot).getSession());
TransientNodeData ntfile =
TransientNodeData.createNodeData(rootData, InternalQName.parse("[]blob" + i), Constants.NT_FILE);
@@ -218,7 +220,9 @@
data.add(new TransientValueData(fBLOB2));
}
else
+ {
data.add(new TransientValueData(fBLOB1));
+ }
TransientPropertyData resData =
TransientPropertyData.createPropertyData(res, Constants.JCR_DATA, PropertyType.BINARY, data.size() > 1,
@@ -259,7 +263,7 @@
{
final DataManager dm =
((NodeImpl)testRoot).getSession().getTransientNodesManager().getTransactManager().getStorageDataManager();
- final SessionChangesLog changes = new SessionChangesLog(((NodeImpl)testRoot).getSession().getId());
+ final SessionChangesLog changes = new SessionChangesLog(((NodeImpl)testRoot).getSession());
class Remover
{
@@ -301,12 +305,18 @@
}
if (item == null)
+ {
break;
+ }
if (item.isNode())
+ {
parent = (NodeData)item;
+ }
else if (i < relPathEntries.length - 1)
+ {
throw new IllegalPathException("Path can not contains a property as the intermediate element");
+ }
}
return item;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/version/BaseVersionImplTest.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/version/BaseVersionImplTest.java 2011-10-19 07:55:25 UTC (rev 5067)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/version/BaseVersionImplTest.java 2011-10-19 08:09:57 UTC (rev 5068)
@@ -223,11 +223,11 @@
versionedVersionHistoryData = new ArrayList<ValueData>();
versionedVersionHistoryData.add(new TestTransientValueData(versionedVersionHistoryUuid.getBytes(), 0));
- changesLog = new SessionChangesLog(session.getId());
+ changesLog = new SessionChangesLog(session);
ntManager = (NodeTypeManagerImpl)session.getWorkspace().getNodeTypeManager();
- SessionChangesLog initChanges = new SessionChangesLog(session.getId());
+ SessionChangesLog initChanges = new SessionChangesLog(session);
NodeData wsRoot = (NodeData)((NodeImpl)session.getRootNode()).getData();
testRoot =
@@ -267,7 +267,7 @@
public void createVersionable(int testCase) throws Exception
{
- versionableLog = new SessionChangesLog(session.getId());
+ versionableLog = new SessionChangesLog(session);
// target node
versionable =
Added: jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1671/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1671/readme.txt (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.11-GA/JCR-1671/readme.txt 2011-10-19 08:09:57 UTC (rev 5068)
@@ -0,0 +1,73 @@
+Summary
+
+ * Status: Problem of EventListener not triggered when renaming a document
+ * CCP Issue: CCP-1106, Product Jira Issue: JCR-1671.
+ * Complexity: N/A
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+ * We want to add a listener that implements javax.jcr.observation.EventListener to intercept the event of renaming.
+ For this, there are five types of event: NODE_ADDED, NODE_REMOVED, PROPERTY_ADDED, PROPERTY_REMOVED, PROPERTY_CHANGED
+ Normally, the event of renaming should be considered as "delete" and "add" so when renaming a node the two events NODE_ADDED and NODE_REMOVED must be triggered which is not our case.
+
+Fix description
+Problem analysis
+ * The root cause is incorrect usage of JCR Sessions. UI performs operations on non-alive session. Such sessions are removed from SessionRegistry and therefore not found when broadcasting events. But session instance is mandatory there.
+
+How is the problem fixed?
+ * Inject a Session instance to PlainChangesLogImpl class, that is invoked in dataflow. Mentioned Session instance is retrieved from log when preparing the events to broadcast.
+
+Patch file: JCR-1671.patch
+
+Tests to perform
+
+Reproduction test
+
+ * Platform behavior successfully reproduced within JCR-level unit test org.exoplatform.services.jcr.api.observation.TestSessionsObservation#testMoveOnClosedSession()
+
+Tests performed at DevLevel
+
+ * Both steps to reproduce given in issue's description and reproduction unit test.
+
+Tests performed at QA/Support Level
+*
+
+Documentation changes
+
+Documentation changes:
+
+ * none
+
+Configuration changes
+
+Configuration changes:
+
+ * none
+
+Will previous configuration continue to work?
+
+ * yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+
+ * Internal components changed: Interface PlainChangesLog extended with new method and PlainChangesLogImpl and its derivative classes updated. New field and group of new constructors introduced. This doesn't affect serialization.
+
+Is there a performance risk/cost?
+
+ * Session instance can be swept by GC a bit later, comparing to previous state because it is handled by log instance. There is no performance risk.
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch validated
+
+Support Comment
+* Patch validated
+
+QA Feedbacks
+*
+
14 years, 6 months
exo-jcr SVN: r5067 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/core/query and 6 other directories.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-10-19 03:55:25 -0400 (Wed, 19 Oct 2011)
New Revision: 5067
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/AbstractRepositorySuspender.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLog.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLogWriter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositorySuspendController.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
Log:
EXOJCR-1471 : commit patch with comments added to the code.
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/AbstractRepositorySuspender.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/AbstractRepositorySuspender.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/AbstractRepositorySuspender.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,91 @@
+/*
+ * 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.services.jcr.core.ManageableRepository;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 4.10.2011 skarpenko $
+ *
+ */
+public abstract class AbstractRepositorySuspender
+{
+ /**
+ * The current repository.
+ */
+ private final ManageableRepository repository;
+
+ /**
+ * AbstractRepositorySuspender constructor.
+ */
+ public AbstractRepositorySuspender(ManageableRepository repository)
+ {
+ this.repository = repository;
+ }
+
+ /**
+ * Suspend repository which means that allow only read operations.
+ * All writing threads will wait until resume operations invoked.
+ */
+ protected void suspendRepository() throws RepositoryException
+ {
+ // Need privileges to manage repository.
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+ repository.setState(ManageableRepository.SUSPENDED);
+ }
+
+ /**
+ * Resume repository. All previously suspended threads continue working.
+ */
+ protected void resumeRepository() throws RepositoryException
+ {
+ // Need privileges to manage repository.
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+ }
+ repository.setState(ManageableRepository.ONLINE);
+ }
+
+ /**
+ * Returns repository state title.
+ */
+ protected String getRepositoryStateTitle()
+ {
+ return repository.getStateTitle();
+ }
+
+ /**
+ * Returns repository state.
+ */
+ protected int getRepositoryState()
+ {
+ return repository.getState();
+ }
+
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/AbstractRepositorySuspender.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLog.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLog.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLog.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,77 @@
+/*
+ * 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 java.io.IOException;
+
+/**
+ * Interface of inspection log. It provides general methods for logging consistency issues.
+ *
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 4.10.2011 skarpenko $
+ *
+ */
+public interface InspectionLog
+{
+ // represents broken object state
+ public enum InspectionStatus {
+ ERR("Error"), WARN("Warning"), REINDEX("Reindex");
+ final String text;
+
+ InspectionStatus(String text)
+ {
+ this.text = text;
+ }
+
+ public String toString()
+ {
+ return text;
+ }
+ }
+
+ /**
+ * @return true, if inconsistency was found
+ */
+ boolean hasInconsistency();
+
+ /**
+ * @return true, if inconsistency or warning was found
+ */
+ boolean hasWarnings();
+
+ /**
+ * Adds comment to log
+ */
+ void logComment(String message) throws IOException;
+
+ /**
+ * Adds description to log
+ */
+ void logInspectionDescription(String description) throws IOException;
+
+ /**
+ * Adds detailed event to log, with issue found
+ */
+ void logBrokenObjectInfo(String brokenObjectDesc, String comment, InspectionStatus status) throws IOException;
+
+ /**
+ * Adds exception with full trace to the log
+ */
+ void logException(String message, Exception ex) throws IOException;
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLog.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLogWriter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLogWriter.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLogWriter.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,133 @@
+/*
+ * 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 java.io.IOException;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Text-based inspection log implementation. It uses any compatible Writer instance for output.
+ *
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 6.10.2011 skarpenko $
+ *
+ */
+public class InspectionLogWriter implements InspectionLog
+{
+ private static final String LINE_COMMENT = "//";
+
+ private static final String LINE_DELIMITER = "\n";
+
+ private static final String WSP = " ";
+
+ private final Writer out;
+
+ private final Set<InspectionStatus> statusSet = new HashSet<InspectionStatus>();
+
+ public InspectionLogWriter(Writer out)
+ {
+ this.out = out;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasInconsistency()
+ {
+ return statusSet.contains(InspectionStatus.ERR) || statusSet.contains(InspectionStatus.REINDEX);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasWarnings()
+ {
+ return statusSet.contains(InspectionStatus.WARN);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void logComment(String message) throws IOException
+ {
+ writeLine(message);
+ out.flush();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void logInspectionDescription(String description) throws IOException
+ {
+ writeLine(description);
+ out.flush();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void logBrokenObjectInfo(String brokenObjectDesc, String comment, InspectionStatus status) throws IOException
+ {
+ statusSet.add(status);
+
+ out.write(status.toString());
+ out.write(WSP);
+ out.write(brokenObjectDesc);
+ out.write(WSP);
+ out.write(comment);
+ out.write(LINE_DELIMITER);
+ out.flush();
+ }
+
+ public void logException(String message, Exception ex) throws IOException
+ {
+ statusSet.add(InspectionStatus.ERR);
+
+ writeLine(message);
+ writeStackTrace(ex);
+ out.flush();
+ }
+
+ private void writeLine(String message) throws IOException
+ {
+ out.write(LINE_COMMENT);
+ out.write(message);
+ out.write(LINE_DELIMITER);
+ }
+
+ 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);
+ }
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/InspectionLogWriter.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,424 @@
+/*
+ * 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.PrivilegedFileHelper;
+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.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.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+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@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 3.10.2011 skarpenko $
+ */
+@Managed
+@NameTemplate(@Property(key = "service", value = "RepositoryCheckController"))
+public class RepositoryCheckController extends AbstractRepositorySuspender implements Startable
+{
+ /**
+ * Logger.
+ */
+ protected static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RepositorySuspendController");
+
+ protected static final String FILE_NAME = "report";
+
+ protected class InspectorThread extends Thread
+ {
+ private final DataStorage[] checkData;
+
+ InspectorThread(DataStorage[] checkData)
+ {
+ super();
+ this.checkData = checkData;
+ this.setDaemon(true);
+ }
+
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run()
+ {
+ String result = checkRepositoryDataConsistency(checkData);
+ inspectionFinished(result);
+ }
+ }
+
+ protected enum DataStorage {
+ DB, VALUE_STORAGE, LUCENE_INDEX
+ };
+
+ private InspectorThread inspectorThread = null;
+
+ private File inspectionLogFile = null;
+
+ private String lastResult = null;
+
+ /**
+ * The current repository.
+ */
+ private final ManageableRepository repository;
+
+ /**
+ * RepositoryCheckController constructor.
+ */
+ public RepositoryCheckController(ManageableRepository repository)
+ {
+ super(repository);
+ this.repository = 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."
+ + "All writing threads will wait until check become finished.")
+ public String checkRepositoryDataConsistency()
+ {
+ return startInspectionInThread(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
+ DataStorage.LUCENE_INDEX});
+ }
+
+ @Managed
+ @ManagedDescription("Check repository database consistency."
+ + "All writing threads will wait until check become finished.")
+ public String checkRepositoryDataBaseConsistency()
+ {
+ return startInspectionInThread(new DataStorage[]{DataStorage.DB});
+ }
+
+ @Managed
+ @ManagedDescription("Check repository value storage consistency."
+ + "All writing threads will wait until check become finished.")
+ public String checkRepositoryValueStorageConsistency()
+ {
+ return startInspectionInThread(new DataStorage[]{DataStorage.VALUE_STORAGE});
+ }
+
+ @Managed
+ @ManagedDescription("Check repository search index consistency."
+ + "All writing threads will wait until check become finished.")
+ public String checkRepositorySearchIndexConsistency()
+ {
+ return startInspectionInThread(new DataStorage[]{DataStorage.LUCENE_INDEX});
+ }
+
+ @Managed
+ @ManagedDescription("Get inspection status.")
+ public String getStatus()
+ {
+ if (inspectorThread != null)
+ {
+ return "Data consistency inspection in progress..";
+ }
+ else
+ {
+ return lastResult;
+ }
+ }
+
+ protected void inspectionFinished(String resultMessage)
+ {
+ this.lastResult = resultMessage;
+ inspectorThread = null;
+ }
+
+ protected synchronized String startInspectionInThread(DataStorage[] checkData)
+ {
+ if (inspectorThread == null)
+ {
+ inspectorThread = new InspectorThread(checkData);
+ inspectorThread.start();
+
+ return "Data consistency inspection started.";
+ }
+ else
+ {
+ return "Current inspection process is not finished.";
+ }
+ }
+
+ protected String checkRepositoryDataConsistency(DataStorage[] checkData)
+ {
+ inspectionLogFile = null;
+ try
+ {
+ if (getRepositoryState() == ManageableRepository.SUSPENDED)
+ {
+ return "Can not check data consistency. Repository is already suspended.";
+ }
+
+ Writer reportWriter = null;
+ try
+ {
+ try
+ {
+ suspendRepository();
+ }
+ catch (RepositoryException e)
+ {
+ return "Can not check data consistency. Repository was not suspended. Error: " + e.getMessage();
+ }
+
+ // DO CHECK
+ inspectionLogFile =
+ new File(FILE_NAME + "-" + repository.getConfiguration().getName() + "-"
+ + new SimpleDateFormat("dd-MMM-yy-HH-mm").format(new Date()) + ".txt");
+ if (!PrivilegedFileHelper.exists(inspectionLogFile)
+ && !PrivilegedFileHelper.createNewFile(inspectionLogFile))
+ {
+ LOG.error("Inspection log file was not created. "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile));
+ return "Can not check data consistency. Inspection log file was not created. "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+
+ reportWriter =
+ new BufferedWriter(new OutputStreamWriter(PrivilegedFileHelper.fileOutputStream(inspectionLogFile)));
+ InspectionLog report = new InspectionLogWriter(reportWriter);
+ for (DataStorage cd : checkData)
+ {
+ switch (cd)
+ {
+ case DB :
+ try
+ {
+ checkDB(report);
+ }
+ catch (RepositoryException e)
+ {
+ report.logException("RepositoryException occures during DB consistency check.", e);
+ return "RepositoryException occures during DB consistency check. Error: " + e.getMessage()
+ + ". See log here: " + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ catch (IOException e)
+ {
+ report.logException("IOException occures during DB consistency check.", e);
+ return "IOException occures during DB consistency check. Error: " + e.getMessage()
+ + ". See log here: " + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ break;
+ case VALUE_STORAGE :
+ try
+ {
+ checkVS(report);
+ }
+ catch (RepositoryException e)
+ {
+ report.logException("RepositoryException occures during ValueStorage consistency check.", e);
+ return "RepositoryException occures during ValueStorage consistency check. Error: "
+ + e.getMessage() + ". See log here: "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ catch (IOException e)
+ {
+ report.logException("IOException occures during ValueStorage consistency check.", e);
+ return "IOException occures during ValueStorage consistency check. Error: " + e.getMessage()
+ + ". See log here: " + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ break;
+ case LUCENE_INDEX :
+ try
+ {
+ checkLuceneIndex(report);
+ }
+ catch (RepositoryException e)
+ {
+ report.logException("RepositoryException occures during SearchIndex consistency check.", e);
+ return "RepositoryException occures during SearchIndex consistency check. Error: "
+ + e.getMessage() + ". See log here: "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ catch (IOException e)
+ {
+ report.logException("IOException occures during SearchIndex consistency check.", e);
+ return "IOException occures during SearchIndex consistency check. Error: " + e.getMessage()
+ + ". See log here: " + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ break;
+ }
+ }
+
+ if (report.hasInconsistency())
+ {
+ report.logComment("Repository data is NOT consistent.");
+ return "Repository data is inconsistent. See full report by path "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ else if (report.hasWarnings())
+ {
+ report.logComment("Repository data is consistent, except some warnings.");
+ return "Repository data is consistent, except some warnings. See full report by path "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ else
+ {
+ report.logComment("Repository data is consistent");
+ return "Repository data is consistent. See full report by path "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile);
+ }
+ }
+ finally
+ {
+ if (reportWriter != null)
+ {
+ try
+ {
+ reportWriter.flush();
+ reportWriter.close();
+ }
+ catch (IOException e)
+ {
+ LOG.error("Can not close file " + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile), e);
+ }
+ }
+
+ //resume repository
+ try
+ {
+ resumeRepository();
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Can not resume repository. Error: " + e.getMessage(), e);
+ }
+ if (getRepositoryState() != ManageableRepository.ONLINE)
+ {
+ LOG.error("Repository was not resumed and now it is OFFLINE");
+ }
+ }
+ }
+ catch (Throwable e)
+ {
+ LOG.error(e.getMessage(), e);
+ return "Exception thrown during repository data validation: "
+ + e
+ + (inspectionLogFile != null ? " See log by path "
+ + PrivilegedFileHelper.getAbsolutePath(inspectionLogFile) : "");
+ }
+ }
+
+ private void checkDB(InspectionLog inspectionLog) throws RepositoryException, IOException
+ {
+ String[] wsNames = repository.getWorkspaceNames();
+ for (String wsName : wsNames)
+ {
+ inspectionLog.logComment("Check DB consistency. Workspace " + wsName);
+ JDBCWorkspaceDataContainer dataContainer =
+ (JDBCWorkspaceDataContainer)repository.getWorkspaceContainer(wsName).getComponent(
+ JDBCWorkspaceDataContainer.class);
+ JDBCWorkspaceDataContainerChecker.checkDB(dataContainer, inspectionLog);
+ }
+ }
+
+ private void checkVS(InspectionLog inspectionLog) throws RepositoryException, IOException
+ {
+ String[] wsNames = repository.getWorkspaceNames();
+ for (String wsName : wsNames)
+ {
+ inspectionLog.logComment("Check ValueStorage consistency. Workspace " + wsName);
+
+ JDBCWorkspaceDataContainer dataContainer =
+ (JDBCWorkspaceDataContainer)repository.getWorkspaceContainer(wsName).getComponent(
+ JDBCWorkspaceDataContainer.class);
+
+ ValueStoragePluginProvider vsPlugin =
+ (ValueStoragePluginProvider)repository.getWorkspaceContainer(wsName).getComponent(
+ ValueStoragePluginProvider.class);
+
+ JDBCWorkspaceDataContainerChecker.checkValueStorage(dataContainer, vsPlugin, inspectionLog);
+ }
+ }
+
+ private void checkLuceneIndex(InspectionLog inspectionLog) throws RepositoryException, IOException
+ {
+ final String[] wsNames = repository.getWorkspaceNames();
+ final String systemWS = repository.getConfiguration().getSystemWorkspaceName();
+ for (String wsName : wsNames)
+ {
+ inspectionLog.logComment("Check SearchIndex consistency. Workspace " + wsName);
+ SearchManager searchManager =
+ (SearchManager)repository.getWorkspaceContainer(wsName).getComponent(SearchManager.class);
+ searchManager.checkIndex(inspectionLog, systemWS.equals(wsName));
+ }
+ }
+
+ /**
+ * For test purposes.
+ * @return
+ */
+ protected File getLastLogFile()
+ {
+ return inspectionLogFile;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ if (inspectorThread != null)
+ {
+ inspectorThread.interrupt();
+ }
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -610,6 +610,7 @@
{
registerComponentImplementation(RepositorySuspendController.class);
+ registerComponentImplementation(RepositoryCheckController.class);
registerComponentImplementation(IdGenerator.class);
registerComponentImplementation(RepositoryIndexSearcherHolder.class);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositorySuspendController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositorySuspendController.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositorySuspendController.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -23,7 +23,6 @@
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.core.ManageableRepository;
-import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.picocontainer.Startable;
@@ -38,14 +37,9 @@
*/
@Managed
@NameTemplate(@Property(key = "service", value = "RepositorySuspendController"))
-public class RepositorySuspendController implements Startable
+public class RepositorySuspendController extends AbstractRepositorySuspender implements Startable
{
/**
- * The current repository.
- */
- private final ManageableRepository repository;
-
- /**
* Logger.
*/
protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.RepositorySuspendController");
@@ -55,7 +49,7 @@
*/
public RepositorySuspendController(ManageableRepository repository)
{
- this.repository = repository;
+ super(repository);
}
/**
@@ -69,23 +63,15 @@
"All writing threads will wait until resume operations invoked.")
public String suspend()
{
- // Need privileges to manage repository.
- SecurityManager security = System.getSecurityManager();
- if (security != null)
- {
- security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
- }
-
try
{
- repository.setState(ManageableRepository.SUSPENDED);
+ suspendRepository();
}
catch (RepositoryException e)
{
log.error(e);
}
-
- return getState();
+ return getRepositoryStateTitle();
}
/**
@@ -97,23 +83,15 @@
@ManagedDescription("Resume repository. All previously suspended threads continue working.")
public String resume()
{
- // Need privileges to manage repository.
- SecurityManager security = System.getSecurityManager();
- if (security != null)
- {
- security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
- }
-
try
{
- repository.setState(ManageableRepository.ONLINE);
+ resumeRepository();
}
catch (RepositoryException e)
{
log.error(e);
}
-
- return getState();
+ return getRepositoryStateTitle();
}
/**
@@ -123,7 +101,7 @@
@ManagedDescription("Returns repository state.")
public String getState()
{
- return repository.getStateTitle();
+ return getRepositoryStateTitle();
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -18,7 +18,9 @@
import org.apache.lucene.search.Query;
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.InspectionLog;
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;
@@ -222,4 +224,17 @@
*/
boolean isOnline();
+ /**
+ * Check index consistency. Iterator goes through index documents and check, does each document have
+ * according jcr-node. If <b>autoRepair</b> is true - all broken index-documents will be reindexed,
+ * and documents that do not have corresponding jcr-node will be removed.
+ *
+ * @param itemStateManager
+ * @param isSystem
+ * @param inspectionLog
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ void checkIndex(ItemDataConsumer itemStateManager, boolean isSystem, InspectionLog inspectionLog)
+ throws RepositoryException, IOException;
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -22,6 +22,7 @@
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.WildcardQuery;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.management.annotations.Managed;
@@ -48,6 +49,7 @@
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.InspectionLog;
import org.exoplatform.services.jcr.impl.backup.BackupException;
import org.exoplatform.services.jcr.impl.backup.Backupable;
import org.exoplatform.services.jcr.impl.backup.DataRestore;
@@ -88,6 +90,8 @@
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -391,6 +395,78 @@
}
/**
+ * Check index consistency. Iterator goes through index documents and check, does each document have
+ * according jcr-node. If index is suspended then it will be temporary resumed, while check is running and suspended afterwards.
+ */
+ public void checkIndex(final InspectionLog inspectionLog, final boolean isSystem) throws RepositoryException, IOException
+ {
+
+ if (isSuspended)
+ {
+ try
+ {
+ SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws RepositoryException, IOException
+ {
+ // try resuming the workspace
+ try
+ {
+ if (isSystem && parentSearchManager != null && parentSearchManager.isSuspended)
+ {
+ parentSearchManager.resume();
+ }
+ resume();
+
+ handler.checkIndex(itemMgr, isSystem, inspectionLog);
+ return null;
+ }
+ catch (ResumeException e)
+ {
+ throw new RepositoryException("Can not resume SearchManager for inspection purposes.", e);
+ }
+ finally
+ {
+ // safely return the state of the workspace
+ try
+ {
+ suspend();
+ if (isSystem && parentSearchManager != null && !parentSearchManager.isSuspended)
+ {
+ parentSearchManager.suspend();
+ }
+ }
+ catch (SuspendException e)
+ {
+ log.error(e.getMessage(), e);
+ }
+ }
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ Throwable ex = e.getCause();
+ if (ex instanceof RepositoryException)
+ {
+ throw (RepositoryException)ex;
+ }
+ else if (ex instanceof IOException)
+ {
+ throw (IOException)ex;
+ }
+ else
+ {
+ throw new RepositoryException(ex.getMessage(), ex);
+ }
+ }
+ }else{
+ // simply run checkIndex, if not suspended
+ handler.checkIndex(itemMgr, isSystem, inspectionLog);
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
public Set<String> getFieldNames() throws IndexException
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -44,12 +44,15 @@
import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
+import org.exoplatform.services.jcr.dataflow.ItemDataTraversingVisitor;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
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.InspectionLog;
+import org.exoplatform.services.jcr.impl.InspectionLog.InspectionStatus;
import org.exoplatform.services.jcr.impl.backup.ResumeException;
import org.exoplatform.services.jcr.impl.backup.SuspendException;
import org.exoplatform.services.jcr.impl.backup.Suspendable;
@@ -864,6 +867,127 @@
}
/**
+ * {@inheritDoc}
+ */
+ public void checkIndex(ItemDataConsumer itemStateManager, boolean isSystem, final InspectionLog inspectionLog)
+ throws RepositoryException, IOException
+ {
+
+ // The visitor, that performs item enumeration and checks if all nodes present in
+ // persistent layer are indexed. Also collects the list of all indexed nodes
+ // to optimize the process of backward check, when index is traversed to find
+ // references to already deleted nodes
+ class ItemDataIndexConsistencyVisitor extends ItemDataTraversingVisitor
+ {
+ private final IndexReader indexReader;
+
+ private final Set<String> indexedNodes = new HashSet<String>();
+
+ /**
+ * @param dataManager
+ */
+ public ItemDataIndexConsistencyVisitor(ItemDataConsumer dataManager, IndexReader indexReader)
+ {
+ super(dataManager);
+ this.indexReader = indexReader;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void entering(PropertyData property, int level) throws RepositoryException
+ {
+ // ignore properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void entering(NodeData node, int level) throws RepositoryException
+ {
+ // process node uuids one-by-one
+ try
+ {
+ String uuid = node.getIdentifier();
+ TermDocs docs = indexReader.termDocs(new Term(FieldNames.UUID, uuid));
+
+ if (docs.next())
+ {
+ indexedNodes.add(uuid);
+ docs.doc();
+ if (docs.next())
+ {
+ //multiple entries
+ inspectionLog.logBrokenObjectInfo("ID=" + uuid, "Multiple entires.", InspectionStatus.REINDEX);
+ }
+ }
+ else
+ {
+ inspectionLog.logBrokenObjectInfo("ID=" + uuid, "Not indexed.", InspectionStatus.REINDEX);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ protected void leaving(PropertyData property, int level) throws RepositoryException
+ {
+ // ignore properties
+ }
+
+ @Override
+ protected void leaving(NodeData node, int level) throws RepositoryException
+ {
+ // do nothing
+ }
+
+ @Override
+ protected void visitChildProperties(NodeData node) throws RepositoryException
+ {
+ //do nothing
+ }
+
+ public Set<String> getIndexedNodes()
+ {
+ return indexedNodes;
+ }
+ }
+
+ // check relation Persistent Layer -> Index
+ // If current workspace is system, then need to invoke reader correspondent to system index
+ IndexReader indexReader = getIndexReader(isSystem);
+ ItemData root = itemStateManager.getItemData(Constants.ROOT_UUID);
+ ItemDataIndexConsistencyVisitor visitor = new ItemDataIndexConsistencyVisitor(itemStateManager, indexReader);
+ root.accept(visitor);
+
+ Set<String> documentUUIDs = visitor.getIndexedNodes();
+
+ // check relation Index -> Persistent Layer
+ // find document that do not corresponds to real node
+ // iterate on documents one-by-one
+ for (int i = 0; i < indexReader.maxDoc(); i++)
+ {
+ if (indexReader.isDeleted(i))
+ {
+ continue;
+ }
+ final int currentIndex = i;
+ Document d = indexReader.document(currentIndex, FieldSelectors.UUID);
+ String uuid = d.get(FieldNames.UUID);
+ if (!documentUUIDs.contains(uuid))
+ {
+ inspectionLog.logBrokenObjectInfo("ID=" + uuid, "Document corresponds to removed node.",
+ InspectionStatus.REINDEX);
+ }
+ }
+ }
+
+ /**
* @return the errorLogfileSize
*/
public int getErrorLogfileSize()
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -247,6 +247,11 @@
// VALUE table
/**
+ * PROPERTY_ID
+ */
+ protected static final String COLUMN_VPROPERTY_ID = "PROPERTY_ID";
+
+ /**
* COLUMN_VDATA.
*/
protected static final String COLUMN_VDATA = "DATA";
@@ -340,9 +345,8 @@
/**
* DB_DIALECTS.
*/
- public final static String[] DB_DIALECTS =
- {DB_DIALECT_GENERIC, DB_DIALECT_ORACLE, DB_DIALECT_ORACLEOCI, DB_DIALECT_PGSQL, DB_DIALECT_MYSQL,
- DB_DIALECT_HSQLDB, DB_DIALECT_DB2, DB_DIALECT_DB2V8, DB_DIALECT_MSSQL, DB_DIALECT_SYBASE, DB_DIALECT_DERBY,
- DB_DIALECT_MYSQL_UTF8, DB_DIALECT_INGRES, DB_DIALECT_H2};
+ public final static String[] DB_DIALECTS = {DB_DIALECT_GENERIC, DB_DIALECT_ORACLE, DB_DIALECT_ORACLEOCI,
+ DB_DIALECT_PGSQL, DB_DIALECT_MYSQL, DB_DIALECT_HSQLDB, DB_DIALECT_DB2, DB_DIALECT_DB2V8, DB_DIALECT_MSSQL,
+ DB_DIALECT_SYBASE, DB_DIALECT_DERBY, DB_DIALECT_MYSQL_UTF8, DB_DIALECT_INGRES, DB_DIALECT_H2};
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,415 @@
+/*
+ * 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.storage.jdbc;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.InspectionLog;
+import org.exoplatform.services.jcr.impl.InspectionLog.InspectionStatus;
+import org.exoplatform.services.jcr.impl.storage.value.ValueDataNotFoundException;
+import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
+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;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 14 жовт. 2011 skarpenko $
+ *
+ */
+public class JDBCWorkspaceDataContainerChecker
+{
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JDBCWorkspaceDataContainerChecker");
+
+ /**
+ * Check database.
+ * <p>
+ * Check that database is not broken, and all base relation between jcr-items are not corrupted.
+ * </p>
+ *
+ * @param inspectionLog - log where inspection results will be placed
+ * @return InspectionLog
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ public static void checkDB(JDBCWorkspaceDataContainer jdbcDataContainer, InspectionLog inspectionLog)
+ throws RepositoryException, IOException
+ {
+
+ /**
+ * Data class, contains a combination of SQL states, description, field names and status
+ */
+ class InspectionQuery
+ {
+ /**
+ * SQL query that must be executed.
+ */
+ private final String statement;
+
+ /**
+ * Inspection query description.
+ */
+ private final String description;
+
+ /**
+ * Field names that must be showed in inspection log if something wrong.
+ */
+ private final String[] fieldNames;
+
+ /**
+ * Corruption status. Is it critical - <b>ERR</b>, or not - <b>WARN</b>.
+ */
+ private final InspectionStatus status;
+
+ public InspectionQuery(String statement, String[] fieldNames, String headerMessage, InspectionStatus status)
+ {
+ this.statement = statement;
+ this.description = headerMessage;
+ this.fieldNames = fieldNames;
+ this.status = status;
+ }
+
+ public String getStatement()
+ {
+ return statement;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String[] getFieldNames()
+ {
+ return fieldNames;
+ }
+
+ public InspectionStatus getStatus()
+ {
+ return status;
+ }
+ }
+
+ Set<InspectionQuery> queries = new HashSet<InspectionQuery>();
+
+ // preload queries
+ queries.add(new InspectionQuery(jdbcDataContainer.multiDb
+ ? "select * from JCR_MITEM as I where NOT EXISTS(select * from JCR_MITEM AS P where P.ID = I.PARENT_ID)"
+ : "select * from JCR_SITEM as I where I.CONTAINER_NAME='" + jdbcDataContainer.containerName
+ + "' and NOT EXISTS(select * from JCR_SITEM AS P where P.ID = I.PARENT_ID)", new String[]{
+ DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME, DBConstants.COLUMN_CLASS},
+ "Items that do not have parent nodes", InspectionStatus.ERR));
+ queries
+ .add(new InspectionQuery(
+ jdbcDataContainer.multiDb
+ ? "select * from JCR_MITEM as N where N.I_CLASS=1 and NOT EXISTS (select * from JCR_MITEM AS P where P.I_CLASS=2 and P.PARENT_ID=N.ID)"
+ : "select * from JCR_SITEM as N where N.CONTAINER_NAME='"
+ + jdbcDataContainer.containerName
+ + "' and N.I_CLASS=1 and NOT EXISTS (select * from JCR_SITEM AS P where P.I_CLASS=2 and P.PARENT_ID=N.ID)",
+ new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
+ "Nodes that do not have at least one property", InspectionStatus.ERR));
+ queries
+ .add(new InspectionQuery(
+ jdbcDataContainer.multiDb
+ ? "select * from JCR_MVALUE as V where NOT EXISTS(select * from JCR_MITEM as P where V.PROPERTY_ID = P.ID and P.I_CLASS=2)"
+ : "select * from JCR_SVALUE as V where NOT EXISTS(select * from JCR_SITEM as P where P.CONTAINER_NAME='"
+ + jdbcDataContainer.containerName + "' and V.PROPERTY_ID = P.ID and P.I_CLASS=2)", new String[]{
+ DBConstants.COLUMN_ID, DBConstants.COLUMN_VPROPERTY_ID},
+ "All value records that has not owner-property record", InspectionStatus.ERR));
+ queries
+ .add(new InspectionQuery(
+ jdbcDataContainer.multiDb
+ ? "select * from JCR_MITEM as P where P.I_CLASS=2 and NOT EXISTS( select * from JCR_MVALUE as V where V.PROPERTY_ID=P.ID)"
+ : "select * from JCR_SITEM as P where P.CONTAINER_NAME='" + jdbcDataContainer.containerName
+ + "' and P.I_CLASS=2 and NOT EXISTS( select * from JCR_SVALUE as V where V.PROPERTY_ID=P.ID)",
+ new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
+ "All properties that have not value record.", InspectionStatus.WARN));
+ queries
+ .add(new InspectionQuery(
+ jdbcDataContainer.multiDb
+ ? "select * from JCR_MVALUE where (STORAGE_DESC is null and DATA is null) or (STORAGE_DESC is not null and DATA is not null)"
+ : "select * from JCR_SVALUE where (STORAGE_DESC is null and DATA is null) or (STORAGE_DESC is not null and DATA is not null)",
+ new String[]{DBConstants.COLUMN_ID}, "Incorrect JCR_VALUE records", InspectionStatus.ERR));
+ queries
+ .add(new InspectionQuery(
+ jdbcDataContainer.multiDb
+ ? "select * from JCR_MITEM AS P where P.P_TYPE=9 and NOT EXISTS( select * from JCR_MREF AS R where P.ID=R.PROPERTY_ID)"
+ : "select * from JCR_SITEM AS P where P.CONTAINER_NAME='" + jdbcDataContainer.containerName
+ + "' and P.P_TYPE=9 and NOT EXISTS( select * from JCR_SREF AS R where P.ID=R.PROPERTY_ID)",
+ new String[]{DBConstants.COLUMN_ID, DBConstants.COLUMN_PARENTID, DBConstants.COLUMN_NAME},
+ "Reference properties without reference records", InspectionStatus.ERR));
+
+ // properties can refer to missing node. It is possible to perform this usecase via JCR API with no exceptions
+ queries.add(new InspectionQuery(jdbcDataContainer.multiDb
+ ? "select * from JCR_MREF AS R where NOT EXISTS(select * from JCR_MITEM AS N where R.NODE_ID=N.ID)"
+ : "select * from JCR_SREF AS R where NOT EXISTS(select * from JCR_SITEM AS N where N.CONTAINER_NAME='"
+ + jdbcDataContainer.containerName + "' and R.NODE_ID=N.ID)", new String[]{"NODE_ID", "PROPERTY_ID",
+ DBConstants.COLUMN_VORDERNUM},
+ "Reference records that linked to unexisted nodes. Can be normal for some usecases.", InspectionStatus.WARN));
+
+ // using existing DataSource to get a JDBC Connection.
+ Connection jdbcConn = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+
+ try
+ {
+ // perform all queries on-by-one
+ for (InspectionQuery query : queries)
+ {
+ PreparedStatement st = null;
+ ResultSet resultSet = null;
+ try
+ {
+ st = jdbcConn.prepareStatement(query.getStatement());
+ // the result of query is expected to be empty
+ resultSet = st.executeQuery();
+ if (resultSet.next())
+ {
+ // but if result not empty, then inconsistency takes place
+ inspectionLog.logInspectionDescription(query.getDescription());
+ do
+ {
+ StringBuilder record = new StringBuilder();
+ for (String fieldName : query.getFieldNames())
+ {
+ record.append(fieldName);
+ record.append('=');
+ if (fieldName.equals(DBConstants.COLUMN_NORDERNUM)
+ || fieldName.equals(DBConstants.COLUMN_VORDERNUM))
+ {
+ record.append(resultSet.getInt(fieldName));
+ }
+ else
+ {
+ record.append(resultSet.getString(fieldName));
+ }
+ record.append(' ');
+ }
+ // log inconsistency issue.
+ inspectionLog.logBrokenObjectInfo(record.toString(), "", query.getStatus());
+ }
+ 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);
+ }
+ }
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ // log unexpected exceptions to log
+ inspectionLog.logException("Exception during DB inspection.", e);
+ }
+ finally
+ {
+ // safely close connection
+ if (jdbcConn != null)
+ {
+ try
+ {
+ jdbcConn.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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(JDBCWorkspaceDataContainer jdbcDataContainer,
+ ValueStoragePluginProvider vsPlugin, InspectionLog inspectionLog) throws RepositoryException, IOException
+ {
+ final String valueRecordFormat = "ValueData[PROPERTY_ID=%s ORDER_NUM=%d STORAGE_DESC=%s]";
+
+ Connection connection = jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+ 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 PROPERTY_ID, ORDER_NUM, STORAGE_DESC from JCR_SVALUE where STORAGE_DESC is not null");
+
+ 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);
+
+ // don't acquire channel if it is already open
+ if (channel == null || !channel.getStorageId().equals(storageDesc))
+ {
+ try
+ {
+ if (channel != null)
+ {
+ channel.close();
+ }
+ channel = vsPlugin.getChannel(storageDesc);
+ }
+ catch (ValueStorageNotFoundException e)
+ {
+ inspectionLog.logBrokenObjectInfo("ValueStorage " + storageDesc + " not found. "
+ + String.format(valueRecordFormat, propertyId, orderNumber, storageDesc), e.getMessage(),
+ InspectionStatus.ERR);
+ continue;
+ }
+ }
+
+ try
+ {
+ // check value data
+ final ValueIOChannel vdChannel = channel;
+ SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws ValueDataNotFoundException, IOException
+ {
+ vdChannel.checkValueData(propertyId, orderNumber);
+ return null;
+ }
+ });
+ }
+ // process exception thrown by checkValueData
+ catch (PrivilegedActionException e)
+ {
+ Throwable ex = e.getCause();
+ if (ex instanceof ValueDataNotFoundException)
+ {
+ inspectionLog.logBrokenObjectInfo(String.format(valueRecordFormat, propertyId, orderNumber,
+ storageDesc)
+ + " not found.", ex.getMessage(), InspectionStatus.ERR);
+ }
+ else if (ex instanceof IOException)
+ {
+ inspectionLog.logException(ex.getMessage(), (IOException)ex);
+ }
+ else
+ {
+ throw new RepositoryException(ex.getMessage(), ex);
+ }
+ }
+ }
+ while (resultSet.next());
+ }
+ }
+ catch (SQLException e)
+ {
+ // log unexpceted exception
+ inspectionLog.logException("Exception during ValueStorage inspection.", e);
+ }
+ finally
+ {
+ // safely free resources
+ 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);
+ }
+ }
+
+ if (connection != null)
+ {
+ try
+ {
+ connection.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/value/fs/FileIOChannel.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.storage.value.fs;
import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.storage.value.ValueDataNotFoundException;
import org.exoplatform.services.jcr.impl.storage.value.ValueDataResourceHolder;
import org.exoplatform.services.jcr.impl.storage.value.ValueOperation;
import org.exoplatform.services.jcr.impl.storage.value.fs.operations.DeleteValues;
@@ -30,7 +31,9 @@
import org.exoplatform.services.log.Log;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@@ -166,6 +169,48 @@
}
/**
+ * {@inheritDoc}
+ */
+ public void checkValueData(String propertyId, int orderNumber) throws ValueDataNotFoundException, IOException
+ {
+ try
+ {
+ //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)
+ {
+ }
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new ValueDataNotFoundException("Value data of property [id=" + propertyId + ", ordernum=" + orderNumber
+ + "] can not be read.");
+
+ }
+ }
+
+ /**
* Makes storage file path by propertyId and order number.<br/>
*
* @param propertyId
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/value/ValueIOChannel.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.storage.value;
import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.storage.value.ValueDataNotFoundException;
import java.io.IOException;
@@ -46,6 +47,16 @@
ValueData read(String propertyId, int orderNumber, int maxBufferSize) throws IOException;
/**
+ * Check ValueData. Check that value storage contain this value and value is readable.
+ *
+ * @param propertyId - Property ID
+ * @param orderNumber - Property order number
+ * @throws ValueDataNotFoundException thrown if value data not exist or can not be read
+ * @throws IOException
+ */
+ void checkValueData(String propertyId, int orderNumber) throws ValueDataNotFoundException, IOException;
+
+ /**
* Add or update Property value.
*
* @param propertyId
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java 2011-10-18 13:35:56 UTC (rev 5066)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/SlowQueryHandler.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -17,7 +17,9 @@
package org.exoplatform.services.jcr.api.core.query.lucene;
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.InspectionLog;
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;
@@ -123,4 +125,14 @@
// TODO Auto-generated method stub
}
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#checkIndex(org.exoplatform.services.jcr.dataflow.ItemDataConsumer, boolean, InspectionLog)
+ */
+ @Override
+ public void checkIndex(ItemDataConsumer itemStateManager, boolean isSystem, InspectionLog inspectionLog) throws RepositoryException,
+ IOException
+ {
+ // do nothing
+ }
}
Added: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,122 @@
+/*
+ * 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 junit.framework.TestCase;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.services.jcr.impl.InspectionLog.InspectionStatus;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 11 ����. 2011 skarpenko $
+ *
+ */
+public class TestInspectionLogFile extends TestCase
+{
+
+ private File f;
+
+ private Writer writer;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ f = File.createTempFile("testlog", "suf");
+ writer = new OutputStreamWriter(PrivilegedFileHelper.fileOutputStream(f));
+ }
+
+ public void tearDown() throws Exception
+ {
+ writer.close();
+ f.delete();
+ super.tearDown();
+ }
+
+ public void testLogComment() throws Exception
+ {
+ InspectionLog report = new InspectionLogWriter(writer);
+ report.logComment("test message");
+
+ // read file;
+ Reader reader = new FileReader(f);
+ BufferedReader br = new BufferedReader(reader);
+ String s = br.readLine();
+ br.close();
+ assertEquals("//test message", s);
+ assertFalse(report.hasInconsistency());
+ }
+
+ public void testLogInspectionDescription() throws Exception
+ {
+ InspectionLog report = new InspectionLogWriter(writer);
+ report.logInspectionDescription("description");
+
+ // read file;
+ Reader reader = new FileReader(f);
+ BufferedReader br = new BufferedReader(reader);
+ String s = br.readLine();
+ br.close();
+ assertEquals("//description", s);
+ assertFalse(report.hasInconsistency());
+ }
+
+ public void testLogBrokenObjectInfo() throws Exception
+ {
+ InspectionLog report = new InspectionLogWriter(writer);
+ report.logBrokenObjectInfo("broken object descr", "message", InspectionStatus.REINDEX);
+
+ // read file;
+ Reader reader = new FileReader(f);
+ BufferedReader br = new BufferedReader(reader);
+ String s = br.readLine();
+ br.close();
+
+ assertEquals("Reindex broken object descr message", s);
+ assertTrue(report.hasInconsistency());
+ }
+
+ public void testLogException() throws Exception
+ {
+ Exception e = new Exception("Exception message.");
+
+ InspectionLog report = new InspectionLogWriter(writer);
+ report.logException("message", e);
+
+ // read file;
+ Reader reader = new FileReader(f);
+ BufferedReader br = new BufferedReader(reader);
+ String s = br.readLine();
+ assertEquals("//message", s);
+ s = br.readLine();
+ assertEquals("//" + e.getMessage(), s);
+ s = br.readLine();
+ assertEquals("//" + e.toString(), s);
+ br.close();
+ assertTrue(report.hasInconsistency());
+ }
+
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestInspectionLogFile.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java 2011-10-19 07:55:25 UTC (rev 5067)
@@ -0,0 +1,119 @@
+/*
+ * 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.services.jcr.BaseStandaloneTest;
+import org.exoplatform.services.jcr.impl.RepositoryCheckController.DataStorage;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.jcr.Node;
+
+/**
+ * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 10.10.2011 skarpenko $
+ *
+ */
+public class TestRepositoryCheckController extends BaseStandaloneTest
+{
+
+ private RepositoryCheckController checkController;
+
+ /**
+ * @see org.exoplatform.services.jcr.BaseStandaloneTest#getRepositoryName()
+ */
+ @Override
+ protected String getRepositoryName()
+ {
+ String repName = System.getProperty("test.repository");
+ if (repName == null)
+ {
+ throw new RuntimeException(
+ "Test repository is undefined. Set test.repository system property "
+ + "(For maven: in project.properties: maven.junit.sysproperties=test.repository\ntest.repository=<rep-name>)");
+ }
+ return repName;
+
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ checkController = new RepositoryCheckController(repositoryService.getRepository("db1"));
+ }
+
+ public void tearDown() throws Exception
+ {
+ File f = checkController.getLastLogFile();
+ if (f != null)
+ {
+ f.delete();
+ }
+ super.tearDown();
+ }
+
+ public void testDB()
+ {
+ String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB});
+ System.out.println("\n\n\n\n\n\n"+result+"\n\n\n\n\n\n");
+ assertEquals("Repository data is consistent. See full report by path "
+ + checkController.getLastLogFile().getAbsolutePath(), result);
+ }
+
+ public void testValueStorage() throws Exception
+ {
+ File f = this.createBLOBTempFile(20);
+ InputStream is = new FileInputStream(f);
+ try
+ {
+ Node n = root.addNode("node");
+ n.setProperty("prop", is);
+
+ root.save();
+
+ String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.VALUE_STORAGE});
+ assertEquals("Repository data is consistent. See full report by path "
+ + checkController.getLastLogFile().getAbsolutePath(), result);
+ }
+ finally
+ {
+ is.close();
+ f.delete();
+ }
+ }
+
+ public void testSearchIndex()
+ {
+ String result = checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.LUCENE_INDEX});
+ assertEquals("Repository data is consistent. See full report by path "
+ + checkController.getLastLogFile().getAbsolutePath(), result);
+ }
+
+ public void testAll()
+ {
+ String result =
+ checkController.checkRepositoryDataConsistency(new DataStorage[]{DataStorage.DB, DataStorage.VALUE_STORAGE,
+ DataStorage.LUCENE_INDEX});
+ System.out.println("\n\n\n\n\n\n"+result+"\n\n\n\n\n\n");
+ assertEquals("Repository data is consistent. See full report by path "
+ + checkController.getLastLogFile().getAbsolutePath(), result);
+ }
+}
Property changes on: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
14 years, 6 months