Index: dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java (working copy) @@ -49,6 +49,7 @@ import org.jboss.dna.graph.property.PropertyFactory; import org.jboss.dna.graph.property.ValueComparators; import org.jboss.dna.graph.request.AccessQueryRequest; import org.jboss.dna.graph.request.CacheableRequest; +import org.jboss.dna.graph.request.ChangeRequest; import org.jboss.dna.graph.request.CloneBranchRequest; import org.jboss.dna.graph.request.CloneWorkspaceRequest; import org.jboss.dna.graph.request.CopyBranchRequest; @@ -102,7 +103,8 @@ class JoinRequestProcessor extends RequestProcessor { // this.repository = repository; this.propertyFactory = context.getPropertyFactory(); this.pathFactory = context.getValueFactories().getPathFactory(); - this.mirrorProcessor = new JoinMirrorRequestProcessor(repository.getSourceName(), context, observer, now, + // The mirror processor should never send anything to an observer, since all requests go to this processor's observer + this.mirrorProcessor = new JoinMirrorRequestProcessor(repository.getSourceName(), context, null, now, repository.getDefaultCachePolicy()); } @@ -184,6 +186,10 @@ class JoinRequestProcessor extends RequestProcessor { } mirrorProcessor.setFederatedRequest(forked); mirrorProcessor.process(original); + // If this is a change request, record it on this processor so it goes to the observer ... + if (original instanceof ChangeRequest && !original.hasError() && !original.isCancelled()) { + recordChange((ChangeRequest)original); + } } else { this.federatedRequest = forked; process(original); Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java (working copy) @@ -41,19 +41,8 @@ import org.jboss.dna.common.util.Logger; public abstract class ChangeObserver implements Observer { private final CopyOnWriteArraySet sources = new CopyOnWriteArraySet(); - private final ObservedId id; protected ChangeObserver() { - this.id = new ObservedId(); - } - - /** - * {@inheritDoc} - * - * @see org.jboss.dna.graph.observe.Observer#getId() - */ - public final ObservedId getId() { - return this.id; } /** Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/observe/Changes.java (working copy) @@ -40,7 +40,6 @@ public class Changes implements Comparable, Serializable { private static final long serialVersionUID = 1L; - protected final ObservedId id; protected final String processId; protected final String contextId; protected final String userName; @@ -56,7 +55,6 @@ public class Changes implements Comparable, Serializable { List requests ) { assert requests != null; assert !requests.isEmpty(); - this.id = new ObservedId(); this.userName = userName; this.sourceName = sourceName; this.timestamp = timestamp; @@ -71,7 +69,6 @@ public class Changes implements Comparable, Serializable { } protected Changes( Changes changes ) { - this.id = new ObservedId(); this.userName = changes.userName; this.sourceName = changes.sourceName; this.timestamp = changes.timestamp; @@ -85,13 +82,6 @@ public class Changes implements Comparable, Serializable { assert this.processId != null; assert this.contextId != null; } - - /** - * @return the unique ID of these changes - */ - public ObservedId getId() { - return this.id; - } /** * Get the user that made these changes. Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java (working copy) @@ -78,7 +78,7 @@ public abstract class NetChangeObserver extends ChangeObserver { protected NetChangeObserver() { } - + /** * @param workspace the workspace of the location (never null) * @param location the location whose details are being deleted (never null) @@ -163,7 +163,7 @@ public abstract class NetChangeObserver extends ChangeObserver { } } else if (change instanceof SetPropertyRequest) { SetPropertyRequest set = (SetPropertyRequest)change; - + if (set.isNewProperty()) { details.addProperty(set.property()); } else { @@ -197,7 +197,8 @@ public abstract class NetChangeObserver extends ChangeObserver { } else if (change instanceof CopyBranchRequest) { details.addEventType(ChangeType.NODE_ADDED); } else if (change instanceof MoveBranchRequest) { - // the old location is a removed node event and if it is the same location as the original location it is a reorder + // the old location is a removed node event and if it is the same location as the original location it is a + // reorder Location original = ((MoveBranchRequest)change).getActualLocationBefore(); NetChangeDetails originalDetails = findDetailsByLocation(workspace, original, detailsByLocationByWorkspace); originalDetails.addEventType(ChangeType.NODE_REMOVED); @@ -206,13 +207,13 @@ public abstract class NetChangeObserver extends ChangeObserver { details.addEventType(ChangeType.NODE_ADDED); } else if (change instanceof CloneBranchRequest) { CloneBranchRequest cloneRequest = (CloneBranchRequest)change; - + // create event details for any nodes that were removed for (Location removed : cloneRequest.getRemovedNodes()) { NetChangeDetails removedDetails = findDetailsByLocation(workspace, removed, detailsByLocationByWorkspace); removedDetails.addEventType(ChangeType.NODE_REMOVED); } - + // create event details for new node details.addEventType(ChangeType.NODE_ADDED); } else if (change instanceof RenameNodeRequest) { @@ -226,7 +227,7 @@ public abstract class NetChangeObserver extends ChangeObserver { } else if (change instanceof UpdateValuesRequest) { // TODO need to know if this is a new property UpdateValuesRequest updateValuesRequest = (UpdateValuesRequest)change; - + if (!updateValuesRequest.addedValues().isEmpty() || !updateValuesRequest.removedValues().isEmpty()) { details.addEventType(ChangeType.PROPERTY_CHANGED); // TODO need to set property like details.changeProperty(property); @@ -319,6 +320,7 @@ public abstract class NetChangeObserver extends ChangeObserver { private final EnumSet eventTypes; private final Set addedProperties; private final Set modifiedProperties; + private final Set addedOrModifiedProperties; private final Set removedProperties; private final int hc; @@ -334,12 +336,29 @@ public abstract class NetChangeObserver extends ChangeObserver { this.location = location; this.hc = HashCode.compute(this.workspaceName, this.location); this.eventTypes = eventTypes; - if (addedProperties == null) addedProperties = Collections.emptySet(); - if (modifiedProperties == null) modifiedProperties = Collections.emptySet(); + Set addedOrModified = null; + if (addedProperties == null) { + addedProperties = Collections.emptySet(); + addedOrModified = modifiedProperties; // may be null + } else { + addedOrModified = addedProperties; + } + if (modifiedProperties == null) { + if (addedOrModified == null) addedOrModified = Collections.emptySet(); + modifiedProperties = Collections.emptySet(); + } else { + if (addedOrModified == null) { + addedOrModified = modifiedProperties; + } else { + addedOrModified = new HashSet(modifiedProperties); + addedOrModified.addAll(addedProperties); + } + } if (removedProperties == null) removedProperties = Collections.emptySet(); this.addedProperties = Collections.unmodifiableSet(addedProperties); this.modifiedProperties = Collections.unmodifiableSet(modifiedProperties); this.removedProperties = Collections.unmodifiableSet(removedProperties); + this.addedOrModifiedProperties = Collections.unmodifiableSet(addedOrModified); } /** @@ -378,6 +397,15 @@ public abstract class NetChangeObserver extends ChangeObserver { } /** + * Get the combination of {@link #getAddedProperties() added} and {@link #getModifiedProperties() modified} properties. + * + * @return the immutable set of properties that were added or modified; never null but possibly empty + */ + public Set getAddedOrModifiedProperties() { + return this.addedOrModifiedProperties; + } + + /** * @return removedProperties */ public Set getRemovedProperties() { @@ -530,7 +558,7 @@ public abstract class NetChangeObserver extends ChangeObserver { if (property.getName().equals(propertyName)) { handled = true; this.addedProperties.remove(property); - + // get rid of event type if no longer applicable if (this.addedProperties.isEmpty()) { this.eventTypes.remove(ChangeType.PROPERTY_ADDED); @@ -545,7 +573,7 @@ public abstract class NetChangeObserver extends ChangeObserver { for (Property property : this.modifiedProperties) { if (property.getName().equals(propertyName)) { this.modifiedProperties.remove(property); - + // get rid of event type if no longer applicable if (this.modifiedProperties.isEmpty()) { this.eventTypes.remove(ChangeType.PROPERTY_CHANGED); Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java (working copy) @@ -32,20 +32,8 @@ import net.jcip.annotations.ThreadSafe; @ThreadSafe public class ObservationBus implements Observable, Observer { private final ChangeObservers observers = new ChangeObservers(); - - private final ObservedId id; public ObservationBus() { - this.id = new ObservedId(); - } - - /** - * {@inheritDoc} - * - * @see org.jboss.dna.graph.observe.Observer#getId() - */ - public ObservedId getId() { - return this.id; } /** Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservedId.java deleted file mode 100644 =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservedId.java (revision 1396) +++ /dev/null (working copy) @@ -1,61 +0,0 @@ -/* - * JBoss DNA (http://www.jboss.org/dna) - * See the COPYRIGHT.txt file distributed with this work for information - * regarding copyright ownership. Some portions may be licensed - * to Red Hat, Inc. under one or more contributor license agreements. - * See the AUTHORS.txt file in the distribution for a full listing of - * individual contributors. - * - * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA - * is licensed to you under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * JBoss DNA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.jboss.dna.graph.observe; - -import java.io.Serializable; -import java.util.concurrent.atomic.AtomicLong; -import net.jcip.annotations.Immutable; - -/** - * A unique identifier for an event or observer that can be compared with IDs created before or after this ID. - */ -@Immutable -public final class ObservedId implements Serializable { - - private static final long serialVersionUID = 1L; - - private static final AtomicLong idSequencer = new AtomicLong(0); - - private static long getNextId() { - return idSequencer.getAndIncrement(); - } - - private final long id; - - /** - * Constructs a unique ID. - */ - public ObservedId() { - this.id = getNextId(); - } - - /** - * @param otherId the ID being compared to - * @return true if this ID sequentially comes before the other ID - */ - public boolean isBefore(ObservedId otherId) { - return (this.id < otherId.id); - } - -} Index: dna-graph/src/main/java/org/jboss/dna/graph/observe/Observer.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/observe/Observer.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/observe/Observer.java (working copy) @@ -29,14 +29,6 @@ package org.jboss.dna.graph.observe; public interface Observer { /** - * The ID that uniquely identifies this observer. This ID can be used to determine if {@link Changes changes} came before or - * after this observer was created. - * - * @return the unique observer identifier (never null) - */ - ObservedId getId(); - - /** * Method that is called for each {@link Changes set of changes} from the {@link Observable} instance(s) with which this * observer is registered. * Index: dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java =================================================================== --- dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java (revision 1396) +++ dna-graph/src/main/java/org/jboss/dna/graph/request/SetPropertyRequest.java (working copy) @@ -140,7 +140,7 @@ public class SetPropertyRequest extends ChangeRequest { * @throws IllegalStateException if the request is frozen */ public void setNewProperty( boolean created ) { - this.actualCreation = true; + this.actualCreation = created; } /** Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrObservationManager.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrObservationManager.java (revision 1396) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrObservationManager.java (working copy) @@ -539,7 +539,6 @@ final class JcrObservationManager implements ObservationManager { // don't accept unless IDs are different return !getSessionId().equals(changes.getContextId()); } - return true; } @@ -661,12 +660,12 @@ final class JcrObservationManager implements ObservationManager { */ @Override public void notify( Changes changes ) { - - // don't process if changes occurred before this listener was registered - if (changes.getId().isBefore(getId())) { - return; - } - + // + // // don't process if changes occurred before this listener was registered + // if (changes.getId().isBefore(getId())) { + // return; + // } + // // check source first if (!acceptBasedOnEventSource(changes)) { return; Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java (revision 1396) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java (working copy) @@ -33,6 +33,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -73,7 +74,6 @@ import org.jboss.dna.graph.connector.federation.ProjectionParser; import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource; import org.jboss.dna.graph.observe.Changes; import org.jboss.dna.graph.observe.Observable; -import org.jboss.dna.graph.observe.ObservedId; import org.jboss.dna.graph.observe.Observer; import org.jboss.dna.graph.property.Name; import org.jboss.dna.graph.property.NamespaceRegistry; @@ -280,7 +280,7 @@ public class JcrRepository implements Repository { * @param repositoryObservable the repository library observable associated with this repository (never null) * @param descriptors the {@link #getDescriptorKeys() descriptors} for this repository; may be null. * @param options the optional {@link Option settings} for this repository; may be null - * @throws IllegalArgumentException If executionContext, connectionFactory, + * @throws IllegalArgumentException If executionContext, connectionFactory, * repositorySourceName, or repositoryObservable is null. */ public JcrRepository( ExecutionContext executionContext, @@ -557,6 +557,19 @@ public class JcrRepository implements Repository { return sourceName; } + String getSystemSourceName() { + return systemSourceName; + } + + /** + * Get the name of the source that we want to observe. + * + * @return the name of the source that should be observed; never null + */ + String getObservableSourceName() { + return WORKSPACES_SHARE_SYSTEM_BRANCH ? federatedSource.getName() : sourceName; + } + /** * @return executionContext */ @@ -796,16 +809,6 @@ public class JcrRepository implements Repository { return lockManager; } - /** - * Returns the name of this repository - * - * @return the name of this repository - * @see #sourceName - */ - String getName() { - return this.sourceName; - } - protected class FederatedRepositoryContext implements RepositoryContext { private final RepositoryConnectionFactory connectionFactory; @@ -941,22 +944,11 @@ public class JcrRepository implements Repository { } protected class RepositoryObservationManager implements Observable, Observer { - + private final ExecutorService observerService = Executors.newSingleThreadExecutor(); private final CopyOnWriteArrayList observers = new CopyOnWriteArrayList(); - private final ObservedId id; - - public RepositoryObservationManager() { - this.id = new ObservedId(); - } - /** - * {@inheritDoc} - * - * @see org.jboss.dna.graph.observe.Observer#getId() - */ - public ObservedId getId() { - return this.id; + protected RepositoryObservationManager() { } /** @@ -965,22 +957,35 @@ public class JcrRepository implements Repository { * @see org.jboss.dna.graph.observe.Observer#notify(org.jboss.dna.graph.observe.Changes) */ public void notify( final Changes changes ) { - final List listeners = observers; - - Runnable command = new Runnable() { + // We only care about events that come from the federated source ... + if (!changes.getSourceName().equals(getObservableSourceName())) return; + + // We're still in the thread where the connector published its changes, + // so we need to create a runnable that will send these changes to all + // of the observers at this moment. Because 'observers' is + // a CopyOnWriteArrayList, we can't old onto the list (because the list's content + // might change). Instead, hold onto the Iterator over the listeners, + // and that will be a snapshot of the listeners at this moment + if (observers.isEmpty()) return; + final Iterator observerIterator = observers.iterator(); + + Runnable sender = new Runnable() { public void run() { - for (Observer observer : listeners) { + while (observerIterator.hasNext()) { + Observer observer = observerIterator.next(); + assert observer != null; observer.notify(changes); } - } + } }; - this.observerService.execute(command); + // Now let the executor service run this in another thread ... + this.observerService.execute(sender); } /** * {@inheritDoc} - * + * * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.Observer) */ public boolean register( Observer observer ) { @@ -990,7 +995,7 @@ public class JcrRepository implements Repository { /** * {@inheritDoc} - * + * * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.Observer) */ public boolean unregister( Observer observer ) { @@ -998,5 +1003,4 @@ public class JcrRepository implements Repository { return this.observers.remove(observer); } } - } Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java (revision 1396) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSession.java (working copy) @@ -335,8 +335,8 @@ class JcrSession implements Session { String workspaceName ) { SecurityContext context = getExecutionContext().getSecurityContext(); - return context.hasRole(roleName) || context.hasRole(roleName + "." + this.repository.getName()) - || context.hasRole(roleName + "." + this.repository.getName() + "." + workspaceName); + return context.hasRole(roleName) || context.hasRole(roleName + "." + this.repository.getRepositorySourceName()) + || context.hasRole(roleName + "." + this.repository.getRepositorySourceName() + "." + workspaceName); } /** Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrObservationManagerTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrObservationManagerTest.java (revision 1396) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrObservationManagerTest.java (working copy) @@ -167,8 +167,10 @@ public class JcrObservationManagerTest extends TestSuite { final String SOURCE = "store"; this.config = new JcrConfiguration(); - this.config.repositorySource("store").usingClass(InMemoryRepositorySource.class).setRetryLimit(100).setProperty("defaultWorkspaceName", - WORKSPACE); + this.config.repositorySource("store") + .usingClass(InMemoryRepositorySource.class) + .setRetryLimit(100) + .setProperty("defaultWorkspaceName", WORKSPACE); this.config.repository(REPOSITORY).setSource(SOURCE).setOption(Option.JAAS_LOGIN_CONFIG_NAME, "dna-jcr"); this.config.save(); @@ -186,13 +188,15 @@ public class JcrObservationManagerTest extends TestSuite { } void checkResults( TestListener listener ) { - if ( listener.getActualEventCount() != listener.getExpectedEventCount() ) { + if (listener.getActualEventCount() != listener.getExpectedEventCount()) { // Wrong number ... StringBuilder sb = new StringBuilder(" Actual events were: "); - for ( Event event : listener.getEvents() ) { + for (Event event : listener.getEvents()) { sb.append('\n').append(event); } - assertThat("Received incorrect number of events."+ sb.toString(), listener.getActualEventCount(), is(listener.getExpectedEventCount())); + assertThat("Received incorrect number of events." + sb.toString(), + listener.getActualEventCount(), + is(listener.getExpectedEventCount())); assertThat(listener.getErrorMessage(), listener.getErrorMessage(), is(nullValue())); } } @@ -286,10 +290,12 @@ public class JcrObservationManagerTest extends TestSuite { @Test public void shouldReceiveNodeAddedEventWhenRegisteredToReceiveAllEvents() throws Exception { // register listener (add + 3 property events) + Node root = getRoot(); + save(); TestListener listener = addListener(4, ALL_EVENTS, null, false, null, null, false); // add node - Node addedNode = getRoot().addNode("node1", UNSTRUCTURED); + Node addedNode = root.addNode("node1", UNSTRUCTURED); save(); // event handling @@ -568,9 +574,8 @@ public class JcrObservationManagerTest extends TestSuite { // make sure same listener isn't added again getObservationManager().addEventListener(listener, ALL_EVENTS, null, false, null, null, false); - assertThat("The same listener should not be added more than once.", - getObservationManager().getRegisteredEventListeners().getSize(), - is(2L)); + assertThat("The same listener should not be added more than once.", getObservationManager().getRegisteredEventListeners() + .getSize(), is(2L)); } /** @@ -1133,8 +1138,8 @@ public class JcrObservationManagerTest extends TestSuite { // tests checkResults(listener); - assertTrue("Path for jrc:primaryType property was not found.", - containsPath(listener, node.getProperty("jcr:primaryType").getPath())); + assertTrue("Path for jrc:primaryType property was not found.", containsPath(listener, node.getProperty("jcr:primaryType") + .getPath())); } // =========================================================================================================================== Index: dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java =================================================================== --- dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java (revision 1396) +++ dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java (working copy) @@ -43,7 +43,6 @@ import org.jboss.dna.graph.Subgraph; import org.jboss.dna.graph.connector.RepositorySource; import org.jboss.dna.graph.observe.Changes; import org.jboss.dna.graph.observe.NetChangeObserver; -import org.jboss.dna.graph.observe.ObservedId; import org.jboss.dna.graph.observe.Observer; import org.jboss.dna.graph.property.Name; import org.jboss.dna.graph.property.Path; @@ -113,7 +112,6 @@ public class RepositoryService implements AdministeredService, Observer { } } - private final ObservedId id; private final ExecutionContext context; private final RepositoryLibrary sources; private final String configurationSourceName; @@ -150,7 +148,6 @@ public class RepositoryService implements AdministeredService, Observer { if (problems == null) problems = new SimpleProblems(); Path sourcesPath = pathFactory.create(pathToConfigurationRoot, DnaLexicon.SOURCES); - this.id = new ObservedId(); this.sources = new RepositoryLibrary(configurationSource, configurationWorkspaceName, sourcesPath, context); this.sources.addSource(configurationSource); this.pathToConfigurationRoot = pathToConfigurationRoot; @@ -163,15 +160,6 @@ public class RepositoryService implements AdministeredService, Observer { /** * {@inheritDoc} - * - * @see org.jboss.dna.graph.observe.Observer#getId() - */ - public ObservedId getId() { - return this.id; - } - - /** - * {@inheritDoc} */ public final ServiceAdministrator getAdministrator() { return this.administrator; Index: dna-repository/src/main/java/org/jboss/dna/repository/sequencer/SequencingService.java =================================================================== --- dna-repository/src/main/java/org/jboss/dna/repository/sequencer/SequencingService.java (revision 1396) +++ dna-repository/src/main/java/org/jboss/dna/repository/sequencer/SequencingService.java (working copy) @@ -417,7 +417,7 @@ public class SequencingService implements AdministeredService { for (Sequencer sequencer : allSequencers) { final SequencerConfig config = sequencer.getConfiguration(); for (SequencerPathExpression pathExpression : config.getPathExpressions()) { - for (Property property : change.getModifiedProperties()) { + for (Property property : change.getAddedOrModifiedProperties()) { Name propertyName = property.getName(); String propertyNameStr = context.getValueFactories().getStringFactory().create(propertyName); String path = nodePathStr + "/@" + propertyNameStr;