Index: modeshape-graph/src/main/java/org/modeshape/graph/request/SetPropertyRequest.java
===================================================================
--- modeshape-graph/src/main/java/org/modeshape/graph/request/SetPropertyRequest.java (revision 2408)
+++ modeshape-graph/src/main/java/org/modeshape/graph/request/SetPropertyRequest.java (working copy)
@@ -35,7 +35,7 @@ import org.modeshape.graph.property.Property;
* Instruction to set a particular property on the node at the specified location. This request never removes the node,
* even if the property is empty.
*/
-public class SetPropertyRequest extends ChangeRequest {
+public class SetPropertyRequest extends ChangeRequest implements PropertyChangeRequest {
private static final long serialVersionUID = 1L;
Index: modeshape-graph/src/main/java/org/modeshape/graph/request/UpdatePropertiesRequest.java
===================================================================
--- modeshape-graph/src/main/java/org/modeshape/graph/request/UpdatePropertiesRequest.java (revision 2408)
+++ modeshape-graph/src/main/java/org/modeshape/graph/request/UpdatePropertiesRequest.java (working copy)
@@ -53,7 +53,7 @@ import org.modeshape.graph.property.Property;
* is possible for a property to have no values.
*
*/
-public class UpdatePropertiesRequest extends ChangeRequest {
+public class UpdatePropertiesRequest extends ChangeRequest implements PropertyChangeRequest {
private static final long serialVersionUID = 1L;
Index: modeshape-graph/src/main/java/org/modeshape/graph/request/UpdateValuesRequest.java
===================================================================
--- modeshape-graph/src/main/java/org/modeshape/graph/request/UpdateValuesRequest.java (revision 2408)
+++ modeshape-graph/src/main/java/org/modeshape/graph/request/UpdateValuesRequest.java (working copy)
@@ -27,7 +27,7 @@ import org.modeshape.graph.property.Property;
* is possible for a property to have no values.
*
*/
-public class UpdateValuesRequest extends ChangeRequest {
+public class UpdateValuesRequest extends ChangeRequest implements PropertyChangeRequest {
private static final long serialVersionUID = 1L;
Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrObservationManager.java
===================================================================
--- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrObservationManager.java (revision 2408)
+++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrObservationManager.java (working copy)
@@ -63,6 +63,7 @@ import org.modeshape.graph.property.ValueFactories;
import org.modeshape.graph.property.ValueFactory;
import org.modeshape.graph.property.ValueFormatException;
import org.modeshape.graph.request.ChangeRequest;
+import org.modeshape.graph.request.PropertyChangeRequest;
/**
* The implementation of JCR {@link ObservationManager}.
@@ -805,7 +806,14 @@ final class JcrObservationManager implements ObservationManager {
if (shouldCheckNodeType()) {
ValueFactory stringFactory = getValueFactories().getStringFactory();
- Location parentLocation = Location.create(change.getLocation().getPath().getParent());
+ Path changePath = null;
+ if (change.includes(ChangeType.NODE_ADDED, ChangeType.NODE_REMOVED)) {
+ changePath = change.getPath().getParent();
+ } else {
+ changePath = change.getPath();
+ }
+
+ Location parentLocation = Location.create(changePath);
Map propMap = this.propertiesByLocation.get(parentLocation);
assert (propMap != null);
@@ -933,6 +941,7 @@ final class JcrObservationManager implements ObservationManager {
List changedLocations = new ArrayList();
// loop through changes saving the parent locations of the changed locations
+ Location root = null;
for (ChangeRequest request : changes.getChangeRequests()) {
String changedWorkspaceName = request.changedWorkspace();
// If this event is not from this session's workspace ...
@@ -945,13 +954,26 @@ final class JcrObservationManager implements ObservationManager {
}
}
Path changedPath = request.changedLocation().getPath();
- Path parentPath = changedPath.getParent();
- changedLocations.add(Location.create(parentPath));
+ if (!(request instanceof PropertyChangeRequest)) {
+ // We want the primary type and mixin types of the parent node ...
+ changedPath = changedPath.getParent();
+ }
+ Location location = Location.create(changedPath);
+ if (root == null && changedPath.isRoot()) root = location;
+ changedLocations.add(location);
}
if (!changedLocations.isEmpty()) {
// more efficient to get all of the locations at once then it is one at a time using the NetChange
Graph graph = getGraph();
this.propertiesByLocation = graph.getProperties(PRIMARY_TYPE, MIXIN_TYPES).on(changedLocations);
+ if (root != null && !propertiesByLocation.containsKey(root)) {
+ // The connector doesn't actually have any properties for the root node, so assume 'mode:root' ...
+ // For details, see MODE-959.
+ Property primaryType = graph.getContext().getPropertyFactory().create(JcrLexicon.PRIMARY_TYPE,
+ ModeShapeLexicon.ROOT);
+ Map props = Collections.singletonMap(primaryType.getName(), primaryType);
+ this.propertiesByLocation.put(root, props);
+ }
}
}
Index: modeshape-jcr/src/test/java/org/modeshape/jcr/JcrObservationManagerTest.java
===================================================================
--- modeshape-jcr/src/test/java/org/modeshape/jcr/JcrObservationManagerTest.java (revision 2408)
+++ modeshape-jcr/src/test/java/org/modeshape/jcr/JcrObservationManagerTest.java (working copy)
@@ -458,6 +458,27 @@ public final class JcrObservationManagerTest extends TestSuite {
+ propPath, containsPath(listener, propPath));
}
+ @Test
+ public void shouldReceivePropertyAddedEventWhenRegisteredToReceiveEventsBasedUponNodeTypeName() throws Exception {
+ // register listener
+ String[] nodeTypeNames = {"mode:root"};
+ TestListener listener = addListener(1, ALL_EVENTS, null, true, null, nodeTypeNames, false);
+
+ // add the property
+ this.session.getRootNode().setProperty("fooProp", "bar");
+ save();
+
+ // event handling
+ listener.waitForEvents();
+ removeListener(listener);
+
+ // tests
+ checkResults(listener);
+ String propPath = "/fooProp";
+ assertTrue("Path for added property is wrong: actual=" + listener.getEvents().get(0).getPath() + ", expected=" + propPath,
+ containsPath(listener, propPath));
+ }
+
// ===========================================================================================================================
// @see org.apache.jackrabbit.test.api.observation.EventIteratorTest
// ===========================================================================================================================