Author: mreutegg
Date: Thu Mar 3 06:05:35 2005
New Revision: 156039
URL: http://svn.apache.org/viewcvs?view=rev&rev=156039
Log:
- Extended observation test cases
- fixed observation bug that caused ItemStateException in case a property is removed and added again with the same name
Added:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java (with props)
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/NodeRemovedTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyAddedTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyChangedTest.java
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/WorkspaceImpl.java Thu Mar 3 06:05:35 2005
@@ -954,7 +954,7 @@
if (obsMgr == null) {
try {
- obsMgr = rep.getObservationManagerFactory(wspConfig.getName()).createObservationManager(session, session.hierMgr, session.getItemManager());
+ obsMgr = rep.getObservationManagerFactory(wspConfig.getName()).createObservationManager(session, session.getItemManager());
} catch (NoSuchWorkspaceException nswe) {
// should never get here
String msg = "internal error: failed to instantiate observation manager";
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java?view=auto&rev=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java Thu Mar 3 06:05:35 2005
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.observation;
+
+import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.HierarchyManagerImpl;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.state.ItemStateManager;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Implements a {@link HierarchyManager} that uses a {@link ChangeLog} for
+ * the 'transient' changes on an underlying {@link ItemStateManager}.
+ * {@link ItemState}s in attic are provided from the removed {@link ItemState}s
+ * in the {@link ChangeLog}. The modified and added {@link ItemState}s in
+ * the {@link ChangeLog} overlay the {@link ItemState}s in the
+ * {@link ItemStateManager}.
+ */
+class ChangeLogBasedHierarchyMgr extends HierarchyManagerImpl {
+
+ /**
+ * Creates a new ChangeLogBasedHierarchyMgr that overlays
+ * manager with changes and uses the deleted
+ * map of the changes as an attic ItemStateManager.
+ * @param rootNodeUUID the uuid of the root node.
+ * @param manager the item state manager.
+ * @param changes the changes that will be applied on the item state manager.
+ * @param resolver the namespace resolver of the current session.
+ */
+ ChangeLogBasedHierarchyMgr(String rootNodeUUID,
+ ItemStateManager manager,
+ ChangeLog changes,
+ NamespaceResolver resolver) {
+ super(rootNodeUUID,
+ new ChangeLogItemStateManager(manager, changes),
+ resolver,
+ new AtticItemStateManager(changes));
+ }
+
+ /**
+ * Implements an ItemStateManager that is overlayed by a ChangeLog.
+ */
+ private static class ChangeLogItemStateManager implements ItemStateManager {
+
+ /**
+ * The changes that will be applied to the {@link #base}.
+ */
+ private final ChangeLog changes;
+
+ /**
+ * The underlying {@link ItemStateManager}.
+ */
+ private final ItemStateManager base;
+
+ /**
+ * Creates a new ChangeLogItemStateManager that overlays
+ * the {@link ItemState}s in base with the one found in
+ * changes.
+ * @param base the underlying {@link ItemStateManager}.
+ * @param changes
+ */
+ private ChangeLogItemStateManager(ItemStateManager base, ChangeLog changes) {
+ this.base = base;
+ this.changes = changes;
+ }
+
+ /**
+ * Returns the {@link ItemState} with the id. This
+ * ItemState manager first looks up the ChangeLog and then
+ * tries to find the ItemState in the base {@link ItemStateManager}.
+ * @param id the id of the {@link ItemState}.
+ * @return the {@link ItemState} with id.
+ * @throws NoSuchItemStateException if there is no ItemState with
+ * id.
+ * @throws ItemStateException if any other error occurs.
+ */
+ public ItemState getItemState(ItemId id) throws NoSuchItemStateException, ItemStateException {
+ // check ChangeLog first
+ try {
+ ItemState state = changes.get(id);
+ if (state != null) {
+ return state;
+ }
+ } catch (NoSuchItemStateException e) {
+ // item has been deleted, but we still return it by asking base
+ }
+ return base.getItemState(id);
+ }
+
+ /**
+ * Returns true if there exists a {@link ItemState} either
+ * in the {@link ChangeLog} or the base {@link ItemStateManager};
+ * otherwise false is returned.
+ * @param id the id of the {@link ItemState}.
+ * @return true if there exists a {@link ItemState} either
+ * in the {@link ChangeLog} or the base {@link ItemStateManager};
+ * otherwise false.
+ */
+ public boolean hasItemState(ItemId id) {
+ // check ChangeLog first
+ try {
+ ItemState state = changes.get(id);
+ if (state != null) {
+ return true;
+ }
+ } catch (NoSuchItemStateException e) {
+ // item has been deleted, but we still might return true by asking base
+ }
+ return base.hasItemState(id);
+ }
+
+ /**
+ * Always throws a {@link UnsupportedOperationException}.
+ */
+ public NodeReferences getNodeReferences(NodeReferencesId id)
+ throws NoSuchItemStateException, ItemStateException {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Returns the removed {@link ItemState}s from the ChangeLog.
+ */
+ private static class AtticItemStateManager implements ItemStateManager {
+
+ /**
+ * Map of deleted {@link ItemState}s indexed by {@link ItemId}.
+ */
+ private final Map deleted = new HashMap();
+
+ /**
+ * Creates a new AtticItemStateManager based on
+ * changes.
+ * @param changes deleted {@link ItemState} are retrieved from this
+ * ChangeLog.
+ */
+ private AtticItemStateManager(ChangeLog changes) {
+ for (Iterator it = changes.deletedStates(); it.hasNext();) {
+ ItemState state = (ItemState) it.next();
+ deleted.put(state.getId(), state);
+ }
+ }
+
+ /**
+ * Returns an {@link ItemState} it is found in the deleted map of the
+ * {@link ChangeLog}.
+ * @param id the id of the {@link ItemState}.
+ * @return the deleted {@link ItemState}.
+ * @throws NoSuchItemStateException if the {@link ItemState} cannot
+ * be found in the deleted map.
+ * @throws ItemStateException if any other error occurs.
+ */
+ public ItemState getItemState(ItemId id) throws NoSuchItemStateException, ItemStateException {
+ ItemState state = (ItemState) deleted.get(id);
+ if (state != null) {
+ return state;
+ } else {
+ throw new NoSuchItemStateException();
+ }
+ }
+
+ /**
+ * Returns true if an {@link ItemState} with id
+ * is found in the deleted map of the {@link ChangeLog}; false
+ * otherwise.
+ * @param id the id of the {@link ItemState}.
+ * @return true if an {@link ItemState} with id
+ * is found in the deleted map of the {@link ChangeLog}; false
+ * otherwise.
+ */
+ public boolean hasItemState(ItemId id) {
+ return deleted.containsKey(id);
+ }
+
+ /**
+ * Always throws a {@link UnsupportedOperationException}.
+ */
+ public NodeReferences getNodeReferences(NodeReferencesId id)
+ throws NoSuchItemStateException, ItemStateException {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ChangeLogBasedHierarchyMgr.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java Thu Mar 3 06:05:35 2005
@@ -66,33 +66,32 @@
private final SessionImpl session;
/**
- * The HierarchyManager of the session that creates the events.
- */
- private final HierarchyManager hmgr;
-
- /**
* Creates a new empty EventStateCollection.
*
* @param session the session that created these events.
*/
EventStateCollection(ObservationManagerFactory dispatcher,
- SessionImpl session,
- HierarchyManager hmgr) {
+ SessionImpl session) {
this.dispatcher = dispatcher;
this.session = session;
- this.hmgr = hmgr;
}
/**
* Creates {@link EventState} instances from ItemState
* changes.
+ * @param rootNodeUUID the UUID of the root node.
* @param changes the changes on ItemStates.
* @param provider an ItemStateProvider to provide ItemState
* of items that are not contained in the changes collection.
* @throws ItemStateException if an error occurs while creating events
* states for the item state changes.
*/
- public void createEventStates(ChangeLog changes, ItemStateManager provider) throws ItemStateException {
+ public void createEventStates(String rootNodeUUID, ChangeLog changes, ItemStateManager provider) throws ItemStateException {
+ // create a hierarchy manager, that is based on the ChangeLog and
+ // the ItemStateProvider
+ // todo use CachingHierarchyManager ?
+ HierarchyManager hmgr = new ChangeLogBasedHierarchyMgr(rootNodeUUID, provider, changes, session.getNamespaceResolver());
+
for (Iterator it = changes.modifiedStates(); it.hasNext();) {
ItemState state = (ItemState) it.next();
if (state.isNode()) {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java Thu Mar 3 06:05:35 2005
@@ -21,7 +21,6 @@
import org.apache.commons.collections.UnboundedFifoBuffer;
import org.apache.log4j.Logger;
import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.ItemManager;
import java.util.Collections;
@@ -141,9 +140,8 @@
* @return an ObservationManager.
*/
public ObservationManagerImpl createObservationManager(SessionImpl session,
- HierarchyManager hmgr,
ItemManager itemMgr) {
- return new ObservationManagerImpl(this, session, hmgr, itemMgr);
+ return new ObservationManagerImpl(this, session, itemMgr);
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java Thu Mar 3 06:05:35 2005
@@ -11,14 +11,12 @@
* accordance with the terms of the license agreement you entered into
* with Day.
*/
-
package org.apache.jackrabbit.core.observation;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.ItemManager;
import org.apache.jackrabbit.core.Path;
import org.apache.jackrabbit.core.MalformedPathException;
-import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
import org.apache.log4j.Logger;
@@ -45,11 +43,6 @@
private final SessionImpl session;
/**
- * The HierarchyManager of the session.
- */
- private final HierarchyManager hmgr;
-
- /**
* The ItemManager for this ObservationManager.
*/
private final ItemManager itemMgr;
@@ -62,7 +55,6 @@
*
* @param session the Session this ObservationManager
* belongs to.
- * @param hmgr the HierarchyManager of the session.
* @param itemMgr {@link org.apache.jackrabbit.core.ItemManager} of the passed
* Session.
* @throws NullPointerException if session or itemMgr
@@ -70,7 +62,6 @@
*/
ObservationManagerImpl(ObservationManagerFactory obsMgrFactory,
SessionImpl session,
- HierarchyManager hmgr,
ItemManager itemMgr) {
if (session == null) {
throw new NullPointerException("session");
@@ -81,7 +72,6 @@
this.obsMgrFactory = obsMgrFactory;
this.session = session;
- this.hmgr = hmgr;
this.itemMgr = itemMgr;
}
@@ -159,7 +149,7 @@
* @return a new EventStateCollection.
*/
public EventStateCollection createEventStateCollection() {
- return new EventStateCollection(obsMgrFactory, session, hmgr);
+ return new EventStateCollection(obsMgrFactory, session);
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Thu Mar 3 06:05:35 2005
@@ -440,7 +440,7 @@
EventStateCollection events = null;
if (obsMgr != null) {
events = obsMgr.createEventStateCollection();
- events.createEventStates(local, this);
+ events.createEventStates(root.getUUID(), local, this);
events.prepare();
}
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/NodeRemovedTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/NodeRemovedTest.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/NodeRemovedTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/NodeRemovedTest.java Thu Mar 3 06:05:35 2005
@@ -43,7 +43,7 @@
public void testSingleNodeRemoved() throws RepositoryException {
EventResult result = new EventResult(log);
addEventListener(result, Event.NODE_REMOVED);
- Node foo = testRootNode.addNode(nodeName1);
+ Node foo = testRootNode.addNode(nodeName1, testNodeType);
testRootNode.save();
foo.remove();
testRootNode.save();
@@ -59,7 +59,7 @@
public void testMultiNodesRemoved() throws RepositoryException {
EventResult result = new EventResult(log);
addEventListener(result, Event.NODE_REMOVED);
- Node n1 = testRootNode.addNode(nodeName1);
+ Node n1 = testRootNode.addNode(nodeName1, testNodeType);
n1.addNode(nodeName2);
testRootNode.save();
n1.remove();
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyAddedTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyAddedTest.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyAddedTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyAddedTest.java Thu Mar 3 06:05:35 2005
@@ -46,7 +46,7 @@
public void testSystemGenerated() throws RepositoryException {
EventResult result = new EventResult(log);
addEventListener(result, Event.PROPERTY_ADDED);
- testRootNode.addNode(nodeName1);
+ testRootNode.addNode(nodeName1, testNodeType);
testRootNode.save();
removeEventListener(result);
Event[] events = result.getEvents(DEFAULT_WAIT_TIMEOUT);
@@ -64,7 +64,7 @@
* @throws RepositoryException
*/
public void testSinglePropertyAdded() throws RepositoryException {
- Node foo = testRootNode.addNode(nodeName1);
+ Node foo = testRootNode.addNode(nodeName1, testNodeType);
testRootNode.save();
EventResult result = new EventResult(log);
addEventListener(result, Event.PROPERTY_ADDED);
@@ -80,7 +80,7 @@
* when multiple properties are added.
*/
public void testMultiPropertyAdded() throws RepositoryException {
- Node foo = testRootNode.addNode(nodeName1);
+ Node foo = testRootNode.addNode(nodeName1, testNodeType);
testRootNode.save();
EventResult result = new EventResult(log);
addEventListener(result, Event.PROPERTY_ADDED);
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyChangedTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyChangedTest.java?view=diff&r1=156038&r2=156039
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyChangedTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/observation/PropertyChangedTest.java Thu Mar 3 06:05:35 2005
@@ -16,8 +16,14 @@
*/
package org.apache.jackrabbit.test.api.observation;
+import org.apache.jackrabbit.test.NotExecutableException;
+
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import javax.jcr.PropertyType;
+import javax.jcr.StringValue;
+import javax.jcr.LongValue;
+import javax.jcr.nodetype.NodeType;
import javax.jcr.observation.Event;
/**
@@ -42,7 +48,7 @@
* triggered when a single property is changed.
*/
public void testSinglePropertyChanged() throws RepositoryException {
- Node node = testRootNode.addNode(nodeName1);
+ Node node = testRootNode.addNode(nodeName1, testNodeType);
node.setProperty(propertyName1, "foo");
testRootNode.save();
EventResult result = new EventResult(log);
@@ -60,7 +66,7 @@
* @throws RepositoryException
*/
public void testMultiPropertyChanged() throws RepositoryException {
- Node node = testRootNode.addNode(nodeName1);
+ Node node = testRootNode.addNode(nodeName1, testNodeType);
node.setProperty(propertyName1, "foo");
node.setProperty(propertyName2, "bar");
testRootNode.save();
@@ -80,7 +86,7 @@
* triggered only for changed properties and not for new properties.
*/
public void testSinglePropertyChangedWithAdded() throws RepositoryException {
- Node node = testRootNode.addNode(nodeName1);
+ Node node = testRootNode.addNode(nodeName1, testNodeType);
node.setProperty(propertyName1, "foo");
testRootNode.save();
EventResult result = new EventResult(log);
@@ -93,4 +99,49 @@
checkPropertyChanged(events, new String[]{nodeName1 + "/" + propertyName1});
}
+ /**
+ * Tests if either a
+ *