Author: sergiykarpenko
Date: 2010-03-29 06:39:11 -0400 (Mon, 29 Mar 2010)
New Revision: 2178
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
Log:
EXOJCR-587: .InvalidItemStateException - No same-name sibling exists fixed
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2010-03-29
09:37:22 UTC (rev 2177)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2010-03-29
10:39:11 UTC (rev 2178)
@@ -252,6 +252,30 @@
return parentCache.get(fqn, key);
}
+ /**
+ * Look for Object by Fqn and key in internal buffer. If Buffer do not contain object,
than return from JBoss-cache.
+ *
+ * @param fqn - Fqn
+ * @param key
+ * @return
+ */
+ public Object getFromBuffer(Fqn fqn, Serializable key)
+ {
+ //look at buffer for first
+ CompressedChangesBuffer changesContainer = getChangesBufferSafe();
+
+ Object objectFromBuffer = getObjectFromChangesContainer(changesContainer, fqn,
key);
+
+ if (objectFromBuffer != null)
+ {
+ return objectFromBuffer;
+ }
+ else
+ {
+ return parentCache.get(fqn, key);
+ }
+ }
+
/* (non-Javadoc)
* @see org.jboss.cache.Cache#get(java.lang.String, java.lang.Object)
*/
@@ -442,6 +466,45 @@
return parentCache.get(fqn, key);
}
+ public Object putInBuffer(Fqn fqn, Serializable key, Object value)
+ {
+ CompressedChangesBuffer changesContainer = getChangesBufferSafe();
+
+ // take Object from buffer for first
+ Object prevObject = getObjectFromChangesContainer(changesContainer, fqn, key);
+
+ changesContainer.add(new PutKeyValueContainer(fqn, key, value, parentCache,
changesContainer.getHistoryIndex(),
+ local.get()));
+
+ if (prevObject != null)
+ {
+ return prevObject;
+ }
+ else
+ {
+ return parentCache.get(fqn, key);
+ }
+ }
+
+ private Object getObjectFromChangesContainer(CompressedChangesBuffer changesContainer,
Fqn fqn, Serializable key)
+ {
+ List<ChangesContainer> changes = changesContainer.getSortedList();
+ Object object = null;
+ for (ChangesContainer change : changes)
+ {
+ if (change.getChangesType().equals(ChangesType.PUT_KEY) &&
change.getFqn().equals(fqn))
+ {
+ PutKeyValueContainer cont = ((PutKeyValueContainer)change);
+ if (cont.key.equals(key))
+ {
+ object = ((PutKeyValueContainer)change).value;
+ }
+ }
+ }
+
+ return object;
+ }
+
/* (non-Javadoc)
* @see org.jboss.cache.Cache#put(java.lang.String, java.util.Map)
*/
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-03-29
09:37:22 UTC (rev 2177)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-03-29
10:39:11 UTC (rev 2178)
@@ -406,11 +406,13 @@
{
if (state.isPersisted())
{
- ItemData prevItem = putItem(state.getData());
+ // 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())
{
- // nodes reordered, if prev is null it's InvalidItemState case
- update((NodeData)state.getData(), (NodeData)prevItem);
+ // nodes reordered, if previous is null it's InvalidItemState
case
+ updateInBuffer((NodeData)state.getData(), (NodeData)prevItem);
}
}
}
@@ -749,6 +751,19 @@
}
}
+ protected ItemData putItemInBufferedCache(ItemData item)
+ {
+ if (item.isNode())
+ {
+ return putNodeInBufferedCache((NodeData)item, ModifyChildOption.MODIFY);
+ }
+ else
+ {
+ return putProperty((PropertyData)item, ModifyChildOption.MODIFY);
+ }
+
+ }
+
/**
* Internal put Node.
*
@@ -776,6 +791,27 @@
return (ItemData)cache.put(makeItemFqn(node.getIdentifier()), ITEM_DATA, node);
}
+ protected ItemData putNodeInBufferedCache(NodeData node, ModifyChildOption
modifyListsOfChild)
+ {
+ // if not a root node
+ if (node.getParentIdentifier() != null)
+ {
+ // add in CHILD_NODES
+ cache.put(makeChildFqn(childNodes, node.getParentIdentifier(),
node.getQPath().getEntries()[node.getQPath()
+ .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)
+ || modifyListsOfChild == ModifyChildOption.FORCE_MODIFY)
+ {
+ cache.addToList(makeChildListFqn(childNodesList, node.getParentIdentifier()),
ITEM_LIST, node
+ .getIdentifier());
+ }
+ }
+ // add in ITEMS
+ return (ItemData)cache.putInBuffer(makeItemFqn(node.getIdentifier()), ITEM_DATA,
node);
+ }
+
/**
* Internal put Property.
*
@@ -896,6 +932,36 @@
}
/**
+ * This method duplicate update method, except using getFromBuffer inside.
+ *
+ * @param node NodeData
+ * @param prevNode NodeData
+ */
+ protected void updateInBuffer(final NodeData node, final NodeData prevNode)
+ {
+ // 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]);
+ if (node.getIdentifier().equals(cache.getFromBuffer(prevFqn, ITEM_ID)))
+ {
+ // it's same-name siblings re-ordering, delete previous child
+ if (!cache.removeNode(prevFqn) && LOG.isDebugEnabled())
+ {
+ LOG.debug("Node not extists as a child but update asked " +
node.getQPath().getAsString());
+ }
+ }
+
+ // update childs paths if index changed
+ int nodeIndex = node.getQPath().getEntries()[node.getQPath().getEntries().length -
1].getIndex();
+ int prevNodeIndex =
prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1].getIndex();
+ if (nodeIndex != prevNodeIndex)
+ {
+ updateTreePath(node.getIdentifier(), node.getQPath(), null); // don't change
ACL, it's same parent
+ }
+ }
+
+ /**
* Update Nodes tree with new path.
*
* @param parentId String - root node id of JCR subtree.