exo-jcr SVN: r728 - jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2009-11-17 11:35:30 -0500 (Tue, 17 Nov 2009)
New Revision: 728
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration-replication.xml
Log:
test configuration updated
Modified: jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration-replication.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration-replication.xml 2009-11-17 16:35:30 UTC (rev 727)
+++ jcr/trunk/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration-replication.xml 2009-11-17 16:35:30 UTC (rev 728)
@@ -186,7 +186,7 @@
<value-param>
<name>conf-path</name>
<description>JCR configuration file</description>
- <value>file:src/test/java/conf/standalone/test-jcr-ext-config-replication.xml</value>
+ <value>file:src/test/resources/conf/standalone/test-jcr-ext-config-replication.xml</value>
</value-param>
</init-params>
</component>
16 years, 8 months
exo-jcr SVN: r727 - jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2009-11-17 11:35:30 -0500 (Tue, 17 Nov 2009)
New Revision: 727
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
Log:
EXOJCR-203: JDBC loader exists()
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java 2009-11-17 16:24:46 UTC (rev 726)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java 2009-11-17 16:35:30 UTC (rev 727)
@@ -131,7 +131,7 @@
cache.startBatch();
this.nodes = cacheRoot.addChild(Fqn.fromElements(JBossCacheStorage.NODES));
this.properties = cacheRoot.addChild(Fqn.fromElements(JBossCacheStorage.PROPS));
- this.session = cacheRoot.addChild(Fqn.fromElements(JBossCacheStorage.SESSION));
+ this.session = cacheRoot.addChild(Fqn.fromElements(JBossCacheStorage.SESSION)); // TODO remove it
this.locks = cacheRoot.addChild(Fqn.fromElements(JBossCacheStorage.LOCKS));
cache.endBatch(true);
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java 2009-11-17 16:24:46 UTC (rev 726)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java 2009-11-17 16:35:30 UTC (rev 727)
@@ -18,25 +18,13 @@
*/
package org.exoplatform.services.jcr.impl.storage.jbosscache;
-import java.sql.SQLException;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.RepositoryException;
-
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.datamodel.IllegalNameException;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.log.ExoLogger;
@@ -49,6 +37,15 @@
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.loader.AbstractCacheLoader;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS.
*
@@ -270,7 +267,7 @@
Map<Object, Object> attrs;
- WorkspaceStorageConnection conn = dataContainer.openConnection();
+ JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
try
{
@@ -393,8 +390,15 @@
*/
public boolean exists(Fqn name) throws Exception
{
- // TODO Will be created specialization code to checking exist node or property in DB without getting NodeData or PropertyData from DB.
- return get(name) != null;
+ // TODO Will be created specialization code to checking exist node or property in DB without getting NodeData or PropertyData from DB.
+ try
+ {
+ return get(name) != null;
+ }
+ catch (JDBCCacheLoaderException e)
+ {
+ return false;
+ }
}
/**
@@ -409,7 +413,7 @@
// /$NODES/<NODE_ID>
if (name.size() == 2)
{
- WorkspaceStorageConnection conn = dataContainer.openConnection();
+ JDBCStorageConnection conn = (JDBCStorageConnection) dataContainer.openConnection();
try
{
String nodeId = (String)name.get(1);
@@ -455,7 +459,9 @@
childs.add(JBossCacheStorage.NODES);
childs.add(JBossCacheStorage.PROPS);
childs.add(JBossCacheStorage.LOCKS);
- } else {
+ }
+ else
+ {
childs = null;
}
16 years, 8 months
exo-jcr SVN: r726 - jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2009-11-17 11:24:46 -0500 (Tue, 17 Nov 2009)
New Revision: 726
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java
Log:
EXOJCR-249 : The JDBCStorageConnection, SQLExceptionHandler was changed.
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2009-11-17 16:20:15 UTC (rev 725)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2009-11-17 16:24:46 UTC (rev 726)
@@ -1937,7 +1937,7 @@
{
if (LOG.isDebugEnabled())
LOG.error("Node remove. Database error: " + e, e);
- exceptionHandler.handleDeleteException(e, identifier, true, "");
+ exceptionHandler.handleDeleteException(e, identifier, true);
}
}
@@ -1991,7 +1991,7 @@
{
if (LOG.isDebugEnabled())
LOG.error("Property remove. Database error: " + e, e);
- exceptionHandler.handleDeleteException(e, identifier, true, "");
+ exceptionHandler.handleDeleteException(e, identifier, true);
}
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java 2009-11-17 16:20:15 UTC (rev 725)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java 2009-11-17 16:24:46 UTC (rev 726)
@@ -338,21 +338,20 @@
*
* @param e
* - an SQLException
- * @param item
- * - context ItemData
+ * @param itemId
+ * - identifier of ItemData
* @return String with error message
* @throws RepositoryException
* if <code>RepositoryException</code> should be thrown
* @throws InvalidItemStateException
* if <code>InvalidItemStateException</code> should be thrown
*/
- protected String handleDeleteException(SQLException e, String itemId, boolean isNode, String path ) throws RepositoryException,
+ protected String handleDeleteException(SQLException e, String itemId, boolean isNode) throws RepositoryException,
InvalidItemStateException
{
String message = "[" + containerName + "] DELETE " + (isNode ? "NODE. " : "PROPERTY. ");
String errMessage = e.getMessage();
- String itemInfo =
- path + " " + itemId
+ String itemInfo = "ID = " + itemId
+ (errMessage != null ? ". Cause >>>> " + errMessage : "");
if (errMessage != null)
16 years, 8 months
exo-jcr SVN: r725 - jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/dataflow.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2009-11-17 11:20:15 -0500 (Tue, 17 Nov 2009)
New Revision: 725
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/dataflow/LockPlainChangesLogImpl.java
Log:
EXOJCR-242: LockPlainChangesLog updated. (minor fix)
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/dataflow/LockPlainChangesLogImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/dataflow/LockPlainChangesLogImpl.java 2009-11-17 16:18:57 UTC (rev 724)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/dataflow/LockPlainChangesLogImpl.java 2009-11-17 16:20:15 UTC (rev 725)
@@ -20,7 +20,7 @@
import org.exoplatform.services.jcr.impl.core.lock.LockData;
-import java.util.ArrayList;
+import java.util.List;
/**
* This plain changes log is used to pass lock information through DataManager down to
@@ -39,9 +39,9 @@
* @param id
* @param lock
*/
- public LockPlainChangesLogImpl(ArrayList<ItemState> arrayList, String id, int lock)
+ public LockPlainChangesLogImpl(List<ItemState> items, String sessionId, int eventType)
{
- super(arrayList, id, lock);
+ super(items, sessionId, eventType);
}
public LockData getLockData()
16 years, 8 months
exo-jcr SVN: r724 - jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2009-11-17 11:18:57 -0500 (Tue, 17 Nov 2009)
New Revision: 724
Modified:
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCStorageConnectionTest.java
Log:
EXOJCR-203: test fix
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCStorageConnectionTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCStorageConnectionTest.java 2009-11-17 16:18:15 UTC (rev 723)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCStorageConnectionTest.java 2009-11-17 16:18:57 UTC (rev 724)
@@ -18,12 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.storage;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.access.AccessControlEntry;
import org.exoplatform.services.jcr.access.PermissionType;
@@ -43,9 +37,15 @@
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
-import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS Author : Peter Nedonosko peter.nedonosko(a)exoplatform.com.ua
* 30.01.2008
@@ -274,7 +274,7 @@
PropertyData primaryTypeData = propertysData.get(0);
- WorkspaceStorageConnection connection = dataContainer.openConnection();
+ JDBCStorageConnection connection = (JDBCStorageConnection) dataContainer.openConnection();
connection.deleteProperty(primaryTypeData.getIdentifier());
connection.deleteNode(testRoot.getIdentifier());
16 years, 8 months
exo-jcr SVN: r723 - in jcr/branches/1.12.0-JBC/component/core/src: main/java/org/exoplatform/services/jcr/impl and 5 other directories.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2009-11-17 11:18:15 -0500 (Tue, 17 Nov 2009)
New Revision: 723
Added:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
Removed:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
Log:
EXOJCR-243: Initial implementation of new lock manager: Created class: SessionLockManager, updated NodeImpl and SessionImpl to use it, reworked LockData and LockImpl. Removed LockCacheLoaders and it's tests, old LockManager and LockRemover*. Needed to implement: Lock removing on session logout, lock removing by time out. Fill JBossCacheWorkspaceDataManager with functionality.
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/core/lock/ExtendedLock.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.jcr.core.lock;
+import org.exoplatform.services.jcr.impl.core.lock.LockData;
+
import javax.jcr.lock.Lock;
/**
@@ -31,4 +33,9 @@
* @return The time to death in sec
*/
public long getTimeToDeath();
+
+ /**
+ * @return LockData instance
+ */
+ public LockData getLockData();
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -40,7 +40,6 @@
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.core.WorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.access.DefaultAccessManagerImpl;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeDataManagerImpl;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
import org.exoplatform.services.jcr.impl.core.nodetype.registration.JcrNodeTypeDataPersister;
@@ -259,23 +258,6 @@
workspaceContainer.registerComponentImplementation(LocalWorkspaceDataManagerStub.class);
workspaceContainer.registerComponentImplementation(ObservationManagerRegistry.class);
- // Lock manager and Lock persister is a optional parameters
- if (wsConfig.getLockManager() != null && wsConfig.getLockManager().getPersister() != null)
- {
- try
- {
- Class<?> lockPersister = Class.forName(wsConfig.getLockManager().getPersister().getType());
- workspaceContainer.registerComponentImplementation(lockPersister);
- }
- catch (ClassNotFoundException e)
- {
- throw new RepositoryConfigurationException("Class not found for workspace lock persister "
- + wsConfig.getLockManager().getPersister().getType() + ", container " + wsConfig.getUniqueName()
- + " : " + e);
- }
- }
- workspaceContainer.registerComponentImplementation(LockManagerImpl.class);
-
// Query handler
if (wsConfig.getQueryHandler() != null)
{
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -29,6 +29,7 @@
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.core.nodetype.PropertyDefinitionData;
import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.LockPlainChangesLogImpl;
import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
import org.exoplatform.services.jcr.datamodel.Identifier;
@@ -895,7 +896,7 @@
checkValid();
- LockImpl lock = session.getLockManager().getLock(this);
+ LockImpl lock = session.getLockManager().getLock((NodeData)this.getData());
if (lock == null)
throw new LockException("Lock not found " + getPath());
return lock;
@@ -1279,7 +1280,6 @@
*/
public boolean isLocked() throws RepositoryException
{
-
checkValid();
return session.getLockManager().isLocked((NodeData)this.getData());
}
@@ -1359,7 +1359,7 @@
public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException,
LockException, AccessDeniedException, RepositoryException
{
-
+ // checks
checkValid();
if (!isNodeType(Constants.MIX_LOCKABLE))
@@ -1368,25 +1368,14 @@
if (dataManager.hasPendingChanges(getInternalPath()))
throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
- Lock newLock = session.getLockManager().addPendingLock(this, isDeep, isSessionScoped, -1);
+ if (session.getLockManager().isLocked((NodeData)this.getData()))
+ {
+ throw new LockException("Node is already locked itself or due to deep lock of parent, ");
+ }
+ Lock lock = session.getLockManager().lock((NodeData)data, isDeep, isSessionScoped, -1);
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
-
- PropertyData propData =
- TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
- new TransientValueData(session.getUserID()));
- changesLog.add(ItemState.createAddedState(propData));
-
- propData =
- TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
- new TransientValueData(isDeep));
- changesLog.add(ItemState.createAddedState(propData));
-
- dataManager.getTransactManager().save(changesLog);
-
session.getActionHandler().postLock(this);
- return newLock;
+ return lock;
}
@@ -1396,6 +1385,7 @@
public Lock lock(boolean isDeep, long timeOut) throws UnsupportedRepositoryOperationException, LockException,
AccessDeniedException, RepositoryException
{
+ // checks
checkValid();
if (!isNodeType(Constants.MIX_LOCKABLE))
@@ -1404,25 +1394,15 @@
if (dataManager.hasPendingChanges(getInternalPath()))
throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
- Lock newLock = session.getLockManager().addPendingLock(this, isDeep, false, timeOut);
+ if (session.getLockManager().isLocked((NodeData)this.getData()))
+ {
+ throw new LockException("Node is already locked itself or due to deep lock of parent, ");
+ }
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+ Lock lock = session.getLockManager().lock((NodeData)data, isDeep, false, timeOut);
- PropertyData propData =
- TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
- new TransientValueData(session.getUserID()));
- changesLog.add(ItemState.createAddedState(propData));
-
- propData =
- TransientPropertyData.createPropertyData(nodeData(), Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
- new TransientValueData(isDeep));
- changesLog.add(ItemState.createAddedState(propData));
-
- dataManager.getTransactManager().save(changesLog);
-
session.getActionHandler().postLock(this);
- return newLock;
+ return lock;
}
@@ -2023,13 +2003,13 @@
if (!session.getLockManager().holdsLock((NodeData)this.getData()))
throw new LockException("The node not locked " + getPath());
- if (!session.getLockManager().isLockHolder(this))
+ if (!session.getLockManager().isLockHolder((NodeData)this.getData()))
throw new LockException("There are no permission to unlock the node " + getPath());
if (dataManager.hasPendingChanges(getInternalPath()))
throw new InvalidItemStateException("Node has pending unsaved changes " + getPath());
- doUnlock();
+ session.getLockManager().unlock((NodeData)data);
session.getActionHandler().postUnlock(this);
}
@@ -2167,8 +2147,8 @@
boolean checkLocking() throws RepositoryException
{
- return (!isLocked() || session.getLockManager().isLockHolder(this) || session.getUserID().equals(
- SystemIdentity.SYSTEM));
+ return (!isLocked() || session.getLockManager().isLockHolder((NodeData)this.getData()) || session.getUserID()
+ .equals(SystemIdentity.SYSTEM));
}
protected void doOrderBefore(QPath srcPath, QPath destPath) throws RepositoryException
@@ -2330,28 +2310,6 @@
dataManager.getChangesLog().addAll(changes);
}
- /**
- * Remove mix:lockable properties.
- *
- * @throws RepositoryException if error occurs
- */
- protected void doUnlock() throws RepositoryException
- {
-
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.UNLOCK);
-
- ItemData lockOwner = dataManager.getItemData(nodeData(), new QPathEntry(Constants.JCR_LOCKOWNER, 0));
-
- changesLog.add(ItemState.createDeletedState(lockOwner));
-
- ItemData lockIsDeep = dataManager.getItemData(nodeData(), new QPathEntry(Constants.JCR_LOCKISDEEP, 0));
-
- changesLog.add(ItemState.createDeletedState(lockIsDeep));
-
- dataManager.getTransactManager().save(changesLog);
- }
-
protected NodeData nodeData()
{
return (NodeData)data;
@@ -2372,11 +2330,11 @@
{
// locked, should be unlocked
- if (!session.getLockManager().isLockHolder(this))
+ if (!session.getLockManager().isLockHolder((NodeData)this.getData()))
throw new LockException("There are no permission to unlock the node " + getPath());
// remove mix:lockable properties (as the node is locked)
- doUnlock();
+ session.getLockManager().unlock((NodeData)data);
}
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -31,7 +31,7 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeImpl;
import org.exoplatform.services.jcr.impl.core.observation.ObservationManagerImpl;
import org.exoplatform.services.jcr.impl.core.observation.ObservationManagerRegistry;
@@ -118,7 +118,7 @@
private final LocationFactory systemLocationFactory;
- private final LockManagerImpl lockManager;
+ private final SessionLockManager sessionLockManager;
protected final String workspaceName;
@@ -152,7 +152,6 @@
this.systemLocationFactory = (LocationFactory)container.getComponentInstanceOfType(LocationFactory.class);
this.accessManager = (AccessManager)container.getComponentInstanceOfType(AccessManager.class);
- this.lockManager = (LockManagerImpl)container.getComponentInstanceOfType(LockManagerImpl.class);
WorkspaceEntry wsConfig = (WorkspaceEntry)container.getComponentInstanceOfType(WorkspaceEntry.class);
WorkspaceFileCleanerHolder cleanerHolder =
(WorkspaceFileCleanerHolder)container.getComponentInstanceOfType(WorkspaceFileCleanerHolder.class);
@@ -177,9 +176,12 @@
this.workspace = new WorkspaceImpl(workspaceName, container, this, observationManager);
+ // TODO: try to get lock time out from workspace configuration, as it was before
+ this.sessionLockManager = new SessionLockManager(this, SessionLockManager.DEFAULT_LOCK_TIMEOUT);
+
this.lifecycleListeners = new ArrayList<SessionLifecycleListener>();
this.registerLifecycleListener((ObservationManagerImpl)observationManager);
- this.registerLifecycleListener(lockManager);
+ this.registerLifecycleListener(sessionLockManager);
SessionActionCatalog catalog =
(SessionActionCatalog)container.getComponentInstanceOfType(SessionActionCatalog.class);
@@ -197,7 +199,7 @@
*/
public void addLockToken(String lt)
{
- getLockManager().addLockToken(getId(), lt);
+ sessionLockManager.addLockToken(lt);
}
/**
@@ -543,9 +545,9 @@
return locationFactory;
}
- public LockManagerImpl getLockManager()
+ public SessionLockManager getLockManager()
{
- return lockManager;
+ return sessionLockManager;
}
/**
@@ -553,7 +555,7 @@
*/
public String[] getLockTokens()
{
- return getLockManager().getLockTokens(getId());
+ return sessionLockManager.getLockTokens();
}
/**
@@ -901,7 +903,7 @@
*/
public void removeLockToken(String lt)
{
- getLockManager().removeLockToken(getId(), lt);
+ sessionLockManager.removeLockToken(lt);
}
/**
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockData.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -18,11 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.core.lock;
-import org.exoplatform.services.jcr.access.SystemIdentity;
-
-import java.util.HashSet;
-import java.util.Set;
-
/**
* Created by The eXo Platform SAS.
*
@@ -49,15 +44,10 @@
private boolean live;
/**
- * List of session id's which holds a lock tokens.
- */
- private final Set<String> lockHolders = new HashSet<String>();
-
- /**
* A lock token is a string that uniquely identifies a particular lock and acts as a “key”
- * allowing a user to alter a locked node.
+ * allowing a user to alter a locked node. LockData stores only token hash.
*/
- private String lockToken;
+ private String tokenHash;
/**
* Identifier of locked node.
@@ -95,7 +85,7 @@
long timeOut)
{
this.nodeIdentifier = nodeIdentifier;
- this.lockToken = lockToken;
+ this.tokenHash = lockToken;
this.deep = deep;
this.sessionScoped = sessionScoped;
this.owner = owner;
@@ -104,15 +94,6 @@
this.birthday = System.currentTimeMillis() / 1000;
}
- /**
- * @param sessionId
- * @return
- */
- public boolean addLockHolder(String sessionId)
- {
- return lockHolders.add(sessionId);
- }
-
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
@@ -131,20 +112,11 @@
return false;
}
- public int getLockHolderSize()
+ public String getTokenHash()
{
- return lockHolders.size();
+ return tokenHash;
}
- public String getLockToken(String sessionId)
- {
- if (isLockHolder(sessionId))
- {
- return lockToken;
- }
- return null;
- }
-
/**
* @return the nodeIdentifier
*/
@@ -176,7 +148,7 @@
@Override
public int hashCode()
{
- return super.hashCode() + lockToken.hashCode();
+ return super.hashCode() + tokenHash.hashCode();
}
public boolean isDeep()
@@ -193,17 +165,8 @@
}
/**
- * @param sessionId
* @return
*/
- public boolean isLockHolder(String sessionId)
- {
- return lockHolders.contains(sessionId) || SystemIdentity.SYSTEM.equals(sessionId);
- }
-
- /**
- * @return
- */
public boolean isSessionScoped()
{
return sessionScoped;
@@ -218,15 +181,6 @@
}
/**
- * @param sessionId
- * @return
- */
- public boolean removeLockHolder(String sessionId)
- {
- return lockHolders.remove(sessionId);
- }
-
- /**
* @param the
* live to set
*/
@@ -236,31 +190,6 @@
}
/**
- * @param lockToken
- */
- public void setLockToken(String lockToken)
- {
- this.lockToken = lockToken;
- }
-
- /**
- * @param nodeIdentifier
- * the nodeIdentifier to set
- */
- public void setNodeIdentifier(String nodeIdentifier)
- {
- this.nodeIdentifier = nodeIdentifier;
- }
-
- /**
- * @param owner
- */
- public void setOwner(String owner)
- {
- this.owner = owner;
- }
-
- /**
* @return
*/
protected long getTimeOut()
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -38,27 +38,47 @@
private SessionImpl session;
- public LockImpl(SessionImpl session, LockData lockData)
+ // Token is not stored in lockData any more
+ private String token;
+
+ /**
+ * @param session
+ * @param lockData
+ */
+ public LockImpl(SessionImpl session, LockData lockData, String token)
{
this.lockData = lockData;
this.session = session;
+ this.token = token;
}
+ /**
+ * @see javax.jcr.lock.Lock#getLockOwner()
+ */
public String getLockOwner()
{
return lockData.getOwner();
}
+ /**
+ * @see javax.jcr.lock.Lock#getLockToken()
+ */
public String getLockToken()
{
- return lockData.getLockToken(session.getId());
+ return token;
}
+ /**
+ * @see javax.jcr.lock.Lock#isLive()
+ */
public boolean isLive()
{
return lockData.isLive();
}
+ /**
+ * @see javax.jcr.lock.Lock#refresh()
+ */
public void refresh() throws LockException, RepositoryException
{
if (!isLive())
@@ -66,6 +86,9 @@
lockData.refresh();
}
+ /**
+ * @see javax.jcr.lock.Lock#getNode()
+ */
public Node getNode()
{
try
@@ -74,29 +97,49 @@
}
catch (RepositoryException e)
{
- e.printStackTrace();
}
return null;
}
+ /**
+ * @see javax.jcr.lock.Lock#isDeep()
+ */
public boolean isDeep()
{
return lockData.isDeep();
}
+ /**
+ * @see javax.jcr.lock.Lock#isSessionScoped()
+ */
public boolean isSessionScoped()
{
return lockData.isSessionScoped();
}
+ /**
+ * @see org.exoplatform.services.jcr.core.lock.ExtendedLock#getTimeToDeath()
+ */
public long getTimeToDeath()
{
return lockData.getTimeToDeath();
}
+ /**
+ * @see org.exoplatform.services.jcr.core.lock.ExtendedLock#getLockData()
+ */
+ public LockData getLockData()
+ {
+ return lockData;
+ }
+
+ /**
+ * @param timeOut
+ */
protected void setTimeOut(long timeOut)
{
lockData.setTimeOut(timeOut);
}
+
}
Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManager.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core.lock;
-
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.core.NodeImpl;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-
-/**
- * @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a>
- * @version $Id$
- */
-public interface LockManager
-{
- /**
- * Invoked by a session to inform that a lock token has been added.
- *
- * @param session
- * session that has a added lock token
- * @param lt
- * added lock token
- */
- public void addLockToken(String sessionId, String lt);
-
- public Lock addPendingLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut)
- throws LockException, RepositoryException;
-
- /**
- * Returns the Lock object that applies to a node. This may be either a lock on this node itself
- * or a deep lock on a node above this node.
- *
- * @param node
- * node
- * @return lock object
- * @throws LockException
- * if this node is not locked
- * @see javax.jcr.Node#getLock
- */
- public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException;
-
- /**
- * Return lock tokens enshrined by session
- *
- * @param sessionID
- * - Id of session.
- * @return array of lock tokens.
- */
- public String[] getLockTokens(String sessionID);
-
- /**
- * Returns <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>.
- *
- * @param node
- * node
- * @return <code>true</code> if the node given holds a lock; otherwise returns <code>false</code>
- * @see javax.jcr.Node#holdsLock
- */
- public boolean holdsLock(NodeData node) throws RepositoryException;
-
- /**
- * Returns <code>true</code> if this node is locked either as a result of a lock held by this node
- * or by a deep lock on a node above this node; otherwise returns <code>false</code>
- *
- * @param node
- * node
- * @return <code>true</code> if this node is locked either as a result of a lock held by this node
- * or by a deep lock on a node above this node; otherwise returns <code>false</code>
- * @see javax.jcr.Node#isLocked
- */
- public boolean isLocked(NodeData node);
-
- /**
- * Returns <code>true</code> if the specified session holds a lock on the given node; otherwise
- * returns <code>false</code>. <p/> Note that <code>isLockHolder(session, node)==true</code>
- * implies <code>holdsLock(node)==true</code>.
- *
- * @param session
- * session
- * @param node
- * node
- * @return if the specified session holds a lock on the given node; otherwise returns
- * <code>false</code>
- */
- public boolean isLockHolder(NodeImpl node) throws RepositoryException;
-
- /**
- * Invoked by a session to inform that a lock token has been removed.
- *
- * @param session
- * session that has a removed lock token
- * @param lt
- * removed lock token
- */
- public void removeLockToken(String sessionId, String lt);
-
-}
Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockManagerImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core.lock;
-
-import org.exoplatform.management.annotations.Managed;
-import org.exoplatform.management.annotations.ManagedDescription;
-import org.exoplatform.management.jmx.annotations.NameTemplate;
-import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.access.SystemIdentity;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.core.ExtendedSession;
-import org.exoplatform.services.jcr.core.SessionLifecycleListener;
-import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
-import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
-import org.exoplatform.services.jcr.dataflow.DataManager;
-import org.exoplatform.services.jcr.dataflow.ItemState;
-import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
-import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
-import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.ItemData;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.datamodel.ValueData;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.NodeImpl;
-import org.exoplatform.services.jcr.impl.core.SessionImpl;
-import org.exoplatform.services.jcr.impl.dataflow.AbstractValueData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
-import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.exoplatform.services.jcr.observation.ExtendedEvent;
-import org.exoplatform.services.jcr.util.IdGenerator;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.jboss.cache.factories.annotations.NonVolatile;
-import org.picocontainer.Startable;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.AccessDeniedException;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
- * @version $Id$
- */
-@Managed
-@NameTemplate(@Property(key = "service", value = "lockmanager"))
-@NonVolatile
-public class LockManagerImpl implements ItemsPersistenceListener, SessionLifecycleListener, LockManager, Startable
-{
- /**
- * Default lock time out. 30min
- */
- public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
-
- // Search constants
- /**
- * The exact lock token.
- */
- private static final int SEARCH_EXECMATCH = 1;
-
- /**
- * Lock token of closed parent
- */
- private static final int SEARCH_CLOSEDPARENT = 2;
-
- /**
- * Lock token of closed child
- */
- private static final int SEARCH_CLOSEDCHILD = 4;
-
- /**
- * Logger
- */
- private final Log log = ExoLogger.getLogger("jcr.lock.LockManager");
-
- /**
- * Map NodeIdentifier -- lockData
- *
- * TODO: changed from private to protected
- */
- protected final Map<String, LockData> locks;
-
- /**
- * Data manager.
- */
- private final DataManager dataManager;
-
- /**
- * Map NodeIdentifier -- lockData
- *
- * TODO: changed from private to protected
- */
- protected final Map<String, LockData> pendingLocks;
-
- /**
- * Map lockToken --lockData
- */
- private final Map<String, LockData> tokensMap;
-
- /**
- * Run time lock time out.
- */
- private long lockTimeOut;
-
- /**
- * Lock remover thread.
- */
- private LockRemover lockRemover;
-
- /**
- * Lock persister instance.
- */
- private final LockPersister persister;
-
- /**
- * Constructor for workspace without LockPersister
- *
- * @param dataManager
- * @param config
- */
- public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config)
- {
- this(dataManager, config, null);
- }
-
- public LockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config, LockPersister persister)
- {
-
- this.dataManager = dataManager;
- this.persister = persister;
- if (config.getLockManager() != null)
- {
- lockTimeOut =
- config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
- }
- else
- lockTimeOut = DEFAULT_LOCK_TIMEOUT;
-
- locks = new HashMap<String, LockData>();
- pendingLocks = new HashMap<String, LockData>();
- tokensMap = new HashMap<String, LockData>();
-
- dataManager.addItemPersistenceListener(this);
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#lockTokenAdded(org.exoplatform.services
- * .jcr.impl.core.SessionImpl, java.lang.String)
- */
- public synchronized void addLockToken(String sessionId, String lt)
- {
- LockData currLock = tokensMap.get(lt);
- if (currLock != null)
- {
- currLock.addLockHolder(sessionId);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#addPendingLock(org.exoplatform.services
- * .jcr.impl.core.NodeImpl, boolean, boolean, long)
- */
- public synchronized Lock addPendingLock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeOut)
- throws LockException
- {
- LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
- if (lData != null)
- {
- if (lData.getNodeIdentifier().equals(node.getInternalIdentifier()))
- {
- throw new LockException("Node already locked: " + node.getData().getQPath());
- }
- else if (lData.isDeep())
- {
- throw new LockException("Parent node has deep lock.");
- }
- }
-
- if (isDeep && getLockData((NodeData)node.getData(), SEARCH_CLOSEDCHILD) != null)
- {
- throw new LockException("Some child node is locked.");
- }
-
- String lockToken = IdGenerator.generate();
- lData =
- new LockData(node.getInternalIdentifier(), lockToken, isDeep, isSessionScoped, node.getSession().getUserID(),
- timeOut > 0 ? timeOut : lockTimeOut);
-
- lData.addLockHolder(node.getSession().getId());
- pendingLocks.put(node.getInternalIdentifier(), lData);
- tokensMap.put(lockToken, lData);
-
- LockImpl lock = new LockImpl(node.getSession(), lData);
- return lock;
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#getLock(org.exoplatform.services.jcr
- * .impl.core.NodeImpl)
- */
- public LockImpl getLock(NodeImpl node) throws LockException, RepositoryException
- {
-
- LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
- if (lData == null || (!node.getInternalIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
- {
- throw new LockException("Node not locked: " + node.getData().getQPath());
-
- }
- return new LockImpl(node.getSession(), lData);
- }
-
- /*
- * (non-Javadoc)
- * @see org.exoplatform.services.jcr.impl.core.lock.LockManager#getLockTokens(java.lang.String)
- */
- public synchronized String[] getLockTokens(String sessionID)
- {
- List<String> retval = new ArrayList<String>();
-
- for (LockData lockData : locks.values())
- {
- if (lockData.isLockHolder(sessionID))
- retval.add(lockData.getLockToken(sessionID));
-
- }
- return retval.toArray(new String[retval.size()]);
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#holdsLock(org.exoplatform.services.
- * jcr.impl.core.NodeImpl)
- */
- public boolean holdsLock(NodeData node) throws RepositoryException
- {
- return getLockData(node, SEARCH_EXECMATCH) != null;
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#isLocked(org.exoplatform.services.jcr
- * .datamodel.NodeData)
- */
- public boolean isLocked(NodeData node)
- {
- LockData lData = getLockData(node, SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
- if (lData == null || (!node.getIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
- {
- return false;
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#isLockHolder(org.exoplatform.services
- * .jcr.impl.core.NodeImpl)
- */
- public boolean isLockHolder(NodeImpl node) throws RepositoryException
- {
- LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
- return lData != null && lData.isLockHolder(node.getSession().getId());
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.core.SessionLifecycleListener#onCloseSession(org.exoplatform.services
- * .jcr.core.ExtendedSession)
- */
- public synchronized void onCloseSession(ExtendedSession session)
- {
- // List<String> deadLocksList = new ArrayList<String>();
- SessionImpl sessionImpl = (SessionImpl)session;
- for (Iterator<Map.Entry<String, LockData>> entries = locks.entrySet().iterator(); entries.hasNext();)
- {
- Map.Entry<String, LockData> entry = entries.next();
- LockData lockData = entry.getValue();
- if (lockData.isLive())
- {
- if (lockData.isLockHolder(session.getId()))
- {
- if (lockData.isSessionScoped())
- {
- // if no session currently holds lock except this
- try
- {
- // TODO it's possible to have next error
- // java.lang.NullPointerException
- // at
- // org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl.onCloseSession(LockManagerImpl.java:312)
- // at org.exoplatform.services.jcr.impl.core.SessionImpl.logout(SessionImpl.java:794)
- // at
- // org.exoplatform.services.jcr.impl.core.XASessionImpl.logout(XASessionImpl.java:254)
- // at
- // org.exoplatform.services.jcr.impl.core.SessionRegistry$SessionCleaner.callPeriodically(SessionRegistry.java:165)
- // at
- // org.exoplatform.services.jcr.impl.proccess.WorkerThread.run(WorkerThread.java:46)
- ((NodeImpl)sessionImpl.getTransientNodesManager().getItemByIdentifier(
- lockData.getNodeIdentifier(), false)).unlock();
- }
- catch (UnsupportedRepositoryOperationException e)
- {
- log.error(e.getLocalizedMessage());
- }
- catch (LockException e)
- {
- log.error(e.getLocalizedMessage());
- }
- catch (AccessDeniedException e)
- {
- log.error(e.getLocalizedMessage());
- }
- catch (RepositoryException e)
- {
- log.error(e.getLocalizedMessage());
- }
-
- }
- else
- {
- lockData.removeLockHolder(session.getId());
- }
- }
- }
- else
- {
- entries.remove();
- }
- }
- }
-
- /*
- * (non-Javadoc)
- * @seeorg.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener#onSaveItems(org.
- * exoplatform.services.jcr.dataflow.ItemStateChangesLog)
- */
- @Deprecated
- public void onSaveItems(ItemStateChangesLog changesLog)
- {
- List<PlainChangesLog> chengesLogList = new ArrayList<PlainChangesLog>();
- if (changesLog instanceof TransactionChangesLog)
- {
- ChangesLogIterator logIterator = ((TransactionChangesLog)changesLog).getLogIterator();
-
- while (logIterator.hasNextLog())
- {
- chengesLogList.add(logIterator.nextLog());
- }
- }
- else if (changesLog instanceof PlainChangesLog)
- {
- chengesLogList.add((PlainChangesLog)changesLog);
- }
- else if (changesLog instanceof CompositeChangesLog)
- {
- for (ChangesLogIterator iter = ((CompositeChangesLog)changesLog).getLogIterator(); iter.hasNextLog();)
- {
- chengesLogList.add(iter.nextLog());
- }
- }
-
- for (PlainChangesLog currChangesLog : chengesLogList)
- {
- String nodeIdentifier;
- try
- {
- switch (currChangesLog.getEventType())
- {
- case ExtendedEvent.LOCK :
- if (currChangesLog.getSize() < 2)
- {
- log.error("Incorrect changes log of type ExtendedEvent.LOCK size=" + currChangesLog.getSize()
- + "<2 \n" + currChangesLog.dump());
- break;
- }
- nodeIdentifier = currChangesLog.getAllStates().get(0).getData().getParentIdentifier();
-
- if (pendingLocks.containsKey(nodeIdentifier))
- {
- internalLock(nodeIdentifier);
- }
- else
- {
- log.warn("No lock in pendingLocks for identifier " + nodeIdentifier
- + " Probably lock come from replication.");
-
- String lockToken = IdGenerator.generate();
- ItemState ownerState = getItemState(currChangesLog, Constants.JCR_LOCKOWNER);
- ItemState isDeepState = getItemState(currChangesLog, Constants.JCR_LOCKISDEEP);
- if (ownerState != null && isDeepState != null)
- {
-
- String owner =
- new String(((((TransientPropertyData)(ownerState.getData())).getValues()).get(0))
- .getAsByteArray(), Constants.DEFAULT_ENCODING);
-
- boolean isDeep =
- Boolean.valueOf(
- new String(((((TransientPropertyData)(isDeepState.getData())).getValues()).get(0))
- .getAsByteArray(), Constants.DEFAULT_ENCODING)).booleanValue();
-
- createRemoteLock(currChangesLog.getSessionId(), nodeIdentifier, lockToken, isDeep, false, owner);
- }
- }
- break;
- case ExtendedEvent.UNLOCK :
- if (currChangesLog.getSize() < 2)
- {
- log.error("Incorrect changes log of type ExtendedEvent.UNLOCK size=" + currChangesLog.getSize()
- + "<2 \n" + currChangesLog.dump());
- break;
- }
-
- internalUnLock(currChangesLog.getSessionId(), currChangesLog.getAllStates().get(0).getData()
- .getParentIdentifier());
- break;
- default :
- HashSet<String> removedLock = new HashSet<String>();
- for (ItemState itemState : currChangesLog.getAllStates())
- {
- // this is a node and node is locked
- if (itemState.getData().isNode() && locks.containsKey(itemState.getData().getIdentifier()))
- {
- nodeIdentifier = itemState.getData().getIdentifier();
- if (itemState.isDeleted())
- {
- removedLock.add(nodeIdentifier);
- }
- else if (itemState.isAdded() || itemState.isRenamed() || itemState.isUpdated())
- {
- removedLock.remove(nodeIdentifier);
- }
- }
- }
- for (String identifier : removedLock)
- {
- internalUnLock(currChangesLog.getSessionId(), identifier);
- }
- break;
- }
- }
- catch (LockException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (UnsupportedEncodingException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (IllegalStateException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (IOException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- }
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#lockTokenRemoved(org.exoplatform.services
- * .jcr.impl.core.SessionImpl, java.lang.String)
- */
- public synchronized void removeLockToken(String sessionId, String lt)
- {
- LockData lData = tokensMap.get(lt);
- if (lData != null && lData.isLockHolder(sessionId))
- {
- lData.removeLockHolder(sessionId);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#start()
- */
- public void start()
- {
- lockRemover = new LockRemover(this);
- }
-
- // Quick method. We need to reconstruct
- synchronized List<LockData> getLockList()
- {
- return new ArrayList<LockData>(locks.values());
- }
-
- /**
- * Remove expired locks. Used from LockRemover.
- */
- synchronized void removeExpired()
- {
- final List<String> removeLockList = new ArrayList<String>();
-
- for (LockData lock : locks.values())
- {
- if (!lock.isSessionScoped() && lock.getTimeToDeath() < 0)
- {
- removeLockList.add(lock.getNodeIdentifier());
- }
- }
-
- for (String rLock : removeLockList)
- {
- removeLock(rLock);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#stop()
- */
- public void stop()
- {
- lockRemover.halt();
- lockRemover.interrupt();
- locks.clear();
- pendingLocks.clear();
- tokensMap.clear();
- }
-
- /**
- * Copy <code>PropertyData prop<code> to new TransientItemData
- *
- * @param prop
- * @return
- * @throws RepositoryException
- */
- private TransientItemData copyItemData(PropertyData prop) throws RepositoryException
- {
-
- if (prop == null)
- return null;
-
- // make a copy
- TransientPropertyData newData =
- new TransientPropertyData(prop.getQPath(), prop.getIdentifier(), prop.getPersistedVersion(), prop.getType(),
- prop.getParentIdentifier(), prop.isMultiValued());
-
- List<ValueData> values = null;
- // null is possible for deleting items
- if (prop.getValues() != null)
- {
- values = new ArrayList<ValueData>();
- for (ValueData val : prop.getValues())
- {
- values.add(((AbstractValueData)val).createTransientCopy());
- }
- }
- newData.setValues(values);
- return newData;
- }
-
- /**
- * Search item with name <code>itemName<code> in changesLog
- *
- * @param changesLog
- * @param itemName
- * @return Item
- */
- private ItemState getItemState(PlainChangesLog changesLog, InternalQName itemName)
- {
- List<ItemState> allStates = changesLog.getAllStates();
- for (int i = allStates.size() - 1; i >= 0; i--)
- {
- ItemState state = allStates.get(i);
- if (state.getData().getQPath().getName().equals(itemName))
- return state;
- }
- return null;
- }
-
- /**
- * Search lock in maps.
- *
- * @param data
- * @param searchType
- * @return
- */
- private LockData getLockData(NodeData data, int searchType)
- {
- if (data == null || locks.size() == 0)
- return null;
- LockData retval = null;
- try
- {
- if ((searchType & SEARCH_EXECMATCH) != 0)
- {
- retval = locks.get(data.getIdentifier());
- }
- if (retval == null && (searchType & SEARCH_CLOSEDPARENT) != 0)
- {
-
- NodeData parentData = (NodeData)dataManager.getItemData(data.getParentIdentifier());
- if (parentData != null)
- {
- retval = locks.get(parentData.getIdentifier());
- // parent not found try to fo upper
- if (retval == null)
- {
- retval = getLockData(parentData, SEARCH_CLOSEDPARENT);
- }
- }
- }
- if (retval == null && (searchType & SEARCH_CLOSEDCHILD) != 0)
- {
-
- List<NodeData> childData = dataManager.getChildNodesData(data);
- for (NodeData nodeData : childData)
- {
- retval = locks.get(nodeData.getIdentifier());
- if (retval != null)
- break;
- }
- if (retval == null)
- {
- // child not found try to find diper
- for (NodeData nodeData : childData)
- {
- retval = getLockData(nodeData, SEARCH_CLOSEDCHILD);
- if (retval != null)
- break;
- }
- }
- }
- }
- catch (RepositoryException e)
- {
- return null;
- }
-
- return retval;
- }
-
- /**
- * Internal lock
- *
- * @param nodeIdentifier
- * @throws LockException
- *
- * TODO: Changed from private to public. Need for LockCacheLoader.
- */
- public synchronized void internalLock(String nodeIdentifier) throws LockException
- {
- LockData ldata = pendingLocks.get(nodeIdentifier);
- if (ldata != null)
- {
- locks.put(nodeIdentifier, ldata);
-
- if (persister != null)
- {
- persister.add(ldata);
- }
- pendingLocks.remove(nodeIdentifier);
- }
- else
- {
- throw new LockException("No lock in pending locks");
- }
- }
-
- /**
- * Internal unlock.
- *
- * @param sessionId
- * @param nodeIdentifier
- * @throws LockException
- *
- * TODO: Changed from private to public. Need for LockCacheLoader.
- */
- public synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
- {
- LockData lData = locks.get(nodeIdentifier);
-
- if (lData != null)
- {
- tokensMap.remove(lData.getLockToken(sessionId));
- locks.remove(nodeIdentifier);
-
- lData.setLive(false);
- if (persister != null)
- {
- persister.remove(lData);
- }
- lData = null;
- }
- }
-
- /**
- * For locks comes from remote JCRs (replication usecase)
- *
- * @param sessionId
- * String
- * @param nodeIdentifier
- * String
- * @param lockToken
- * String
- * @param isDeep
- * boolean
- * @param sessionScoped
- * boolean
- * @param owner
- * String
- * @return LockData
- *
- * TODO: Changed from private to public. Need for LockCacheLoader.
- */
- public synchronized LockData createRemoteLock(String sessionId, String nodeIdentifier, String lockToken,
- boolean isDeep, boolean sessionScoped, String owner)
- {
- LockData lData = new LockData(nodeIdentifier, lockToken, isDeep, sessionScoped, owner, lockTimeOut);
- lData.addLockHolder(sessionId);
- locks.put(nodeIdentifier, lData);
- tokensMap.put(lockToken, lData);
-
- return lData;
- }
-
- /**
- * Remove lock, used by Lock remover.
- *
- * @param nodeIdentifier String
- */
- protected void removeLock(String nodeIdentifier)
- {
- try
- {
- NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), SystemIdentity.SYSTEM, ExtendedEvent.UNLOCK);
-
- ItemData lockOwner =
- copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
-
- changesLog.add(ItemState.createDeletedState(lockOwner));
-
- ItemData lockIsDeep =
- copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKISDEEP, 1)));
- changesLog.add(ItemState.createDeletedState(lockIsDeep));
-
- // lock probably removed by other thread
- if (lockOwner == null && lockIsDeep == null)
- return;
- dataManager.save(new TransactionChangesLog(changesLog));
- }
- catch (RepositoryException e)
- {
- log.error("Error occur during removing lock" + e.getLocalizedMessage());
- }
- }
-
- @Managed
- @ManagedDescription("The number of active locks")
- public int getNumLocks()
- {
- return locks.size();
- }
-
- @Managed
- @ManagedDescription("Remove the expired locks")
- public void cleanExpiredLocks()
- {
- removeExpired();
- }
-
- /**
- * TODO: Added. Need for LockCacheLoader..
- */
- public boolean hasPendingLocks(String nodeIdentifier)
- {
- return pendingLocks.containsKey(nodeIdentifier);
- }
-
- /**
- * TODO: Added. Need for LockCacheLoader..
- */
- public boolean hasLockNode(String nodeIdentifier)
- {
- return locks.containsKey(nodeIdentifier);
- }
-}
Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemover.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core.lock;
-
-import org.exoplatform.services.jcr.impl.proccess.WorkerThread;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a>
- * @version $Id$
- */
-public class LockRemover extends WorkerThread
-{
-
- private final Log log = ExoLogger.getLogger("jcr.lock.LockRemover");
-
- public static final long DEFAULT_THREAD_TIMEOUT = 30000; // 30
-
- // sec
-
- private final LockManagerImpl lockManagerImpl;
-
- public LockRemover(LockManagerImpl lockManagerImpl)
- {
- this(lockManagerImpl, DEFAULT_THREAD_TIMEOUT);
- }
-
- private LockRemover(LockManagerImpl lockManagerImpl, long timeout)
- {
- super(timeout);
- this.lockManagerImpl = lockManagerImpl;
- setName("LockRemover " + getId());
- setPriority(Thread.MIN_PRIORITY);
- setDaemon(true);
- start();
- if (log.isDebugEnabled())
- log.debug("LockRemover instantiated name= " + getName() + " timeout= " + timeout);
- }
-
- @Override
- protected void callPeriodically() throws Exception
- {
- lockManagerImpl.removeExpired();
- }
-}
Added: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java (rev 0)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.lock;
+
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.core.ExtendedSession;
+import org.exoplatform.services.jcr.core.SessionLifecycleListener;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.LockPlainChangesLogImpl;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.observation.ExtendedEvent;
+import org.exoplatform.services.jcr.util.IdGenerator;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+
+/**
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id$
+ *
+ */
+public class SessionLockManager implements SessionLifecycleListener
+{
+ /**
+ * Default lock time out. 30min
+ */
+ public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
+
+ /**
+ * Search lockData for given node
+ */
+ private static final int SEARCH_EXACMATCH = 1;
+
+ /**
+ * Search lockData for parent's of given node
+ */
+ private static final int SEARCH_PARENT = 2;
+
+ /**
+ * Search lockData for children of given node
+ */
+ private static final int SEARCH_CHILD = 4;
+
+ /**
+ * Session through which this lock manager is created
+ */
+ private final SessionImpl session;
+
+ protected final Log log = ExoLogger.getLogger(this.getClass().getName());
+
+ /**
+ * Holds session's tokens and their hashes to avoid calculation every time.
+ * Token <--> Hash
+ */
+ private Map<String, String> tokens;
+
+ /**
+ * Holds session's tokens and their hashes to avoid calculation every time.
+ * Hash <--> Token
+ * Added to speed up operations
+ */
+ private Map<String, String> tokenHash;
+
+ /**
+ * Configured lock timeout
+ */
+ private long lockTimeOut;
+
+ /**
+ * @param session
+ * @param lockTimeOut
+ */
+ public SessionLockManager(SessionImpl session, long lockTimeOut)
+ {
+ this.session = session;
+ this.lockTimeOut = lockTimeOut;
+ // TODO: configured lock timeout should be acquired from WSconfig
+ /* if (config.getLockManager() != null)
+ {
+ lockTimeOut =
+ config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
+ }
+ else
+ lockTimeOut = DEFAULT_LOCK_TIMEOUT;*/
+ }
+
+ /**
+ * Adds token to current session
+ * @param token
+ */
+ public void addLockToken(String token)
+ {
+ String hash = getHash(token);
+ tokens.put(token, hash);
+ tokenHash.put(hash, token);
+ }
+
+ /**
+ * Removes token from current session
+ * @param token
+ */
+ public void removeLockToken(String token)
+ {
+ String hash = getHash(token);
+ tokens.remove(token);
+ tokenHash.remove(hash);
+ }
+
+ /**
+ * Tries to get Lock for node. Is node is not a lockholder, then parent with deep lock is looked for.
+ *
+ * @param node
+ * @return
+ * @throws LockException
+ * @throws RepositoryException
+ */
+ public LockImpl getLock(NodeData node) throws LockException, RepositoryException
+ {
+ LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+
+ if (lockData == null || (!node.getIdentifier().equals(lockData.getNodeIdentifier()) && !lockData.isDeep()))
+ {
+ throw new LockException("Node not locked: " + node.getQPath());
+ }
+ // if session doesn't have token, null will be returned
+ return new LockImpl(session, lockData, tokenHash.get(lockData.getTokenHash()));
+ }
+
+ /**
+ * Returns the list of token that current session owns.
+ * @return
+ */
+ public String[] getLockTokens()
+ {
+ return tokens.keySet().toArray(new String[tokens.size()]);
+ }
+
+ /**
+ * Checks if node actually has a lock.
+ *
+ * @param node
+ * @return
+ * @throws RepositoryException
+ */
+ public boolean holdsLock(NodeData node) throws RepositoryException
+ {
+ return getLockData(node, SEARCH_EXACMATCH) != null;
+ }
+
+ /**
+ * Checks if current session has a token (access) for this node.
+ *
+ * @param node
+ * @return
+ * @throws RepositoryException
+ */
+ public boolean isLockHolder(NodeData node) throws RepositoryException
+ {
+ LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+ return lockData != null && isLockHolder(lockData);
+ }
+
+ /**
+ * Checks if node is locked, or it's any parent has a deep lock.
+ *
+ * @param node
+ * @return
+ */
+ public boolean isLocked(NodeData node)
+ {
+ LockData lockData = getLockData(node, SEARCH_EXACMATCH | SEARCH_PARENT);
+
+ if (lockData == null || (!node.getIdentifier().equals(lockData.getNodeIdentifier()) && !lockData.isDeep()))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Actually locks the node, adding jcr:lockOwner and jcr:lockIsDeep properties to node and adds lock token
+ * to current session.
+ *
+ * @param node
+ * @param isDeep
+ * @param isSessionScoped
+ * @param timeOut
+ * @return
+ * @throws LockException
+ * @throws RepositoryException
+ */
+ public LockImpl lock(NodeData node, boolean isDeep, boolean isSessionScoped, long timeOut) throws LockException,
+ RepositoryException
+ {
+ // check child node is not locked
+ if (isDeep && getLockData(node, SEARCH_CHILD) != null)
+ {
+ throw new LockException("Can't place deep lock: some child node is locked.");
+ }
+
+ String token = IdGenerator.generate();
+ String hash = getHash(token);
+
+ LockData lockData =
+ new LockData(node.getIdentifier(), hash, isDeep, isSessionScoped, session.getUserID(), timeOut > 0 ? timeOut
+ : lockTimeOut);
+
+ tokens.put(token, hash);
+ tokenHash.put(hash, token);
+
+ // Create and pass changes log
+ LockPlainChangesLogImpl changesLog =
+ new LockPlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.LOCK);
+
+ changesLog.setLockData(lockData);
+
+ PropertyData propData =
+ TransientPropertyData.createPropertyData(node, Constants.JCR_LOCKOWNER, PropertyType.STRING, false,
+ new TransientValueData(session.getUserID()));
+ changesLog.add(ItemState.createAddedState(propData));
+
+ propData =
+ TransientPropertyData.createPropertyData(node, Constants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false,
+ new TransientValueData(isDeep));
+ changesLog.add(ItemState.createAddedState(propData));
+
+ LockImpl newLock = new LockImpl(session, lockData, token);
+
+ session.getTransientNodesManager().getTransactManager().save(changesLog);
+ return newLock;
+ }
+
+ /**
+ * Actually unlock the node also removing jcr:lockOwner and jcr:lockIsDeep properties
+ *
+ * @param node
+ * @throws RepositoryException
+ */
+ public void unlock(NodeData node) throws RepositoryException
+ {
+ PlainChangesLog changesLog =
+ new PlainChangesLogImpl(new ArrayList<ItemState>(), session.getId(), ExtendedEvent.UNLOCK);
+
+ ItemData lockOwner =
+ session.getTransientNodesManager().getItemData(node, new QPathEntry(Constants.JCR_LOCKOWNER, 0));
+
+ changesLog.add(ItemState.createDeletedState(lockOwner));
+
+ ItemData lockIsDeep =
+ session.getTransientNodesManager().getItemData(node, new QPathEntry(Constants.JCR_LOCKISDEEP, 0));
+
+ changesLog.add(ItemState.createDeletedState(lockIsDeep));
+
+ session.getTransientNodesManager().getTransactManager().save(changesLog);
+ }
+
+ /**
+ * Calculates md5 hash of string.
+ *
+ * @param token
+ * @return
+ */
+ private String getHash(String token)
+ {
+ String hash = "";
+ try
+ {
+ MessageDigest m = MessageDigest.getInstance("MD5");
+ m.update(token.getBytes(), 0, token.length());
+ hash = new BigInteger(1, m.digest()).toString(16);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ log.error("Can't get instanse of MD5 MessageDigest!", e);
+ }
+ return hash;
+ }
+
+ /**
+ * Search lock with given search options:
+ * * for only given node
+ * * for any upper parent of given node
+ * * for any deeper child of given node
+ *
+ * @param data
+ * @param searchType
+ * @return
+ */
+ private LockData getLockData(NodeData data, int searchType)
+ {
+ if (data == null)
+ return null;
+ LockData retval = null;
+ try
+ {
+ if ((searchType & SEARCH_EXACMATCH) != 0)
+ {
+ retval = session.getTransientNodesManager().getLockData(data.getIdentifier());
+ }
+ if (retval == null && (searchType & SEARCH_PARENT) != 0)
+ {
+
+ NodeData parentData = (NodeData)session.getTransientNodesManager().getItemData(data.getParentIdentifier());
+ if (parentData != null)
+ {
+ retval = session.getTransientNodesManager().getLockData(parentData.getIdentifier());
+ // parent not found try to find upper
+ if (retval == null)
+ {
+ retval = getLockData(parentData, SEARCH_PARENT);
+ }
+ }
+ }
+ if (retval == null && (searchType & SEARCH_CHILD) != 0)
+ {
+
+ List<NodeData> childData = session.getTransientNodesManager().getChildNodesData(data);
+ for (NodeData nodeData : childData)
+ {
+ retval = session.getTransientNodesManager().getLockData(nodeData.getIdentifier());
+ if (retval != null)
+ break;
+ }
+ if (retval == null)
+ {
+ // child not found try to find deeper
+ for (NodeData nodeData : childData)
+ {
+ retval = getLockData(nodeData, SEARCH_CHILD);
+ if (retval != null)
+ break;
+ }
+ }
+ }
+ }
+ catch (RepositoryException e)
+ {
+ return null;
+ }
+
+ return retval;
+ }
+
+ /**
+ * Checks if session has token to this lock data or session is System.
+ *
+ * @param lockData
+ * @return
+ */
+ private boolean isLockHolder(LockData lockData)
+ {
+ return (SystemIdentity.SYSTEM.equals(session.getId()) || tokenHash.get(lockData.getTokenHash()) != null);
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.core.SessionLifecycleListener#onCloseSession(org.exoplatform.services.jcr.core.ExtendedSession)
+ */
+ public void onCloseSession(ExtendedSession session)
+ {
+ // TODO: remove session scoped locks
+ }
+
+}
Property changes on: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/SessionLockManager.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoader.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2003-2009 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.services.jcr.impl.storage.jbosscache;
-
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
-import org.exoplatform.services.jcr.util.IdGenerator;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Modification;
-import org.jboss.cache.Modification.ModificationType;
-import org.jboss.cache.factories.annotations.Inject;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id$
- */
-public class LockCacheLoader extends AbstractWriteOnlyCacheLoader
-{
-
- /**
- * Lock manager.
- */
- private LockManagerImpl lockManager;
-
- /**
- * Logger.
- */
- private final Log log = ExoLogger.getLogger("jcr.LockCacheLoader");
-
- /**
- * Injection dependencies.
- *
- * @param lockManager LockManagerImpl
- */
- @Inject
- public void injectDependencies(LockManagerImpl lockManager) throws RepositoryConfigurationException
- {
- if (this.lockManager != null)
- {
- throw new RepositoryConfigurationException("Cannot set LockManagerImpl twice");
- }
-
- this.lockManager = lockManager;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void put(List<Modification> modifications) throws Exception
- {
- String sessionId = null;
- HashSet<String> removedLock = new HashSet<String>();
- List<Modification> lockChanges = new ArrayList<Modification>();
-
- for (Modification m : modifications)
- {
- if (m.getFqn().get(0).equals(JBossCacheStorage.SESSION))
- {
- switch (m.getType())
- {
- case PUT_DATA_ERASE :
- break;
- case PUT_DATA :
- break;
- case PUT_KEY_VALUE :
- // begin new changes log
- if (m.getKey().equals(JBossCacheStorage.SESSION_ID))
- {
- sessionId = (String)m.getValue();
- }
- break;
- case REMOVE_DATA :
- // end changes log
- if (lockChanges.size() == 2)
- {
- if (lockChanges.get(0).getType() == ModificationType.PUT_KEY_VALUE
- && lockChanges.get(1).getType() == ModificationType.PUT_KEY_VALUE)
- {
- performLock(lockChanges, sessionId);
- }
- else if (lockChanges.get(0).getType() == ModificationType.REMOVE_KEY_VALUE
- && lockChanges.get(1).getType() == ModificationType.REMOVE_KEY_VALUE)
- {
- performUnLock(lockChanges, (String)lockChanges.get(0).getFqn().get(1), sessionId);
- }
- else
- {
- log.error("Incorrect changes log contains lock and unlock operation simultaneously");
- }
- }
- else if (lockChanges.size() != 0)
- {
- log.error("Incorrect changes log size for lock or unlock operation");
- }
-
- for (String identifier : removedLock)
- {
- lockManager.internalUnLock(identifier, sessionId);
- }
-
- lockChanges = new ArrayList<Modification>();
- removedLock = new HashSet<String>();
- sessionId = null;
- break;
- case REMOVE_KEY_VALUE :
- break;
- case REMOVE_NODE :
- break;
- case MOVE :
- break;
- default :
- throw new CacheException("Unknown modification " + m.getType());
- }
- }
- else if (m.getFqn().get(0).equals(JBossCacheStorage.PROPS))
- {
- switch (m.getType())
- {
- case PUT_DATA_ERASE :
- break;
- case PUT_DATA :
- break;
- case PUT_KEY_VALUE :
- // lock operation
- if (m.getKey().equals(JBossCacheStorage.ITEM_DATA))
- {
- InternalQName propName = ((PropertyData)m.getValue()).getQPath().getName();
- if (propName.equals(Constants.JCR_LOCKISDEEP) || propName.equals(Constants.JCR_LOCKOWNER))
- {
- lockChanges.add(m);
- }
- }
- break;
- case REMOVE_DATA :
- break;
- case REMOVE_KEY_VALUE :
- break;
- case REMOVE_NODE :
- break;
- case MOVE :
- break;
- default :
- throw new CacheException("Unknown modification " + m.getType());
- }
- }
- else if (m.getFqn().get(0).equals(JBossCacheStorage.NODES))
- {
- switch (m.getType())
- {
- case PUT_DATA_ERASE :
- break;
- case PUT_DATA :
- if (m.getFqn().size() == 2)
- {
- String nodeIdentifier = (String)m.getFqn().get(1);
- if (lockManager.hasLockNode(nodeIdentifier))
- {
- removedLock.remove(nodeIdentifier);
- }
- }
- break;
- case PUT_KEY_VALUE :
- break;
- case REMOVE_DATA :
- break;
- case REMOVE_KEY_VALUE :
- // unLock operation
- if (m.getKey().equals(Constants.JCR_LOCKISDEEP.getAsString())
- || m.getKey().equals(Constants.JCR_LOCKOWNER.getAsString()))
- {
- lockChanges.add(m);
- }
- break;
- case REMOVE_NODE :
- if (m.getFqn().size() == 2)
- {
- String nodeIdentifier = (String)m.getFqn().get(1);
- if (lockManager.hasLockNode(nodeIdentifier))
- {
- removedLock.add(nodeIdentifier);
- }
- }
- break;
- case MOVE :
- if (m.getFqn().size() == 2)
- {
- String nodeIdentifier = (String)m.getFqn().get(1);
- if (lockManager.hasLockNode(nodeIdentifier))
- {
- removedLock.remove(nodeIdentifier);
- }
- }
- break;
- default :
- throw new CacheException("Unknown modification " + m.getType());
- }
- }
- }
- }
-
- /**
- * Perform lock operation.
- *
- * @param lockChanges
- * @throws LockException
- */
- private void performLock(List<Modification> lockChanges, String sessionId)
- {
- String nodeIdentifier = ((PropertyData)lockChanges.get(0).getValue()).getParentIdentifier();
-
- try
- {
- if (lockManager.hasPendingLocks(nodeIdentifier))
- {
- log.info("Perform lock operation nodeIdentifier=" + nodeIdentifier);
- lockManager.internalLock(nodeIdentifier);
- }
- else
- {
- log.warn("No lock in pendingLocks for identifier " + nodeIdentifier
- + " Probably lock come from replication.");
-
- String lockToken = IdGenerator.generate();
- Modification ownerModification = getModification(lockChanges, Constants.JCR_LOCKOWNER);
- Modification isDeepModification = getModification(lockChanges, Constants.JCR_LOCKISDEEP);
-
- if (ownerModification != null && isDeepModification != null)
- {
-
- String owner =
- new String(((((TransientPropertyData)(ownerModification.getValue())).getValues()).get(0))
- .getAsByteArray(), Constants.DEFAULT_ENCODING);
-
- boolean isDeep =
- Boolean.valueOf(
- new String(((((TransientPropertyData)(isDeepModification.getValue())).getValues()).get(0))
- .getAsByteArray(), Constants.DEFAULT_ENCODING)).booleanValue();
-
- lockManager.createRemoteLock(sessionId, nodeIdentifier, lockToken, isDeep, false, owner);
- }
- }
- }
- catch (LockException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (UnsupportedEncodingException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (IllegalStateException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (IOException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- }
-
- private void performUnLock(List<Modification> lockChanges, String nodeIdentifier, String sessionId)
- {
- try
- {
- log.info("Perform unlock operation nodeIdentifier=" + nodeIdentifier + " sessionId=" + sessionId);
- lockManager.internalUnLock(nodeIdentifier, sessionId);
- }
- catch (LockException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- }
-
- /**
- * Search item with name <code>itemName<code> in modification list
- *
- * @param changes
- * @param itemName
- * @return Item
- */
- private Modification getModification(List<Modification> changes, InternalQName itemName)
- {
- for (Modification m : changes)
- {
- if (((PropertyData)changes.get(0).getValue()).getQPath().getName().equals(itemName))
- return m;
- }
- return null;
- }
-
-}
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/core/lock/TestLockImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -32,11 +32,10 @@
{
private ExtendedNode lockedNode = null;
- private LockManagerImpl service;
-
private static final long LOCK_TIMEOUT = 5; // sec
- private static final long LOCK_REMOVER_WAIT = LockRemover.DEFAULT_THREAD_TIMEOUT + (LOCK_TIMEOUT + 1) * 1000; // 15
+ //private static final long LOCK_REMOVER_WAIT = LockRemover.DEFAULT_THREAD_TIMEOUT + (LOCK_TIMEOUT + 1) * 1000; // 15
+ private static final long LOCK_REMOVER_WAIT = (LOCK_TIMEOUT + 30) * 1000; //
// sec
@@ -45,8 +44,6 @@
super.setUp();
- service = (LockManagerImpl)container.getComponentInstanceOfType(LockManagerImpl.class);
-
if (lockedNode == null)
try
{
Deleted: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/LockCacheLoaderTest.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2003-2009 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.services.jcr.impl.storage.jbosscache;
-
-import org.exoplatform.services.idgenerator.impl.IDGeneratorServiceImpl;
-import org.exoplatform.services.jcr.config.ContainerEntry;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.SimpleParameterEntry;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.datamodel.QPath;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.lock.LockData;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
-import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.storage.value.StandaloneStoragePluginProvider;
-import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-import org.exoplatform.services.jcr.util.IdGenerator;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Modification;
-import org.jboss.cache.Node;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.PropertyType;
-import javax.naming.Context;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id$
- */
-public class LockCacheLoaderTest extends AbstractCacheLoaderTest
-{
-
- private TesterLockManagerImpl lockManager;
-
- private LockCacheLoader lockCacheLoader;
-
- private final QPath testRoot = QPath.makeChildPath(Constants.ROOT_PATH, new InternalQName("", "testRoot"));
-
- public void setUp() throws Exception
- {
- super.setUp();
-
- lockManager = new TesterLockManagerImpl();
- lockCacheLoader = new LockCacheLoader();
- lockCacheLoader.injectDependencies(lockManager);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void tearDown() throws Exception
- {
-
- super.tearDown();
- }
-
- public void testLock() throws Exception
- {
- List<Modification> modifications = new ArrayList<Modification>();
- String nodeIdentifier = "node1";
- String sessionId = "session1";
-
- TransientPropertyData lockIsDeepData =
- new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKISDEEP), "prop1", 1,
- PropertyType.BOOLEAN, nodeIdentifier, false);
- TransientValueData lockIsDeepValue = new TransientValueData(false);
- lockIsDeepData.setValue(lockIsDeepValue);
-
- TransientPropertyData lockOwnerData =
- new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKOWNER), "prop2", 1,
- PropertyType.BOOLEAN, nodeIdentifier, false);
- TransientValueData lockOwner = new TransientValueData("__system");
- lockOwnerData.setValue(lockOwner);
-
- lockManager.addPendingLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
- modifications.addAll(addSessionInfo(sessionId, "userId"));
- modifications.addAll(addProperty(lockIsDeepData));
- modifications.addAll(addProperty(lockOwnerData));
- modifications.addAll(removeSessionInfo());
- lockCacheLoader.put(modifications);
-
- assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
- }
-
- public void testUnLock() throws Exception
- {
- List<Modification> modifications = new ArrayList<Modification>();
- String nodeIdentifier = "node1";
- String sessionId = "session1";
-
- TransientPropertyData lockIsDeepData =
- new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKISDEEP), "prop1", 1,
- PropertyType.BOOLEAN, nodeIdentifier, false);
- TransientValueData lockIsDeepValue = new TransientValueData(false);
- lockIsDeepData.setValue(lockIsDeepValue);
-
- TransientPropertyData lockOwnerData =
- new TransientPropertyData(QPath.makeChildPath(testRoot, Constants.JCR_LOCKOWNER), "prop2", 1,
- PropertyType.BOOLEAN, nodeIdentifier, false);
- TransientValueData lockOwner = new TransientValueData("__system");
- lockOwnerData.setValue(lockOwner);
-
- modifications.addAll(addSessionInfo(sessionId, "userId"));
- modifications.addAll(removeProperty(lockIsDeepData));
- modifications.addAll(removeProperty(lockOwnerData));
- modifications.addAll(removeSessionInfo());
- lockCacheLoader.put(modifications);
-
- assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
- assertEquals(sessionId, lockManager.getSessionid());
- }
-
- public void testAddNodeLock() throws Exception
- {
- List<Modification> modifications = new ArrayList<Modification>();
- String nodeIdentifier = "node1";
- String sessionId = "session1";
-
- TransientNodeData node =
- new TransientNodeData(testRoot, nodeIdentifier, 0, null, null, 0, Constants.ROOT_UUID, null);
-
- lockManager.addLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
- modifications.addAll(addSessionInfo(sessionId, "userId"));
- modifications.addAll(addNode(node));
- modifications.addAll(removeSessionInfo());
- lockCacheLoader.put(modifications);
-
- assertNull(lockManager.getNodeIdentifier());
- assertNull(lockManager.getSessionid());
- }
-
- public void testRemoveNodeLock() throws Exception
- {
- List<Modification> modifications = new ArrayList<Modification>();
- String nodeIdentifier = "node1";
- String sessionId = "session1";
-
- TransientNodeData node =
- new TransientNodeData(testRoot, nodeIdentifier, 0, null, null, 0, Constants.ROOT_UUID, null);
-
- lockManager.addLock(nodeIdentifier, new LockData(nodeIdentifier, "token", false, false, "__system", -1));
-
- modifications.addAll(addSessionInfo(sessionId, "userId"));
- modifications.addAll(removeNode(node));
- modifications.addAll(removeSessionInfo());
- lockCacheLoader.put(modifications);
-
- assertEquals(nodeIdentifier, lockManager.getNodeIdentifier());
- assertEquals(sessionId, lockManager.getSessionid());
- }
-}
Deleted: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java 2009-11-17 16:14:29 UTC (rev 722)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/TesterLockManagerImpl.java 2009-11-17 16:18:15 UTC (rev 723)
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2003-2009 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.services.jcr.impl.storage.jbosscache;
-
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.lock.LockData;
-import org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl;
-import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.jboss.cache.factories.annotations.NonVolatile;
-
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * <br/>Date: 2009
- *
- * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id$
- */
-@NonVolatile
-public class TesterLockManagerImpl extends LockManagerImpl
-{
-
- private String nodeIdentifier = null;
-
- private String sessionId = null;
-
- public TesterLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config)
- {
- super(dataManager, config);
- }
-
- public TesterLockManagerImpl()
- {
- this(new TesterWorkspacePersistedDataManager(null, null), new TesterWorkspaceEntry());
- }
-
- /**
- * Internal lock
- */
- public synchronized void internalLock(String nodeIdentifier) throws LockException
- {
- if (this.nodeIdentifier != null)
- throw new LockException("NodeIdentifier already exist!");
-
- this.nodeIdentifier = nodeIdentifier;
- }
-
- /**
- * Internal lock
- */
- public synchronized void internalUnLock(String nodeIdentifier, String sessionId) throws LockException
- {
- if (this.nodeIdentifier != null)
- throw new LockException("NodeIdentifier already exist!");
-
- if (this.sessionId != null)
- throw new LockException("SessionId already exist!");
-
- this.nodeIdentifier = nodeIdentifier;
- this.sessionId = sessionId;
- }
-
- public String getNodeIdentifier()
- {
- return nodeIdentifier;
- }
-
- public String getSessionid()
- {
- return sessionId;
- }
-
- public void addPendingLock(String nodeIdentifier, LockData lData)
- {
- pendingLocks.put(nodeIdentifier, lData);
- }
-
- public void addLock(String nodeIdentifier, LockData lData)
- {
- locks.put(nodeIdentifier, lData);
- }
-}
16 years, 8 months
exo-jcr SVN: r722 - in jcr/branches/1.12.0-JBC/component/core/src: main/java/org/exoplatform/services/jcr/impl/storage/jbosscache and 3 other directories.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2009-11-17 11:14:29 -0500 (Tue, 17 Nov 2009)
New Revision: 722
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheTreeStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoaderTest.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/ObservationCacheLoaderTest.java
Log:
EXOJCR-203: JDBC loader get(Fqn), getChildrenNames(Fqn); WS connection rework
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/inmemory/InmemoryStorageConnection.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -276,24 +276,4 @@
return null;
}
- /**
- * {@inheritDoc}
- */
- public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -379,26 +379,6 @@
/**
* {@inheritDoc}
*/
- public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
public ItemData getItemData(String identifier) throws RepositoryException, IllegalStateException
{
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheTreeStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheTreeStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheTreeStorageConnection.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -436,24 +436,4 @@
throw new UnsupportedOperationException();
}
- /**
- * {@inheritDoc}
- */
- public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoader.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.storage.jbosscache;
+import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -25,14 +26,17 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import javax.jcr.InvalidItemStateException;
import javax.jcr.RepositoryException;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.datamodel.IllegalNameException;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.log.ExoLogger;
@@ -77,7 +81,7 @@
* @param dataContainer WorkspaceDataContainer
*/
@Inject
- public void injectDependencies(WorkspaceDataContainer dataContainer) throws RepositoryConfigurationException
+ public void init(WorkspaceDataContainer dataContainer) throws RepositoryConfigurationException
{
if (this.dataContainer != null)
{
@@ -96,11 +100,6 @@
*/
protected void apply(WorkspaceStorageConnection conn, List<Modification> modifications) throws RepositoryException
{
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Modifications list size = " + modifications.size());
- }
-
// Prepare modifications list.
// Will be added oldValueData to modification for UPDATE.
//prepareModifications(modifications);
@@ -153,10 +152,6 @@
LOG.debug("Modifications list size = " + modifications.size());
}
- // Prepare modifications list.
- // Will be added oldValueData to modification for UPDATE.
- //prepareModifications(modifications);
-
WorkspaceStorageConnection conn = dataContainer.openConnection();
try
{
@@ -165,12 +160,12 @@
}
catch (RepositoryException e)
{
- LOG.error("RepositoryException: ", e); // TODO cleanup
+ LOG.error("RepositoryException: ", e); // TODO don't catch
throw new RepositoryException(e);
}
catch (IllegalStateException e)
{
- LOG.error("IllegalStateException: ", e); // TODO cleanup
+ LOG.error("IllegalStateException: ", e); // TODO don't catch
throw new IllegalStateException(e);
}
finally
@@ -268,173 +263,129 @@
}
/**
- * Prepare list of modifications.
- *
- * Will be checked the UPDATE, ADD, REMOVE.
- *
- * @param modifications
- * @throws RepositoryException
- */
- @Deprecated
- private void prepareModifications(List<Modification> modifications) throws RepositoryException
- {
- WorkspaceStorageConnection conn = dataContainer.openConnection();
-
- try
- {
- for (int i = 0; i < modifications.size(); i++)
- {
- Modification m = modifications.get(i);
- if (m.getType() == ModificationType.PUT_KEY_VALUE)
- {
- ItemData itemData = null;
-
- //Check add or update node data.
- if (m.getValue() instanceof NodeData)
- {
- NodeData nodeData = (NodeData)m.getValue();
- itemData = conn.getItemData(nodeData.getIdentifier());
-
- // Set oldValueData for update node.
- if (itemData != null)
- modifications.get(i).setOldValue(itemData);
- }
- else if (m.getValue() instanceof PropertyData)
- {
- PropertyData propertyData = (PropertyData)m.getValue();
- itemData = conn.getItemData(propertyData.getIdentifier());
-
- // Set oldValueData for update property.
- if (itemData != null)
- modifications.get(i).setOldValue(itemData);
- }
- }
- else if (m.getType() == ModificationType.REMOVE_NODE)
- {
- if (m.getFqn().size() == 2
- && (m.getFqn().get(0).equals(JBossCacheStorage.NODES) || m.getFqn().get(0).equals(
- JBossCacheStorage.PROPS)))
- {
- String id = (String)m.getFqn().get(1);
- ItemData removedItemData = conn.getItemData(id);
-
- // Set valueData for update property or node.
- if (removedItemData != null)
- modifications.get(i).setValue(removedItemData);
- }
- }
- }
- }
- finally
- {
- conn.close();
- }
- }
-
- protected QPathEntry[] makeNodePath(Fqn<String> nodeFqn) throws NumberFormatException, IllegalNameException
- {
- List<String> elements = nodeFqn.peekElements();
- QPathEntry[] path = new QPathEntry[elements.size()];
-
- for (int i = 0; i < elements.size(); i++)
- {
- path[i] = QPathEntry.parse(elements.get(i));
- }
-
- return path;
- }
-
- /**
* {@inheritDoc}
*/
public Map<Object, Object> get(Fqn name) throws Exception
{
- Map<Object, Object> attrs = new LinkedHashMap<Object, Object>();
+ Map<Object, Object> attrs;
- if (name.size() > 1)
+ WorkspaceStorageConnection conn = dataContainer.openConnection();
+ try
{
- if (name.get(0).equals(JBossCacheStorage.NODES))
+
+ if (name.size() > 1)
{
- // /$NODES/<NODE_ID>
- if (name.size() == 2)
+ if (name.get(0).equals(JBossCacheStorage.NODES))
{
- // return NodeData [ITEM_DATA : NodeData]
- WorkspaceStorageConnection conn = dataContainer.openConnection();
-
- try
+ // /$NODES/<NODE_ID>
+ if (name.size() == 2)
{
- NodeData nodeData = (NodeData)conn.getItemData(name.getLastElementAsString());
-
+ String nodeId = name.getLastElementAsString();
+ NodeData nodeData = (NodeData)conn.getItemData(nodeId);
if (nodeData != null)
{
+ // TODO use dedicated select, not child datas
+ List<PropertyData> childProps = conn.getChildPropertiesData(nodeData);
+ if (childProps.size() <= 0)
+ {
+ throw new JDBCCacheLoaderException("FATAL Empty attributes for Node " + nodeId + " '" + name
+ + "'");
+ }
+
+ attrs = new LinkedHashMap<Object, Object>();
attrs.put(JBossCacheStorage.ITEM_DATA, nodeData);
-
- // put [PROPERTY_NAME : propertyData_ID]
- for (PropertyData prop : conn.getChildPropertiesData(nodeData))
+ for (PropertyData prop : childProps)
{
attrs.put(prop.getQPath().getName().getAsString(), prop.getIdentifier());
}
}
+ else
+ {
+ attrs = null;
+ }
}
- finally
+ // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
+ else if (name.size() == 3)
{
- conn.close();
- }
- }
- // /$NODES/<NODE_ID>/<SUB_NODE_NAME>
- else if (name.size() == 3)
- {
- QPathEntry nodeName = QPathEntry.parse(name.getLastElementAsString());
+ QPathEntry childNodeName = QPathEntry.parse(name.getLastElementAsString());
+ String parentId = (String)name.get(1);
- // return [ITEM_Id : nodeData_ID]
- WorkspaceStorageConnection conn = dataContainer.openConnection();
-
- try
- {
- NodeData parentNodeData = (NodeData)conn.getItemData((String)name.get(1));
-
- //TODO We do not throw exception if parentNodeData not exists in DB, because we use that method (get(Fqn name)) in exists(Fqn name).
- /*if (parentNodeData == null)
- throw new JDBCCacheLoaderException("The parent node with ID = " + (String)name.get(1) + " not exis, FQN = '" + name + "'.");*/
-
- if (parentNodeData != null)
+ // TODO use non-data method, check ACL creation
+ NodeData parentData = (NodeData)conn.getItemData(parentId);
+ if (parentData != null)
{
- NodeData nodeData = (NodeData)conn.getItemData(parentNodeData, nodeName);
+ NodeData nodeData = (NodeData)conn.getItemData(parentData, childNodeName);
if (nodeData != null)
+ {
+ attrs = new LinkedHashMap<Object, Object>();
attrs.put(JBossCacheStorage.ITEM_ID, nodeData.getIdentifier());
+ }
+ else
+ {
+ throw new JDBCCacheLoaderException("FATAL Child Node data not found "
+ + parentData.getQPath().getAsString() + childNodeName.getAsString(true) + " for '" + name
+ + "'");
+ }
}
+ else
+ {
+ throw new JDBCCacheLoaderException("FATAL Parent not found " + parentId + " for '" + name + "'");
+ }
}
- finally
+ else
{
- conn.close();
+ attrs = null;
+ LOG.warn("Unexpected Fqn asked " + name);
}
}
- }
- // /$PROPS/<PROPERTY_ID>
- else if (name.get(0).equals(JBossCacheStorage.PROPS))
- {
- if (name.size() == 2)
+ // /$PROPS/<PROPERTY_ID>
+ else if (name.get(0).equals(JBossCacheStorage.PROPS))
{
- // return PropertyData [ITEM_DATA : PropertyData]
- WorkspaceStorageConnection conn = dataContainer.openConnection();
-
- try
+ if (name.size() == 2)
{
- PropertyData propertyData = (PropertyData)conn.getItemData(name.getLastElementAsString());
-
+ String propertyId = name.getLastElementAsString();
+ PropertyData propertyData = (PropertyData)conn.getItemData(propertyId);
if (propertyData != null)
+ {
+ attrs = new LinkedHashMap<Object, Object>();
attrs.put(JBossCacheStorage.ITEM_DATA, propertyData);
+ }
+ else
+ {
+ attrs = null;
+ }
}
- finally
+ else
{
- conn.close();
+ attrs = null;
+ LOG.warn("Unexpected Fqn asked " + name);
}
}
+ else
+ {
+ attrs = null;
+ LOG.warn("Unexpected Fqn asked " + name);
+ }
}
+ else if (name.equals(Fqn.ROOT) || name.equals(JBossCacheStorage.PROPS) || name.equals(JBossCacheStorage.NODES)
+ || name.equals(JBossCacheStorage.LOCKS))
+ {
+ // roots, like NODES, PROPS etc
+ attrs = new LinkedHashMap<Object, Object>();
+ }
+ else
+ {
+ LOG.warn("Unexpected Fqn asked " + name);
+ attrs = null;
+ }
}
+ finally
+ {
+ conn.close();
+ }
- return (attrs.size() == 0 ? null : attrs);
+ return attrs;
}
/**
@@ -453,7 +404,7 @@
{
// return child nodes names
- Set<String> childs = new LinkedHashSet<String>();
+ Set<String> childs;
// /$NODES/<NODE_ID>
if (name.size() == 2)
@@ -461,25 +412,54 @@
WorkspaceStorageConnection conn = dataContainer.openConnection();
try
{
- NodeData parentNodeData = (NodeData)conn.getItemData((String)name.get(1));
-
- if (parentNodeData == null)
- throw new JDBCCacheLoaderException("The parent node with ID = " + (String)name.get(1)
- + " not exis, FQN = '" + name + "'.");
-
- // get child nodes by parent Id
- for (NodeData node : conn.getChildNodesData(parentNodeData))
+ String nodeId = (String)name.get(1);
+ NodeData parentData = (NodeData)conn.getItemData(nodeId);
+ if (parentData != null)
{
- childs.add(node.getQPath().getEntries()[node.getQPath().getEntries().length - 1].getAsString(true));
+ childs = new LinkedHashSet<String>();
+ // TODO get child nodes by parent Id, we need only id and name
+ for (NodeData node : conn.getChildNodesData(parentData))
+ {
+ childs.add(node.getQPath().getEntries()[node.getQPath().getEntries().length - 1].getAsString(true));
+ }
}
+ else
+ {
+ // TODO by JBC API we can just retur null, but it will not be normal for this loader contract
+ throw new JDBCCacheLoaderException("FATAL Parent not found " + nodeId + " '" + name + "'");
+ }
}
finally
{
conn.close();
}
}
+ else if (name.equals(JBossCacheStorage.NODES))
+ {
+ // TODO return all Nodes in workspace
+ childs = new LinkedHashSet<String>();
+ }
+ else if (name.equals(JBossCacheStorage.PROPS))
+ {
+ // TODO return all Properties in workspace
+ childs = new LinkedHashSet<String>();
+ }
+ else if (name.equals(JBossCacheStorage.LOCKS))
+ {
+ // TODO return all Locks in workspace
+ childs = new LinkedHashSet<String>();
+ }
+ else if (name.equals(Fqn.ROOT))
+ {
+ childs = new LinkedHashSet<String>();
+ childs.add(JBossCacheStorage.NODES);
+ childs.add(JBossCacheStorage.PROPS);
+ childs.add(JBossCacheStorage.LOCKS);
+ } else {
+ childs = null;
+ }
- return (childs.size() == 0 ? null : childs);
+ return childs;
}
/**
@@ -618,4 +598,82 @@
// etc.
-}
+ /**
+ * Prepare list of modifications.
+ *
+ * Will be checked the UPDATE, ADD, REMOVE.
+ *
+ * @param modifications
+ * @throws RepositoryException
+ */
+ @Deprecated
+ private void prepareModifications(List<Modification> modifications) throws RepositoryException
+ {
+ WorkspaceStorageConnection conn = dataContainer.openConnection();
+
+ try
+ {
+ for (int i = 0; i < modifications.size(); i++)
+ {
+ Modification m = modifications.get(i);
+ if (m.getType() == ModificationType.PUT_KEY_VALUE)
+ {
+ ItemData itemData = null;
+
+ //Check add or update node data.
+ if (m.getValue() instanceof NodeData)
+ {
+ NodeData nodeData = (NodeData)m.getValue();
+ itemData = conn.getItemData(nodeData.getIdentifier());
+
+ // Set oldValueData for update node.
+ if (itemData != null)
+ modifications.get(i).setOldValue(itemData);
+ }
+ else if (m.getValue() instanceof PropertyData)
+ {
+ PropertyData propertyData = (PropertyData)m.getValue();
+ itemData = conn.getItemData(propertyData.getIdentifier());
+
+ // Set oldValueData for update property.
+ if (itemData != null)
+ modifications.get(i).setOldValue(itemData);
+ }
+ }
+ else if (m.getType() == ModificationType.REMOVE_NODE)
+ {
+ if (m.getFqn().size() == 2
+ && (m.getFqn().get(0).equals(JBossCacheStorage.NODES) || m.getFqn().get(0).equals(
+ JBossCacheStorage.PROPS)))
+ {
+ String id = (String)m.getFqn().get(1);
+ ItemData removedItemData = conn.getItemData(id);
+
+ // Set valueData for update property or node.
+ if (removedItemData != null)
+ modifications.get(i).setValue(removedItemData);
+ }
+ }
+ }
+ }
+ finally
+ {
+ conn.close();
+ }
+ }
+
+ @Deprecated
+ private QPathEntry[] makeNodePath(Fqn<String> nodeFqn) throws NumberFormatException, IllegalNameException
+ {
+ List<String> elements = nodeFqn.peekElements();
+ QPathEntry[] path = new QPathEntry[elements.size()];
+
+ for (int i = 0; i < elements.size(); i++)
+ {
+ path[i] = QPathEntry.parse(elements.get(i));
+ }
+
+ return path;
+ }
+
+}
\ No newline at end of file
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -456,7 +456,7 @@
try
{
- deleteValues(cid, data, false);
+ deleteValues(cid, data.getIdentifier(), false);
// delete references
deleteReference(cid);
@@ -490,30 +490,10 @@
exceptionHandler.handleDeleteException(e, data);
}
}
-
- /**
- * {@inheritDoc}
- */
- public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
- }
-
/**
* {@inheritDoc}
*/
- public void deleteProperty(String identifier) throws RepositoryException,
- UnsupportedOperationException, InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
public void update(NodeData data) throws RepositoryException, UnsupportedOperationException,
InvalidItemStateException, IllegalStateException
{
@@ -575,7 +555,7 @@
}
// do Values update: delete all and add all
- deleteValues(cid, data, true);
+ deleteValues(cid, data.getIdentifier(), true);
addValues(cid, data);
if (LOG.isDebugEnabled())
@@ -1653,8 +1633,8 @@
*
* @param cid
* Property id
- * @param pdata
- * PropertyData
+ * @param propertyIdentifier
+ * the identifier the PropertyData
* @param update
* boolean true if it's delete-add sequence (update operation)
* @throws IOException
@@ -1664,7 +1644,7 @@
* @throws ValueStorageNotFoundException
* if no such storage found with Value storageId
*/
- private void deleteValues(String cid, PropertyData pdata, boolean update) throws IOException, SQLException,
+ private void deleteValues(String cid, String propertyIdentifier, boolean update) throws IOException, SQLException,
ValueStorageNotFoundException
{
@@ -1684,7 +1664,7 @@
final ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
try
{
- channel.delete(pdata.getIdentifier());
+ channel.delete(propertyIdentifier);
valueChanges.add(channel);
}
finally
@@ -1913,6 +1893,181 @@
}
}
+ // for JBC etc.
+
+ /**
+ * Deletes <code>NodeData</code> by identifier.
+ *
+ * @param identifier
+ * the identifier of NodeData to be deleted
+ *
+ * @throws InvalidItemStateException
+ * if the data is already deleted
+ * @throws UnsupportedOperationException
+ * if operation is not supported (it is container for level 1)
+ * @throws RepositoryException
+ * if some exception occured
+ * @throws IllegalStateException
+ * if connection is closed
+ */
+ public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
+ InvalidItemStateException, IllegalStateException
+ {
+ checkIfOpened();
+
+ final String cid = getInternalId(identifier);
+
+ try
+ {
+ int nc = deleteItemByIdentifier(cid);
+
+ if (nc <= 0)
+ {
+ throw new JCRInvalidItemStateException("(delete) Node not found " + identifier
+ + ". Probably was deleted by another session ", identifier, ItemState.DELETED);
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Node deleted id " + identifier);
+ }
+
+ }
+ catch (SQLException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.error("Node remove. Database error: " + e, e);
+ exceptionHandler.handleDeleteException(e, identifier, true, "");
+ }
+
+ }
+
+ /**
+ * Deletes <code>PropertyData</code> by identifier.
+ *
+ * @param identifier
+ * the identifier of PropertyData to be deleted
+ *
+ * @throws InvalidItemStateException
+ * if the data is already deleted
+ * @throws UnsupportedOperationException
+ * if operation is not supported (it is container for level 1)
+ * @throws RepositoryException
+ * if some exception occured
+ * @throws IllegalStateException
+ * if connection is closed
+ */
+ public void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException,
+ InvalidItemStateException, IllegalStateException
+ {
+ checkIfOpened();
+
+ final String cid = getInternalId(identifier);
+
+ try
+ {
+ deleteValues(cid, identifier, false);
+
+ // delete references
+ deleteReference(cid);
+
+ // delete item
+ int nc = deleteItemByIdentifier(cid);
+ if (nc <= 0)
+ throw new JCRInvalidItemStateException("(delete) Property not found ID = " + identifier
+ + ". Probably was deleted by another session ", identifier, ItemState.DELETED);
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("Property deleted ID = " + identifier);
+
+ }
+ catch (IOException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.error("Property remove. IO error: " + e, e);
+ throw new RepositoryException("Error of Property Value delete " + e, e);
+ }
+ catch (SQLException e)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.error("Property remove. Database error: " + e, e);
+ exceptionHandler.handleDeleteException(e, identifier, true, "");
+ }
+ }
+
+ public String getItemIdentifier(String parentId, String name) throws RepositoryException, IllegalStateException
+ {
+
+ return null; // TODO
+ }
+
+ class PropertyDataInfo {
+ String propertyId;
+ String propertyName;
+ }
+
+ public List<PropertyDataInfo> getChildProperties(String parentId) throws RepositoryException, IllegalStateException
+ {
+
+ return new ArrayList<PropertyDataInfo>(); // TODO
+ }
+
+ public List<String> getChildNodeNames(String parentId) throws RepositoryException, IllegalStateException
+ {
+ checkIfOpened();
+ try
+ {
+ ResultSet node = findChildNodesByParentIdentifier(getInternalId(parentId));
+ List<String> childrens = new ArrayList<String>();
+ //while (node.next())
+ //childrens.add((NodeData)itemData(parent.getQPath(), node, I_CLASS_NODE, parent.getACL()));
+
+ return childrens;
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
+ public List<String> getAllPropertyIdentifiers() throws RepositoryException, IllegalStateException
+ {
+ checkIfOpened();
+ try
+ {
+ ResultSet node = findChildNodesByParentIdentifier(getInternalId("???"));
+ List<String> childrens = new ArrayList<String>();
+ //while (node.next())
+ //childrens.add((NodeData)itemData(parent.getQPath(), node, I_CLASS_NODE, parent.getACL()));
+
+ return childrens;
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
+ public List<String> getAllNodeIdentifiers() throws RepositoryException, IllegalStateException
+ {
+ checkIfOpened();
+ try
+ {
+ ResultSet node = findChildNodesByParentIdentifier(getInternalId("???"));
+ List<String> childrens = new ArrayList<String>();
+ //while (node.next())
+ //childrens.add((NodeData)itemData(parent.getQPath(), node, I_CLASS_NODE, parent.getACL()));
+
+ return childrens;
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
+ // abstract to be impl
+
protected abstract int addNodeRecord(NodeData data) throws SQLException;
protected abstract int addPropertyRecord(PropertyData prop) throws SQLException;
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLExceptionHandler.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -332,7 +332,50 @@
message += "Error of item delete " + itemInfo;
throw new RepositoryException(message, e);
}
+
+ /**
+ * Handle delete Exceptions.
+ *
+ * @param e
+ * - an SQLException
+ * @param item
+ * - context ItemData
+ * @return String with error message
+ * @throws RepositoryException
+ * if <code>RepositoryException</code> should be thrown
+ * @throws InvalidItemStateException
+ * if <code>InvalidItemStateException</code> should be thrown
+ */
+ protected String handleDeleteException(SQLException e, String itemId, boolean isNode, String path ) throws RepositoryException,
+ InvalidItemStateException
+ {
+ String message = "[" + containerName + "] DELETE " + (isNode ? "NODE. " : "PROPERTY. ");
+ String errMessage = e.getMessage();
+ String itemInfo =
+ path + " " + itemId
+ + (errMessage != null ? ". Cause >>>> " + errMessage : "");
+ if (errMessage != null)
+ {
+ // try detect error by foreign key names
+ String umsg = errMessage.toLowerCase().toUpperCase();
+ if (umsg.indexOf(conn.JCR_FK_ITEM_PARENT) >= 0)
+ {
+ message += "Can not delete parent till childs exists. Item " + itemInfo;
+ throw new JCRInvalidItemStateException(message, itemId, ItemState.DELETED, e);
+ }
+ else if (umsg.indexOf(conn.JCR_FK_VALUE_PROPERTY) >= 0)
+ {
+ message +=
+ "[FATAL] Can not delete property item till it contains values. Condition: property ID. " + itemInfo;
+ throw new RepositoryException(message, e);
+ }
+ }
+
+ message += "Error of item delete " + itemInfo;
+ throw new RepositoryException(message, e);
+ }
+
/**
* Handle update Exceptions.
*
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceStorageConnection.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -261,42 +261,6 @@
IllegalStateException;
/**
- * Deletes <code>NodeData</code> by identifier.
- *
- * @param identifier
- * the identifier of NodeData to be deleted
- *
- * @throws InvalidItemStateException
- * if the data is already deleted
- * @throws UnsupportedOperationException
- * if operation is not supported (it is container for level 1)
- * @throws RepositoryException
- * if some exception occured
- * @throws IllegalStateException
- * if connection is closed
- */
- void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException, InvalidItemStateException,
- IllegalStateException;
-
- /**
- * Deletes <code>PropertyData</code> by identifier.
- *
- * @param identifier
- * the identifier of PropertyData to be deleted
- *
- * @throws InvalidItemStateException
- * if the data is already deleted
- * @throws UnsupportedOperationException
- * if operation is not supported (it is container for level 1)
- * @throws RepositoryException
- * if some exception occured
- * @throws IllegalStateException
- * if connection is closed
- */
- void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException, InvalidItemStateException,
- IllegalStateException;
-
- /**
* Deletes <code>PropertyData</code>.
*
* @param data
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoaderTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoaderTest.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JDBCCacheLoaderTest.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -82,7 +82,7 @@
initPersistence();
loader = new JDBCCacheLoader();
- loader.injectDependencies(persistentContainer);
+ loader.init(persistentContainer);
initJCRRoot();
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/ObservationCacheLoaderTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/ObservationCacheLoaderTest.java 2009-11-17 16:08:08 UTC (rev 721)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/ObservationCacheLoaderTest.java 2009-11-17 16:14:29 UTC (rev 722)
@@ -572,26 +572,6 @@
return null;
}
- /**
- * {@inheritDoc}
- */
- public void deleteNode(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void deleteProperty(String identifier) throws RepositoryException, UnsupportedOperationException,
- InvalidItemStateException, IllegalStateException
- {
- // TODO Auto-generated method stub
-
- }
-
}
}
16 years, 8 months
exo-jcr SVN: r721 - in jcr/branches/1.12.0-JBC/component/core/src: test/java/org/exoplatform/services/jcr/impl/storage/jbosscache and 1 other directory.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2009-11-17 11:08:08 -0500 (Tue, 17 Nov 2009)
New Revision: 721
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnectionTest.java
Log:
EXOJCR-245: JBossCacheStorageConnectionTest updated
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java 2009-11-17 16:07:53 UTC (rev 720)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java 2009-11-17 16:08:08 UTC (rev 721)
@@ -457,34 +457,31 @@
String nodeUUID = data.getIdentifier();
- //1. Update renamed node and also get old parent node UUID
+ //1. Update renamed node and also get old nodeData
Node<Serializable, Object> node = nodesRoot.getChild(makeNodeFqn(nodeUUID));
if (node == null)
{
throw new RepositoryException("FATAL renamed node is not exist" + data.getQPath().getAsString());
}
- String oldParentIdentifier = null;
- Object itemData = node.put(ITEM_DATA, data);
- if (itemData != null)
+
+ NodeData oldNodeData = (NodeData)node.put(ITEM_DATA, data);
+ if (oldNodeData == null)
{
- oldParentIdentifier = ((NodeData)itemData).getParentIdentifier();
- }
- else
- {
throw new RepositoryException("FATAL NodeData is empty " + data.getQPath().getAsString());
}
// 2. remove renamed node from child list of previous parent node
// check if parent is cached
- Node<Serializable, Object> oldparent = nodesRoot.getChild(makeNodeFqn(oldParentIdentifier));
+ Node<Serializable, Object> oldparent = nodesRoot.getChild(makeNodeFqn(oldNodeData.getParentIdentifier()));
if (oldparent == null)
{
throw new RepositoryException("Nodes old parent doesn't exist " + data.getQPath().getAsString());
}
- // remove child on old Parent
+ // remove node form old parent child list
boolean removed =
- oldparent.removeChild(makeChildNodeFqn(data.getQPath().getEntries()[data.getQPath().getEntries().length - 1]));
+ oldparent
+ .removeChild(makeChildNodeFqn(oldNodeData.getQPath().getEntries()[oldNodeData.getQPath().getEntries().length - 1]));
if (!removed)
{
throw new RepositoryException("Node was not removed from child list of old parent "
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnectionTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnectionTest.java 2009-11-17 16:07:53 UTC (rev 720)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnectionTest.java 2009-11-17 16:08:08 UTC (rev 721)
@@ -26,7 +26,6 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
@@ -717,4 +716,64 @@
}
}
+ public void testMoveNode() throws Exception
+ {
+ // add root (/)
+ conn.add(new TransientNodeData(Constants.ROOT_PATH, Constants.ROOT_UUID, 1, Constants.NT_UNSTRUCTURED,
+ new InternalQName[0], 0, null, new AccessControlList()));
+
+ // add node (/node)
+ String node1id = "1";
+ QPath node1path = QPath.parse("[]:1[]firstParent:1");
+ conn.add(new TransientNodeData(node1path, node1id, 1, Constants.NT_UNSTRUCTURED, new InternalQName[0], 0,
+ Constants.ROOT_UUID, new AccessControlList()));
+
+ String node2id = "2";
+ QPath node2path = QPath.parse("[]:1[]secondParent:1");
+ conn.add(new TransientNodeData(node2path, node2id, 1, Constants.NT_UNSTRUCTURED, new InternalQName[0], 0,
+ Constants.ROOT_UUID, new AccessControlList()));
+
+ String node3id = "3";
+ QPath node3path = QPath.parse("[]:1[]firstParent:1[]node:1");
+ conn.add(new TransientNodeData(node3path, node3id, 1, Constants.NT_UNSTRUCTURED, new InternalQName[0], 0,
+ node1id, new AccessControlList()));
+
+ // check in nodes
+ treePrint(nodes);
+
+ // get root node ([]:1)
+ Node<Serializable, Object> rootNode = nodes.getChild(Fqn.fromElements(Constants.ROOT_UUID));
+ assertNotNull("Node expected", rootNode);
+
+ // check root Node
+ checkNode(rootNode, Constants.ROOT_UUID, Constants.ROOT_PATH);
+
+ // cechk childs
+ assertEquals("Childs expected", 2, rootNode.getChildren().size());
+ checkChildNode(rootNode, node1id, node1path);
+ checkChildNode(rootNode, node2id, node2path);
+
+ Node<Serializable, Object> firstParent = nodes.getChild(Fqn.fromElements(node1id));
+ assertEquals("Childs expected", 1, firstParent.getChildren().size());
+ checkChildNode(firstParent, node3id, node3path);
+
+ Node<Serializable, Object> secondParent = nodes.getChild(Fqn.fromElements(node2id));
+ assertEquals("Childs expected", 0, secondParent.getChildren().size());
+
+ // lets move node
+
+ QPath newnode3path = QPath.parse("[]:1[]secondParent:1[]nodesec:1");
+ conn.rename(new TransientNodeData(newnode3path, node3id, 1, Constants.NT_UNSTRUCTURED, new InternalQName[0], 0,
+ node2id, new AccessControlList()));
+
+ //check results
+ firstParent = nodes.getChild(Fqn.fromElements(node1id));
+ assertEquals("Childs expected", 0, firstParent.getChildren().size());
+
+ secondParent = nodes.getChild(Fqn.fromElements(node2id));
+ assertEquals("Childs expected", 1, secondParent.getChildren().size());
+ checkChildNode(secondParent, node3id, newnode3path);
+
+ }
+
}
16 years, 8 months
exo-jcr SVN: r720 - in jcr/branches/1.12.0-JBC/component/core/src: main/java/org/exoplatform/services/jcr/impl/core/query and 4 other directories.
by do-not-reply@jboss.org
Author: skabashnyuk
Date: 2009-11-17 11:07:53 -0500 (Tue, 17 Nov 2009)
New Revision: 720
Added:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexInterceptor.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexModificationsBuilder.java
Removed:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManagerHolder.java
Modified:
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexerCacheLoader.java
jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderRuntimeTest.java
jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderTest.java
jcr/branches/1.12.0-JBC/component/core/src/test/resources/conf/standalone/test-jbosscache-config-exoloader.xml
Log:
EXOJCR-241 : IndexInterceptor initial implementation
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -48,9 +48,9 @@
import org.exoplatform.services.jcr.impl.core.query.QueryManagerFactory;
import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
-import org.exoplatform.services.jcr.impl.core.query.SearchManagerHolder;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManagerHolder;
+import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexInterceptor;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.JBossCacheWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
@@ -221,7 +221,8 @@
//so IndexerCacheLoader will use it.
//registerComponentInstance(new SearchManagerHolder());
// workspaceContainer.registerComponentImplementation(SearchManagerHolder.class);
- workspaceContainer.registerComponentInstance(new SearchManagerHolder());
+ workspaceContainer.registerComponentImplementation(IndexInterceptor.class);
+
if (isSystem)
{
//registerComponentInstance(new SearchManagerHolder());
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -42,6 +42,8 @@
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexInterceptor;
+import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexModificationsBuilder;
import org.exoplatform.services.jcr.impl.core.query.lucene.FieldNames;
import org.exoplatform.services.jcr.impl.core.query.lucene.LuceneVirtualTableResolver;
import org.exoplatform.services.jcr.impl.core.query.lucene.QueryHits;
@@ -54,6 +56,7 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.jboss.cache.commands.WriteCommand;
import org.jboss.cache.factories.annotations.NonVolatile;
import org.picocontainer.Startable;
@@ -165,7 +168,7 @@
public SearchManager(QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm,
- final RepositoryIndexSearcherHolder indexSearcherHolder, final SearchManagerHolder searchManagerHolder)
+ final RepositoryIndexSearcherHolder indexSearcherHolder, IndexInterceptor indexInterceptor)
throws RepositoryException, RepositoryConfigurationException
{
@@ -178,8 +181,9 @@
this.cfm = cfm;
this.virtualTableResolver = new LuceneVirtualTableResolver(nodeTypeDataManager, nsReg);
this.parentSearchManager = parentSearchManager != null ? parentSearchManager.get() : null;
- itemMgr.addItemPersistenceListener(this);
- searchManagerHolder.put(this);
+ //itemMgr.addItemPersistenceListener(this);
+ //searchManagerHolder.put(this);
+ indexInterceptor.addIndexInterceptorListener(this);
}
/**
@@ -243,6 +247,41 @@
return handler;
}
+ public void onSaveItems(List<WriteCommand> modifications) throws RepositoryException
+ {
+ try
+ {
+ // nodes that need to be removed from the index.
+ HashSet<String> removedNodes = new HashSet<String>();
+
+ // nodes that need to be added to the index.
+ HashSet<String> addedNodes = new HashSet<String>();
+
+ // node thst must be updated
+ HashSet<String> updateNodes = new HashSet<String>();
+
+ IndexModificationsBuilder indexModificationsBuilder =
+ new IndexModificationsBuilder(addedNodes, removedNodes, updateNodes);
+ for (WriteCommand cacheCommand : modifications)
+ {
+ cacheCommand.acceptVisitor(null, indexModificationsBuilder);
+ }
+
+ for (String uuid : updateNodes)
+ {
+ removedNodes.add(uuid);
+ addedNodes.add(uuid);
+ }
+
+ updateIndex(removedNodes, addedNodes);
+ }
+ catch (Throwable e)
+ {
+ e.printStackTrace();
+ throw new RepositoryException(e.getLocalizedMessage(), e.getCause());
+ }
+ }
+
public void onSaveItems(ItemStateChangesLog changesLog)
{
Exception es = new Exception();
Deleted: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManagerHolder.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManagerHolder.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManagerHolder.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2003-2009 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.services.jcr.impl.core.query;
-
-import org.jboss.cache.factories.annotations.NonVolatile;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * <br/>Date:
- *
- * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
- * @version $Id: SearchManagerHolder.java 111 2008-11-11 11:11:11Z serg $
- */
-@NonVolatile
-public class SearchManagerHolder
-{
- protected SearchManager manager;
-
- public SearchManagerHolder()
- {
- }
-
- public void put(SearchManager manager)
- {
- this.manager = manager;
- }
-
- public SearchManager get()
- {
- return manager;
- }
-}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -26,6 +26,7 @@
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexInterceptor;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -64,10 +65,10 @@
public SystemSearchManager(QueryHandlerEntry config, NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, DocumentReaderService service, ConfigurationManager cfm,
- RepositoryIndexSearcherHolder indexSearcherHolder, SearchManagerHolder holder) throws RepositoryException,
+ RepositoryIndexSearcherHolder indexSearcherHolder, IndexInterceptor indexInterceptor) throws RepositoryException,
RepositoryConfigurationException
{
- super(config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder, holder);
+ super(config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder, indexInterceptor);
}
@Override
Added: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexInterceptor.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexInterceptor.java (rev 0)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexInterceptor.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.cacheloader;
+
+import org.exoplatform.services.jcr.impl.core.query.SearchManager;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.interceptors.base.CommandInterceptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z ksm $
+ *
+ */
+public class IndexInterceptor extends CommandInterceptor
+{
+ private final Log log = ExoLogger.getLogger(IndexInterceptor.class);
+
+ /**
+ * List of index interceptor listeners.
+ */
+ private final List<SearchManager> indexInterceptorListners;
+
+ /**
+ * Default constructor.
+ */
+ public IndexInterceptor()
+ {
+ super();
+ this.indexInterceptorListners = new ArrayList<SearchManager>();
+ }
+
+ /**
+ * @see org.jboss.cache.commands.AbstractVisitor#visitPrepareCommand(org.jboss.cache.InvocationContext, org.jboss.cache.commands.tx.PrepareCommand)
+ */
+ @Override
+ public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable
+ {
+ // try
+ // {
+ // if (ctx.getTransactionContext().getModifications().size() > 0)
+ // {
+ // for (SearchManager searchManager : indexInterceptorListners)
+ // {
+ // searchManager.onSaveItems(ctx.getTransactionContext().getModifications());
+ // }
+ // }
+ // }
+ // catch (RepositoryException e)
+ // {
+ // //TODO handle rollback
+ // log.error(e.getLocalizedMessage());
+ // }
+
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ /**
+ * Add new SearchManager to the indexInterceptorListners list.
+ * @param searchManager - search manager.
+ */
+ public void addIndexInterceptorListener(SearchManager searchManager)
+ {
+ indexInterceptorListners.add(searchManager);
+ }
+
+ /**
+ * Add new SearchManager to the indexInterceptorListners list.
+ * @param searchManager - search manager.
+ */
+ public boolean removeIndexInterceptorListener(SearchManager searchManager)
+ {
+ return indexInterceptorListners.remove(searchManager);
+ }
+}
Property changes on: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexInterceptor.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexModificationsBuilder.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexModificationsBuilder.java (rev 0)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexModificationsBuilder.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.cacheloader;
+
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.impl.storage.jbosscache.JBossCacheStorage;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.commands.AbstractVisitor;
+import org.jboss.cache.commands.write.ClearDataCommand;
+import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z ksm $
+ *
+ */
+public class IndexModificationsBuilder extends AbstractVisitor
+{
+
+ // nodes that need to be removed from the index.
+ private final Set<String> removedNodes;
+
+ // nodes that need to be added to the index.
+ private final Set<String> addedNodes;
+
+ // node thst must be updated
+ private final Set<String> updateNodes;
+
+ public IndexModificationsBuilder(HashSet<String> addedNodes, HashSet<String> removedNodes,
+ HashSet<String> updateNodes)
+ {
+ // nodes that need to be removed from the index.
+ this.removedNodes = removedNodes;
+
+ // nodes that need to be added to the index.
+ this.addedNodes = addedNodes;
+
+ // node thst must be updated
+ this.updateNodes = updateNodes;
+
+ }
+
+ @Override
+ public Object visitClearDataCommand(InvocationContext ctx, ClearDataCommand command) throws Throwable
+ {
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+
+ if (isNode(fqn))
+ {
+ // add node
+ String uuid = parseUUID(fqn);
+ removedNodes.add(uuid);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object visitMoveCommand(InvocationContext ctx, MoveCommand command) throws Throwable
+ {
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+
+ if (isNode(fqn))
+ {
+ //remove first
+ removedNodes.add(parseUUID(command.getFqn()));
+ //add second
+ addedNodes.add(parseUUID(command.getTo()));
+ }
+ else
+ {
+ // this is property - do nothing
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object visitPutDataMapCommand(InvocationContext ctx, PutDataMapCommand command) throws Throwable
+ {
+
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+
+ if (isNode(fqn))
+ {
+ // add node
+ String uuid = parseUUID(fqn);
+ addedNodes.add(uuid);
+ }
+ else
+ {
+ // this is property - do nothing
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
+ {
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+ String uuid = parseUUID(fqn);
+ if (!isNode(fqn))
+ {
+ PropertyData property = (PropertyData)command.getValue();
+ uuid = property.getParentIdentifier();
+ }
+ if (!addedNodes.contains(uuid))
+ {
+ updateNodes.add(uuid);
+ }
+
+ }
+ return null;
+
+ }
+
+ @Override
+ public Object visitRemoveKeyCommand(InvocationContext ctx, RemoveKeyCommand command) throws Throwable
+ {
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+
+ if (isNode(fqn))
+ {
+ // add node
+ String uuid = parseUUID(fqn);
+ if (!removedNodes.contains(uuid))
+ {
+ updateNodes.add(uuid);
+ }
+ }
+ }
+ return null;
+
+ }
+
+ @Override
+ public Object visitRemoveNodeCommand(InvocationContext ctx, RemoveNodeCommand command) throws Throwable
+ {
+ Fqn fqn = command.getFqn();
+ if (fqn.size() == 2)
+ {
+
+ if (isNode(fqn))
+ {
+ // add node
+ String uuid = parseUUID(fqn);
+ removedNodes.add(uuid);
+ }
+ else
+ {
+ // this is property - do nothing
+ }
+ }
+ return null;
+ }
+
+ private boolean isNode(Fqn<String> fqn)
+ {
+ String items = (String)fqn.get(0);
+ String s = items.toString();
+ return s.equals(JBossCacheStorage.NODES);
+ }
+
+ private String parseUUID(Fqn<String> fqn)
+ {
+ if (fqn.size() > 1)
+ {
+
+ // get only uuid
+ String uuid = (String)fqn.get(1);
+ //remove slash
+ return uuid;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+}
Property changes on: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexModificationsBuilder.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexerCacheLoader.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexerCacheLoader.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/cacheloader/IndexerCacheLoader.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -17,7 +17,6 @@
package org.exoplatform.services.jcr.impl.core.query.cacheloader;
import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.impl.core.query.SearchManagerHolder;
import org.exoplatform.services.jcr.impl.storage.jbosscache.AbstractWriteOnlyCacheLoader;
import org.exoplatform.services.jcr.impl.storage.jbosscache.JBossCacheStorage;
import org.exoplatform.services.log.ExoLogger;
@@ -25,7 +24,6 @@
import org.jboss.cache.CacheException;
import org.jboss.cache.Fqn;
import org.jboss.cache.Modification;
-import org.jboss.cache.factories.annotations.Inject;
import java.util.HashSet;
import java.util.List;
@@ -39,6 +37,7 @@
* @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
* @version $Id: CacheIndexer.java 111 2008-11-11 11:11:11Z serg $
*/
+@Deprecated
public class IndexerCacheLoader extends AbstractWriteOnlyCacheLoader
{
@@ -47,17 +46,17 @@
*/
private static final Log log = ExoLogger.getLogger(IndexerCacheLoader.class);
- SearchManagerHolder searchManagerHolder = null;
+ //IndexInterceptorHolder searchManagerHolder = null;
public IndexerCacheLoader()
{
}
- @Inject
- public void injectDependencies(SearchManagerHolder holder)
- {
- searchManagerHolder = holder;
- }
+ // @Inject
+ // public void injectDependencies(IndexInterceptorHolder holder)
+ // {
+ // searchManagerHolder = holder;
+ // }
private String parseUUID(Fqn<String> fqn)
{
@@ -85,10 +84,10 @@
@Override
public void put(List<Modification> modifications) throws Exception
{
- if (searchManagerHolder == null && searchManagerHolder.get() != null)
- {
- return;
- }
+ // if (searchManagerHolder == null || searchManagerHolder.get() == null)
+ // {
+ // return;
+ // }
// nodes that need to be removed from the index.
final Set<String> removedNodes = new HashSet<String>();
@@ -219,7 +218,15 @@
addedNodes.add(uuid);
}
- searchManagerHolder.get().updateIndex(removedNodes, addedNodes);
+ try
+ {
+ //searchManagerHolder.get().updateIndex(removedNodes, addedNodes);
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
}
Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheWorkspaceDataContainer.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -21,7 +21,7 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.query.SearchManagerHolder;
+import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexInterceptor;
import org.exoplatform.services.jcr.impl.storage.WorkspaceDataContainerBase;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
@@ -36,6 +36,7 @@
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.interceptors.CacheStoreInterceptor;
import org.picocontainer.Startable;
import java.io.IOException;
@@ -81,8 +82,8 @@
*/
public JBossCacheWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider,
- SearchManagerHolder searchManagerHolder) throws RepositoryConfigurationException, NamingException,
- RepositoryException, IOException
+ IndexInterceptor indexInterceptor) throws RepositoryConfigurationException, NamingException, RepositoryException,
+ IOException
{
this.repositoryName = repConfig.getName();
this.containerName = wsConfig.getName();
@@ -114,13 +115,14 @@
((CacheSPI<Serializable, Object>)cache).getComponentRegistry().registerComponent(this.persistentContainer,
WorkspaceDataContainer.class);
- ((CacheSPI<Serializable, Object>)cache).getComponentRegistry().registerComponent(searchManagerHolder,
- SearchManagerHolder.class);
+ // SearchManager stub. We need it because IndexInterceptor will be created
+ // much earlier when SearchManager
// TODO check lifecycle, might be we have to create in start(), with jdbc start.
// initializes configuration state, the root node, etc.
this.cache.create();
this.cache.start();
+ this.cache.addInterceptor(indexInterceptor, CacheStoreInterceptor.class);
Node<Serializable, Object> cacheRoot = cache.getRoot();
//Node<Serializable, Object> wsRoot = cacheRoot.addChild(Fqn.fromElements(repositoryName, containerName));
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderRuntimeTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderRuntimeTest.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderRuntimeTest.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -50,7 +50,6 @@
import org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeDataPersister;
import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
-import org.exoplatform.services.jcr.impl.core.query.SearchManagerHolder;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManagerHolder;
import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexerCacheLoader;
import org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex;
@@ -97,7 +96,7 @@
SearchManager manager;
- SearchManagerHolder holder;
+ //IndexInterceptorHolder holder;
public void createNewDataSource(String dataSourceName) throws Exception
{
@@ -126,7 +125,7 @@
initPersistence();
loader = new IndexerCacheLoader();
- loader.injectDependencies(holder);
+ //loader.injectDependencies(holder);
initJCRRoot();
@@ -860,7 +859,7 @@
protected void initPersistence() throws Exception
{
- holder = new SearchManagerHolder();
+ //holder = new IndexInterceptorHolder();
// Create WorkspaceEntry
ContainerEntry containerEntry = new ContainerEntry();
@@ -908,9 +907,9 @@
DocumentReaderService extractor = null;
ConfigurationManager cfm = new ConfigurationManagerImpl();
- manager =
- new SearchManager(ws.getQueryHandler(), nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
- indexSearcherHolder, holder);
+ // manager =
+ // new SearchManager(ws.getQueryHandler(), nsReg, ntReg, itemMgr, parentSearchManager, extractor, cfm,
+ // indexSearcherHolder, holder);
}
@Override
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderTest.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderTest.java 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/java/org/exoplatform/services/jcr/impl/storage/jbosscache/IndexerCacheLoaderTest.java 2009-11-17 16:07:53 UTC (rev 720)
@@ -31,7 +31,6 @@
import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
-import org.exoplatform.services.jcr.impl.core.query.SearchManagerHolder;
import org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexerCacheLoader;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
@@ -60,7 +59,7 @@
private DummySearchManager searchManager;
- private SearchManagerHolder holder;
+ //private IndexInterceptorHolder holder;
/**
* @see junit.framework.TestCase#setUp()
@@ -70,9 +69,9 @@
{
// TODO Auto-generated method stub
super.setUp();
- holder = new SearchManagerHolder();
+ // holder = new IndexInterceptorHolder();
indexerCacheLoader = new IndexerCacheLoader();
- indexerCacheLoader.injectDependencies(holder);
+ //indexerCacheLoader.injectDependencies(holder);
searchManager = new DummySearchManager();
}
@@ -270,7 +269,7 @@
public DummySearchManager() throws RepositoryException, RepositoryConfigurationException
{
- super(null, null, null, null, null, null, null, new RepositoryIndexSearcherHolder(), holder);
+ super(null, null, null, null, null, null, null, new RepositoryIndexSearcherHolder(), null);
}
/**
Modified: jcr/branches/1.12.0-JBC/component/core/src/test/resources/conf/standalone/test-jbosscache-config-exoloader.xml
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/test/resources/conf/standalone/test-jbosscache-config-exoloader.xml 2009-11-17 13:17:40 UTC (rev 719)
+++ jcr/branches/1.12.0-JBC/component/core/src/test/resources/conf/standalone/test-jbosscache-config-exoloader.xml 2009-11-17 16:07:53 UTC (rev 720)
@@ -9,7 +9,7 @@
<clustering mode="replication">
<jgroupsConfig>
- <UDP discard_incompatible_packets="true" enable_bundling="false" enable_diagnostics="false" ip_ttl="2"
+ <!--UDP discard_incompatible_packets="true" enable_bundling="false" enable_diagnostics="false" ip_ttl="2"
loopback="false" max_bundle_size="64000" max_bundle_timeout="30" mcast_addr="228.10.10.10"
mcast_port="45588" mcast_recv_buf_size="25000000" mcast_send_buf_size="640000"
oob_thread_pool.enabled="true" oob_thread_pool.keep_alive_time="10000" oob_thread_pool.max_threads="4"
@@ -19,16 +19,17 @@
thread_pool.queue_enabled="true" thread_pool.queue_max_size="10" thread_pool.rejection_policy="Run"
tos="8" ucast_recv_buf_size="20000000" ucast_send_buf_size="640000" use_concurrent_stack="true"
use_incoming_packet_handler="true" />
- <PING num_initial_members="3" timeout="2000" />
+ <PING num_initial_members="3" timeout="2000" /-->
- <!-- TCP bind_addr="192.168.0.15" start_port="7800" loopback="true" recv_buf_size="20000000" send_buf_size="640000" discard_incompatible_packets="true"
+ <TCP bind_addr="localhost" start_port="7800" loopback="true" recv_buf_size="20000000" send_buf_size="640000" discard_incompatible_packets="true"
max_bundle_size="64000" max_bundle_timeout="30" use_incoming_packet_handler="true" enable_bundling="true" use_send_queues="false" sock_conn_timeout="300"
skip_suspected_members="true" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="1" thread_pool.max_threads="25"
thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="false" thread_pool.queue_max_size="100" thread_pool.rejection_policy="run"
oob_thread_pool.enabled="true" oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000"
oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="run" />
- <MPING timeout="2000" num_initial_members="3" mcast_port="34526" bind_addr="192.168.0.15" mcast_addr="224.0.0.1" /-->
+ <MPING timeout="2000" num_initial_members="3" mcast_port="34526" bind_addr="localhost" mcast_addr="224.0.0.1" />
+
<MERGE2 max_interval="30000" min_interval="10000"/>
<FD_SOCK/>
@@ -66,17 +67,12 @@
</properties>
</loader>
- <loader class="org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexerCacheLoader"
+ <!-- loader class="org.exoplatform.services.jcr.impl.core.query.cacheloader.IndexerCacheLoader"
async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
<properties>
</properties>
- </loader>
+ </loader-->
- <loader class="org.exoplatform.services.jcr.impl.storage.jbosscache.LockCacheLoader"
- async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
- <properties>
- </properties>
- </loader>
</loaders>
<!-- Enable batching -->
16 years, 8 months
exo-jcr SVN: r719 - in jcr/branches/1.12.0-OPT/exo.jcr.component.core/src: test/java/org/exoplatform/services/jcr/api/core/query and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2009-11-17 08:17:40 -0500 (Tue, 17 Nov 2009)
New Revision: 719
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/UpperLowerCaseQueryTest.java
Log:
EXOJCR-221: add, getNodes improvement
Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java 2009-11-17 13:13:23 UTC (rev 718)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ItemImpl.java 2009-11-17 13:17:40 UTC (rev 719)
@@ -104,20 +104,15 @@
protected ValueFactoryImpl valueFactory;
/**
- * Hashcode.
- */
- protected final int itemHashCode;
-
- /**
- * ItemImpl constructor.
- *
- * @param data
- * ItemData object
- * @param session
- * Session object
- * @throws RepositoryException
- * if any Exception is occurred
- */
+ * ItemImpl constructor.
+ *
+ * @param data
+ * ItemData object
+ * @param session
+ * Session object
+ * @throws RepositoryException
+ * if any Exception is occurred
+ */
ItemImpl(ItemData data, SessionImpl session) throws RepositoryException
{
@@ -127,8 +122,6 @@
this.dataManager = session.getTransientNodesManager();
this.locationFactory = session.getLocationFactory();
this.valueFactory = session.getValueFactory();
-
- itemHashCode = (session.getWorkspace().getName() + data.getIdentifier()).hashCode();
}
protected void invalidate()
@@ -803,15 +796,6 @@
return false;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode()
- {
- return itemHashCode;
- }
-
private ValueData valueData(Value value, int type) throws RepositoryException, ValueFormatException
{
Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2009-11-17 13:13:23 UTC (rev 718)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2009-11-17 13:17:40 UTC (rev 719)
@@ -466,18 +466,12 @@
public boolean isNew(String identifier)
{
- List<ItemState> states = changesLog.getItemStates(identifier);
- ItemState lastState = states.size() > 0 ? states.get(states.size() - 1) : null;
+ ItemState lastState = changesLog.getItemState(identifier);
if (lastState == null || lastState.isDeleted())
return false;
- for (ItemState state : states)
- {
- if (state.isAdded())
- return true;
- }
- return false;
+ return changesLog.getItemState(identifier, ItemState.ADDED) != null;
}
/**
@@ -534,7 +528,8 @@
// [PN] 21.12.07 use item data
NodeData parent = (NodeData)getItemData(data.getParentIdentifier());
// skip not permitted
- if (accessManager.hasPermission(parent.getACL(), PermissionType.READ, session.getUserState().getIdentity()))
+ if (accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.READ}, session.getUserState()
+ .getIdentity()))
{
PropertyImpl item = null;
ItemState state = changesLog.getItemState(identifier);
@@ -587,7 +582,8 @@
session.getActionHandler().postRead(item);
- if (accessManager.hasPermission(data.getACL(), PermissionType.READ, session.getUserState().getIdentity()))
+ if (accessManager.hasPermission(data.getACL(), new String[]{PermissionType.READ}, session.getUserState()
+ .getIdentity()))
{
if (pool)
item = (NodeImpl)itemsPool.get(item);
@@ -633,7 +629,8 @@
{
ItemImpl item = itemFactory.createItem(data);
session.getActionHandler().postRead(item);
- if (accessManager.hasPermission(parent.getACL(), PermissionType.READ, session.getUserState().getIdentity()))
+ if (accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.READ}, session.getUserState()
+ .getIdentity()))
{
if (pool)
item = itemsPool.get(item);
@@ -676,31 +673,8 @@
*/
public int getChildNodesCount(NodeData parent) throws RepositoryException
{
- int childsCount = changesLog.getChildNodesCount(parent.getIdentifier());
-
- // for (ItemState change : changesLog.getAllStates())
- // {
- // if (change.isNode() && change.isPersisted()
- // && parent.getIdentifier().equals(change.getData().getParentIdentifier()))
- // {
- // if (change.isDeleted())
- // {
- // childsCount--;
- // }
- // else if (change.isAdded())
- // {
- // childsCount++;
- // }
- // }
- // }
- //
- // if (childsCount != changesLog.getChildNodesCount(parent.getIdentifier()))
- // {
- // System.out.println("");
- // changesLog.getChildNodesCount(parent.getIdentifier());
- // }
-
- childsCount = transactionableManager.getChildNodesCount(parent) + childsCount;
+ int childsCount =
+ changesLog.getChildNodesCount(parent.getIdentifier()) + transactionableManager.getChildNodesCount(parent);
if (childsCount < 0)
{
throw new InvalidItemStateException("Node's child nodes were changed in another Session "
@@ -1303,8 +1277,8 @@
// Remove propery or node
if (changedItem.isDeleted())
{
- if (!accessManager.hasPermission(parent.getACL(), PermissionType.REMOVE, session.getUserState()
- .getIdentity()))
+ if (!accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.REMOVE}, session
+ .getUserState().getIdentity()))
throw new AccessDeniedException("Access denied: REMOVE "
+ changedItem.getData().getQPath().getAsString() + " for: " + session.getUserID() + " item owner "
+ parent.getACL().getOwner());
@@ -1314,8 +1288,8 @@
// add node
if (changedItem.isAdded())
{
- if (!accessManager.hasPermission(parent.getACL(), PermissionType.ADD_NODE, session.getUserState()
- .getIdentity()))
+ if (!accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.ADD_NODE}, session
+ .getUserState().getIdentity()))
{
throw new AccessDeniedException("Access denied: ADD_NODE "
+ changedItem.getData().getQPath().getAsString() + " for: " + session.getUserID() + " item owner "
@@ -1326,8 +1300,8 @@
else if (changedItem.isAdded() || changedItem.isUpdated())
{
// add or update property
- if (!accessManager.hasPermission(parent.getACL(), PermissionType.SET_PROPERTY, session.getUserState()
- .getIdentity()))
+ if (!accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.SET_PROPERTY}, session
+ .getUserState().getIdentity()))
throw new AccessDeniedException("Access denied: SET_PROPERTY "
+ changedItem.getData().getQPath().getAsString() + " for: " + session.getUserID() + " item owner "
+ parent.getACL().getOwner());
@@ -1686,10 +1660,6 @@
{
ret.add(childNode);
- if (log.isDebugEnabled())
- log.debug("Traverse transient (N) " + childNode.getData().getQPath().getAsString() + " "
- + ItemState.nameFromValue(childNode.getState()));
-
if (deep)
traverseTransientDescendants(childNode.getData(), deep, action, ret);
}
@@ -1700,17 +1670,14 @@
for (ItemState childProp : childProps)
{
ret.add(childProp);
-
- if (log.isDebugEnabled())
- log.debug("Traverse transient (P) " + childProp.getData().getQPath().getAsString());
}
}
}
}
/**
- * Pool for touched items.
- */
+ * Pool for touched items.
+ */
protected final class ItemReferencePool
{
Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/UpperLowerCaseQueryTest.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/UpperLowerCaseQueryTest.java 2009-11-17 13:13:23 UTC (rev 718)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/core/query/UpperLowerCaseQueryTest.java 2009-11-17 13:17:40 UTC (rev 719)
@@ -16,9 +16,9 @@
*/
package org.exoplatform.services.jcr.api.core.query;
-
-
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Random;
import java.util.Set;
@@ -32,295 +32,276 @@
* fn:upper-case() in XPath, LOWER() and UPPER() in SQL and UpperCase and
* LowerCase in JQOM.
*/
-public class UpperLowerCaseQueryTest extends AbstractQueryTest {
+public class UpperLowerCaseQueryTest extends AbstractQueryTest
+{
-// /**
-// * Maps operator strings to QueryObjectModelConstants.
-// */
-// private static final Map OPERATORS = new HashMap();
-//
-// static {
-// OPERATORS.put("=", new Integer(OPERATOR_EQUAL_TO));
-// OPERATORS.put(">", new Integer(OPERATOR_GREATER_THAN));
-// OPERATORS.put(">=", new Integer(OPERATOR_GREATER_THAN_OR_EQUAL_TO));
-// OPERATORS.put("<", new Integer(OPERATOR_LESS_THAN));
-// OPERATORS.put("<=", new Integer(OPERATOR_LESS_THAN_OR_EQUAL_TO));
-// OPERATORS.put("like", new Integer(OPERATOR_LIKE));
-// OPERATORS.put("!=", new Integer(OPERATOR_NOT_EQUAL_TO));
-// }
+ // /**
+ // * Maps operator strings to QueryObjectModelConstants.
+ // */
+ // private static final Map OPERATORS = new HashMap();
+ //
+ // static {
+ // OPERATORS.put("=", new Integer(OPERATOR_EQUAL_TO));
+ // OPERATORS.put(">", new Integer(OPERATOR_GREATER_THAN));
+ // OPERATORS.put(">=", new Integer(OPERATOR_GREATER_THAN_OR_EQUAL_TO));
+ // OPERATORS.put("<", new Integer(OPERATOR_LESS_THAN));
+ // OPERATORS.put("<=", new Integer(OPERATOR_LESS_THAN_OR_EQUAL_TO));
+ // OPERATORS.put("like", new Integer(OPERATOR_LIKE));
+ // OPERATORS.put("!=", new Integer(OPERATOR_NOT_EQUAL_TO));
+ // }
- public void testEqualsGeneralComparison() throws RepositoryException {
- check(new String[]{"foo", "Foo", "fOO", "FOO", "fooBar", "fo", "fooo"},
- "=",
- "foo",
- new boolean[]{true, true, true, true, false, false, false});
- check(new String[]{"foo"}, "=", "", new boolean[]{false});
- check(new String[]{""}, "=", "", new boolean[]{true});
- }
+ public void testEqualsGeneralComparison() throws RepositoryException
+ {
+ check(new String[]{"foo", "Foo", "fOO", "FOO", "fooBar", "fo", "fooo"}, "=", "foo", new boolean[]{true, true,
+ true, true, false, false, false});
+ check(new String[]{"foo"}, "=", "", new boolean[]{false});
+ check(new String[]{""}, "=", "", new boolean[]{true});
+ }
- public void testGreaterThanGeneralComparison() throws RepositoryException {
- // check edges
- check(new String[]{"foo", "FOO", "FoO", "fOo", "FON", "fon", "fo", "FO"},
- ">",
- "foo",
- new boolean[]{false, false, false, false, false, false, false, false});
- check(new String[]{"foo ", "FOOa", "FoOO", "fOo1", "FOp", "foP", "fp", "g", "G"},
- ">",
- "foo",
- new boolean[]{true, true, true, true, true, true, true, true, true});
- // check combinations
- check(new String[]{"foo", "fooo", "FooO", "fo", "FON", "fon"},
- ">",
- "foo",
- new boolean[]{false, true, true, false, false, false});
- }
+ public void testGreaterThanGeneralComparison() throws RepositoryException
+ {
+ // check edges
+ check(new String[]{"foo", "FOO", "FoO", "fOo", "FON", "fon", "fo", "FO"}, ">", "foo", new boolean[]{false, false,
+ false, false, false, false, false, false});
+ check(new String[]{"foo ", "FOOa", "FoOO", "fOo1", "FOp", "foP", "fp", "g", "G"}, ">", "foo", new boolean[]{true,
+ true, true, true, true, true, true, true, true});
+ // check combinations
+ check(new String[]{"foo", "fooo", "FooO", "fo", "FON", "fon"}, ">", "foo", new boolean[]{false, true, true,
+ false, false, false});
+ }
- public void testLessThanGeneralComparison() throws RepositoryException {
- // check edges
- check(new String[]{"foo", "FOO", "FoO", "fOo", "foOo", "foo ", "fooa", "fop"},
- "<",
- "foo",
- new boolean[]{false, false, false, false, false, false, false, false});
- check(new String[]{"fo", "FOn", "FoN", "fO", "FO1", "fn", "fN", "E", "e"},
- "<",
- "foo",
- new boolean[]{true, true, true, true, true, true, true, true, true});
- // check combinations
- check(new String[]{"foo", "fooo", "FooO", "fo", "FON", "fon"},
- "<",
- "foo",
- new boolean[]{false, false, false, true, true, true});
- }
+ public void testLessThanGeneralComparison() throws RepositoryException
+ {
+ // check edges
+ check(new String[]{"foo", "FOO", "FoO", "fOo", "foOo", "foo ", "fooa", "fop"}, "<", "foo", new boolean[]{false,
+ false, false, false, false, false, false, false});
+ check(new String[]{"fo", "FOn", "FoN", "fO", "FO1", "fn", "fN", "E", "e"}, "<", "foo", new boolean[]{true, true,
+ true, true, true, true, true, true, true});
+ // check combinations
+ check(new String[]{"foo", "fooo", "FooO", "fo", "FON", "fon"}, "<", "foo", new boolean[]{false, false, false,
+ true, true, true});
+ }
- public void testGreaterEqualsGeneralComparison() throws RepositoryException {
- // check edges
- check(new String[]{"fo", "FO", "Fon", "fONo", "FON", "fO", "fo", "FO"},
- ">=",
- "foo",
- new boolean[]{false, false, false, false, false, false, false, false});
- check(new String[]{"foo", "FoO", "FoOO", "fOo1", "FOp", "foP", "fp", "g", "G"},
- ">=",
- "foo",
- new boolean[]{true, true, true, true, true, true, true, true, true});
- // check combinations
- check(new String[]{"foo", "fooo", "FOo", "fo", "FON", "fon"},
- ">=",
- "foo",
- new boolean[]{true, true, true, false, false, false});
- }
+ public void testGreaterEqualsGeneralComparison() throws RepositoryException
+ {
+ // check edges
+ check(new String[]{"fo", "FO", "Fon", "fONo", "FON", "fO", "fo", "FO"}, ">=", "foo", new boolean[]{false, false,
+ false, false, false, false, false, false});
+ check(new String[]{"foo", "FoO", "FoOO", "fOo1", "FOp", "foP", "fp", "g", "G"}, ">=", "foo", new boolean[]{true,
+ true, true, true, true, true, true, true, true});
+ // check combinations
+ check(new String[]{"foo", "fooo", "FOo", "fo", "FON", "fon"}, ">=", "foo", new boolean[]{true, true, true, false,
+ false, false});
+ }
- public void testLessEqualsGeneralComparison() throws RepositoryException {
- // check edges
- check(new String[]{"fooo", "FOoo", "Fop", "fOpo", "FOP", "fOo ", "fp", "G"},
- "<=",
- "foo",
- new boolean[]{false, false, false, false, false, false, false, false});
- check(new String[]{"foo", "FoO", "Foo", "fOn", "FO", "fo", "f", "E", "e"},
- "<=",
- "foo",
- new boolean[]{true, true, true, true, true, true, true, true, true});
- // check combinations
- check(new String[]{"foo", "fo", "FOo", "fop", "FOP", "fooo"},
- "<=",
- "foo",
- new boolean[]{true, true, true, false, false, false});
- }
+ public void testLessEqualsGeneralComparison() throws RepositoryException
+ {
+ // check edges
+ check(new String[]{"fooo", "FOoo", "Fop", "fOpo", "FOP", "fOo ", "fp", "G"}, "<=", "foo", new boolean[]{false,
+ false, false, false, false, false, false, false});
+ check(new String[]{"foo", "FoO", "Foo", "fOn", "FO", "fo", "f", "E", "e"}, "<=", "foo", new boolean[]{true, true,
+ true, true, true, true, true, true, true});
+ // check combinations
+ check(new String[]{"foo", "fo", "FOo", "fop", "FOP", "fooo"}, "<=", "foo", new boolean[]{true, true, true, false,
+ false, false});
+ }
- public void testNotEqualsGeneralComparison() throws RepositoryException {
- // check edges
- check(new String[]{"fooo", "FOoo", "Fop", "fOpo", "FOP", "fOo ", "fp", "G", ""},
- "!=",
- "foo",
- new boolean[]{true, true, true, true, true, true, true, true, true});
- check(new String[]{"foo", "FoO", "Foo", "foO", "FOO"},
- "!=",
- "foo",
- new boolean[]{false, false, false, false, false});
- // check combinations
- check(new String[]{"foo", "fo", "FOo", "fop", "FOP", "fooo"},
- "!=",
- "foo",
- new boolean[]{false, true, false, true, true, true});
- }
+ public void testNotEqualsGeneralComparison() throws RepositoryException
+ {
+ // check edges
+ check(new String[]{"fooo", "FOoo", "Fop", "fOpo", "FOP", "fOo ", "fp", "G", ""}, "!=", "foo", new boolean[]{true,
+ true, true, true, true, true, true, true, true});
+ check(new String[]{"foo", "FoO", "Foo", "foO", "FOO"}, "!=", "foo", new boolean[]{false, false, false, false,
+ false});
+ // check combinations
+ check(new String[]{"foo", "fo", "FOo", "fop", "FOP", "fooo"}, "!=", "foo", new boolean[]{false, true, false,
+ true, true, true});
+ }
- public void testLikeComparison() throws RepositoryException {
- check(new String[]{"foo", "Foo", "fOO", "FO "},
- "like",
- "fo_",
- new boolean[]{true, true, true, true});
- check(new String[]{"foo", "Foo", "fOO", "FOO"},
- "like",
- "f_o",
- new boolean[]{true, true, true, true});
- check(new String[]{"foo", "Foo", "fOO", " OO"},
- "like",
- "_oo",
- new boolean[]{true, true, true, true});
- check(new String[]{"foo", "Foa", "fOO", "FO", "foRm", "fPo", "fno", "FPo", "Fno"},
- "like",
- "fo%",
- new boolean[]{true, true, true, true, true, false, false, false, false});
- }
+ public void testLikeComparison() throws RepositoryException
+ {
+ check(new String[]{"foo", "Foo", "fOO", "FO "}, "like", "fo_", new boolean[]{true, true, true, true});
+ check(new String[]{"foo", "Foo", "fOO", "FOO"}, "like", "f_o", new boolean[]{true, true, true, true});
+ check(new String[]{"foo", "Foo", "fOO", " OO"}, "like", "_oo", new boolean[]{true, true, true, true});
+ check(new String[]{"foo", "Foa", "fOO", "FO", "foRm", "fPo", "fno", "FPo", "Fno"}, "like", "fo%", new boolean[]{
+ true, true, true, true, true, false, false, false, false});
+ }
- public void testLikeComparisonRandom() throws RepositoryException {
- String abcd = "abcd";
- Random random = new Random();
- for (int i = 0; i < 50; i++) {
- String pattern = "";
- pattern += getRandomChar(abcd, random);
- pattern += getRandomChar(abcd, random);
+ public void testLikeComparisonRandom() throws RepositoryException
+ {
+ String abcd = "abcd";
+ Random random = new Random();
+ for (int i = 0; i < 50; i++)
+ {
+ String pattern = "";
+ pattern += getRandomChar(abcd, random);
+ pattern += getRandomChar(abcd, random);
- // create 10 random values with 4 characters
- String[] values = new String[10];
- boolean[] matches = new boolean[10];
- for (int n = 0; n < 10; n++) {
- // at least the first character always matches
- String value = String.valueOf(pattern.charAt(0));
- for (int r = 1; r < 4; r++) {
- char c = getRandomChar(abcd, random);
- if (random.nextBoolean()) {
- c = Character.toUpperCase(c);
- }
- value += c;
- }
- matches[n] = value.toLowerCase().startsWith(pattern);
- values[n] = value;
+ // create 10 random values with 4 characters
+ String[] values = new String[10];
+ boolean[] matches = new boolean[10];
+ for (int n = 0; n < 10; n++)
+ {
+ // at least the first character always matches
+ String value = String.valueOf(pattern.charAt(0));
+ for (int r = 1; r < 4; r++)
+ {
+ char c = getRandomChar(abcd, random);
+ if (random.nextBoolean())
+ {
+ c = Character.toUpperCase(c);
+ }
+ value += c;
}
- pattern += "%";
- check(values, "like", pattern, matches);
- }
- }
+ matches[n] = value.toLowerCase().startsWith(pattern);
+ values[n] = value;
+ }
+ pattern += "%";
+ check(values, "like", pattern, matches);
+ }
+ }
- public void testRangeWithEmptyString() throws RepositoryException {
- check(new String[]{" ", "a", "A", "1", "3", "!", "@"},
- ">",
- "",
- new boolean[]{true, true, true, true, true, true, true});
- check(new String[]{"", "a", "A", "1", "3", "!", "@"},
- ">=",
- "",
- new boolean[]{true, true, true, true, true, true, true});
- check(new String[]{"", "a", "A", "1", "3", "!", "@"},
- "<",
- "",
- new boolean[]{false, false, false, false, false, false, false});
- check(new String[]{"", "a", "A", "1", "3", "!", "@"},
- "<=",
- "",
- new boolean[]{true, false, false, false, false, false, false});
- }
+ public void testRangeWithEmptyString() throws RepositoryException
+ {
+ check(new String[]{" ", "a", "A", "1", "3", "!", "@"}, ">", "", new boolean[]{true, true, true, true, true, true,
+ true});
+ check(new String[]{"", "a", "A", "1", "3", "!", "@"}, ">=", "", new boolean[]{true, true, true, true, true, true,
+ true});
+ check(new String[]{"", "a", "A", "1", "3", "!", "@"}, "<", "", new boolean[]{false, false, false, false, false,
+ false, false});
+ check(new String[]{"", "a", "A", "1", "3", "!", "@"}, "<=", "", new boolean[]{true, false, false, false, false,
+ false, false});
+ }
- public void testInvalidQuery() throws RepositoryException {
- try {
- executeXPathQuery("//*[fn:lower-case(@foo) = 123]", new Node[]{});
- fail("must throw InvalidQueryException");
- } catch (InvalidQueryException e) {
- // correct
- }
+ public void testInvalidQuery() throws RepositoryException
+ {
+ try
+ {
+ executeXPathQuery("//*[fn:lower-case(@foo) = 123]", new Node[]{});
+ fail("must throw InvalidQueryException");
+ }
+ catch (InvalidQueryException e)
+ {
+ // correct
+ }
- try {
- executeSQLQuery("select * from nt:base where LOWER(foo) = 123", new Node[]{});
- fail("must throw InvalidQueryException");
- } catch (InvalidQueryException e) {
- // correct
- }
- }
+ try
+ {
+ executeSQLQuery("select * from nt:base where LOWER(foo) = 123", new Node[]{});
+ fail("must throw InvalidQueryException");
+ }
+ catch (InvalidQueryException e)
+ {
+ // correct
+ }
+ }
- public void testWrongCaseNeverMatches() throws RepositoryException {
- Node n = testRootNode.addNode("node");
- n.setProperty("foo", "Bar");
- testRootNode.save();
- executeXPathQuery(testPath + "/*[jcr:like(fn:lower-case(@foo), 'BA%')]", new Node[]{});
- }
+ public void testWrongCaseNeverMatches() throws RepositoryException
+ {
+ Node n = testRootNode.addNode("node");
+ n.setProperty("foo", "Bar");
+ testRootNode.save();
+ executeXPathQuery(testPath + "/*[jcr:like(fn:lower-case(@foo), 'BA%')]", new Node[]{});
+ }
- //----------------------------< internal >----------------------------------
+ //----------------------------< internal >----------------------------------
- private void check(String[] values, String operation, String queryTerm, boolean[] matches)
- throws RepositoryException {
- if (values.length != matches.length) {
- throw new IllegalArgumentException("values and matches must have same length");
- }
- // create log message
- StringBuffer logMsg = new StringBuffer();
- logMsg.append("queryTerm: ").append(queryTerm);
- logMsg.append(" values: ");
- String separator = "";
- for (int i = 0; i < values.length; i++) {
- logMsg.append(separator);
- separator = ", ";
- if (matches[i]) {
- logMsg.append("+");
- } else {
- logMsg.append("-");
- }
- logMsg.append(values[i]);
- }
- log.println(logMsg.toString());
- for (NodeIterator it = testRootNode.getNodes(); it.hasNext();) {
- it.nextNode().remove();
- }
- Set matchingNodes = new HashSet();
- for (int i = 0; i < values.length; i++) {
- Node n = testRootNode.addNode("node" + i);
- n.setProperty(propertyName1, values[i]);
- if (matches[i]) {
- matchingNodes.add(n);
- }
- }
- testRootNode.save();
+ private void check(String[] values, String operation, String queryTerm, boolean[] matches)
+ throws RepositoryException
+ {
+ if (values.length != matches.length)
+ {
+ throw new IllegalArgumentException("values and matches must have same length");
+ }
+ // create log message
+ StringBuffer logMsg = new StringBuffer();
+ logMsg.append("queryTerm: ").append(queryTerm);
+ logMsg.append(" values: ");
+ String separator = "";
+ for (int i = 0; i < values.length; i++)
+ {
+ logMsg.append(separator);
+ separator = ", ";
+ if (matches[i])
+ {
+ logMsg.append("+");
+ }
+ else
+ {
+ logMsg.append("-");
+ }
+ logMsg.append(values[i]);
+ }
+ log.println(logMsg.toString());
+ for (NodeIterator it = testRootNode.getNodes(); it.hasNext();)
+ {
+ it.nextNode().remove();
+ }
+ List matchingNodes = new ArrayList();
+ for (int i = 0; i < values.length; i++)
+ {
+ Node n = testRootNode.addNode("node" + i);
+ n.setProperty(propertyName1, values[i]);
+ if (matches[i])
+ {
+ matchingNodes.add(n);
+ }
+ }
+ testRootNode.save();
- Node[] nodes = (Node[]) matchingNodes.toArray(new Node[matchingNodes.size()]);
- String sqlOperation = operation;
- if (operation.equals("!=")) {
- sqlOperation = "<>";
- }
+ Node[] nodes = (Node[])matchingNodes.toArray(new Node[matchingNodes.size()]);
+ String sqlOperation = operation;
+ if (operation.equals("!="))
+ {
+ sqlOperation = "<>";
+ }
- // run queries with lower-case
- String xpath = testPath;
- if (operation.equals("like")) {
- xpath += "/*[jcr:like(fn:lower-case(@" + propertyName1 +
- "), '" + queryTerm.toLowerCase() + "')]";
- } else {
- xpath += "/*[fn:lower-case(@" + propertyName1 +
- ") " + operation + " '" + queryTerm.toLowerCase() + "']";
- }
- executeXPathQuery(xpath, nodes);
+ // run queries with lower-case
+ String xpath = testPath;
+ if (operation.equals("like"))
+ {
+ xpath += "/*[jcr:like(fn:lower-case(@" + propertyName1 + "), '" + queryTerm.toLowerCase() + "')]";
+ }
+ else
+ {
+ xpath += "/*[fn:lower-case(@" + propertyName1 + ") " + operation + " '" + queryTerm.toLowerCase() + "']";
+ }
+ executeXPathQuery(xpath, nodes);
- String sql = "select * from nt:base where jcr:path like '" +
- testRoot + "/%' and LOWER(" + propertyName1 + ") " +
- sqlOperation + " '" + queryTerm.toLowerCase() + "'";
- executeSQLQuery(sql, nodes);
+ String sql =
+ "select * from nt:base where jcr:path like '" + testRoot + "/%' and LOWER(" + propertyName1 + ") "
+ + sqlOperation + " '" + queryTerm.toLowerCase() + "'";
+ executeSQLQuery(sql, nodes);
+ // run queries with upper-case
+ xpath = testPath;
+ if (operation.equals("like"))
+ {
+ xpath += "/*[jcr:like(fn:upper-case(@" + propertyName1 + "), '" + queryTerm.toUpperCase() + "')]";
+ }
+ else
+ {
+ xpath += "/*[fn:upper-case(@" + propertyName1 + ") " + operation + " '" + queryTerm.toUpperCase() + "']";
+ }
+ executeXPathQuery(xpath, nodes);
+ sql =
+ "select * from nt:base where jcr:path like '" + testRoot + "/%' and UPPER(" + propertyName1 + ") "
+ + sqlOperation + " '" + queryTerm.toUpperCase() + "'";
+ executeSQLQuery(sql, nodes);
- // run queries with upper-case
- xpath = testPath;
- if (operation.equals("like")) {
- xpath += "/*[jcr:like(fn:upper-case(@" + propertyName1 +
- "), '" + queryTerm.toUpperCase() + "')]";
- } else {
- xpath += "/*[fn:upper-case(@" + propertyName1 +
- ") " + operation + " '" + queryTerm.toUpperCase() + "']";
- }
- executeXPathQuery(xpath, nodes);
+ }
- sql = "select * from nt:base where jcr:path like '" +
- testRoot + "/%' and UPPER(" + propertyName1 + ") " +
- sqlOperation + " '" + queryTerm.toUpperCase() + "'";
- executeSQLQuery(sql, nodes);
+ private char getRandomChar(String pool, Random random)
+ {
+ return pool.charAt(random.nextInt(pool.length()));
+ }
-
- }
-
- private char getRandomChar(String pool, Random random) {
- return pool.charAt(random.nextInt(pool.length()));
- }
-
-// protected static int getOperatorForString(String operator) {
-// Integer i = (Integer) OPERATORS.get(operator);
-// if (i == null) {
-// throw new IllegalArgumentException("unknown operator: " + operator);
-// }
-// return i.intValue();
-// }
+ // protected static int getOperatorForString(String operator) {
+ // Integer i = (Integer) OPERATORS.get(operator);
+ // if (i == null) {
+ // throw new IllegalArgumentException("unknown operator: " + operator);
+ // }
+ // return i.intValue();
+ // }
}
16 years, 8 months