Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (revision 957189)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (revision )
@@ -401,7 +401,7 @@
}
/**
- * Same as {@link #getDescendantTransientItemStates(NodeId)}
+ * Same as {@link #getDescendantTransientItemStates(ItemId)}
* except that item state instances in the attic are returned.
*
* @param id identifier of the common parent of the transient item state
@@ -819,8 +819,8 @@
transientState.setModCount(local.getModCount());
transientState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
} catch (ItemStateException e) {
- // something went wrong, mark as stale
- transientState.setStatus(ItemState.STATUS_STALE_MODIFIED);
+ // something went wrong
+ transientState.setStatus(ItemState.STATUS_UNDEFINED);
}
}
visibleState = transientState;
@@ -838,61 +838,7 @@
*/
public void stateModified(ItemState modified) {
ItemState visibleState = modified;
- if (modified.getContainer() != this) {
- // local state was modified
- ItemState transientState = transientStore.get(modified.getId());
- if (transientState != null) {
- if (transientState.isNode() && !transientState.isStale()) {
- // try to silently merge non-conflicting changes (JCR-584)
- NodeStateMerger.MergeContext context =
- new NodeStateMerger.MergeContext() {
- public boolean isAdded(ItemId id) {
- ItemState is = transientStore.get(id);
- return is != null
- && is.getStatus() == ItemState.STATUS_NEW;
- }
-
- public boolean isDeleted(ItemId id) {
- return atticStore.contains(id);
- }
-
- public boolean isModified(ItemId id) {
- ItemState is = transientStore.get(id);
- return is != null
- && is.getStatus() == ItemState.STATUS_EXISTING_MODIFIED;
- }
-
- public boolean allowsSameNameSiblings(NodeId id) {
- try {
- NodeState ns = (NodeState) getItemState(id);
- NodeState parent = (NodeState) getItemState(ns.getParentId());
- Name name = parent.getChildNodeEntry(id).getName();
- EffectiveNodeType ent = ntReg.getEffectiveNodeType(
- parent.getNodeTypeName(),
- parent.getMixinTypeNames());
- QNodeDefinition def = ent.getApplicableChildNodeDef(name, ns.getNodeTypeName(), ntReg);
- return def != null && def.allowsSameNameSiblings();
- } catch (Exception e) {
- log.warn("Unable to get node definition", e);
- return false;
- }
- }
- };
- if (NodeStateMerger.merge((NodeState) transientState, context)) {
- // merge succeeded
- return;
- }
- }
- transientState.setStatus(ItemState.STATUS_STALE_MODIFIED);
- visibleState = transientState;
- }
- // check attic as well (JCR-1432)
- transientState = atticStore.get(modified.getId());
- if (transientState != null) {
- transientState.setStatus(ItemState.STATUS_STALE_MODIFIED);
- visibleState = transientState;
- }
- }
+ // JCR-2650: ignore external changes, they will be considered/merged on save().
dispatcher.notifyStateModified(visibleState);
}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision 962485)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision )
@@ -770,48 +770,44 @@
NodeState transientState = data.getNodeState();
- NodeState persistentState = (NodeState) transientState.getOverlayedState();
- if (persistentState == null) {
+ NodeState localState = (NodeState) transientState.getOverlayedState();
+ if (localState == null) {
// this node is 'new'
- persistentState = stateMgr.createNew(transientState);
+ localState = stateMgr.createNew(transientState);
}
- synchronized (persistentState) {
- // check staleness of transient state first
- if (transientState.isStale()) {
- String msg =
- this + ": the node cannot be saved because it has been"
- + " modified externally.";
- log.debug(msg);
- throw new InvalidItemStateException(msg);
- }
+ synchronized (localState) {
// copy state from transient state:
// parent id's
- persistentState.setParentId(transientState.getParentId());
+ localState.setParentId(transientState.getParentId());
// primary type
- persistentState.setNodeTypeName(transientState.getNodeTypeName());
+ localState.setNodeTypeName(transientState.getNodeTypeName());
// mixin types
- persistentState.setMixinTypeNames(transientState.getMixinTypeNames());
+ localState.setMixinTypeNames(transientState.getMixinTypeNames());
// child node entries
- persistentState.setChildNodeEntries(transientState.getChildNodeEntries());
+ localState.setChildNodeEntries(transientState.getChildNodeEntries());
// property entries
- persistentState.setPropertyNames(transientState.getPropertyNames());
+ localState.setPropertyNames(transientState.getPropertyNames());
// shared set
- persistentState.setSharedSet(transientState.getSharedSet());
+ localState.setSharedSet(transientState.getSharedSet());
+ // modCount
+ if (localState.getModCount() != transientState.getModCount()) {
+ localState.setModCount(transientState.getModCount());
+ }
// make state persistent
- stateMgr.store(persistentState);
+ stateMgr.store(localState);
}
// tell state manager to disconnect item state
stateMgr.disconnectTransientItemState(transientState);
- // swap transient state with persistent state
- data.setState(persistentState);
+ // swap transient state with local state
+ data.setState(localState);
// reset status
data.setStatus(STATUS_NORMAL);
if (isShareable() && data.getPrimaryParentId() == null) {
- data.setPrimaryParentId(persistentState.getParentId());
+ data.setPrimaryParentId(localState.getParentId());
}
}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemRefreshOperation.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemRefreshOperation.java (revision 962485)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemRefreshOperation.java (revision )
@@ -57,7 +57,6 @@
// check status of this item's state
if (state.isTransient()) {
switch (state.getStatus()) {
- case ItemState.STATUS_STALE_MODIFIED:
case ItemState.STATUS_STALE_DESTROYED:
// add this item's state to the list
transientStates.add(state);
@@ -87,7 +86,6 @@
for (ItemState transientState
: stateMgr.getDescendantTransientItemStates(state.getId())) {
switch (transientState.getStatus()) {
- case ItemState.STATUS_STALE_MODIFIED:
case ItemState.STATUS_STALE_DESTROYED:
case ItemState.STATUS_NEW:
case ItemState.STATUS_EXISTING_MODIFIED:
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemState.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemState.java (revision 792437)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemState.java (revision )
@@ -53,10 +53,6 @@
*/
public static final int STATUS_NEW = 4;
/**
- * 'existing', i.e. persistent state that has been persistently modified by somebody else
- */
- public static final int STATUS_STALE_MODIFIED = 5;
- /**
* 'existing', i.e. persistent state that has been destroyed by somebody else
*/
public static final int STATUS_STALE_DESTROYED = 6;
@@ -286,14 +282,9 @@
* @return true if this item state has become stale, false otherwise.
*/
public boolean isStale() {
- if (isTransient) {
- return status == STATUS_STALE_MODIFIED
- || status == STATUS_STALE_DESTROYED;
- } else {
- return overlayedState != null
- && modCount != overlayedState.getModCount();
- }
+ return overlayedState != null
+ && modCount != overlayedState.getModCount();
+ }
- }
/**
* Returns the NodeId of the parent NodeState or null
@@ -324,7 +315,6 @@
case STATUS_EXISTING:
case STATUS_EXISTING_REMOVED:
case STATUS_EXISTING_MODIFIED:
- case STATUS_STALE_MODIFIED:
case STATUS_STALE_DESTROYED:
case STATUS_UNDEFINED:
status = newStatus;
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (revision 957571)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (revision )
@@ -1086,7 +1086,6 @@
*/
case ItemState.STATUS_EXISTING_REMOVED:
case ItemState.STATUS_EXISTING_MODIFIED:
- case ItemState.STATUS_STALE_MODIFIED:
ItemState persistentState = discarded.getOverlayedState();
// the state is a transient wrapper for the underlying
// persistent state, therefore restore the persistent state
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemSaveOperation.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemSaveOperation.java (revision 962485)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemSaveOperation.java (revision )
@@ -290,7 +290,7 @@
/**
* Builds a list of transient (i.e. new or modified) item states that are
- * within the scope of this.{@link #save()}. The collection
+ * within the scope of this.{@link #perform(SessionContext)}. The collection
* returned is ordered depth-first, i.e. the item itself (if transient)
* comes last.
*
@@ -316,11 +316,6 @@
dirty.add(transientState);
break;
- case ItemState.STATUS_STALE_MODIFIED:
- throw new InvalidItemStateException(
- "Item cannot be saved because it has been "
- + "modified externally: " + this);
-
case ItemState.STATUS_STALE_DESTROYED:
throw new InvalidItemStateException(
"Item cannot be saved because it has been "
@@ -351,11 +346,6 @@
throw new RepositoryException(
"Cannot save a new item: " + this);
- case ItemState.STATUS_STALE_MODIFIED:
- throw new InvalidItemStateException(
- "Item cannot be saved because it has been"
- + " modified externally: " + this);
-
case ItemState.STATUS_STALE_DESTROYED:
throw new InvalidItemStateException(
"Item cannot be saved because it has been"
@@ -380,7 +370,7 @@
/**
* Builds a list of transient descendant item states in the attic
* (i.e. those marked as 'removed') that are within the scope of
- * this.{@link #save()}.
+ * this.{@link #perform(SessionContext)}.
*
* @return list of transient item states
* @throws InvalidItemStateException
@@ -394,14 +384,8 @@
for (ItemState transientState
: sism.getDescendantTransientItemStatesInAttic(state.getId())) {
// check if stale
- switch (transientState.getStatus()) {
- case ItemState.STATUS_STALE_MODIFIED:
+ if (transientState.getStatus() == ItemState.STATUS_STALE_DESTROYED) {
throw new InvalidItemStateException(
- "Item can't be removed because it has been"
- + " modified externally: "
- + transientState.getId());
- case ItemState.STATUS_STALE_DESTROYED:
- throw new InvalidItemStateException(
"Item can't be removed because it has already"
+ " been deleted externally: "
+ transientState.getId());
@@ -922,4 +906,4 @@
}
}
-}
\ No newline at end of file
+}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateMap.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateMap.java (revision 792437)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateMap.java (revision )
@@ -126,9 +126,6 @@
case ItemState.STATUS_STALE_DESTROYED:
ps.print("[stale, destroyed] ");
break;
- case ItemState.STATUS_STALE_MODIFIED:
- ps.print("[stale, modified] ");
- break;
case ItemState.STATUS_UNDEFINED:
ps.print("[undefined] ");
break;