You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2008/10/15 14:59:22 UTC
svn commit: r704898 [1/4] - in /jackrabbit/branches/1.5: ./
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/
jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit...
Author: jukka
Date: Wed Oct 15 05:59:19 2008
New Revision: 704898
URL: http://svn.apache.org/viewvc?rev=704898&view=rev
Log:
1.5: Merged revisions 704358 and 704361 (JCR-1783, JCR-1799 and JCR-1800)
Added:
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AddPropertyTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/AddPropertyTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/ExternalModificationTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/ExternalModificationTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/GetPropertyTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/GetPropertyTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MixinModificationTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MixinModificationTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MoveCombinedTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MoveCombinedTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MoveToNewTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MoveToNewTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RemoveMovedNodeTest.java
- copied unchanged from r704361, jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RemoveMovedNodeTest.java
Modified:
jackrabbit/branches/1.5/ (props changed)
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/LazyItemIterator.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeAttic.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntriesImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntries.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntriesImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryValidation.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManagerImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntry.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/PropertyEntryImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractCopy.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddProperty.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkin.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Checkout.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Clone.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Copy.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRefresh.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockRelease.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Merge.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Operation.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveVersion.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ResolveMergeConflict.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Restore.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetPropertyValue.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Update.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/WorkspaceImport.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateFactory.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/HierarchyNodeTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/MoveNewTreeTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/NodeOrderTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RefreshMovedTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RefreshTrueTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RemoveNodeTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/ReorderMoveTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/RevertMoveTest.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java
jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/nodetype/AddMixinTest.java
jackrabbit/branches/1.5/jackrabbit-spi2jcr/pom.xml
jackrabbit/branches/1.5/jackrabbit-spi2jcr/src/test/java/org/apache/jackrabbit/spi2jcr/RepositoryStubImpl.java
Propchange: jackrabbit/branches/1.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct 15 05:59:19 2008
@@ -1,2 +1,2 @@
/jackrabbit/branches/1.3:631261
-/jackrabbit/trunk:703899-704158,704165,704167,704324
+/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java Wed Oct 15 05:59:19 2008
@@ -236,15 +236,16 @@
public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException {
// check session status
session.checkIsAlive();
+ int status = state.getStatus();
// check if item has been removed by this or another session
- if (Status.isTerminal(state.getStatus()) || Status.EXISTING_REMOVED == state.getStatus()) {
+ if (Status.isTerminal(status) || Status.EXISTING_REMOVED == status) {
throw new InvalidItemStateException("Item '" + this + "' doesn't exist anymore");
}
/* If 'keepChanges' is true, items that do not have changes pending have
their state refreshed to reflect the current saved state */
if (keepChanges) {
- if (state.getStatus() != Status.NEW &&
+ if (status != Status.NEW &&
session.getCacheBehaviour() != CacheBehaviour.OBSERVATION) {
// merge current transient modifications with latest changes
// from the 'server'.
@@ -254,7 +255,7 @@
}
} else {
// check status of item state
- if (state.getStatus() == Status.NEW) {
+ if (status == Status.NEW) {
String msg = "Cannot refresh a new item (" + safeGetJCRPath() + ").";
log.debug(msg);
throw new RepositoryException(msg);
@@ -416,7 +417,7 @@
}
// now check if valid
if (!state.isValid()) {
- throw new InvalidItemStateException("Item '" + this + "' doesn't exist anymore");
+ throw new InvalidItemStateException("Item '" + this + "' doesn't exist anymore. (Status = " +Status.getName(state.getStatus())+ ")");
}
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/LazyItemIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/LazyItemIterator.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/LazyItemIterator.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/LazyItemIterator.java Wed Oct 15 05:59:19 2008
@@ -127,12 +127,8 @@
HierarchyEntry entry = (HierarchyEntry) iter.next();
try {
nextItem = itemMgr.getItem(entry);
- } catch (ItemNotFoundException e) {
- log.debug("Ignoring nonexistent item " + entry);
- // reduce the size ... and try the next one
- size--;
} catch (RepositoryException e) {
- log.error("failed to fetch item " + entry + ", skipping...", e);
+ log.warn("Failed to fetch item " + entry + ", skipping.", e.getMessage());
// reduce the size... and try the next one
size--;
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Wed Oct 15 05:59:19 2008
@@ -1272,17 +1272,9 @@
Operation an = AddNode.create(getNodeState(), nodeName, nodeTypeName, null);
session.getSessionItemStateManager().execute(an);
- // retrieve id of state that has been created during execution of AddNode
- NodeEntry entry;
- List cne = getNodeEntry().getNodeEntries(nodeName);
- if (definition.allowsSameNameSiblings()) {
- // TODO TOBEFIXED find proper solution. problem with SNSs
- entry = ((NodeEntry)cne.get(cne.size()-1));
- } else {
- entry = ((NodeEntry)cne.get(0));
- }
// finally retrieve the new node
- return (Node) itemMgr.getItem(entry);
+ List addedStates = ((AddNode) an).getAddedStates();
+ return (Node) itemMgr.getItem(((NodeState) addedStates.get(0)).getHierarchyEntry());
}
/**
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java Wed Oct 15 05:59:19 2008
@@ -703,7 +703,7 @@
try {
ItemState target = changeLog.getTarget();
batch = service.createBatch(sessionInfo, target.getId());
- Iterator it = changeLog.getOperations();
+ Iterator it = changeLog.getOperations().iterator();
while (it.hasNext()) {
Operation op = (Operation) it.next();
log.debug("executing " + op.getName());
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeAttic.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeAttic.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeAttic.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeAttic.java Wed Oct 15 05:59:19 2008
@@ -116,12 +116,17 @@
attic.add(movedEntry);
}
- void remove(NodeEntryImpl movedEntry) {
+ boolean remove(NodeEntryImpl movedEntry) {
if (attic.contains(movedEntry)) {
- attic.remove(movedEntry);
+ return attic.remove(movedEntry);
}
+ return false;
}
+ Iterator iterator() {
+ return attic.iterator();
+ }
+
void clear() {
if (attic != null) {
attic.clear();
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java Wed Oct 15 05:59:19 2008
@@ -18,7 +18,6 @@
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
-import org.apache.jackrabbit.spi.ChildInfo;
import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
@@ -33,6 +32,13 @@
public interface ChildNodeEntries {
/**
+ * @return <code>true</code> if this <code>ChildNodeEntries</code> have
+ * been updated or completely loaded without being invalidated in the
+ * mean time.
+ */
+ boolean isComplete();
+
+ /**
* Mark <code>ChildNodeEntries</code> in order to force reloading the
* entries.
*/
@@ -88,16 +94,6 @@
NodeEntry get(Name nodeName, String uniqueID);
/**
- * Find the matching NodeEntry for the given <code>ChildInfo</code>. Returns
- * <code>null</code> if no matching entry can be found. NOTE, that no check
- * for validity of the entries is made.
- *
- * @param childInfo
- * @return matching entry or <code>null</code>.
- */
- NodeEntry get(ChildInfo childInfo);
-
- /**
* Adds a <code>NodeEntry</code> to the end of the list. Same as
* {@link #add(NodeEntry, int)}, where the index is {@link Path#INDEX_UNDEFINED}.
*
@@ -123,9 +119,10 @@
* Adds a the new <code>NodeEntry</code> before <code>beforeEntry</code>.
*
* @param entry
+ * @param index
* @param beforeEntry
*/
- void add(NodeEntry entry, NodeEntry beforeEntry);
+ void add(NodeEntry entry, int index, NodeEntry beforeEntry);
/**
* Removes the child node entry refering to the node state.
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntriesImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntriesImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntriesImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntriesImpl.java Wed Oct 15 05:59:19 2008
@@ -65,33 +65,6 @@
private final NodeEntry parent;
private final EntryFactory factory;
- /**
- * Create a new <code>ChildNodeEntries</code> collection and retrieve
- * the entries from the persistent layer if the parent is neither
- * NEW nor in a terminal status.
- */
- ChildNodeEntriesImpl(NodeEntry parent, EntryFactory factory) throws ItemNotFoundException, RepositoryException {
- this.parent = parent;
- this.factory = factory;
-
- if (parent.getStatus() != Status.NEW && !Status.isTerminal(parent.getStatus())) {
- NodeId id = parent.getWorkspaceId();
- Iterator childNodeInfos = factory.getItemStateFactory().getChildNodeInfos(id);
- // simply add all child entries to the empty collection
- while (childNodeInfos.hasNext()) {
- ChildInfo ci = (ChildInfo) childNodeInfos.next();
- NodeEntry entry = factory.createNodeEntry(parent, ci.getName(), ci.getUniqueID());
- add(entry, ci.getIndex());
- }
- } /* else: cannot retrieve child-entries from persistent layer. the parent
- * is NEW (transient only) or already removed from the persistent layer.
- */
-
- /* all child infos have been read from the persistent layer therefore
- mark this child-node-entries as 'complete' */
- complete = true;
- }
-
/**
* Create a new <code>ChildNodeEntries</code> collection from the given
* <code>childNodeInfos</code> instead of retrieving them from the
@@ -122,10 +95,24 @@
}
/**
- * @see ChildNodeEntries#getStatus()
+ * @param childEntry
+ * @return The node entry that directly follows the given <code>childEntry</code>
+ * or <code>null</code> if the given <code>childEntry</code> has no successor
+ * or was not found in this <code>ChildNodeEntries</code>.
+ */
+ NodeEntry getNext(NodeEntry childEntry) {
+ LinkedEntries.LinkNode ln = entries.getLinkNode(childEntry);
+ LinkedEntries.LinkNode nextLn = (ln == null) ? null : ln.getNextLinkNode();
+ return (nextLn == null) ? null : nextLn.getNodeEntry();
+ }
+
+ /**
+ * @see ChildNodeEntries#isComplete()
*/
- public int getStatus() {
- return status;
+ public boolean isComplete() {
+ return (status == STATUS_OK && complete) ||
+ parent.getStatus() == Status.NEW ||
+ Status.isTerminal(parent.getStatus());
}
/**
@@ -139,8 +126,7 @@
* @see ChildNodeEntries#reload()
*/
public synchronized void reload() throws ItemNotFoundException, RepositoryException {
- if (status == STATUS_OK && complete ||
- parent.getStatus() == Status.NEW || Status.isTerminal(parent.getStatus())) {
+ if (isComplete()) {
// nothing to do
return;
}
@@ -150,45 +136,38 @@
update(childNodeInfos);
}
+ /**
+ * Update the child node entries according to the child-infos obtained
+ * from the persistent layer.
+ * NOTE: the status of the entries already present is not respected. Thus
+ * new or removed entries are not touched in order not to modify the
+ * transient status of the parent. Operations that affect the set or order
+ * of child entries (AddNode, Move, Reorder) currently assert the
+ * completeness of the ChildNodeEntries, therefore avoiding an update
+ * resulting in inconsistent entries.
+ *
+ * @param childNodeInfos
+ * @see HierarchyEntry#reload(boolean, boolean) that ignores items with
+ * pending changes.
+ * @see org.apache.jackrabbit.jcr2spi.operation.AddNode
+ * @see org.apache.jackrabbit.jcr2spi.operation.Move
+ * @see org.apache.jackrabbit.jcr2spi.operation.Reorder
+ */
synchronized void update(Iterator childNodeInfos) {
- // TODO: should existing (not-new) entries that are not present in the childInfos be removed?
- // create list from all ChildInfos (for multiple loop)
- List cInfos = new ArrayList();
+ // insert missing entries and reorder all if necessary.
+ LinkedEntries.LinkNode prevLN = null;
while (childNodeInfos.hasNext()) {
- cInfos.add(childNodeInfos.next());
- }
- // first make sure the ordering of all existing entries is ok
- NodeEntry entry = null;
- for (Iterator it = cInfos.iterator(); it.hasNext();) {
- ChildInfo ci = (ChildInfo) it.next();
- NodeEntry nextEntry = get(ci);
- if (nextEntry != null) {
- if (entry != null) {
- reorder(entry, nextEntry);
- }
- entry = nextEntry;
- }
- }
- // then insert the 'new' entries
- List newEntries = new ArrayList();
- for (Iterator it = cInfos.iterator(); it.hasNext();) {
- ChildInfo ci = (ChildInfo) it.next();
- NodeEntry beforeEntry = get(ci);
- if (beforeEntry == null) {
- NodeEntry ne = factory.createNodeEntry(parent, ci.getName(), ci.getUniqueID());
- newEntries.add(ne);
- } else {
- // insert all new entries from the list BEFORE the existing
- // 'nextEntry'. Then clear the list.
- for (int i = 0; i < newEntries.size(); i++) {
- add((NodeEntry) newEntries.get(i), beforeEntry);
- }
- newEntries.clear();
- }
- }
- // deal with new entries at the end
- for (int i = 0; i < newEntries.size(); i++) {
- add((NodeEntry) newEntries.get(i));
+ ChildInfo ci = (ChildInfo) childNodeInfos.next();
+ LinkedEntries.LinkNode ln = entriesByName.getLinkNode(ci.getName(), ci.getIndex(), ci.getUniqueID());
+ if (ln == null) {
+ // add missing at the correct position.
+ NodeEntry entry = factory.createNodeEntry(parent, ci.getName(), ci.getUniqueID());
+ ln = internalAddAfter(entry, ci.getIndex(), prevLN);
+ } else if (prevLN != null) {
+ // assert correct order of existing
+ reorderAfter(ln, prevLN);
+ }
+ prevLN = ln;
}
// finally reset the status
status = STATUS_OK;
@@ -241,26 +220,6 @@
}
/**
- * @see ChildNodeEntries#get(ChildInfo)
- */
- public NodeEntry get(ChildInfo childInfo) {
- String uniqueID = childInfo.getUniqueID();
- NodeEntry child = null;
- if (uniqueID != null) {
- child = get(childInfo.getName(), uniqueID);
- }
- // try to load the child entry by name and index.
- // this is required in case of a null uniqueID OR if the child entry has
- // been created but never been resolved and therefore the uniqueID might
- // be unknown.
- if (child == null) {
- int index = childInfo.getIndex();
- child = entriesByName.getNodeEntry(childInfo.getName(), index);
- }
- return child;
- }
-
- /**
* Adds a <code>NodeEntry</code> to the end of the list. Same as
* {@link #add(NodeEntry, int)}, where the index is {@link Path#INDEX_UNDEFINED}.
*
@@ -282,6 +241,24 @@
}
/**
+ * @see ChildNodeEntries#add(NodeEntry, int, NodeEntry)
+ */
+ public synchronized void add(NodeEntry entry, int index, NodeEntry beforeEntry) {
+ if (beforeEntry != null) {
+ // the link node where the new entry is ordered before
+ LinkedEntries.LinkNode beforeLN = entries.getLinkNode(beforeEntry);
+ if (beforeLN == null) {
+ throw new NoSuchElementException();
+ }
+ LinkedEntries.LinkNode insertLN = internalAdd(entry, index);
+ reorder(entry.getName(), insertLN, beforeLN);
+ } else {
+ // 'before' is null -> simply append new entry at the end
+ add(entry);
+ }
+ }
+
+ /**
*
* @param entry
* @param index
@@ -308,8 +285,8 @@
}
// add new entry
- LinkedEntries.LinkNode ln = entries.add(entry);
- entriesByName.put(nodeName, ln);
+ LinkedEntries.LinkNode ln = entries.add(entry, index);
+ entriesByName.put(nodeName, index, ln);
// reorder the child entries if, the new entry must be inserted rather
// than appended at the end of the list.
@@ -320,21 +297,18 @@
}
/**
- * @see ChildNodeEntries#add(NodeEntry, NodeEntry)
+ * Add the specified new entry after the specified <code>insertAfter</code>.
+ *
+ * @param newEntry
+ * @param index
+ * @param insertAfter
+ * @return
*/
- public synchronized void add(NodeEntry entry, NodeEntry beforeEntry) {
- if (beforeEntry != null) {
- // the link node where the new entry is ordered before
- LinkedEntries.LinkNode beforeLN = entries.getLinkNode(beforeEntry);
- if (beforeLN == null) {
- throw new NoSuchElementException();
- }
- LinkedEntries.LinkNode insertLN = internalAdd(entry, Path.INDEX_UNDEFINED);
- reorder(entry.getName(), insertLN, beforeLN);
- } else {
- // 'before' is null -> simply append new entry at the end
- add(entry);
- }
+ private LinkedEntries.LinkNode internalAddAfter(NodeEntry newEntry, int index,
+ LinkedEntries.LinkNode insertAfter) {
+ LinkedEntries.LinkNode ln = entries.addAfter(newEntry, index, insertAfter);
+ entriesByName.put(newEntry.getName(), index, ln);
+ return ln;
}
/**
@@ -411,7 +385,7 @@
LinkedEntries.LinkNode ln = (LinkedEntries.LinkNode) it.next();
if (ln == beforeLN) {
break;
- } else if (ln != insertLN && ln.getNodeEntry().getName().equals(insertName)) {
+ } else if (ln != insertLN && insertName.equals(ln.qName)) {
position++;
} // else: ln == inserLN OR no SNS -> not relevant for position count
}
@@ -422,6 +396,60 @@
entries.reorderNode(insertLN, beforeLN);
}
+ /**
+ *
+ * @param insertEntry
+ * @param afterEntry
+ */
+ private void reorderAfter(LinkedEntries.LinkNode insertLN, LinkedEntries.LinkNode afterLN) {
+ // the link node to move
+ if (insertLN == null) {
+ throw new NoSuchElementException();
+ }
+ // the link node where insertLN is ordered after
+ if (afterLN == null) {
+ // move to first position
+ afterLN = entries.getHeader();
+ }
+
+ LinkedEntries.LinkNode currentAfter = afterLN.getNextLinkNode();
+ if (currentAfter == insertLN) {
+ log.debug("Already ordered behind 'afterEntry'.");
+ // nothing to do
+ return;
+ } else {
+ // reorder named map
+ Name insertName = insertLN.qName;
+ if (entriesByName.containsSiblings(insertName)) {
+ int position = -1; // default: reorder to the end.
+ if (afterLN == entries.getHeader()) {
+ // move to the beginning
+ position = 0;
+ } else {
+ // count all SNS-entries that are before 'afterLN' in order to
+ // determine the new position of the reordered node regarding
+ // his siblings.
+ position = 0;
+ for (Iterator it = entries.linkNodeIterator(); it.hasNext(); ) {
+ LinkedEntries.LinkNode ln = (LinkedEntries.LinkNode) it.next();
+ if (!insertName.equals(ln.qName)) {
+ continue; // not a SNS -> not relevant for position count
+ }
+ if (ln != insertLN) {
+ position++;
+ } // ln == inserLN -> not relevant for position count
+ if (ln == afterLN) {
+ break;
+ }
+ }
+ }
+ entriesByName.reorder(insertName, insertLN, position);
+ }
+ // reorder in linked list
+ entries.reorderNode(insertLN, afterLN.getNextLinkNode());
+ }
+ }
+
//-------------------------------------------------< AbstractLinkedList >---
/**
* An implementation of a linked list which provides access to the internal
@@ -455,19 +483,49 @@
return null;
}
+ private LinkedEntries.LinkNode getHeader() {
+ return (LinkedEntries.LinkNode) header;
+ }
+
/**
- * Adds a child node entry to this list.
+ * Adds a child node entry at the end of this list.
*
* @param cne the child node entry to add.
+ * @param index
* @return the LinkNode which refers to the added <code>NodeEntry</code>.
*/
- LinkedEntries.LinkNode add(NodeEntry cne) {
- LinkedEntries.LinkNode ln = new LinkedEntries.LinkNode(cne);
+ LinkedEntries.LinkNode add(NodeEntry cne, int index) {
+ LinkedEntries.LinkNode ln = new LinkedEntries.LinkNode(cne, index);
addNode(ln, header);
return ln;
}
/**
+ * Adds the given child node entry to this list after the specified
+ * <code>entry</code> or at the beginning if <code>entry</code> is
+ * <code>null</code>.
+ *
+ * @param cne the child node entry to add.
+ * @param index
+ * @param node after which to insert the new entry
+ * @return the LinkNode which refers to the added <code>NodeEntry</code>.
+ */
+ LinkedEntries.LinkNode addAfter(NodeEntry cne, int index, LinkedEntries.LinkNode insertAfter) {
+ LinkedEntries.LinkNode newNode;
+ if (insertAfter == null) {
+ // insert at the beginning
+ newNode = new LinkedEntries.LinkNode(cne, index);
+ addFirst(cne);
+ } else if (insertAfter.getNextLinkNode() == null) {
+ newNode = add(cne, index);
+ } else {
+ newNode = new LinkedEntries.LinkNode(cne, index);
+ addNode(newNode, insertAfter.getNextLinkNode());
+ }
+ return newNode;
+ }
+
+ /**
* Remove the LinkEntry the contains the given NodeEntry as value.
*
* @param cne NodeEntry to be removed.
@@ -507,7 +565,7 @@
* @see AbstractLinkedList#createNode(Object)
*/
protected Node createNode(Object value) {
- return new LinkedEntries.LinkNode(value);
+ return new LinkedEntries.LinkNode(value, Path.INDEX_DEFAULT);
}
/**
@@ -538,8 +596,10 @@
qName = null;
}
- protected LinkNode(Object value) {
- super(new WeakReference(value));
+ protected LinkNode(Object value, int index) {
+ // add weak reference from linkNode to the NodeEntry (value)
+ // unless the entry is a SNSibling. TODO: review again.
+ super(index > Path.INDEX_DEFAULT ? value : new WeakReference(value));
qName = ((NodeEntry) value).getName();
}
@@ -548,10 +608,17 @@
}
protected Object getValue() {
- Reference val = (Reference) super.getValue();
+ Object val = super.getValue();
+ NodeEntry ne;
+ if (val == null) {
+ ne = null;
+ } else if (val instanceof Reference) {
+ ne = (NodeEntry) ((Reference) val).get();
+ } else {
+ ne = (NodeEntry) val;
+ }
// if the nodeEntry has been g-collected in the mean time
// create a new NodeEntry in order to avoid returning null.
- NodeEntry ne = (val == null) ? null : (NodeEntry) val.get();
if (ne == null && this != header) {
ne = factory.createNodeEntry(parent, qName, null);
super.setValue(new WeakReference(ne));
@@ -715,7 +782,35 @@
}
}
- public void put(Name qName, LinkedEntries.LinkNode value) {
+ public LinkedEntries.LinkNode getLinkNode(Name qName, int index, String uniqueID) {
+ if (uniqueID != null) {
+ // -> try if any entry matches.
+ // if none matches it be might that entry doesn't have uniqueID
+ // set yet -> search without uniqueID
+ LinkedEntries.LinkNode val = (LinkedEntries.LinkNode) nameMap.get(qName);
+ if (val != null) {
+ if (uniqueID.equals(val.getNodeEntry().getUniqueID())) {
+ return val;
+ }
+ } else {
+ // look in snsMap
+ List l = (List) snsMap.get(qName);
+ if (l != null) {
+ for (Iterator it = l.iterator(); it.hasNext();) {
+ LinkedEntries.LinkNode ln = (LinkedEntries.LinkNode) it.next();
+ if (uniqueID.equals(ln.getNodeEntry().getUniqueID())) {
+ return ln;
+ }
+ }
+ }
+ }
+ }
+ // no uniqueID passed or not match.
+ // try to load the child entry by name and index.
+ return getLinkNode(qName, index);
+ }
+
+ public void put(Name qName, int index, LinkedEntries.LinkNode value) {
// if 'nameMap' already contains a single entry -> move it to snsMap
LinkedEntries.LinkNode single = (LinkedEntries.LinkNode) nameMap.remove(qName);
List l;
@@ -729,9 +824,16 @@
}
if (l == null) {
+ // no same name siblings -> simply put to the name map.
nameMap.put(qName, value);
} else {
- l.add(value);
+ // sibling(s) already present -> insert into the list
+ int position = index - 1;
+ if (position < 0 || position > l.size()) {
+ l.add(value); // invalid position -> append at the end.
+ } else {
+ l.add(position, value); // insert with the correct index.
+ }
}
}
@@ -753,12 +855,11 @@
return;
}
// reorder sns in the name-list
- if (position < 0) {
+ sns.remove(insertValue);
+ if (position < 0 || position > sns.size()) {
// simply move to end of list
- sns.remove(insertValue);
sns.add(insertValue);
} else {
- sns.remove(insertValue);
sns.add(position, insertValue);
}
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntries.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntries.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntries.java Wed Oct 15 05:59:19 2008
@@ -75,9 +75,9 @@
/**
* Remove the collection entry with the given <code>Name</code>.
*
- * @param propertyName
- * @return true If this <code>ChildPropertyEntries</code> contained any
- * entry with the given <code>Name</code>. False otherwise.
+ * @param propertyEntry
+ * @return true If this <code>ChildPropertyEntries</code> contained the
+ * given entry. False otherwise.
*/
- public boolean remove(Name propertyName);
+ public boolean remove(PropertyEntry propertyEntry);
}
\ No newline at end of file
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntriesImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntriesImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntriesImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildPropertyEntriesImpl.java Wed Oct 15 05:59:19 2008
@@ -115,9 +115,16 @@
}
/**
- * @see ChildPropertyEntries#remove(Name)
+ * @see ChildPropertyEntries#remove(PropertyEntry)
*/
- public boolean remove(Name propertyName) {
- return properties.remove(propertyName) != null;
+ public boolean remove(PropertyEntry propertyEntry) {
+ Name pName = propertyEntry.getName();
+ PropertyEntry pe = get(pName);
+ if (pe == propertyEntry) {
+ properties.remove(pName);
+ return true;
+ } else {
+ return false;
+ }
}
}
\ No newline at end of file
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryValidation.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryValidation.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryValidation.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryValidation.java Wed Oct 15 05:59:19 2008
@@ -18,6 +18,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.jcr2spi.state.Status;
import javax.jcr.RepositoryException;
import javax.jcr.ItemNotFoundException;
@@ -81,6 +82,23 @@
}
/**
+ * Returns <code>true</code> if the given childnode entry is not
+ * <code>null</code> and resolves to a NodeState, that is neither NEW
+ * nor REMOVED.
+ *
+ * @param cne NodeEntry to check.
+ * @return <code>true</code> if the given entry is valid.
+ */
+ static boolean isValidWorkspaceNodeEntry(NodeEntry cne) {
+ // shortcut.
+ if (cne == null) {
+ return false;
+ }
+ int status = cne.getStatus();
+ return status != Status.NEW && status != Status.REMOVED;
+ }
+
+ /**
* Returns <code>true</code> if the given childproperty entry is not
* <code>null</code> and resolves to a PropertyState, that is valid or if the
* childproperty entry has not been resolved up to now (assuming the corresponding
@@ -101,7 +119,7 @@
// may occur if the cached state is marked 'INVALIDATED' and
// does not exist any more on the persistent layer -> invalid.
} catch (RepositoryException e) {
- // probably deleted in the meantime. should not occur.
+ // probably removed in the meantime. should not occur.
}
} else {
// assume entry is valid // TODO check if this assumption is correct.
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java Wed Oct 15 05:59:19 2008
@@ -19,8 +19,8 @@
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.jcr2spi.state.ItemState;
-import org.apache.jackrabbit.jcr2spi.state.ChangeLog;
import org.apache.jackrabbit.jcr2spi.state.Status;
+import org.apache.jackrabbit.jcr2spi.operation.Operation;
import javax.jcr.RepositoryException;
import javax.jcr.InvalidItemStateException;
@@ -106,9 +106,8 @@
* Set the ItemState this hierarchyEntry will be resolved to.
*
* @param state
- * @throws IllegalStateException If the entry has already been resolved.
*/
- public void setItemState(ItemState state) throws IllegalStateException;
+ public void setItemState(ItemState state);
/**
* Invalidates the underlying <code>ItemState</code> if available. If the
@@ -133,7 +132,7 @@
/**
* Reloads this hierarchy entry and the corresponding ItemState, if this
* entry has already been resolved. If '<code>keepChanges</code>' is true,
- * states with transient changes are left untouched in order to obtain stale
+ * states with transient changes are left untouched in order to detect stale
* item states. Otherwise this state gets its data reloaded from the
* persistent storage. If '<code>recursive</code>' the complete hierarchy
* below this entry is reloaded as well.
@@ -165,18 +164,9 @@
public void remove();
/**
- * Checks if the underlying <code>ItemState</code> is available and if it
- * has been transiently modified or if is new or stale modified. If either of
- * the conditions is true, the state is added to the <code>ChangeLog</code>.
- * If this <code>HierarchyEntry</code> has children it will call
- * {@link #collectStates(ChangeLog, boolean)} recursively.
- *
- * @param changeLog the <code>ChangeLog</code> collecting the transient
- * item states present in a given tree.
- * @param throwOnStale If the given flag is true, this methods throws
- * InvalidItemStateException if this state is stale.
- * @throws InvalidItemStateException if <code>throwOnStale</code> is true and
- * this state is stale.
+ * Clean up this entry upon {@link Operation#undo()} or {@link Operation#persisted()}.
+ *
+ * @param transientOperation
*/
- public void collectStates(ChangeLog changeLog, boolean throwOnStale) throws InvalidItemStateException;
+ public void complete(Operation transientOperation) throws RepositoryException;
}
\ No newline at end of file
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntryImpl.java Wed Oct 15 05:59:19 2008
@@ -16,17 +16,17 @@
*/
package org.apache.jackrabbit.jcr2spi.hierarchy;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.jcr2spi.state.ItemState;
-import org.apache.jackrabbit.jcr2spi.state.ChangeLog;
import org.apache.jackrabbit.jcr2spi.state.Status;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateFactory;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.RepositoryException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
import java.lang.ref.WeakReference;
/**
@@ -93,8 +93,9 @@
if (state == null) {
try {
state = doResolve();
- // only set 'target' if not already by upon resolution
- if (!isAvailable()) {
+ // set the item state unless 'setItemState' has already been
+ // called by the ItemStateFactory (recall internalGetItemState)
+ if (internalGetItemState() == null) {
setItemState(state);
}
} catch (ItemNotFoundException e) {
@@ -129,7 +130,6 @@
abstract Path buildPath(boolean workspacePath) throws RepositoryException;
/**
- *
* @return
*/
ItemState internalGetItemState() {
@@ -140,16 +140,6 @@
return state;
}
- /**
- *
- * @param entry
- */
- static void removeEntry(HierarchyEntryImpl entry) {
- ItemState state = entry.internalGetItemState();
- if (state != null) {
- state.setStatus(Status.REMOVED);
- }
- }
//-----------------------------------------------------< HierarchyEntry >---
/**
* @inheritDoc
@@ -218,13 +208,26 @@
* @see HierarchyEntry#setItemState(ItemState)
*/
public synchronized void setItemState(ItemState state) {
- if (state == null || (denotesNode() && !state.isNode()) || (!denotesNode() && state.isNode())) {
+ ItemState currentState = internalGetItemState();
+ if (state == null || state == currentState || denotesNode() != state.isNode()) {
throw new IllegalArgumentException();
}
- if (isAvailable()) {
- throw new IllegalStateException("HierarchyEntry has already been resolved.");
+ if (currentState == null) {
+ // not connected yet to an item state. either a new entry or
+ // an unresolved hierarchy entry.
+ target = new WeakReference(state);
+ } else {
+ // was already resolved before -> merge the existing state
+ // with the passed state.
+ int currentStatus = currentState.getStatus();
+ boolean keepChanges = Status.isTransient(currentStatus) || Status.isStale(currentStatus);
+ boolean modified = currentState.merge(state, keepChanges);
+ if (currentStatus == Status.INVALIDATED) {
+ currentState.setStatus(Status.EXISTING);
+ } else if (modified) {
+ currentState.setStatus(Status.MODIFIED);
+ } // else: not modified. just leave status as it is.
}
- target = new WeakReference(state);
}
/**
@@ -234,10 +237,7 @@
public void invalidate(boolean recursive) {
ItemState state = internalGetItemState();
if (state != null) {
- // session-state TODO: only invalidate if existing?
- if (state.getStatus() == Status.EXISTING) {
- state.setStatus(Status.INVALIDATED);
- }
+ state.setStatus(Status.INVALIDATED);
}
}
@@ -256,53 +256,71 @@
switch (oldStatus) {
case Status.EXISTING_MODIFIED:
case Status.STALE_MODIFIED:
- // revert state from overlayed
+ // revert state modifications
state.revert();
state.setStatus(Status.EXISTING);
break;
case Status.EXISTING_REMOVED:
- // revert state from overlayed
+ // revert state modifications
state.revert();
state.setStatus(Status.EXISTING);
- if (!denotesNode()) {
- parent.revertPropertyRemoval((PropertyEntry) this);
- }
break;
case Status.NEW:
// reverting a NEW state is equivalent to its removal.
- remove();
+ // however: don't remove the complete hierarchy
+ state.setStatus(Status.REMOVED);
+ parent.internalRemoveChildEntry(this);
break;
case Status.STALE_DESTROYED:
- // overlayed does not exist any more -> remove it
+ // overlayed does not exist any more -> reverting of pending
+ // transient changes (that lead to the stale status) can be
+ // omitted and the entry is complete removed instead.
remove();
break;
default:
// Cannot revert EXISTING, REMOVED, INVALIDATED, MODIFIED states.
- // State was implicitely reverted
+ // State was implicitely reverted or external modifications
+ // reverted the modification.
log.debug("State with status " + oldStatus + " cannot be reverted.");
}
}
- /**
+ /**
* {@inheritDoc}
* @see HierarchyEntry#reload(boolean, boolean)
*/
public void reload(boolean keepChanges, boolean recursive) {
- ItemState state = internalGetItemState();
- if (state == null) {
- // nothing to do. entry will be validated upon resolution.
+ int status = getStatus();
+ if (status == Status._UNDEFINED_) {
+ // unresolved: entry will be loaded and validated upon resolution.
+ return;
+ }
+ if (Status.isTransient(status) || Status.isStale(status) || Status.isTerminal(status)) {
+ // transient || stale: avoid reloading
+ // new || terminal: cannot be reloaded from persistent layer anyway.
+ log.debug("Skip reload for item with status " + Status.getName(status) + ".");
return;
}
- /*
- if keepChanges is true only existing or invalidated states must be
- updated. otherwise the state gets updated and might be marked 'Stale'
- if transient changes are present and the workspace-state is modified.
- */
- // TODO: check again if 'reload' is not possible for transiently-modified state
- if (!keepChanges || state.getStatus() == Status.EXISTING
- || state.getStatus() == Status.INVALIDATED) {
- // reload the workspace state from the persistent layer
- state.reload(keepChanges);
+ /**
+ * Retrieved a fresh ItemState from the persistent layer. Which will
+ * then be merged into the current state.
+ */
+ try {
+ ItemStateFactory isf = factory.getItemStateFactory();
+ if (denotesNode()) {
+ NodeEntry ne = (NodeEntry) this;
+ isf.createNodeState(ne.getWorkspaceId(), ne);
+ } else {
+ PropertyEntry pe = (PropertyEntry) this;
+ isf.createPropertyState(pe.getWorkspaceId(), pe);
+ }
+ } catch (ItemNotFoundException e) {
+ // remove hierarchyEntry including all children
+ log.debug("Item '" + getName() + "' cannot be found on the persistent layer -> remove.");
+ remove();
+ } catch (RepositoryException e) {
+ // TODO: rather throw?
+ log.error("Exception while reloading item: " + e);
}
}
@@ -320,15 +338,12 @@
// it in order to determine the current status.
if (state.getStatus() == Status.INVALIDATED) {
reload(false, false);
- // check if upon reload the item has been removed -> nothing to do
- if (Status.isTerminal(state.getStatus())) {
- return;
- }
}
switch (state.getStatus()) {
case Status.NEW:
- remove();
+ state.setStatus(Status.REMOVED);
+ parent.internalRemoveChildEntry(this);
break;
case Status.EXISTING:
case Status.EXISTING_MODIFIED:
@@ -344,38 +359,4 @@
throw new RepositoryException("Cannot transiently remove an ItemState with status " + Status.getName(state.getStatus()));
}
}
-
- /**
- * {@inheritDoc}
- * @see HierarchyEntry#collectStates(ChangeLog, boolean)
- */
- public void collectStates(ChangeLog changeLog, boolean throwOnStale) throws InvalidItemStateException {
- ItemState state = internalGetItemState();
- if (state == null) {
- // nothing to do
- return;
- }
-
- if (throwOnStale && Status.isStale(state.getStatus())) {
- String msg = "Cannot save changes: " + state + " has been modified externally.";
- log.debug(msg);
- throw new InvalidItemStateException(msg);
- }
- // only interested in transient modifications or stale states
- switch (state.getStatus()) {
- case Status.NEW:
- changeLog.added(state);
- break;
- case Status.EXISTING_MODIFIED:
- case Status.STALE_MODIFIED:
- case Status.STALE_DESTROYED:
- changeLog.modified(state);
- break;
- case Status.EXISTING_REMOVED:
- changeLog.deleted(state);
- break;
- default:
- log.debug("Collecting states: Ignored ItemState with status " + Status.getName(state.getStatus()));
- }
- }
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java Wed Oct 15 05:59:19 2008
@@ -28,6 +28,7 @@
import org.apache.jackrabbit.spi.Path;
import javax.jcr.RepositoryException;
+import javax.jcr.PathNotFoundException;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@@ -142,9 +143,24 @@
progress = false;
for (Iterator it = addEvents.iterator(); it.hasNext();) {
Event ev = (Event) it.next();
- NodeEntry parent = (ev.getParentId() != null) ? (NodeEntry) hierarchyMgr.lookup(ev.getParentId()) : null;
- if (parent != null) {
- parent.refresh(ev);
+ NodeId parentId = ev.getParentId();
+ HierarchyEntry parent = null;
+ if (parentId != null) {
+ parent = hierarchyMgr.lookup(parentId);
+ if (parent == null && ev.getPath() != null && parentId.getUniqueID() != null) {
+ // parentID contains a uniqueID part -> try to lookup
+ // the parent by path.
+ try {
+ Path parentPath = ev.getPath().getAncestor(1);
+ parent = hierarchyMgr.lookup(parentPath);
+ } catch (PathNotFoundException e) {
+ // should not occur
+ log.debug(e.getMessage());
+ }
+ }
+ }
+ if (parent != null && parent.denotesNode()) {
+ ((NodeEntry) parent).refresh(ev);
it.remove();
progress = true;
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java Wed Oct 15 05:59:19 2008
@@ -41,7 +41,7 @@
public NodeEntry getRootEntry();
/**
- * Lookup of <code>HierarchyEntry</code> workspace Id, that may be different
+ * Lookup of <code>HierarchyEntry</code> by its workspace Id that may be different
* if a entry (or any of its ancestors) has been transiently moved or
* reordered.<p/>
* If the Hierarchy already lists the entry with the given workspaceItemId it is
@@ -55,6 +55,20 @@
public HierarchyEntry lookup(ItemId workspaceItemId);
/**
+ * Lookup of <code>HierarchyEntry</code> by its workspace path that may be different
+ * if a entry (or any of its ancestors) has been transiently moved or
+ * reordered.<p/>
+ * If the Hierarchy already lists the entry with the given path it is
+ * returned otherwise <code>null</code>. See {@link #getHierarchyEntry(Path)}
+ * for a method that resolves the ItemId including lookup in the persistence
+ * layer if the entry has not been loaded yet.
+ *
+ * @param workspaceItemId
+ * @return
+ */
+ public HierarchyEntry lookup(Path workspacePath);
+
+ /**
* Resolves a itemId into a <code>HierarchyEntry</code>.
*
* @param itemId
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManagerImpl.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManagerImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManagerImpl.java Wed Oct 15 05:59:19 2008
@@ -83,6 +83,13 @@
}
/**
+ * @see HierarchyManager#lookup(Path)
+ */
+ public HierarchyEntry lookup(Path workspacePath) {
+ return rootEntry.lookupDeepEntry(workspacePath);
+ }
+
+ /**
* @see HierarchyManager#getHierarchyEntry(ItemId)
*/
public HierarchyEntry getHierarchyEntry(ItemId itemId) throws ItemNotFoundException, RepositoryException {
Modified: jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java?rev=704898&r1=704897&r2=704898&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java Wed Oct 15 05:59:19 2008
@@ -17,18 +17,19 @@
package org.apache.jackrabbit.jcr2spi.hierarchy;
import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.PropertyState;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.spi.QValue;
import javax.jcr.ItemExistsException;
import javax.jcr.RepositoryException;
import javax.jcr.PathNotFoundException;
import javax.jcr.ItemNotFoundException;
+import javax.jcr.InvalidItemStateException;
import java.util.Iterator;
import java.util.List;
import java.util.Collection;
@@ -41,7 +42,7 @@
/**
* @return the <code>NodeId</code> of this child node entry.
*/
- public NodeId getId();
+ public NodeId getId() throws InvalidItemStateException, RepositoryException;
/**
* Returns the ID that must be used for resolving this entry OR loading its
@@ -52,7 +53,7 @@
* @return
* @see #getId()
*/
- public NodeId getWorkspaceId();
+ public NodeId getWorkspaceId() throws InvalidItemStateException, RepositoryException;
/**
* @return the unique ID of the node state which is referenced by this
@@ -71,8 +72,10 @@
* @return the index of this child node entry to suppport same-name siblings.
* If the index of this entry cannot be determined
* {@link org.apache.jackrabbit.spi.Path#INDEX_UNDEFINED} is returned.
+ * @throws InvalidItemStateException
+ * @throws RepositoryException
*/
- public int getIndex();
+ public int getIndex() throws InvalidItemStateException, RepositoryException;
/**
* @return the referenced <code>NodeState</code>.
@@ -206,7 +209,7 @@
* @return
* @throws RepositoryException If an error occurs.
*/
- public NodeState addNewNodeEntry(Name nodeName, String uniqueID, Name primaryNodeType, QNodeDefinition definition) throws RepositoryException;
+ public NodeEntry addNewNodeEntry(Name nodeName, String uniqueID, Name primaryNodeType, QNodeDefinition definition) throws RepositoryException;
/**
* Determines if there is a property entry with the specified <code>Name</code>.
@@ -275,18 +278,21 @@
* @throws ItemExistsException
* @throws RepositoryException if an unexpected error occurs.
*/
- public void addPropertyEntries(Collection propNames) throws ItemExistsException, RepositoryException;
+ public void setPropertyEntries(Collection propNames) throws ItemExistsException, RepositoryException;
/**
* Add a new, transient <code>PropertyEntry</code> to this <code>NodeEntry</code>
* and return the <code>PropertyState</code> associated with the new entry.
*
* @param propName
- * @return The PropertyState associated with the new property entry.
+ * @param definition
+ * @param values
+ * @param propertyType
+ * @return the new entry.
* @throws ItemExistsException
- * @throws RepositoryException if an unexpected error occurs.
+ * @throws RepositoryException
*/
- public PropertyState addNewPropertyEntry(Name propName, QPropertyDefinition definition) throws ItemExistsException, RepositoryException;
+ public PropertyEntry addNewPropertyEntry(Name propName, QPropertyDefinition definition, QValue[] values, int propertyType) throws ItemExistsException, RepositoryException;
/**
* Reorders this NodeEntry before the sibling entry specified by the given