You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2006/10/06 08:55:28 UTC
svn commit: r453514 - in /jackrabbit/trunk/contrib/spi:
jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/
jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ spi2dav/
spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/
Author: angela
Date: Thu Oct 5 23:55:27 2006
New Revision: 453514
URL: http://svn.apache.org/viewvc?view=rev&rev=453514
Log:
work in progress
- event processing upon saving transient modifications
- extend ItemState.refresh: add Event and ev. ChangeLog as param
- EventImpl: parentId missing
- remove ItemStateListener
- all state changes are covered by ItemStateLifeCycleListener.statusChanged(ItemState, int)
Removed:
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateListener.java
Modified:
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateLifeCycleListener.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
jackrabbit/trunk/contrib/spi/spi2dav/project.xml
jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/EventImpl.java
jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java Thu Oct 5 23:55:27 2006
@@ -234,9 +234,6 @@
checkStatus();
if (keepChanges) {
- /** TODO should reset Item#status field to STATUS_NORMAL
- * of all descendent non-transient instances; maybe also
- * have to reset stale ItemState instances */
return;
}
@@ -276,68 +273,48 @@
//-----------------------------------------< ItemStateLifeCycleListener >---
/**
- * {@inheritDoc}
+ *
+ * @param state
+ * @param previousStatus
*/
- public void stateCreated(ItemState created) {
- }
-
- /**
- * {@inheritDoc}
- */
- public void stateDestroyed(ItemState destroyed) {
- // underlying state has been permanently destroyed
-
- // dispose state
- if (state == destroyed) {
- state.removeListener(this);
- state = null;
- }
- /**
- * notify the listeners that this instance has been
- * permanently invalidated
- */
- notifyDestroyed();
- }
-
- /**
- * {@inheritDoc}
- */
- public void stateModified(ItemState modified) {
- }
-
public void statusChanged(ItemState state, int previousStatus) {
- // TODO: remove this ItemImpl as listener from ItemState when it is destroyed?
+ // TODO: ev. assert that state is this.state?
+
switch (state.getStatus()) {
+ /**
+ * Nothing to do for
+ * - ItemState.STATUS_EXISTING : modifications reverted or saved
+ * - ItemState.STATUS_EXISTING_MODIFIED : transient modification
+ * - ItemState.STATUS_STALE_MODIFIED : external modifications while transient changes pending
+ * - ItemState.MODIFIED : externaly modified -> marker for sessionISM states only
+ */
case ItemState.STATUS_EXISTING:
- // this item was modified and is now reverted or has been saved
- // -> nothing to do
- break;
case ItemState.STATUS_EXISTING_MODIFIED:
- // item was modified and is not existing-modified
- // -> nothing to do
+ case ItemState.STATUS_STALE_MODIFIED:
+ case ItemState.STATUS_MODIFIED:
break;
+ /**
+ * Notify listeners that this item is transiently or permanently
+ * destroyed.
+ * - STATUS_EXISTING_REMOVED : transient removal
+ * - STATUS_REMOVED : permanent removal. item will never get back to life
+ * - STATUS_STALE_DESTROYED : permanent removal. item will never get back to life
+ */
case ItemState.STATUS_EXISTING_REMOVED:
- // item is transiently removed
- // notify listeners of this item that this item has been destroyed
notifyDestroyed();
break;
- case ItemState.STATUS_NEW:
- // should never happen. an item cannot change its state to new
- log.warn("invalid state change to STATUS_NEW");
- break;
case ItemState.STATUS_REMOVED:
- // item has been removed permanently
- notifyDestroyed();
- break;
case ItemState.STATUS_STALE_DESTROYED:
- // item has been removed permanently while there were transient
- // changes pending
+ state.removeListener(this);
+ this.state = null;
notifyDestroyed();
break;
- case ItemState.STATUS_STALE_MODIFIED:
- // item has been modified externaly while there were transient
- // changes pending
- // -> nothing to do
+ /**
+ * Invalid status. A state can never change its state to 'New'.
+ */
+ case ItemState.STATUS_NEW:
+ // should never happen.
+ log.error("invalid state change to STATUS_NEW");
break;
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java Thu Oct 5 23:55:27 2006
@@ -864,8 +864,8 @@
// make sure the specified workspace is visible for the current session.
session.checkAccessibleWorkspace(srcWorkspaceName);
- Operation op = Update.create(getNodeState(), srcWorkspaceName);
- session.getSessionItemStateManager().execute(op);
+ Operation op = Update.create((NodeState) getNodeState().getOverlayedState(), srcWorkspaceName);
+ ((WorkspaceImpl)session.getWorkspace()).getUpdatableItemStateManager().execute(op);
}
/**
@@ -883,7 +883,6 @@
// make sure the workspace exists and is accessible for this session.
session.checkAccessibleWorkspace(srcWorkspace);
- // TODO: improve... (and review return value of VM.merge)
Collection failedIds = session.getVersionManager().merge(getNodeState(), srcWorkspace, bestEffort);
if (failedIds.isEmpty()) {
return IteratorHelper.EMPTY;
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java Thu Oct 5 23:55:27 2006
@@ -281,7 +281,7 @@
} catch (NoSuchItemStateException e) {
throw new ItemNotFoundException(id.toString());
} catch (ItemStateException e) {
- String msg = "failed to retrieve item state of item " + id;
+ String msg = "Failed to retrieve item state of item " + id;
log.error(msg, e);
throw new RepositoryException(msg, e);
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/CachingItemStateManager.java Thu Oct 5 23:55:27 2006
@@ -247,13 +247,13 @@
return state;
}
- //------------------------< ItemStateListener >-----------------------------
+ //-----------------------------------------< ItemStateLifeCycleListener >---
private class ISLifeCycleListener implements ItemStateLifeCycleListener {
public void statusChanged(ItemState state, int previousStatus) {
if (state.getStatus() == ItemState.STATUS_REMOVED ||
- state.getStatus() == ItemState.STATUS_STALE_DESTROYED) {
+ state.getStatus() == ItemState.STATUS_STALE_DESTROYED) {
recentlyUsed.remove(state);
if (state.isNode()) {
NodeState nodeState = (NodeState) state;
@@ -262,15 +262,6 @@
}
}
}
- }
-
- public void stateCreated(ItemState created) {
- }
-
- public void stateModified(ItemState modified) {
- }
-
- public void stateDestroyed(ItemState destroyed) {
}
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ChangeLog.java Thu Oct 5 23:55:27 2006
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.jcr2spi.state;
import org.apache.jackrabbit.jcr2spi.operation.Operation;
-import org.apache.jackrabbit.spi.EventIterator;
import java.util.Iterator;
import java.util.Set;
@@ -238,60 +237,24 @@
//-----------------------------< Inform ChangeLog about Success/Failure >---
/**
- * ChangeLog has successfully been commited. The given <code>EventIterator</code>
- * contains information about all modifications. This ChangeLog needs
- * to notify all transient states involved.
- *
- * @param events
- */
- public void persist(EventIterator events) {
- // TODO: events may reveal additional autocreated items and modifications
- // applied while commiting the changelog (e.g. uuid or nodetype of new nodes).
- push();
- persisted();
- }
-
- /**
- * Push all states contained in the various maps of
- * items we have.
- */
- private void push() {
- Iterator iter = modifiedStates();
- while (iter.hasNext()) {
- ((ItemState) iter.next()).push();
- }
- iter = deletedStates();
- while (iter.hasNext()) {
- ((ItemState) iter.next()).push();
- }
- iter = addedStates();
- while (iter.hasNext()) {
- ((ItemState) iter.next()).push();
- }
- }
-
- /**
* After the states have actually been persisted, update their
* internal states and notify listeners.
*/
- private void persisted() {
+ public void persisted() {
Iterator iter = modifiedStates();
while (iter.hasNext()) {
ItemState state = (ItemState) iter.next();
state.setStatus(ItemState.STATUS_EXISTING);
- state.notifyStateUpdated(); // TODO: is this needed anymore?
}
iter = deletedStates();
while (iter.hasNext()) {
ItemState state = (ItemState) iter.next();
state.setStatus(ItemState.STATUS_REMOVED);
- state.notifyStateDestroyed(); // TODO: is this needed anymore?
}
iter = addedStates();
while (iter.hasNext()) {
ItemState state = (ItemState) iter.next();
state.setStatus(ItemState.STATUS_EXISTING);
- state.notifyStateCreated(); // TODO: is this needed anymore?
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java Thu Oct 5 23:55:27 2006
@@ -19,6 +19,7 @@
import org.apache.jackrabbit.util.WeakIdentityCollection;
import org.apache.jackrabbit.spi.ItemId;
import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.Event;
import org.apache.jackrabbit.name.Path;
import org.apache.jackrabbit.name.MalformedPathException;
import org.apache.jackrabbit.name.QName;
@@ -33,7 +34,7 @@
/**
* <code>ItemState</code> represents the state of an <code>Item</code>.
*/
-public abstract class ItemState implements ItemStateListener {
+public abstract class ItemState implements ItemStateLifeCycleListener {
/**
* Logger instance
@@ -67,9 +68,18 @@
public static final int STATUS_STALE_DESTROYED = 6;
/**
+ * a state is permanently modified either by saving transient changes or
+ * by wsp operations or be external modification
+ * TODO: improve. status only temporarily used to indicate to a SessionISM-state to pull changes
+ */
+ public static final int STATUS_MODIFIED = 7;
+
+ /**
* a new state was deleted and is now 'removed'
+ * or an existing item has been removed by a workspace operation or
+ * by an external modification.
*/
- public static final int STATUS_REMOVED = 7;
+ public static final int STATUS_REMOVED = 8;
/**
* the internal status of this item state
@@ -146,29 +156,9 @@
}
/**
- * Copy state information from another state into this state
- *
- * @param state source state information
+ * Copy state information from overlayed state to this state
*/
- abstract void copyFrom(ItemState state);
-
- /**
- * Pull state information from overlayed state.
- */
- void pull() {
- if (overlayedState != null) {
- copyFrom(overlayedState);
- }
- }
-
- /**
- * Push state information into overlayed state.
- */
- void push() {
- if (overlayedState != null) {
- overlayedState.copyFrom(this);
- }
- }
+ protected abstract void pull();
/**
* Connect this state to some underlying overlayed state.
@@ -183,95 +173,17 @@
this.overlayedState.addListener(this);
}
- /**
- * Reconnect this state to the overlayed state that it has been
- * disconnected from earlier.
- */
- protected void reconnect() {
- if (this.overlayedState == null) {
- throw new IllegalStateException("Item state cannot be reconnected because there's no underlying state to reconnect to: " + this);
- }
- this.overlayedState.addListener(this);
- }
-
- /**
- * Disconnect this state from the underlying overlayed state.
- */
- protected void disconnect() {
- if (overlayedState != null) {
- // de-register listener on overlayed state...
- overlayedState.removeListener(this);
- overlayedState = null;
- }
- }
-
- /**
- * Refreshes this item state
- */
- protected void refresh() {
- // TODO: how is this done? where is the new state retrieved from???
- // TODO: pass in as argument?
- }
- /**
- * Notify the listeners that the persistent state this object is
- * representing has been created.
- */
- protected void notifyStateCreated() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemStateListener[] la;
- synchronized (listeners) {
- la = (ItemStateListener[]) listeners.toArray(new ItemStateListener[listeners.size()]);
- }
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].stateCreated(this);
- }
- }
- }
-
- /**
- * Notify the listeners that the persistent state this object is
- * representing has been updated.
- */
- protected void notifyStateUpdated() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemStateListener[] la;
- synchronized (listeners) {
- la = (ItemStateListener[]) listeners.toArray(new ItemStateListener[listeners.size()]);
- }
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].stateModified(this);
- }
- }
- }
-
- /**
- * Notify the listeners that the persistent state this object is
- * representing has been destroyed.
- */
- protected void notifyStateDestroyed() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemStateListener[] la;
- synchronized (listeners) {
- la = (ItemStateListener[]) listeners.toArray(new ItemStateListener[listeners.size()]);
- }
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].stateDestroyed(this);
- }
- }
- }
+ protected abstract void refresh(Event event, ChangeLog changeLog);
/**
* Notify the life cycle listeners that this state has changed its status.
*/
private void notifyStatusChanged(int oldStatus) {
// copy listeners to array to avoid ConcurrentModificationException
- ItemStateListener[] la;
+ ItemStateLifeCycleListener[] la;
synchronized (listeners) {
- la = (ItemStateListener[]) listeners.toArray(new ItemStateListener[listeners.size()]);
+ la = (ItemStateLifeCycleListener[]) listeners.toArray(new ItemStateLifeCycleListener[listeners.size()]);
}
for (int i = 0; i < la.length; i++) {
if (la[i] instanceof ItemStateLifeCycleListener) {
@@ -284,6 +196,11 @@
* Marks this item state as modified.
*/
protected void markModified() {
+ // only transient states can be marked-modified
+ if (getStatus() != STATUS_NEW && overlayedState == null) {
+ throw new IllegalStateException("persisted cannot be called on workspace state");
+ }
+
switch (status) {
case STATUS_EXISTING:
setStatus(STATUS_EXISTING_MODIFIED);
@@ -296,10 +213,10 @@
break;
case STATUS_STALE_DESTROYED:
case STATUS_STALE_MODIFIED:
- // should actually get here because item should check before
- // it modifies an item state. do nothing because item state
- // is stale anyway.
- break;
+ // should actually not get here because item should check before
+ // it modifies an item state.
+ throw new IllegalStateException("Cannot mark stale state modified.");
+
case STATUS_EXISTING_REMOVED:
default:
String msg = "Cannot mark item state with status " + status + " modified.";
@@ -307,7 +224,6 @@
}
}
-
//--------------------< public READ methods and package private Setters >---
/**
* Determines if this item state represents a node.
@@ -458,6 +374,7 @@
case STATUS_EXISTING_MODIFIED:
case STATUS_STALE_MODIFIED:
case STATUS_STALE_DESTROYED:
+ case STATUS_MODIFIED:
case STATUS_REMOVED:
status = newStatus;
break;
@@ -525,11 +442,11 @@
public abstract void collectTransientStates(Set transientStates);
/**
- * Add an <code>ItemStateListener</code>
+ * Add an <code>ItemStateLifeCycleListener</code>
*
* @param listener the new listener to be informed on modifications
*/
- public void addListener(ItemStateListener listener) {
+ public void addListener(ItemStateLifeCycleListener listener) {
synchronized (listeners) {
assert (!listeners.contains(listener));
listeners.add(listener);
@@ -537,52 +454,65 @@
}
/**
- * Remove an <code>ItemStateListener</code>
+ * Remove an <code>ItemStateLifeCycleListener</code>
*
* @param listener an existing listener
*/
- public void removeListener(ItemStateListener listener) {
+ public void removeListener(ItemStateLifeCycleListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
- //--------------------------------------------------< ItemStateListener >---
+ //-----------------------------------------< ItemStateLifeCycleListener >---
/**
- * {@inheritDoc}
- */
- public void stateCreated(ItemState created) {
- // underlying state has been permanently created
- pull();
- setStatus(STATUS_EXISTING);
- }
-
- /**
- * {@inheritDoc}
+ *
+ * @param state
+ * @param previousStatus
*/
- public void stateDestroyed(ItemState destroyed) {
- // underlying state has been permanently destroyed
- if (isTransient()) {
- setStatus(STATUS_STALE_DESTROYED);
- } else {
- setStatus(STATUS_REMOVED);
- notifyStateDestroyed();
+ public void statusChanged(ItemState state, int previousStatus) {
+ // workspace-states never are listening to another state
+ if (getStatus() != STATUS_NEW && overlayedState == null) {
+ throw new IllegalStateException("statusChanged cannot be called on workspace state");
}
- }
- /**
- * {@inheritDoc}
- */
- public void stateModified(ItemState modified) {
- // underlying state has been modified
- if (isTransient()) {
- setStatus(STATUS_STALE_MODIFIED);
- } else {
- synchronized (this) {
- // this instance represents existing state, update it
- pull();
- notifyStateUpdated();
- }
+ switch (state.getStatus()) {
+ case STATUS_EXISTING:
+ // nothing to do
+ break;
+ case STATUS_MODIFIED:
+ if (previousStatus == STATUS_EXISTING) {
+ // change back
+ state.status = STATUS_EXISTING;
+ // underlying state has been modified
+ if (isTransient()) {
+ setStatus(STATUS_STALE_MODIFIED);
+ } else {
+ synchronized (this) {
+ // this instance represents existing state, update it
+ pull();
+ setStatus(STATUS_EXISTING);
+ }
+ }
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException();
+ }
+ break;
+ case STATUS_REMOVED:
+ if (isTransient()) {
+ setStatus(STATUS_STALE_DESTROYED);
+ } else {
+ setStatus(STATUS_REMOVED);
+ }
+ break;
+ case STATUS_STALE_MODIFIED:
+ case STATUS_STALE_DESTROYED:
+ case STATUS_EXISTING_REMOVED:
+ case STATUS_EXISTING_MODIFIED:
+ case STATUS_NEW:
+ log.error("Workspace state cannot have its state changed to " + state.getStatus());
+ break;
}
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateLifeCycleListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateLifeCycleListener.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateLifeCycleListener.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateLifeCycleListener.java Thu Oct 5 23:55:27 2006
@@ -20,7 +20,7 @@
* <code>ItemStateLifeCycleListener</code> allows an implementing class to get
* notifications about the life cycle of an item state.
*/
-public interface ItemStateLifeCycleListener extends ItemStateListener {
+public interface ItemStateLifeCycleListener {
/**
* Called after an <code>ItemState</code> has changed its status. The new
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java Thu Oct 5 23:55:27 2006
@@ -25,6 +25,8 @@
import org.apache.jackrabbit.name.MalformedPathException;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.spi.PropertyId;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
@@ -191,16 +193,96 @@
/**
* {@inheritDoc}
*/
- protected synchronized void copyFrom(ItemState state) {
- synchronized (state) {
- NodeState nodeState = (NodeState) state;
- name = nodeState.name;
- uuid = nodeState.uuid;
- //parent = nodeState.parent; // TODO: parent from wrong ism layer
- nodeTypeName = nodeState.nodeTypeName;
- definition = nodeState.definition;
+ protected synchronized void pull() {
+ if (overlayedState != null) {
+ synchronized (overlayedState) {
+ NodeState nodeState = (NodeState) overlayedState;
+ name = nodeState.name;
+ uuid = nodeState.uuid;
+ nodeTypeName = nodeState.nodeTypeName;
+ definition = nodeState.definition;
+
+ init(nodeState.getMixinTypeNames(), nodeState.getChildNodeEntries(), nodeState.getPropertyNames(), nodeState.getNodeReferences());
+ }
+ }
+ }
+
+ protected synchronized void refresh(Event event, ChangeLog changeLog) {
+ NodeId id = getNodeId();
+ switch (event.getType()) {
+ case Event.NODE_ADDED:
+ case Event.PROPERTY_ADDED:
+ if (id.equals(event.getParentId())) {
+ ItemId evId = event.getItemId();
+ ItemState newState = null;
+
+ if (evId.denotesNode()) {
+ QName name = event.getQPath().getNameElement().getName();
+ String uuid = (((NodeId)evId).getRelativePath() != null) ? null : ((NodeId)evId).getUUID();
+ ChildNodeEntry cne = childNodeEntries.add(name, uuid);
+ try {
+ newState = cne.getNodeState();
+ } catch (ItemStateException e) {
+ log.error("Internal error", e);
+ }
+ } else {
+ PropertyId pId = (PropertyId) event.getItemId();
+ PropertyReference re = new PropertyReference(this, pId.getQName(), isf, idFactory);
+ properties.put(pId.getQName(), re);
+ try {
+ newState = re.getPropertyState();
+ } catch (ItemStateException e) {
+ log.error("Internal error", e);
+ }
+ }
+
+ // connect the transient state to this state and make
+ // sure its data are updated
+ if (newState != null && changeLog != null) {
+ for (Iterator it = changeLog.addedStates(); it.hasNext();) {
+ ItemState added = (ItemState) it.next();
+ if (added.getId().equals(evId)) {
+ added.connect(newState);
+ added.pull();
+ break;
+ }
+ }
+ }
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException("Illegal event type " + event.getType() + " for NodeState.");
+ }
+ break;
+
+ case Event.NODE_REMOVED:
+ if (id.equals(event.getParentId())) {
+ QName qName = event.getQPath().getNameElement().getName();
+ int index = event.getQPath().getNameElement().getNormalizedIndex();
+ childNodeEntries.remove(qName, index);
+ setStatus(STATUS_MODIFIED);
+ } else if (id.equals(event.getItemId())) {
+ setStatus(STATUS_REMOVED);
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException("Illegal event type " + event.getType() + " for NodeState.");
+ }
+ break;
+
+ case Event.PROPERTY_REMOVED:
+ if (id.equals(event.getParentId())) {
+ PropertyId pId = (PropertyId) event.getItemId();
+ properties.remove(pId.getQName());
+ setStatus(STATUS_MODIFIED);
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException("Illegal event type " + event.getType() + " for NodeState.");
+ }
+ break;
- init(nodeState.getMixinTypeNames(), nodeState.getChildNodeEntries(), nodeState.getPropertyNames(), nodeState.getNodeReferences());
+ case Event.PROPERTY_CHANGED:
+ default:
+ // ILLEGAL
+ throw new IllegalArgumentException("Illegal event type " + event.getType() + " for NodeState.");
}
}
@@ -680,7 +762,6 @@
* <code>QNames</code> objects.
*
* @return set of <code>QNames</code> objects
- * @see #addPropertyName
*/
public synchronized Collection getPropertyNames() {
Collection names;
@@ -700,7 +781,6 @@
* Returns the complete collection of {@link ChildPropertyEntry}s.
*
* @return unmodifiable collection of <code>ChildPropertyEntry</code> objects
- * @see #addPropertyName
*/
public synchronized Collection getPropertyEntries() {
Collection props;
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java Thu Oct 5 23:55:27 2006
@@ -26,6 +26,7 @@
import org.apache.jackrabbit.spi.PropertyId;
import org.apache.jackrabbit.spi.ItemId;
import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.Event;
import org.apache.jackrabbit.value.QValue;
import org.apache.jackrabbit.jcr2spi.nodetype.ValueConstraint;
import org.slf4j.Logger;
@@ -178,20 +179,50 @@
break;
default:
// should never occur. status is validated upon setStatus(int)
+ log.error("Internal error: Invalid state " + getStatus());
}
}
/**
* {@inheritDoc}
*/
- protected synchronized void copyFrom(ItemState state) {
- synchronized (state) {
- PropertyState propState = (PropertyState) state;
- name = propState.name;
- //parent = propState.parent; // TODO: parent from wrong layer
- type = propState.type;
- def = propState.def;
- values = propState.values;
+ protected synchronized void pull() {
+ if (overlayedState != null) {
+ synchronized (overlayedState) {
+ PropertyState propState = (PropertyState) overlayedState;
+ name = propState.name;
+ type = propState.type;
+ def = propState.def;
+ values = propState.values;
+ }
+ }
+ }
+
+ protected synchronized void refresh(Event event, ChangeLog changeLog) {
+ switch (event.getType()) {
+ case Event.PROPERTY_REMOVED:
+ if (event.getItemId().equals(getId())) {
+ setStatus(STATUS_REMOVED);
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException("EventId " + event.getItemId() + " does not match id of this property state.");
+ }
+ break;
+
+ case Event.PROPERTY_CHANGED:
+ if (event.getItemId().equals(getId())) {
+ setStatus(STATUS_MODIFIED);
+ } else {
+ // ILLEGAL
+ throw new IllegalArgumentException("EventId " + event.getItemId() + " does not match id of this property state.");
+ }
+ break;
+
+ case Event.PROPERTY_ADDED:
+ case Event.NODE_ADDED:
+ case Event.NODE_REMOVED:
+ default:
+ throw new IllegalArgumentException("Event type " + event.getType() + " cannot be applied to a PropertyState");
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java Thu Oct 5 23:55:27 2006
@@ -265,6 +265,8 @@
// remove operations just processed
transientStateMgr.disposeOperations(changeLog.getOperations());
+ // now its save to clear the changeLog
+ changeLog.reset();
}
/**
@@ -303,7 +305,6 @@
Iterator it = refTracker.getReferences();
while (it.hasNext()) {
PropertyState propState = (PropertyState) it.next();
- // DIFF JR: remove check (already asserted on processReference)
boolean modified = false;
QValue[] values = propState.getValues();
QValue[] newVals = new QValue[values.length];
@@ -349,8 +350,6 @@
}
/**
- * DIFF JACKRABBIT: copied and adapted from ItemImpl.getTransientStates()
- * <p/>
* Builds a <code>ChangeLog</code> of transient (i.e. new, modified or
* deleted) item states that are within the scope of <code>state</code>.
*
@@ -670,8 +669,7 @@
}
public void visit(Update operation) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
- // TODO: TOBEFIXED. not correct.
- workspaceItemStateMgr.execute(operation);
+ throw new UnsupportedOperationException("Internal error: Update cannot be handled by session ItemStateManager.");
}
public void visit(Restore operation) throws VersionException, PathNotFoundException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
@@ -790,9 +788,7 @@
}
private void removeItemState(ItemState itemState, int options) throws RepositoryException {
- // DIFF JR: check for both, node- and propertyState
validator.checkRemoveItem(itemState, options);
-
// recursively remove the complete tree including the given node state.
boolean success = false;
try {
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java Thu Oct 5 23:55:27 2006
@@ -243,32 +243,9 @@
//-----------------------------------------< ItemStateLifeCycleListener >---
/**
* @inheritDoc
- * @see ItemStateListener#stateCreated(ItemState)
- */
- public void stateCreated(ItemState created) {
- }
-
- /**
- * @inheritDoc
- * @see ItemStateListener#stateModified(ItemState)
- */
- public void stateModified(ItemState modified) {
- }
-
- /**
- * @inheritDoc
- * @see ItemStateListener#stateDestroyed(ItemState)
- */
- public void stateDestroyed(ItemState destroyed) {
- changeLog.deletedStates.remove(destroyed);
- }
-
- /**
- * @inheritDoc
* @see ItemStateLifeCycleListener#statusChanged(ItemState, int)
*/
public void statusChanged(ItemState state, int previousStatus) {
- // TODO: cleanup operations as well.
// TODO: depending on status of state adapt change log
// e.g. a revert on states will reset the status from
// 'existing modified' to 'existing'.
@@ -292,14 +269,6 @@
case ItemState.STATUS_NEW:
// was new and has been saved now
changeLog.addedStates.remove(state);
- // state needs to be connected to the overlayed-state now
- try {
- ItemState overlayedState = parent.getItemState(state.getId());
- state.connect(overlayedState);
- } catch (ItemStateException e) {
- // TODO, handle property
- log.error(e.getMessage());
- }
break;
}
break;
@@ -310,6 +279,7 @@
// check if modified earlier
if (previousStatus == ItemState.STATUS_EXISTING_MODIFIED) {
changeLog.modifiedStates.remove(state);
+ // todo: remove operation(s) as well
}
changeLog.deleted(state);
break;
@@ -317,7 +287,7 @@
if (previousStatus == ItemState.STATUS_NEW) {
// was new and now removed again
changeLog.addedStates.remove(state);
- // TODO remove the 'add' operation as well
+ // TODO: remove operation as well
} else if (previousStatus == ItemState.STATUS_EXISTING_REMOVED) {
// was removed and is now saved
changeLog.deletedStates.remove(state);
@@ -326,6 +296,7 @@
case ItemState.STATUS_STALE_DESTROYED:
// state is now stale. remove from modified
changeLog.modifiedStates.remove(state);
+ // TODO: remove operation as well
break;
case ItemState.STATUS_STALE_MODIFIED:
// state is now stale. keep in modified. wait until refreshed
@@ -335,7 +306,7 @@
changeLog.added(state);
break;
default:
- log.warn("ItemState has invalid status: " + state.getStatus());
+ log.error("ItemState has invalid status: " + state.getStatus());
}
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java Thu Oct 5 23:55:27 2006
@@ -19,9 +19,10 @@
import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
import org.apache.jackrabbit.spi.EventIterator;
import org.apache.jackrabbit.spi.Event;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.PropertyId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.HashSet;
@@ -35,6 +36,8 @@
public class WorkspaceItemStateManager extends CachingItemStateManager
implements InternalEventListener {
+ private static Logger log = LoggerFactory.getLogger(WorkspaceItemStateManager.class);
+
public WorkspaceItemStateManager(ItemStateFactory isf, IdFactory idFactory) {
super(isf, idFactory);
}
@@ -51,73 +54,106 @@
* @param isLocal
*/
public void onEvent(EventIterator events, boolean isLocal) {
+ onEvent(events, isLocal, null);
+ }
+
+ public void onEvent(EventIterator events, ChangeLog changeLog) {
+ if (changeLog == null) {
+ throw new IllegalArgumentException("ChangeLog must not be null.");
+ }
+ // inform all transient states, that they have been persisted and must
+ // connect to their workspace state (and eventually reload the data).
+ changeLog.persisted();
+
+ // inform all existing workspace states about the transient modifications
+ // that have been persisted now.
+ onEvent(events, true, changeLog);
+ }
+
+ private void onEvent(EventIterator events, boolean isLocal, ChangeLog changeLog) {
// collect set of removed node ids
Set removedNodeIds = new HashSet();
+ List addEventList = new ArrayList();
List eventList = new ArrayList();
while (events.hasNext()) {
- Event e = events.nextEvent();
- eventList.add(e);
+ Event event = events.nextEvent();
+ int type = event.getType();
+ if (type == Event.NODE_ADDED || event.getType() == Event.PROPERTY_ADDED) {
+ addEventList.add(event);
+ } else if (type == Event.NODE_REMOVED) {
+ // remember removed nodes separately for proper handling later on.
+ removedNodeIds.add(event.getItemId());
+ eventList.add(event);
+ } else {
+ eventList.add(event);
+ }
}
- if (eventList.isEmpty()) {
+ if (eventList.isEmpty() && addEventList.isEmpty()) {
return;
}
+ /* process remove and change events */
for (Iterator it = eventList.iterator(); it.hasNext(); ) {
- Event e = (Event) it.next();
- ItemId itemId = e.getItemId();
- NodeId parentId = e.getParentId();
- ItemState state;
- NodeState parent;
- switch (e.getType()) {
- case Event.NODE_ADDED:
- case Event.PROPERTY_ADDED:
- state = lookup(itemId);
- if (state != null) {
- // TODO: item already exists ???
- // invalidate
- state.refresh();
- }
- parent = (NodeState) lookup(parentId);
- if (parent != null) {
- // discard and let wsp manager reload state when accessed next time
- parent.refresh();
- }
- break;
- case Event.NODE_REMOVED:
- case Event.PROPERTY_REMOVED:
- state = lookup(itemId);
- if (state != null) {
- state.notifyStateDestroyed();
- }
- state = lookup(parentId);
- if (state != null) {
- parent = (NodeState) state;
- // check if removed as well
- if (removedNodeIds.contains(parent.getId())) {
- // do not invalidate here
- } else {
- // discard and let wsp manager reload state when accessed next time
- parent.refresh();
- }
+ Event event = (Event) it.next();
+ int type = event.getType();
+
+ ItemState state = lookup(event.getItemId());
+ NodeState parent = (event.getParentId() != null) ? (NodeState) lookup(event.getParentId()) : null;
+
+ if (type == Event.NODE_REMOVED || type == Event.PROPERTY_REMOVED) {
+ if (state != null) {
+ state.refresh(event, changeLog);
+ }
+ if (parent != null) {
+ // invalidate parent only if it has not been removed
+ // with the same event bundle.
+ if (!removedNodeIds.contains(event.getParentId())) {
+ parent.refresh(event, changeLog);
}
- break;
- case Event.PROPERTY_CHANGED:
- state = lookup(itemId);
- // discard and let wsp manager reload state when accessed next time
- if (state != null) {
- state.refresh();
+ }
+ } else if (type == Event.PROPERTY_CHANGED) {
+ if (state != null) {
+ try {
+ // TODO: improve.
+ /* retrieve property value and type from server even if
+ changes were issued from this session (changelog).
+ this is currently the only way to update the workspace
+ state, which is not connected to its overlaying session-state.
+ */
+ PropertyState tmp = getItemStateFactory().createPropertyState((PropertyId) state.getId(), state.getParent());
+ ((PropertyState) state).init(tmp.getType(), tmp.getValues());
+ state.refresh(event, changeLog);
+ } catch (ItemStateException e) {
+ log.error("Unexpected error while updating modified property state.", e);
}
+ }
+ } else {
+ // should never occur
+ throw new IllegalArgumentException("Invalid event type: " + event.getType());
}
}
- }
- public void onEvent(EventIterator events, ChangeLog changeLog) {
- if (changeLog == null) {
- throw new IllegalArgumentException("ChangeLog must not be null.");
+ /* Add events need to be processed hierarchically, since its not possible
+ to add a new child reference to a state that is not yet present in
+ the state manager.
+ The 'progress' flag is used to make sure, that during each loop at
+ least one event has been processed and removed from the iterator.
+ If this is not the case, there are not parent states present in the
+ state manager that need to be updated and the remaining events may
+ be ignored.
+ */
+ boolean progress = true;
+ while (!addEventList.isEmpty() && progress) {
+ progress = false;
+ for (Iterator it = addEventList.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ NodeState parent = (NodeState) lookup(event.getParentId());
+ if (parent != null) {
+ parent.refresh(event, changeLog);
+ it.remove();
+ progress = true;
+ }
+ }
}
- // apply the transient changes in changeLog to the ItemStates in the
- // workspace layer and synchronize the changes recorded in the changelog
- // with the events sent.
- changeLog.persist(events);
}
}
Modified: jackrabbit/trunk/contrib/spi/spi2dav/project.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/project.xml?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/project.xml (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/project.xml Thu Oct 5 23:55:27 2006
@@ -100,6 +100,15 @@
<scope>runtime</scope>
</properties>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.2</version>
+ <url>http://jakarta.apache.org/commons/codec/</url>
+ <properties>
+ <scope>runtime</scope>
+ </properties>
+ </dependency>
</dependencies>
<!-- ====================================================================== -->
Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/EventImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/EventImpl.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/EventImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/EventImpl.java Thu Oct 5 23:55:27 2006
@@ -22,6 +22,7 @@
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.spi.SessionInfo;
+import org.apache.jackrabbit.spi.PropertyId;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.observation.ObservationConstants;
import org.apache.jackrabbit.webdav.observation.EventType;
@@ -29,6 +30,7 @@
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.jcr.observation.SubscriptionImpl;
+import org.apache.jackrabbit.util.Text;
import org.w3c.dom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +47,7 @@
private final Element eventElement;
private final int type;
private final ItemId itemId;
+ private final NodeId parentId;
private final Path qPath;
public EventImpl(Element eventElement, URIResolver uriResolver,
@@ -61,8 +64,11 @@
String href = DomUtil.getChildTextTrim(eventElement, DavConstants.XML_HREF, DavConstants.NAMESPACE);
if (type == Event.NODE_ADDED || type == Event.NODE_REMOVED) {
itemId = uriResolver.getNodeId(href, sessionInfo);
+ String parentHref = Text.getRelativeParent(href, 1, true);
+ parentId = uriResolver.getNodeId(parentHref, sessionInfo);
} else {
itemId = uriResolver.getPropertyId(href, sessionInfo);
+ parentId = ((PropertyId)itemId).getParentId();
}
qPath = uriResolver.getQPath(href, sessionInfo);
}
@@ -80,8 +86,7 @@
}
public NodeId getParentId() {
- // TODO not available from XML_EVENT element
- return null;
+ return parentId;
}
public String getUUID() {
Modified: jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=diff&rev=453514&r1=453513&r2=453514
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Thu Oct 5 23:55:27 2006
@@ -1467,17 +1467,13 @@
checkConsumed();
String uri = getItemUri(targetId, sessionInfo);
- try {
- // first unsubscribe in order to retrieve the events
- String subscrUri = (targetId.denotesNode() ? uri : getItemUri(((PropertyId) targetId).getParentId(), sessionInfo));
- EventIterator events = poll(subscrUri, subscriptionId, sessionInfo);
- unsubscribe(subscrUri, subscriptionId, sessionInfo);
- return events;
+ String subscrUri = (targetId.denotesNode() ? uri : getItemUri(((PropertyId) targetId).getParentId(), sessionInfo));
- } finally {
+ UnLockMethod method = null;
+ try {
// make sure the lock initially created is removed again on the
- // server.
- UnLockMethod method = new UnLockMethod(uri, batchId);
+ // server, asking the server to persist the modifications
+ method = new UnLockMethod(uri, batchId);
// todo: check if 'initmethod' would work (ev. conflict with TxId header).
String[] locktokens = sessionInfo.getLockTokens();
if (locktokens != null && locktokens.length > 0) {
@@ -1486,18 +1482,24 @@
}
// in contrast to standard UNLOCK, the tx-unlock provides a
// request body.
- try {
- method.setRequestBody(new TransactionInfo(commit));
- client.executeMethod(method);
- method.checkSuccess();
- } catch (IOException e) {
- throw new RepositoryException(e);
- } catch (DavException e) {
- throw ExceptionConverter.generate(e);
- } finally {
+ method.setRequestBody(new TransactionInfo(commit));
+ client.executeMethod(method);
+ method.checkSuccess();
+
+ // retrieve events
+ EventIterator events = poll(subscrUri, subscriptionId, sessionInfo);
+ return events;
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ } catch (DavException e) {
+ throw ExceptionConverter.generate(e);
+ } finally {
+ if (method != null) {
// release UNLOCK method
method.releaseConnection();
}
+ // unsubscribe
+ unsubscribe(subscrUri, subscriptionId, sessionInfo);
}
}