Author: nzamosenchuk
Date: 2010-04-08 05:51:38 -0400 (Thu, 08 Apr 2010)
New Revision: 2221
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
Log:
EXOJCR-545: Added JBossCache configuration analyzer.
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-08
07:22:21 UTC (rev 2220)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-08
09:51:38 UTC (rev 2221)
@@ -38,8 +38,11 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.transaction.TransactionService;
+import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.eviction.ExpirationAlgorithm;
import java.io.Serializable;
import java.util.ArrayList;
@@ -65,24 +68,24 @@
* <ul>
* <li>/$ITEMS - stores items by Id (i.e. /$ITEMS/itemId)</li>
* <li>/$CHILD_NODES, /$CHILD_PROPS - stores items by parentId and name (i.e.
/$CHILD_NODES/parentId/childName.$ITEM_ID)</li>
- * <li>/$CHILD_NODES_LIST, /$CHILD_PROPS_LIST - stores child list by parentId
and child Id
+ * <li>/$CHILD_NODES_LIST, /$CHILD_PROPS_LIST - stores child list by parentId
and child Id
* (i.e. /$CHILD_NODES_LIST/parentId.lists = serialized
Set<Object>)</li>
* </ul>
- * </li>
+ * </li>
* <li>all child properties/nodes lists should be evicted from parent at same time
* i.e. for /$CHILD_NODES_LIST, /$CHILD_PROPS_LIST we need customized eviction
policy (EvictionActionPolicy) to evict
* whole list on one of childs eviction
- * </li>
+ * </li>
* </ul>
*
- * <p/>
- * Current state notes (subject of change):
+ * <p/>
+ * Current state notes (subject of change):
* <ul>
* <li>cache implements WorkspaceStorageCache, without any stuff about references
and locks</li>
* <li>transaction style implemented via JBC barches, do with JTA (i.e. via
exo's TransactionService + JBoss TM)</li>
* <li>we need customized eviction policy (EvictionActionPolicy) for
/$CHILD_NODES_LIST, /$CHILD_PROPS_LIST</li>
* </ul>
- *
+ *
* @author <a href="mailto:peter.nedonosko@exoplatform.com">Peter
Nedonosko</a>
* @version $Id: JBossCacheWorkspaceStorageCache.java 13869 2008-05-05 08:40:10Z
pnedonosko $
*/
@@ -253,7 +256,7 @@
*/
public JBossCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, TransactionService
transactionService,
ConfigurationManager cfm) throws RepositoryException,
RepositoryConfigurationException
- {
+ {
if (wsConfig.getCache() == null)
{
throw new RepositoryConfigurationException("Cache configuration not
found");
@@ -271,6 +274,39 @@
factory = new ExoJBossCacheFactory<Serializable, Object>(cfm);
}
+ // create parent JBossCache instance
+ Cache<Serializable, Object> parentCache =
factory.createCache(wsConfig.getCache());
+ // get all eviction configurations
+ List<EvictionRegionConfig> evictionConfigurations =
+ parentCache.getConfiguration().getEvictionConfig().getEvictionRegionConfigs();
+ // append and default eviction configuration, since it is not present in region
configurations
+
evictionConfigurations.add(parentCache.getConfiguration().getEvictionConfig().getDefaultEvictionRegionConfig());
+
+ boolean useExpiration = false;
+ Iterator<EvictionRegionConfig> iterator = evictionConfigurations.iterator();
+
+ // looking over all eviction configurations till the end or till some expiration
algorithm subclass not found.
+ while (iterator.hasNext() && !useExpiration)
+ {
+ try
+ {
+ String evictionClassName =
iterator.next().getEvictionAlgorithmConfig().getEvictionAlgorithmClassName();
+ Class<?> evictionClass = Class.forName(evictionClassName);
+ // returns true if ExpirationAlgorithm is superClass of evictionClass
+ useExpiration = useExpiration ||
ExpirationAlgorithm.class.isAssignableFrom(evictionClass);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new RepositoryConfigurationException("Unable to check JBossCache
eviction class.", e);
+ }
+ }
+
+ if (useExpiration)
+ {
+ LOG.info("Using BufferedJBossCache compatible with Expiration
algorithm.");
+ }
+
+ // TODO: create appropriate cache with useExpiration set or not.
this.cache = new BufferedJBossCache(factory.createCache(wsConfig.getCache()));
this.itemsRoot = Fqn.fromElements(ITEMS);
@@ -287,17 +323,17 @@
createResidentNode(childProps);
createResidentNode(childPropsList);
createResidentNode(itemsRoot);
- }
+ }
/**
* Cache constructor with JBossCache JTA transaction support.
*
- * @param wsConfig WorkspaceEntry workspace config
+ * @param wsConfig WorkspaceEntry workspace config
* @throws RepositoryException if error of initialization
* @throws RepositoryConfigurationException if error of configuration
*/
public JBossCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, ConfigurationManager
cfm)
- throws RepositoryException, RepositoryConfigurationException
+ throws RepositoryException, RepositoryConfigurationException
{
this(wsConfig, null, cfm);
}
@@ -336,7 +372,7 @@
/**
* Return TransactionManager used by JBossCache backing the JCR cache.
*
- * @return TransactionManager
+ * @return TransactionManager
*/
public TransactionManager getTransactionManager()
{
@@ -406,8 +442,8 @@
{
if (state.isPersisted())
{
- // There was a problem with removing a list of samename siblings in on
transaction,
- // so putItemInBufferedCache(..) and updateInBufferedCache(..) used
instead put(..) and update (..) methods.
+ // There was a problem with removing a list of samename siblings in on
transaction,
+ // so putItemInBufferedCache(..) and updateInBufferedCache(..) used
instead put(..) and update (..) methods.
ItemData prevItem = putItemInBufferedCache(state.getData());
if (prevItem != null && state.isNode())
{
@@ -446,8 +482,8 @@
}
/**
- * {@inheritDoc}
- */
+ * {@inheritDoc}
+ */
public void addChildNodes(NodeData parent, List<NodeData> childs)
{
boolean inTransaction = cache.isTransactionActive();
@@ -541,7 +577,7 @@
// {
// cache.beginTransaction();
// cache.setLocal(true);
- //
+ //
// }
// finally
// {
@@ -632,7 +668,7 @@
/**
* Internal get child properties.
*
- * @param parentId String
+ * @param parentId String
* @param withValue boolean, if true only "full" Propeties can be returned
* @return List of PropertyData
*/
@@ -777,7 +813,7 @@
{
// add in CHILD_NODES
cache.put(makeChildFqn(childNodes, node.getParentIdentifier(),
node.getQPath().getEntries()[node.getQPath()
- .getEntries().length - 1]), ITEM_ID, node.getIdentifier());
+
.getEntries().length - 1]), ITEM_ID, node.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childNodesList, node
.getParentIdentifier())) != null)
@@ -798,7 +834,7 @@
{
// add in CHILD_NODES
cache.put(makeChildFqn(childNodes, node.getParentIdentifier(),
node.getQPath().getEntries()[node.getQPath()
- .getEntries().length - 1]), ITEM_ID, node.getIdentifier());
+
.getEntries().length - 1]), ITEM_ID, node.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childNodesList, node
.getParentIdentifier())) != null)
@@ -822,7 +858,7 @@
{
// add in CHILD_PROPS
cache.put(makeChildFqn(childProps, prop.getParentIdentifier(),
prop.getQPath().getEntries()[prop.getQPath()
- .getEntries().length - 1]), ITEM_ID, prop.getIdentifier());
+
.getEntries().length - 1]), ITEM_ID, prop.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childPropsList, prop
.getParentIdentifier())) != null)
@@ -844,7 +880,7 @@
// remove from CHILD_NODES of parent
cache.removeNode(makeChildFqn(childNodes, item.getParentIdentifier(),
item.getQPath().getEntries()[item
- .getQPath().getEntries().length - 1]));
+
.getQPath().getEntries().length - 1]));
// remove from CHILD_NODES_LIST of parent
cache.removeFromList(makeChildListFqn(childNodesList,
item.getParentIdentifier()), ITEM_LIST, item
@@ -867,7 +903,7 @@
{
// remove from CHILD_PROPS
cache.removeNode(makeChildFqn(childProps, item.getParentIdentifier(),
item.getQPath().getEntries()[item
- .getQPath().getEntries().length - 1]));
+
.getQPath().getEntries().length - 1]));
// remove from CHILD_PROPS_LIST
cache.removeFromList(makeChildListFqn(childPropsList,
item.getParentIdentifier()), ITEM_LIST, item
@@ -900,7 +936,7 @@
}
/**
- * Update Node hierachy in case of same-name siblings reorder.
+ * Update Node hierachy in case of same-name siblings reorder.
* Assumes the new (updated) nodes already putted in the cache. Previous name of
updated nodes will be calculated
* and that node will be deleted (if has same id as the new node). Childs paths will
be updated to a new node path.
*
@@ -912,7 +948,7 @@
// get previously cached NodeData and using its name remove child on the parent
Fqn<String> prevFqn =
makeChildFqn(childNodes, node.getParentIdentifier(),
prevNode.getQPath().getEntries()[prevNode.getQPath()
- .getEntries().length - 1]);
+
.getEntries().length - 1]);
if (node.getIdentifier().equals(cache.get(prevFqn, ITEM_ID)))
{
// it's same-name siblings re-ordering, delete previous child
@@ -942,7 +978,7 @@
// get previously cached NodeData and using its name remove child on the parent
Fqn<String> prevFqn =
makeChildFqn(childNodes, node.getParentIdentifier(),
prevNode.getQPath().getEntries()[prevNode.getQPath()
- .getEntries().length - 1]);
+
.getEntries().length - 1]);
if (node.getIdentifier().equals(cache.getFromBuffer(prevFqn, ITEM_ID)))
{
// it's same-name siblings re-ordering, delete previous child
@@ -978,15 +1014,15 @@
PropertyData prevProp = iter.next();
if (inheritACL
- && (prevProp.getQPath().getName().equals(Constants.EXO_PERMISSIONS)
|| prevProp.getQPath().getName()
- .equals(Constants.EXO_OWNER)))
+ &&
(prevProp.getQPath().getName().equals(Constants.EXO_PERMISSIONS) ||
prevProp.getQPath().getName()
+ .equals(Constants.EXO_OWNER)))
{
inheritACL = false;
}
// recreate with new path for child Props only
QPath newPath =
QPath
- .makeChildPath(rootPath,
prevProp.getQPath().getEntries()[prevProp.getQPath().getEntries().length - 1]);
+ .makeChildPath(rootPath,
prevProp.getQPath().getEntries()[prevProp.getQPath().getEntries().length - 1]);
TransientPropertyData newProp =
new TransientPropertyData(newPath, prevProp.getIdentifier(),
prevProp.getPersistedVersion(), prevProp
.getType(), prevProp.getParentIdentifier(), prevProp.isMultiValued(),
prevProp.getValues());
@@ -1000,7 +1036,7 @@
// recreate with new path for child Nodes only
QPath newPath =
QPath
- .makeChildPath(rootPath,
prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1]);
+ .makeChildPath(rootPath,
prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1]);
TransientNodeData newNode =
new TransientNodeData(newPath, prevNode.getIdentifier(),
prevNode.getPersistedVersion(), prevNode
.getPrimaryTypeName(), prevNode.getMixinTypeNames(),
prevNode.getOrderNumber(), prevNode
@@ -1035,7 +1071,7 @@
TransientNodeData newNode =
new TransientNodeData(prevNode.getQPath(), prevNode.getIdentifier(),
prevNode.getPersistedVersion(),
prevNode.getPrimaryTypeName(), prevNode.getMixinTypeNames(),
prevNode.getOrderNumber(), prevNode
- .getParentIdentifier(), acl);
+ .getParentIdentifier(), acl);
// update this node
cache.put(makeItemFqn(newNode.getIdentifier()), ITEM_DATA, newNode);
// update childs recursive