jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Mueller <muel...@adobe.com>
Subject Re: svn commit: r1532782 [1/2] - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/core/ oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/ oak-core/src/main...
Date Thu, 17 Oct 2013 09:27:54 GMT
Hi,

I saw Alex fixed the build problem (Thanks!). And Michael told me he found
a way to avoid the "global" node (I thought he is not working today). So I
will not revert the commit(s).

Regards,
Thomas



On 10/17/13 11:08 AM, "Thomas Mueller" <mueller@adobe.com> wrote:

>Hi,
>
>This commit also seems to breaks the build (a missing license header I
>think).
>
>For now, I will try to revert this commit
>
>Regards,
>Thomas
>
>
>
>On 10/17/13 10:58 AM, "Thomas Mueller" <mueller@adobe.com> wrote:
>
>>Hi,
>>
>>When using multiple cluster nodes (using MongoMK), multiple luster nodes
>>concurrently add or modify the node "/:commit-info". This results in a
>>conflict relatively quickly:
>>
>>  The node 1:/:commit-info was changed in revision
>>  r141c598ec6d-0-4, which was appied after the base revision
>>  r141c598e754-0-3, before
>>  r141c598eacd-0-3
>>
>>
>>I suggest to change the mechanism. At least each cluster node should use
>>a>>different node name.
>>
>>Regards,
>>Thomas
>>
>>
>>On 10/16/13 4:43 PM, "mduerig@apache.org" <mduerig@apache.org> wrote:
>>
>>>Author: mduerig
>>>Date: Wed Oct 16 14:43:01 2013
>>>New Revision: 1532782
>>>
>>>URL: http://svn.apache.org/r1532782
>>>Log:
>>>OAK-1055: Occasional test failure in ObservationTest.observation
>>>OAK-1060: Periodically poll for external events
>>>- Remove PostCommitHook argument from NodeStore.merge and make
>>>ChangeDispatcher part of NodeStore imlementations that implement
>>>Observable (i.e. support observation).
>>>- Use :commit-info on the root node to pass commit information across
>>>
>>>Added:
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jakrabbit/oak/plu
>>>g
>>>ins/observation/CommitInfoEditorProvider.java
>>>Removed:
>>>
>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>commit/PostCommitHook.java
>>>Modified:
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/AbstractRoot.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/AbstractTree.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentRepositoryImpl.java
>>>
>>>jackrabit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cor
>>>e
>>>/ContentSessionImpl.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/SystemRoot.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStore.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreBranch.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelRootBuilder.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/AsyncIndexUpdate.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/memory/MemoryNodeStore.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/mongomk/MongoNodeStore.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeDispatcher.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeProcessor.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/Observable.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStore.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/mainjava/org/apache/jackrabbit/oak/plu
>>>g
>>>ins/segment/SegmentNodeStoreBranch.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreService.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>lifecycle/OakInitializer.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStore.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStoreBranch.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeBuilderTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStateTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreCacheTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/LargeKernelNodeStateTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/NodeStoreTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/AsyncIndexUpdateTest.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/nodetype/NodeTypeIndexTest.java
>>>
>>>jackrabit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plu
>>>g
>>>ins/segment/JournalTst.java
>>>
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/MergeTest.java
>>>
>>>jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak
>>>/
>>>u
>>>pgrade/RepositoryUpgrade.java
>>>
>>>Modified:
>>>jackrabit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cor
>>>e
>>>/AbstractRoot.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/core/AbstractRoot.java?rev=1532782&r1=1532781&r
>>>2
>>>=
>>>1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/sc/main/java/org/apache/jackrabbit/oak/cor
>>>e
>>>/AbstractRoot.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jacrabbit/oak/cor
>>>e
>>>/AbstractRoot.java Wed Oct 16 14:43:01 2013
>>>@@ -47,7 +47,6 @@ import org.apache.jackabbit.oak.spi.com
>>> import org.apace.jackrabbit.oak.spi.commit.CompositeHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EditorHook;
>>> import or.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
>>> import org.apache.jackrabit.oak.spi.commit.ValidatorProvider;
>>> import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
>>>@@ -70,8 +69,6 @@ public abstract class AbstractRoot imple
>>>
>>>     private final CommitHook hook;
>>>
>>>-    private final PostCommitHook postHook;
>>>-
>>>     private final String workspaceName;
>>>
>>>     private final Subject subject;
>>>@@ -+126,12 @@ public abstract class AbstractRoot imple
>>>      /
>>>     protected AbstractRoot(NodeStore store,
>>>             CommitHook hook,
>>>-            PostCommitHook postHook,
>>>             String workspaceName,
>>>             Subject subject,
>>>             SecurityProvider securityProvider,
>>             QueryIndexProvider indexProvider) {
>>>         this.store = checkNotNull(store);
>>>         this.hok = checkNotNull(hook);
>>>-        this.postHook = postHook;
>>>         this.workspaceName = checkNotNull(workspaceName);
>>>         this.subject = checkNotNull(subject);
>>>         this.securityProvider = checkNotNull(securityProvider);
>>>@@ -245,7 +240,7 @@ public abstract class AbstractRoot imple
>>>     @Override
>>>     public void commit(final CommitHook... hooks) throws
>>>CommitFailedException {
>>>         checkLive();
>>>-        base = store.merge(builder, getCommitHook(hooks), postHook);
>>>+        base = store.merge(builder, getCommitHook(hooks));
>>>         secureBuilder.baseChanged();
>>>         modCount = 0;
>>>         if (permissionProvider.hasValue()) {
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/AbstractTree.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/core/AbstractTree.java?rev=1532782&r1=1532781&r
>>>2
>>>=
>>>1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/AbstractTree.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/AbstractTree.java Wed Oct 16 14:43:01 2013
>>>@@ -19,7 +19,18 @@
>>>
>>> package org.apache.jackrabbit.oak.core;
>>>
>>>+import static com.google.common.base.Preconditions.checkNotNull;
>>>+import static com.google.cmmon.collect.Iterables.filter;
>>>+import static com.google.common.collect.Iterables.size;
>>>+import static com.google.common.collect.Iterables.transform;
>>>+import static org.apache.jackrabbit.oak.api.Tree.Status.EXISTING;
>>>+import static org.apache.jackrabbit.oak.api.Tree.Status.MODIFIED;
>>>+import static org.apache.jackrabbit.oak.api.Tree.Status.NEW;
>>>+import static org.apache.jackrabbit.oak.api.Type.STRING;
>>>+import static
>>>org.apache.jackrabbit.oak.spi.state.NodeStateUtils.isHidden;
>>>+
>>> import java.util.Iterator;
>>>+
>>> import javax.annotation.Nonnull;
>>>
>>> import com.google.common.base.Function;
>>>@@ -28,19 +39,10 @@ import org.apache.jackrabbit.mk.api.Micr
>>> import org.apache.jackrabbit.oak.api.PropertyState;
>>> import org.apache.jackrabbit.oak.api.Tree;
>>> import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
>>>+import
>>>org.apache.jackrabbit.oak.plugins.observation.CommitInfoEditorProvider;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>
>>>-import static com.google.common.base.Preconditions.checkNotNull;
>>>-import static com.google.common.collect.Iterables.filter;
>>>-import static com.google.common.collect.Iterables.size;
>>>-import static com.google.common.collect.Iterables.transform;
>>>-import static org.apache.jackrabbit.oak.api.Tree.Status.EXISTING;
>>>-import static org.apache.jackrabbit.oak.api.Tree.Status.MODIFIED;
>>>-import static org.apache.jackrabbit.oak.api.Tree.Status.NEW;
>>>-impot static org.apache.jackrabbit.oak.api.Type.STRING;
>>>-import static
>>>org.apache.jackrabbit.oak.spi.state.NodeStateUtils.isHidden;
>>>-
>>> /**
>>>  * {@code AbstractTree} provides default implementations for most
>>>  * read methods of {@code Tree}. Furthermore it handles the
>>>@@ -55,7 +57, @@ public abstract class AbstractTree imple
>>>     public static final String OAK_CHILD_ORDER = ":childOrder";
>>>
>>>     // TODO: make this configurable
>>>-    private static final String[] INTERNAL_NODE_NAMES=
>>>{IndexConstants.INDEX_CONTENT_NODE_NAME, MicroKernel.CONFLICT_NAME};
>>>+    private static final String[] INTERNAL_NODE_NAMES ={
>>>+            IndexConstants.INDEX_CONTENT_NODE_NAME,
>>>+            MicroKernel.CONFLICT_NAME,
>>>CommiInfoEditorProvider.COMMIT_INFO};
>>>
>>>     /**
>>>      * Name of this tree
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentRepositoryImpl.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/core/ContentRepositoryImpl.java?rev=1532782&r1=
>>>1
>>>5
>>>32781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentRepositoryImpl.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentRepositoryImpl.java Wed Oct 16 14:43:01 2013
>>>@@ -26,7 +26,6 @@ import javax.security.auth.login.LoginEx
>>>
>>> import org.apache.jackrabbit.oak.api.ContentRepository;
>>> import org.apache.jackrabbit.oak.api.ContentSession;
>>>-import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
>>> import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
>>>@@ -47,7 +46,6 @@ public class ContentRepositoryImpl imple
>>>     private final String defaultWorkspaceName;
>>>     private final SecurityProvider securityProvider;
>>>     private final QueryIndexProvider indexProvider;
>>>-    private final ChangeDispatcher changeDispatcher;
>>>
>>>     /**
>>>      * Creates an content repository instance based on the given,
>>>already
>>>@@ -69,7 +67,6 @@ public class ContentRepositoryImpl imple
>>>         this.defaultWorkspaceName = checkNotNull(defaultWorkspaceName);
>>>         this.securityProvider = checkNotNull(securityProvider);
>>>         this.indexProvider = indexProvider != null ? indexProvider :
>>>new
>>>CompositeQueryIndexProvider();
>>>-        this.changeDispacher = new ChangeDispatcher(nodeStore);
>>>     }
>>>
>>>     @Nonnull
>>>@@ -89,8 +86,8 @@ public class ContentRepositoryImpl imple
>>>         LoginContext loginContext =
>>>lcProvider.getLoginContext(credentials, workspaceName);
>>>         loginContext.login();
>>>
>>>-        return new ContentSessionImpl(loginContext, securityProvider,
>>>workspaceName,
>>>-                nodeStore, commitHook, changeDispatcher,
>>>indexProvider);
>>>+        reurn new ContentSessionImpl(loginContext, securityProvider,
>>>workspaceName, nodeStore,
>>>+                commitHook, indexProvider);
>>>     }
>>>
>>>     public NodeStore getNodeStore() {
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentSessionImpl.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/core/ContentSessionImpl.java?rev=1532782&r1=153
>>>2
>>>7
>>>81&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentSessionImpl.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/ContentSessionImpl.java Wed Oct 16 14:43:01 2013
>>>@@ -16,6 +16,7 @@
>>>  */
>>> package org.apache.jackrabbit.oak.core;
>>>
>>>+import static com.google.common.base.Preconditions.checkArgument;
>>> import static com.google.common.base.Preconditions.checkState;
>>>
>>> import java.io.IOException;
>>>@@ -28,10 +9,12 @@ import javax.security.auth.login.LoginEx
>>> import org.apache.jackrabbit.oak.api.AuthInfo;
>>> import org.apache.jackrabbit.oak.api.ContentSession;
>>> import org.apache.jackrabbit.oak.api.Root;
>>>-import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
>>> import
>>>org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher.Listener;
>>>+import
>>>org.apache.jackrabbit.oak.plugins.observation.CommitInfoEditorProvider;
>> import org.apache.jackrabbit.oak.plugins.observation.Observable;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>+import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
>>>+import org.apache.jackrabbit.ok.spi.commit.EditorHook;
>>> import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
>>> import org.apache.jackrabbit.oak.spi.security.SecurityProvider;> import
>>>org.apache.jackrabbit.oak.spi.security.authentication.LoginContext;
>>>@@ -56,7 +59,6 @@ class ContentSessionImpl implements Cont
>>>    private final String workspaceName;
>>>     private final NodeStore store;
>>>     private final CommitHook hook;
>>>-    private final ChangeDispatcher changeDispatcher;
>>>     private final QueryIndexProvider indexProvider;
>>>     private final String sessionName;
>>>
>>>@@ -67,14 +69,13 @@ class ContentSessionImpl implements Cont
>>>                               @Nonnull String workspaceName,
>>>                               @Nonnull NodeStore store,
>>>                               @Nonnull CommitHook hook,
>>>-                              @Nonnull ChangeDispatcher
>>>changeDispatcher,
>>>                               @Nonnull QueryIndexProvider
>>>indexProvider)
>>>{
>>>+        checkArgument(store instanceof Observable);
>>>         this.loginContext = loginContext;
>>>         this.securityProvider = securityProvider;
>>>         this.workspaceName = workspaceName;
>>>         this.store = store;
>>>         this.hook = hook;
>>>-        this.changeDispatcher = changeDispatcher;
>>>         this.indexProvider = indexProvider;
>>>         this.sessionName = "session-" +
>>>SESSION_COUNTER.incrementAndGet();
>>>     }
>>>@@ -105,8 +106,12 @@ class ContentSessionImpl mplements Cont
>>>     @Override
>>>     public Root getLatestRoot() {
>>>         checkLive();
>>>-        return new AbstractRoot(store, hook,
>>>changeDispatcher.newHook(ContentSessionImpl.this), workspaceName,
>>>-                loginContext.getSubject(), securityrovider,
>>>indexProvider) {
>>>+
>>>+        EditorHook commitInfoEditor = new EditorHook(
>>>+                new CommitInfoEditorProvider(sessionName,
>>>getAuthInfo().getUserID()));
>>+
>>>+        return new AbstractRoot(store, new CompositeHook(hook,
>>>commitInfoEditor),
>>>+                workspaceNam, loginContext.getSubject(),
>>>securityProvider, indexProvider) {
>>>             @Overrie
>>>             protected void checkLive() {
>>>                 ContentSessionImpl.this.checkLive();
>>>@@ -121,7 +126,7 @@ class ContentSessionImpl implements Cont
>>>
>>>     @Override
>>>     public Listener newListener() {
>>>-        return changeDispatcher.newListener();
>>>+        return ((Observable) store).newListener();
>>>     }
>>>
>>>     //-----------------------------------------------------------<
>>>Closable >---
>>>@@ -139,4 +144,5 @@ class ContentSessionImpl implements Cont
>>>     public String toString() {
>>>         return sessionName;
>>>     }
>>>+
>>> }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/SystemRoot.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/core/SystemRoot.java?rev=1532782&r1=1532781&r2=
>>>1
>>>5
>>>32782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jacrabbit/oak/cor
>>>e
>>>/SystemRoot.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/co
>>>r
>>>e
>>>/SystemRoot.java Wed Oct 16 14:43:01 2013
>>>@@ -23,7 +23,6 @@ import org.apache.jackrabbit.oak.api.Roo
>>> import org.apache.jackrabbit.oak.security.authentication.SystemSubject;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.aache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
>>> import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
>>> import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
>>>@@ -41,8 +40,7 @@ public class SystemRoot extends Abstract
>>>     publi SystemRoot(final NodeStore store, final CommitHook hook,
>>>final String workspaceName,
>>>             final SecurityProvider securityProvider, final
>>>QueryIndexProvider indexProvider) {
>>>
>>>-        super(store, hook, PostCommitHook.EMPTY, workspaceName,
>>>-                SystemSubject.INSTANCE, securityProvider,
>>>indexProvider);
>>>+        super(store, hook, workspaceName, SystemSubject.INSTANCE,
>>>securityProvider, indexProvider);
>>>
>>>         contentSession = new ContentSession() {
>>>             private final AuthInfoImpl authInfo = new AuthInfoImpl(
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStore.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1532782&r1=1532
>>>7
>>>8
>>>1&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStore.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStore.java Wed Oct 16 14:43:01 2013
>>>@@ -38,10 +38,12 @@ import org.apache.jackrabbit.mk.api.Micr
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> importorg.apache.jackrabbit.oak.cache.CacheLIRS;
>>> import org.apache.jackrabbit.oak.cache.CacheStats;
>>>+import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
>>>+import
>>>org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher.Listener;
>>>+import org.apache.jackrabbit.oak.plugins.observation.Observable;
>>> import org.apche.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyObserver;
>>> import org.apache.jackrabbit.oak.spi.ommit.Observer;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>@@ -50,7 +52,7 @@ import org.apache.jackrabbit.oak.spi.sta
>>> /**
>>>  * {@code NodeStore} implementations against {@link MicroKernel}.
>>>  */
>>>-public class KernelNodeStore implements NodeStore {
>>>+public class KernelNodeStore implements NodeStore, Observable {
>>>
>>>     private static final long DEFAULT_CACHE_SIZE = 16 * 1024 * 1024;
>>>
>>>@@ -74,6 +76,8 @@ public class KernelNodeStore implements
>>>      */
>>>     private final Lock mergeLock = new ReentrantLock();
>>>
>>>+    private final ChangeDispatcher changeDispatcher;
>>>+
>>>     /**
>>>      * State of the current root node.
>>>      */
>>>@@ -120,6 +124,7 @@ public class KernelNodeStore implements
>>>         } catch (Exception e) {
>>>             throw new RuntimeException(e);
>>>         }
>>>+        changeDispatcher = new ChangeDispatcher(this);
>>>     }
>>>
>>>     public KernelNodeStore(MicroKernel kernel) {
>>>@@ -143,6 +148,13 @@ public class KernelNodeStore implements
>>>         return getRoot().toString();
>>>     }
>>>
>>>+    //------------------------------------------------------------<
>>>Observable >---
>>>+
>>>+    @Override
>>>+    public Listener newListener() {
>>>+        return changeDispatcher.newListener();
>>>+    }
>>>+
>>>     //----------------------------------------------------------<
>>>NodeStore >---
>>>
>>>     @Override
>>>@@ -157,15 +169,15 @@ public class KernelNodeStore implements
>>>     }
>>>
>>>     /**
>>>-     * This implementation delegates to {@link
>>>KernelRootBuilder#merge(CommitHook, PostCommitHook)}
>>>+     * This implementation delegates to {@link
>>>KernelRootBuilder#merge(CommitHook)}
>>>      * if {@code builder} is a {@link KernelNodeBuilder} instance.
>>>Otherwise it throws
>>>      * an {@code IllegalArgumentException}.
>>>      */
>>>     @Override
>>>-    public NodeState merge(@Nonnull NodeBuilder builder, @Nonnull
>>>CommitHook commitHook,
>>>-            PostCommitHook committed) throws CommitFailedExeption {
>>>+    public NodeState merge(@Nonnull NodeBuilder builder, @Nonnull
>>>CommitHook commitHook)
>>>+            throws CommitFailedException {
>>>         checkArgument(builder instanceof KernelRootBuilder);
>>>-        return ((KernelRootBuilder) builder).merge(commitHook,
>>>committed);
>>>+        return ((KernelRootBuilder) builder).merge(commitHook);
>>>     }
>>>
>>>     /**
>>>@@ -265,4 +277,16 @@ public class KernelNodeStore implements
>>>         return getRootState(kernel.merge(branchHead.getRevision(),
>>>null));
>>>     }
>>>
>>>+    void beforeCommit(NodeState root) {
>>>+        changeDispatcher.beforeCommit(root);
>>>+    }
>>>+
>>>+    void localCommit(NodeState root) {
>>>+        changeDispatcher.localCommit(root);
>>>+    }
>>>+
>>>+    void afterCommit(NodeState root) {
>>>+        changeDispatcher.afterCommit(root);
>>>+    }
>>>+
>>> }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreBranch.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabit/oak/kernel/KernelNodeStoreBranch.java?rev=1532782&r1
>>>=
>>>1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreBranch.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreBranch.java Wed Oct 16 14:43:01 2013
>>>@@ -30,7 +30,6 @@ import org.apache.jackrabbit.mk.api.Micr
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.commons.PathUtils;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import
>>>org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -132,8 +131,8 @@ class KernelNodeStoreBranch implements N
>>>
>>>     @Nonnull
>>>     @Override
>>>-    public NodeState merge(@Nonnull CommitHook hook, PostCommitHook
>>>committed) throws CommitFailedException {
>>>-        return branchState.merge(checkNotNull(hook),
>>>checkNotNull(committed));
>>>+    public NodeState merge(@Nonnull CommitHook hook) throws
>>>CommitFailedException {
>>>+        return branchState.merge(checkNotNull(hook));
>>>     }
>>>
>>>     @Override
>>>@@ -181,7 +180,7 @@ class KernelNodeStoreBranch implements N
>>>         abstract void rebase();
>>>
>>>         @Nonnull
>>>-        abstract NodeState merge(@Nonnull CommitHook hook,
>>>PostCommitHook committed) throws CommitFailedException;
>>>+        abstract NodeState merge(@Nonnull CommitHook hook) throws
>>>CommitFailedException;
>>>     }
>>>
>>>     /**
>>>@@ -191,7 +190,7 @@ class KernelNodeStoreBranch implements N
>>>      * <ul>
>>>      *     <li>{@link InMemory} on {@link #setRoot(NodeState)} if the
>>>new root differs
>>>      *         from the current base</li>.
>>>-     *     <li>{@link Merged} on {@link #merge(CommitHook,
>>>PostCommitHook)}</li>
>>>+     *     <li>{@link Merged} on {@link #merge(CommitHook)}</li>
>>>      * </ul>
>>>      */
>>>     private class Unmodified extends BranchState {
>>>@@ -222,7 +221,7 @@ class KernelNodeStoreBranch implements N
>>>         }
>>>
>>>         @Override
>>>-        NodeState merge(CommitHook hook, PostCommitHook committed)
>>>throws CommitFailedException {
>>>+        NodeState merge(CommitHook hook) throws CommitFailedException {
>>>             branchState = new Merged(base);
>>>             return base;
>>>         }
>>>@@ -237,7 +236,7 @@ class KernelNodeStoreBranch implements N
>>>      *     <li>{@link Unmodified} on {@link #setRoot(NodeState)} if the
>>>new root is the same
>>>      *         as the base of this branch or
>>>      *     <li>{@link Persisted} otherwise.
>>>-     *     <li>{@link Merged} on {@link #merge(CommitHook,
>>>PostCommitHook)}</li>
>>>+     *     <li>{@link Merged} on {@link #merge(CommitHook)}</li>
>>>      * </ul>
>>>      */
>>>     private class InMemory extends BranchState {
>>>@@ -279,15 +278,16 @@ class KernelNodeStoreBranch implements N
>>>         }
>>>
>>>         @Override
>>>-        NodeState merge(CommitHook hook, PostCommitHook committed)
>>>throws CommitFailedException {
>>>+        NodeState merge(CommitHook hook) throws CommitFailedException {
>>>             mergeLock.lock();
>>>             try {
>>>                 rebase();
>>>+                store.beforeCommit(base);
>>>                 NodeState toCommit =
>>>checkNotNull(hook).processCommit(base, head);
>>>                 JsopDiff diff = new JsopDiff(store);
>>>                 toCommit.compareAgainstBaseState(base, diff);
>>>                 NodeState newHead = store.commit(diff.toString(),
>>>base);
>>>-                committed.contentChanged(base, newHead);
>>>+                store.localCommit(newHead);
>>>                 branchState = new Merged(base);
>>>                 return newHead;
>>>             } catch (MicroKernelException e) {
>>>@@ -295,6 +295,7 @@ class KernelNodeStoreBranch implements N
>>>                         "Kernel", 1,
>>>                         "Failed to merge changes to the underlying
>>>MicroKernel", e);
>>>             } finally {
>>>+                store.afterCommit(store.getRoot());
>>>                 mergeLock.unlock();
>>>             }
>>>         }
>>>@@ -308,7 +309,7 @@ class KernelNodeStoreBranch implements N
>>>      * <ul>
>>>      *     <li>{@link Unmodified} on {@link #setRoot(NodeState)} if the
>>>new root is the same
>>>      *         as the base of this branch.
>>>-     *     <li>{@link Merged} on {@link #merge(CommitHook,
>>>PostCommitHook)}</li>
>>>+     *     <li>{@link Merged} on {@link #merge(CommitHook)}</li>
>>>      * </ul>
>>>      */
>>>     private class Persisted extends BranchState {
>>>@@ -361,13 +362,13 @@ class KernelNodeStoreBranch implements N
>>>         }
>>>
>>>         @Override
>>>-        NodeState merge(CommitHook hook, PostCommitHook committed)
>>>throws CommitFailedException {
>>>+        NodeState merge(CommitHook hook) throws CommitFailedException {
>>>             mergeLock.lock();
>>>             try {
>>>                 rebase();
>>>+                store.beforeCommit(base);
>>>                 NodeState toCommit =
>>>checkNotNull(hook).processCommit(base, head);
>>>                 if (toCommit.equals(base)) {
>>>-                    committed.contentChanged(base, base);
>>>                     branchState = new Merged(base);
>>>                     return base;
>>>                 } else {
>>>@@ -375,7 +376,7 @@ class KernelNodeStoreBranch implements N
>>>                     toCommit.compareAgainstBaseState(head, diff);
>>>                     commit(diff.toString());
>>>                     NodeState newRoot = store.merge(head);
>>>-                    committed.contentChanged(base, newRoot);
>>>+                    store.localCommit(newRoot);
>>>                     branchState = new Merged(base);
>>>                     return newRoot;
>>>                 }
>>>@@ -384,6 +385,7 @@ class KernelNodeStoreBranch implements N
>>>                         "Kernel", 1,
>>>                         "Failed to merge changes to the underlying
>>>MicroKernel", e);
>>>             } finally {
>>>+                store.afterCommit(store.getRoot());
>>>                 mergeLock.unlock();
>>>             }
>>>         }
>>>@@ -429,7 +431,7 @@ class KernelNodeStoreBranch implements N
>>>         }
>>>
>>>         @Override
>>>-        NodeState merge(CommitHook hook, PostCommitHook committed)
>>>throws CommitFailedException {
>>>+        NodeState merge(CommitHook hook) throws CommitFailedException {
>>>             throw new IllegalStateException("Branch has already been
>>>merged");
>>>         }
>>>     }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelRootBuilder.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/KernelRootBuilder.java?rev=1532782&r1=15
>>>3
>>>2
>>>781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelRootBuilder.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelRootBuilder.java Wed Oct 16 14:43:01 2013
>>>@@ -21,7 +21,6 @@ import static com.google.common.base.Pre
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
>>>
>>>@@ -132,9 +131,9 @@ class KernelRootBuilder extends MemoryNo
>>>     /**
>>>      * Merge all changes tracked in this builder into the underlying
>>>store.
>>>      */
>>>-    NodeState merge(CommitHook hook, PostCommitHook committed) throws
>>>CommitFailedException {
>>>+    NodeState merge(CommitHook hook) throws CommitFailedException {
>>>         purge();
>>>-        branch.merge(hook, committed);
>>>+        branch.merge(hook);
>>>         return reset();
>>>     }
>>>
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/AsyncIndexUpdate.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1532782
>>>&
>>>r
>>>1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/AsyncIndexUpdate.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/index/AsyncIndexUpdate.java Wed Oct 16 14:43:01 2013
>>>@@ -26,21 +26,19 @@ import java.util.concurrent.TimeUnit;
>>>
>>> import javax.annotation.Nonnull;
>>>
>>>+import com.google.common.base.Objects;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.api.PropertyState;
>>> import org.apache.jackrabbit.oak.api.Type;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>>
>>>-import com.google.common.base.Objects;
>>>-
>>> public class AsyncIndexUpdate implements Runnable {
>>>
>>>     private static final Logger log = LoggerFactory
>>>@@ -119,7 +117,7 @@ public class AsyncIndexUpdate implements
>>>                             throw CONCURRENT_UPDATE;
>>>                         }
>>>                     }
>>>-                }, PostCommitHook.EMPTY);
>>>+                });
>>>             } catch (CommitFailedException e) {
>>>                 if (e != CONCURRENT_UPDATE) {
>>>                     exception = e;
>>>@@ -144,7 +142,7 @@ public class AsyncIndexUpdate implements
>>>         NodeBuilder builder = store.getRoot().builder();
>>>         preAsyncRunStatus(builder);
>>>         try {
>>>-            store.merge(builder, EmptyHook.INSTANCE,
>>>PostCommitHook.EMPTY);
>>>+            store.merge(builder, EmptyHook.INSTANCE);
>>>         } catch (CommitFailedException e) {
>>>             log.warn("Index status update {} failed", name, e);
>>>         }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/memory/MemoryNodeStore.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java?rev=1532782
>>>&
>>>r
>>>1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/memory/MemoryNodeStore.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/memory/MemoryNodeStore.java Wed Oct 16 14:43:01 2013
>>>@@ -33,7 +33,6 @@ import javax.annotation.Nonnull;
>>> import com.google.common.io.ByteStreams;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import
>>>org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -75,21 +74,20 @@ public class MemoryNodeStore implements
>>>      * new branch and immediately merging it back.
>>>      * @param builder  the builder whose changes to apply
>>>      * @param commitHook the commit hook to apply while merging changes
>>>-     * @param committed  the pos commit hook
>>>      * @return the node state resulting from the merge.
>>>      * @throws CommitFailedException
>>>      * @throws IllegalArgumentException if the builder is not acquired
>>>from a root state of
>>>      *                                  this store
>>>      */
>>>     @Override
>>>-    public synchronized NodeState merge(@Nonnull NodeBuilder builder,
>>>@Nonnull CommitHook commitHook,
>>>-            PostCommitHook committed) throws CommitFailedException {
>>>+    public synchronized NodeState merge(@Nonnull NodeBuilder builder,
>>>@Nonnull CommitHook commitHook)
>>>+            throws CommitFailedException {
>>>         checkArgument(builder instanceof MemoryNodeBuilder);
>>>         checkNotNull(commitHook);
>>>         rebase(checkNotNull(builder));
>>>         NodeStoreBranch branch = new MemoryNodeStoreBranch(this,
>>>getRoot());
>>>         branch.setRoot(builder.getNodeState());
>>>-        NodeState merged = branch.merge(commitHook, committed);
>>>+        NodeState merged = branch.merge(commitHook);
>>>         ((MemoryNodeBuilder) builder).reset(merged);
>>>         return merged;
>>>     }
>>>@@ -198,16 +196,12 @@ public class MemoryNodeStore implements
>>>         }
>>>
>>>         @Override
>>>-        public NodeState merge(CommitHook hook, PostCommitHook
>>>committed) throws CommitFailedException {
>>>+        public NodeState merge(CommitHook hook) throws
>>>CommitFailedException {
>>>             // TODO: rebase();
>>>             checkNotMerged();
>>>             NodeState merged =
>>>ModifiedNodeState.squeeze(checkNotNull(hook).processCommit(base, root));
>>>-            synchronized (this) {
>>>-                // FIXME temporarily synchronized to work around the
>>>race described in OAK-1055
>>>-                store.root.set(merged);
>>>-                root = null; // Mark as merged
>>>-                committed.contentChanged(base, merged);
>>>-            }
>>>+            store.root.set(merged);
>>>+            root = null; // Mark as merged
>>>             return merged;
>>>         }
>>>
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/mongomk/MongoNodeStore.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java?rev=1532782
>>>&
>>>r
>>>1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/mongomk/MongoNodeStore.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/mongomk/MongoNodeStore.java Wed Oct 16 14:43:01 2013
>>>@@ -16,6 +16,9 @@
>>>  */
>>> package org.apache.jackrabbit.oak.plugins.mongomk;
>>>
>>>+import static com.google.common.base.Preconditions.checkNotNull;
>>>+import static com.google.common.base.Preconditions.checkState;
>>>+
>>> import java.io.IOException;
>>> import java.io.InputStream;
>>> import java.lang.ref.WeakReference;
>>>@@ -37,6 +40,10 @@ import java.util.concurrent.atomic.Atomi
>>> import javax.annotation.CheckForNull;
>>> import javax.annotation.Nonnull;
>>>
>>>+import com.google.common.base.Function;
>>>+import com.google.common.cache.Cache;
>>>+import com.google.common.collect.Iterables;
>>>+import com.google.common.collect.Maps;
>>> import org.apache.jackrabbit.mk.api.MicroKernelException;
>>> import org.apache.jackrabbit.oak.api.Blob;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>>@@ -46,21 +53,12 @@ import org.apache.jackrabbit.oak.plugins
>>> import
>>>org.apache.jackrabbit.oak.plugins.mongomk.util.TimingDocumentStoreWrappe
>>>r
>>>;
>>> import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>>
>>>-import com.google.common.base.Function;
>>>-import com.google.common.cache.Cache;
>>>-import com.google.common.collect.Iterables;
>>>-import com.google.common.collect.Maps;
>>>-
>>>-import static com.google.common.base.Preconditions.checkNotNull;
>>>-import static com.google.common.base.Preconditions.checkState;
>>>-
>>> /**
>>>  * Implementation of a NodeStore on MongoDB.
>>>  */
>>>@@ -664,8 +662,7 @@ public final class MongoNodeStore implem
>>>     @Nonnull
>>>     @Override
>>>     public NodeState merge(@Nonnull NodeBuilder builder,
>>>-                           @Nonnull CommitHook commitHook,
>>>-                           PostCommitHook committed)
>>>+                           @Nonnull CommitHook commitHook)
>>>             throws CommitFailedException {
>>>         // TODO: implement
>>>         return null;
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeDispatcher.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java?rev=1
>>>5
>>>3
>>>2782&r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeDispatcher.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeDispatcher.java Wed Oct 16 14:43:01 2013
>>>@@ -20,18 +20,21 @@ package org.apache.jackrabbit.oak.plugin
>>>
>>> import static com.google.common.base.Objects.toStringHelper;
>>> import static com.google.common.base.Preconditions.checkNotNull;
>>>-import static
>>>org.apache.jackrabbit.oak.plugins.observation.ObservationConstants.OAK_U
>>>N
>>>K
>>>NOWN;
>>>+import static com.google.common.base.Preconditions.checkState;
>>>+import static org.apache.jackrabbit.oak.api.Type.LONG;
>>>+import static org.apache.jackrabbit.oak.api.Type.STRING;
>>>
>>> import java.util.Queue;
>>> import java.util.Set;
>>>+import java.util.concurrent.atomic.AtomicLong;
>>>
>>> import javax.annotation.CheckForNull;
>>> import javax.annotation.Nonnull;
>>>
>>>+import com.google.common.base.Objects;
>>> import com.google.common.collect.Queues;
>>> import com.google.common.collect.Sets;
>>>-import org.apache.jackrabbit.oak.api.ContentSession;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>>+import org.apache.jackrabbit.oak.api.PropertyState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>
>>>@@ -39,19 +42,27 @@ import org.apache.jackrabbit.oak.spi.sta
>>>  * A {@code ChangeDispatcher} instance records changes to a {@link
>>>NodeStore}
>>>  * and dispatches them to interested parties.
>>>  * <p>
>>>- * The {@link #newHook(ContentSession)} method registers a hook for
>>>- * reporting changes. Actual changes are reported by calling
>>>- * {@link Hook#contentChanged(NodeState, NodeState)}. Such changes are
>>>considered
>>>- * to have occurred on the local cluster node and are recorded as such.
>>>Changes
>>>- * that occurred in-between calls to any hook registered with a change
>>>processor
>>>- * are considered to have occurred on a different cluster node and are
>>>recorded as such.
>>>+ * Actual changes are reported by calling {@link
>>>#beforeCommit(NodeState)},
>>>+ * {@link #localCommit(NodeState)} and {@link #afterCommit(NodeState)}
>>>in that order:
>>>+ * <pre>
>>>+      NodeState root = store.getRoot();
>>>+      branch.rebase();
>>>+      changeDispatcher.beforeCommit(root);
>>>+      try {
>>>+          NodeState head = branch.getHead();
>>>+          branch.merge();
>>>+          changeDispatcher.localCommit(head);
>>>+      } finally {
>>>+          changeDispatcher.afterCommit(store.getRoot());
>>>+      }
>>>+ * </pre>
>>>  * <p>
>>>- * The {@link #newListener()} registers a listener for receiving
>>>changes
>>>reported
>>>- * into a change dispatcher by any of its hooks.
>>>+ * The {@link #newListener()} method registers a listener for receiving
>>>changes reported
>>>+ * into a change dispatcher.
>>>  */
>>> public class ChangeDispatcher {
>>>-    private final NodeStore store;
>>>     private final Set<Listener> listeners = Sets.newHashSet();
>>>+    private final NodeStore store;
>>>
>>>     private NodeState previousRoot;
>>>
>>>@@ -65,20 +76,6 @@ public class ChangeDispatcher {
>>>     }
>>>
>>>     /**
>>>-     * Create a new {@link Hook} for reporting changes occurring in the
>>>-     * passed {@code contentSession}. The content session is used to
>>>-     * determine the user associated with the changes recorded through
>>>this
>>>-     * hook and to determine the originating session of changes.
>>>-     * @param contentSession  session which will be associated with any
>>>changes reported
>>>-     *                        through this hook.
>>>-     * @return a new {@code Hook} instance
>>>-     */
>>>-    @Nonnull
>>>-    public Hook newHook(ContentSession contentSession) {
>>>-        return new Hook(contentSession);
>>>-    }
>>>-
>>>-    /**
>>>      * Create a new {@link Listener} for receiving changes reported
>>>into
>>>      * this change dispatcher. Listeners need to be {@link
>>>Listener#dispose() disposed}
>>>      * when no longer needed.
>>>@@ -91,21 +88,83 @@ public class ChangeDispatcher {
>>>         return listener;
>>>     }
>>>
>>>-    private synchronized void contentChanged(@Nonnull NodeState before,
>>>@Nonnull NodeState after,
>>>-            ContentSession contentSession) {
>>>-        externalChange(checkNotNull(before));
>>>-        internalChange(checkNotNull(after), contentSession);
>>>+    private final AtomicLong changeCount = new AtomicLong(0);
>>>+
>>>+    private boolean inLocalCommit() {
>>>+        return changeCount.get() % 2 == 1;
>>>+    }
>>>+
>>>+    /**
>>>+     * Call with the latest persisted root node state right before
>>>persisting further changes.
>>>+     * Calling this method marks this instance to be inside a local
>>>commit.
>>>+     * <p>
>>>+     * The differences from the root node state passed to the last call
>>>to
>>>+     * {@link #afterCommit(NodeState)} to {@code root} are reported as
>>>cluster external
>>>+     * changes to any listener.
>>>+     *
>>>+     * @param root  latest persisted root node state.
>>>+     * @throws IllegalStateException  if inside a local commit
>>>+     */
>>>+    public synchronized void beforeCommit(@Nonnull NodeState root) {
>>>+        checkState(!inLocalCommit());
>>>+        changeCount.incrementAndGet();
>>>+        externalChange(checkNotNull(root));
>>>+    }
>>>+
>>>+    /**
>>>+     * Call right after changes have been successfully persisted
>>>passing
>>>the new root
>>>+     * node state resulting from the persist operation.
>>>+     * <p>
>>>+     * The differences from the root node state passed to the last call
>>>to
>>>+     * {@link #beforeCommit(NodeState)} to {@code root} are reported as
>>>cluster local
>>>+     * changes to any listener.
>>>+
>>>+     * @param root  root node state just persisted
>>>+     * @throws IllegalStateException  if not inside a local commit
>>>+     */
>>>+    public synchronized void localCommit(@Nonnull NodeState root) {
>>>+        checkState(inLocalCommit());
>>>+        internalChange(checkNotNull(root));
>>>+    }
>>>+
>>>+    /**
>>>+     * Call to mark the end of a persist operation passing the latest
>>>persisted root node state.
>>>+     * Calling this method marks this instance to not be inside a local
>>>commit.
>>>+     * <p>
>>>+     * The difference from the root node state passed to the las call
>>>to
>>>+     * {@link #localCommit(NodeState)} to {@code root} are reported as
>>>cluster external
>>>+     * changes to any listener.
>>>+
>>>+     * @param root  latest persisted root node state.
>>>+     * @throws IllegalStateException  if not inside a local commit
>>>+     */
>>>+    public synchronized void afterCommit(@Nonnull NodeState root) {
>>>+        checkState(inLocalCommit());
>>>+        externalChange(checkNotNull(root));
>>>+        changeCount.incrementAndGet();
>>>+    }
>>>+
>>>+    private void externalChange() {
>>>+        if (!inLocalCommit()) {
>>>+            long c = changeCount.get();
>>>+            NodeState root = store.getRoot();  // Need to get root
>>>outside sync. See OAK-959
>>>+            synchronized (this) {
>>>+                if (c == changeCount.get() && !inLocalCommit()) {
>>>+                    externalChange(root);
>>>+                }
>>>+            }
>>>+        }
>>>     }
>>>
>>>     private synchronized void externalChange(NodeState root) {
>>>         if (!root.equals(previousRoot)) {
>>>-            add(ChangeSet.external(previousRoot, root));
>>>+            add(new ChangeSet(previousRoot, root, true));
>>>             previousRoot = root;
>>>         }
>>>     }
>>>
>>>-    private synchronized void internalChange(NodeState root,
>>>ContentSession contentSession) {
>>>-        add(ChangeSet.local(previousRoot, root, contentSession));
>>>+    private synchronized void internalChange(NodeState root) {
>>>+        add(new ChangeSet(previousRoot, root, false));
>>>         previousRoot = root;
>>>     }
>>>
>>>@@ -133,28 +192,6 @@ public class ChangeDispatcher {
>>>         }
>>>     }
>>>
>>>-    //------------------------------------------------------------<
>>>Sink
>>>>---
>>>-
>>>-    /**
>>>-     * Hook for reporting changes. Actual changes are reported by
>>>calling
>>>-     * {@link Hook#contentChanged(NodeState, NodeState)}. Such changes
>>>are considered
>>>-     * to have occurred on the local cluster node and are recorded as
>>>such. Changes
>>>-     * that occurred in-between calls to any hook registered with a
>>>change processor
>>>-     * are considered to have occurred on a different cluster node and
>>>are recorded as such.
>>>-     */
>>>-    public class Hook implements PostCommitHook {
>>>-        private final ContentSession contentSession;
>>>-
>>>-        private Hook(ContentSession contentSession) {
>>>-            this.contentSession = contentSession;
>>>-        }
>>>-
>>>-        @Override
>>>-        public void contentChanged(@Nonnull NodeState before, @Nonnull
>>>NodeState after) {
>>>-            ChangeDispatcher.this.contentChanged(before, after,
>>>contentSession);
>>>-        }
>>>-    }
>>>-
>>>     //------------------------------------------------------------<
>>>Listener >---
>>>
>>>     /**
>>>@@ -177,6 +214,10 @@ public class ChangeDispatcher {
>>>          */
>>>         @CheckForNull
>>>         public ChangeSet getChanges() {
>>>+            if (changeSets.isEmpty()) {
>>>+                externalChange();
>>>+            }
>>>+
>>>             return changeSets.isEmpty() ? null : changeSets.remove();
>>>         }
>>>
>>>@@ -193,55 +234,45 @@ public class ChangeDispatcher {
>>>      * on the local cluster node, the user causing the changes and the
>>>date the changes
>>>      * where persisted.
>>>      */
>>>-    public abstract static class ChangeSet {
>>>+    public static class ChangeSet {
>>>         private final NodeState before;
>>>         private final NodeState after;
>>>+        private final boolean isExternal;
>>>
>>>-        static ChangeSet local(NodeState base, NodeState head,
>>>ContentSession contentSession) {
>>>-            return new InternalChangeSet(base, head, contentSession,
>>>System.currentTimeMillis());
>>>+        ChangeSet(NodeState before, NodeState after, boolean
>>>isExternal)
>>>{
>>>+            this.before = before;
>>>+            this.after = after;
>>>+            this.isExternal = isExternal;
>>>         }
>>>
>>>-        static ChangeSet external(NodeState base, NodeState head) {
>>>-            return new ExternalChangeSet(base, head);
>>>+        public boolean isExternal() {
>>>+            return isExternal;
>>>         }
>>>
>>>-        protected ChangeSet(NodeState before, NodeState after) {
>>>-            this.before = before;
>>>-            this.after = after;
>>>+        public boolean isLocal(String sessionId) {
>>>+            return Objects.equal(getSessionId(), sessionId);
>>>         }
>>>
>>>-        /**
>>>-         * Determine whether these changes originate from the local
>>>cluster node
>>>-         * or an external cluster node.
>>>-         * @return  {@code true} iff the changes originate from a
>>>remote
>>>cluster node.
>>>-         */
>>>-        public abstract boolean isExternal();
>>>-
>>>-        /**
>>>-         * Determine whether these changes where caused by the passed
>>>content
>>>-         * session.
>>>-         * @param contentSession  content session to test for
>>>-         * @return  {@code true} iff these changes where cause by the
>>>passed content session.
>>>-         *          Always {@code false} if {@link #isExternal()} is
>>>{@code true}.
>>>-         */
>>>-        public abstract boolean isLocal(ContentSession contentSession);
>>>+        @CheckForNull
>>>+        public String getSessionId() {
>>>+            return getStringOrNull(getCommitInfo(after),
>>>CommitInfoEditorProvider.SESSION_ID);
>>>+        }
>>>
>>>-        /**
>>>-         * Determine the user associated with these changes.
>>>-         * @return  user id or {@link ObservationConstants#OAK_UNKNOWN}
>>>if {@link #isExternal()} is {@code true}.
>>>-         */
>>>-        public abstract String getUserId();
>>>+        @CheckForNull
>>>+        public String getUserId() {
>>>+            return getStringOrNull(getCommitInfo(after),
>>>CommitInfoEditorProvider.USER_ID);
>>>+        }
>>>
>>>-        /**
>>>-         * Determine the date when these changes where persisted.
>>>-         * @return  date or {@code 0} if {@link #isExternal()} is
>>>{@code
>>>true}.
>>>-         */
>>>-        public abstract long getDate();
>>>+        public long getDate() {
>>>+            PropertyState property =
>>>getCommitInfo(after).getProperty(CommitInfoEditorProvider.TIME_STAMP);
>>>+            return property == null ? 0 : property.getValue(LONG);
>>>+        }
>>>
>>>         /**
>>>          * State before the change
>>>          * @return  before state
>>>          */
>>>+        @Nonnull
>>>         public NodeState getBeforeState() {
>>>             return before;
>>>         }
>>>@@ -250,6 +281,7 @@ public class ChangeDispatcher {
>>>          * State after the change
>>>          * @return  after state
>>>          */
>>>+        @Nonnull
>>>         public NodeState getAfterState() {
>>>             return after;
>>>         }
>>>@@ -259,8 +291,10 @@ public class ChangeDispatcher {
>>>             return toStringHelper(this)
>>>                 .add("base", before)
>>>                 .add("head", after)
>>>-                .add("userId", getUserId())
>>>-                .add("date", getDate())
>>>+                .add(CommitInfoEditorProvider.USER_ID, getUserId())
>>>+                .add(CommitInfoEditorProvider.TIME_STAMP, getDate())
>>>+                .add(CommitInfoEditorProvider.SESSION_ID,
>>>getSessionId())
>>>+                .add("external", isExternal)
>>>                 .toString();
>>>         }
>>>
>>>@@ -274,7 +308,8 @@ public class ChangeDispatcher {
>>>             }
>>>
>>>             ChangeSet that = (ChangeSet) other;
>>>-            return before.equals(that.before) &&
>>>after.equals(that.after);
>>>+            return before.equals(that.before) &&
>>>after.equals(that.after) &&
>>>+                    isExternal == that.isExternal;
>>>         }
>>>
>>>         @Override
>>>@@ -282,73 +317,13 @@ public class ChangeDispatcher {
>>>             return 31 * before.hashCode() + after.hashCode();
>>>         }
>>>
>>>-        private static class InternalChangeSet extends ChangeSet {
>>>-            private final ContentSession contentSession;
>>>-            private final String userId;
>>>-            private final long date;
>>>-
>>>-            InternalChangeSet(NodeState base, NodeState head,
>>>ContentSession contentSession, long date) {
>>>-                super(base, head);
>>>-                this.contentSession = contentSession;
>>>-                this.userId = contentSession.getAuthInfo().getUserID();
>>>-                this.date = date;
>>>-            }
>>>-
>>>-            @Override
>>>-            public boolean isExternal() {
>>>-                return false;
>>>-            }
>>>-
>>>-            @Override
>>>-            public boolean isLocal(ContentSession contentSession) {
>>>-                return this.contentSession == contentSession;
>>>-            }
>>>-
>>>-            @Override
>>>-            public String getUserId() {
>>>-                return userId;
>>>-            }
>>>-
>>>-            @Override
>>>-            public long getDate() {
>>>-                return date;
>>>-            }
>>>-
>>>-            @Override
>>>-            public boolean equals(Object other) {
>>>-                if (!super.equals(other)) {
>>>-                    return false;
>>>-                }
>>>-
>>>-                InternalChangeSet that = (InternalChangeSet) other;
>>>-                return date == that.date && contentSession ==
>>>that.contentSession;
>>>-            }
>>>+        private static String getStringOrNull(NodeState commitInfo,
>>>String name) {
>>>+            PropertyState property = commitInfo.getProperty(name);
>>>+            return property == null ? null : property.getValue(STRING);
>>>         }
>>>
>>>-        private static class ExternalChangeSet extends ChangeSet {
>>>-            ExternalChangeSet(NodeState base, NodeState head) {
>>>-                super(base, head);
>>>-            }
>>>-
>>>-            @Override
>>>-            public boolean isExternal() {
>>>-                return true;
>>>-            }
>>>-
>>>-            @Override
>>>-            public boolean isLocal(ContentSession contentSession) {
>>>-                return false;
>>>-            }
>>>-
>>>-            @Override
>>>-            public String getUserId() {
>>>-                return OAK_UNKNOWN;
>>>-            }
>>>-
>>>-            @Override
>>>-            public long getDate() {
>>>-                return 0;
>>>-            }
>>>+        private static NodeState getCommitInfo(NodeState after) {
>>>+            return
>>>after.getChildNode(CommitInfoEditorProvider.COMMIT_INFO);
>>>         }
>>>
>>>     }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeProcessor.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java?rev=15
>>>3
>>>2
>>>782&r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeProcessor.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/ChangeProcessor.java Wed Oct 16 14:43:01 2013
>>>@@ -18,10 +18,22 @@
>>>  */
>>> package org.apache.jackrabbit.oak.plugins.observation;
>>>
>>>+import static com.google.common.base.Preconditions.checkArgument;
>>>+import static com.google.common.base.Preconditions.checkState;
>>>+import static com.google.common.collect.Iterators.emptyIterator;
>>>+import static com.google.common.collect.Iterators.singletonIterator;
>>>+import static com.google.common.collect.Iterators.transform;
>>>+import static javax.jcr.observation.Event.NODE_ADDED;
>>>+import static javax.jcr.observation.Event.NODE_REMOVED;
>>>+import static javax.jcr.observation.Event.PROPERTY_ADDED;
>>>+import static javax.jcr.observation.Event.PROPERTY_REMOVED;
>>>+import static
>>>org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager.getIdenti
>>>f
>>>i
>>>er;
>>>+
>>> import java.util.ArrayList;
>>> import java.util.Iterator;
>>> import java.util.List;
>>> import java.util.concurrent.atomic.AtomicReference;
>>>+
>>> import javax.annotation.Nonnull;
>>> import javax.jcr.observation.Event;
>>> import javax.jcr.observation.EventListener;
>>>@@ -50,17 +62,6 @@ import org.apache.jackrabbit.oak.spi.whi
>>> import org.slf4j.Logger;
>>> import org.slf4j.LoggerFactory;
>>>
>>>-import static com.google.common.base.Preconditions.checkArgument;
>>>-import static com.google.common.base.Preconditions.checkState;
>>>-import static com.google.common.collect.Iterators.emptyIterator;
>>>-import static com.google.common.collect.Iterators.singletonIterator;
>>>-import static com.google.common.collect.Iterators.transform;
>>>-import static javax.jcr.observation.Event.NODE_ADDED;
>>>-import static javax.jcr.observation.Event.NODE_REMOVED;
>>>-import static javax.jcr.observation.Event.PROPERTY_ADDED;
>>>-import static javax.jcr.observation.Event.PROPERTY_REMOVED;
>>>-import static
>>>org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager.getIdenti
>>>f
>>>i
>>>er;
>>>-
>>> /**
>>>  * A {@code ChangeProcessor} generates observation {@link
>>>javax.jcr.observation.Event}s
>>>  * based on a {@link EventFilter} and delivers them to an {@link
>>>javax.jcr.observation.EventListener}.
>>>@@ -189,7 +190,9 @@ public class ChangeProcessor implements
>>>             ChangeSet changes = changeListener.getChanges();
>>>             while (!stopping && changes != null) {
>>>                 EventFilter filter = filterRef.get();
>>>-                if (!(filter.excludeLocal() &&
>>>changes.isLocal(contentSession))) {
>>>+                // FIXME don't rely on toString for session id
>>>+                // FIXME make cluster node id part of session id
>>>+                if (!(filter.excludeLocal() &&
>>>changes.isLocal(contentSession.toString()))) {
>>>                     String path =
>>>namePathMapper.getOakPath(filter.getPath());
>>>                     ImmutableTree beforeTree =
>>>getTree(changes.getBeforeState(), path);
>>>                     ImmutableTree afterTree =
>>>getTree(changes.getAfterState(), path);
>>>
>>>Added:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/CommitInfoEditorProvider.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/observation/CommitInfoEditorProvider.ja
>>>v
>>>a
>>>?rev=1532782&view=auto
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/CommitInfoEditorProvider.java (added)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/CommitInfoEditorProvider.java Wed Oct 16 14:43:01 2013
>>>@@ -0,0 +1,69 @@
>>>+package org.apache.jackrabbit.oak.plugins.observation;
>>>+
>>>+import static com.google.common.base.Preconditions.checkNotNull;
>>>+
>>>+import javax.annotation.Nonnull;
>>>+
>>>+import org.apache.jackrabbit.oak.spi.commit.DefaultEditor;
>>>+import org.apache.jackrabbit.oak.spi.commit.Editor;
>>>+import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
>>>+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>>+import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>+
>>>+/**
>>>+ * Provider for a {@link Editor} that amends each commit with
>>>+ * a commit info record. That record is stored in a child node
>>>+ * named {@link #COMMIT_INFO} of the root node.
>>>+ */
>>>+public class CommitInfoEditorProvider implements EditorProvider {
>>>+
>>>+    /**
>>>+     * Node name for the commit info record
>>>+     */
>>>+    public static final String COMMIT_INFO = ":commit-info";
>>>+
>>>+    /**
>>>+     * Name of the property containing the id of the session that
>>>committed
>>>+     * this revision.
>>>+     * <p>
>>>+     * In a clustered environment this property might contain a
>>>synthesised
>>>+     * value if the respective revision is the result of a cluster
>>>sync.
>>>+     */
>>>+    public static final String SESSION_ID = "session-id";
>>>+
>>>+    /**
>>>+     * Name of the property containing the id of the user that
>>>committed
>>>+     * this revision.
>>>+     * <p>
>>>+     * In a clustered environment this property might contain a
>>>synthesised
>>>+     * value if the respective revision is the result of a cluster
>>>sync.
>>>+     */
>>>+    public static final String USER_ID = "user-id";
>>>+
>>>+    /**
>>>+     * Name of the property containing the time stamp when this
>>>revision
>>>was
>>>+     * committed.
>>>+     */
>>>+    public static final String TIME_STAMP = "time-stamp";
>>>+
>>>+    private final String sessionId;
>>>+    private final String userId;
>>>+
>>>+    public CommitInfoEditorProvider(@Nonnull String sessionId, String
>>>userID) {
>>>+        this.sessionId = checkNotNull(sessionId);
>>>+        this.userId = userID;
>>>+    }
>>>+
>>>+    @Override
>>>+    public Editor getRootEditor(NodeState before, NodeState after,
>>>final
>>>NodeBuilder builder) {
>>>+        return new DefaultEditor() {
>>>+            @Override
>>>+            public void enter(NodeState before, NodeState after) {
>>>+                NodeBuilder commitInfo =
>>>builder.setChildNode(COMMIT_INFO);
>>>+                commitInfo.setProperty(USER_ID,
>>>String.valueOf(userId));
>>>+                commitInfo.setProperty(SESSION_ID, sessionId);
>>>+                commitInfo.setProperty(TIME_STAMP,
>>>System.currentTimeMillis());
>>>+            }
>>>+        };
>>>+    }
>>>+}
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/Observable.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/observation/Observable.java?rev=1532782
>>>&
>>>r
>>>1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/Observable.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/observation/Observable.java Wed Oct 16 14:43:01 2013
>>>@@ -23,14 +23,15 @@ import org.apache.jackrabbit.oak.plugins
>>>
>>> /**
>>>  * An {@code Observable} supports attaching {@link Listener} instances
>>>for
>>>- * listening to changes in a {@code ContentSession}.
>>>+ * listening to content changes.
>>>+ *
>>>  * @see ChangeDispatcher
>>>  */
>>> public interface Observable {
>>>
>>>     /**
>>>      * Register a new {@code Listener}. Clients need to call
>>>-     * {@link ChangeDispatcher.Listener#dispose()} when to free
>>>+     * {@link ChangeDispatcher.Listener#dispose()} to free
>>>      * up any resources associated with the listener when done.
>>>      * @return a fresh {@code Listener} instance.
>>>      */
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStore.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java?rev=15327
>>>8
>>>2
>>>&r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStore.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStore.java Wed Oct 16 14:43:01 2013
>>>@@ -29,16 +29,18 @@ import javax.annotation.Nonnull;
>>>
>>> import org.apache.jackrabbit.oak.api.Blob;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>>+import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
>>>+import
>>>org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher.Listener;
>>>+import org.apache.jackrabbit.oak.plugins.observation.Observable;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyObserver;
>>> import org.apache.jackrabbit.oak.spi.commit.Observer;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import
>>>org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>
>>>-public class SegmentNodeStore implements NodeStore {
>>>+public class SegmentNodeStore implements NodeStore, Observable {
>>>
>>>     static final String ROOT = "root";
>>>
>>>@@ -48,6 +50,8 @@ public class SegmentNodeStore implements
>>>
>>>     private final Observer observer;
>>>
>>>+    private final ChangeDispatcher changeDispatcher;
>>>+
>>>     private SegmentNodeState head;
>>>
>>>     private long maximumBackoff = MILLISECONDS.convert(10, SECONDS);
>>>@@ -58,6 +62,7 @@ public class SegmentNodeStore implements
>>>         this.observer = EmptyObserver.INSTANCE;
>>>         this.head = new SegmentNodeState(
>>>                 store.getWriter().getDummySegment(),
>>>this.journal.getHead());
>>>+        this.changeDispatcher = new ChangeDispatcher(this);
>>>     }
>>>
>>>     public SegmentNodeStore(SegmentStore store) {
>>>@@ -78,7 +83,22 @@ public class SegmentNodeStore implements
>>>     }
>>>
>>>     boolean setHead(SegmentNodeState base, SegmentNodeState head) {
>>>-        return journal.setHead(base.getRecordId(), head.getRecordId());
>>>+        changeDispatcher.beforeCommit(base.getChildNode(ROOT));
>>>+        try {
>>>+            if (journal.setHead(base.getRecordId(),
>>>head.getRecordId()))
>>>{
>>>+                changeDispatcher.localCommit(head.getChildNode(ROOT));
>>>+                return true;
>>>+            } else {
>>>+                return false;
>>>+            }
>>>+        } finally {
>>>+            changeDispatcher.afterCommit(getRoot());
>>>+        }
>>>+    }
>>>+
>>>+    @Override
>>>+    public Listener newListener() {
>>>+        return changeDispatcher.newListener();
>>>     }
>>>
>>>     @Override @Nonnull
>>>@@ -89,7 +109,7 @@ public class SegmentNodeStore implements
>>>     @Override
>>>     public synchronized NodeState merge(
>>>             @Nonnull NodeBuilder builder,
>>>-            @Nonnull CommitHook commitHook, PostCommitHook committed)
>>>+            @Nonnull CommitHook commitHook)
>>>             throws CommitFailedException {
>>>         checkArgument(builder instanceof SegmentNodeBuilder);
>>>         checkNotNull(commitHook);
>>>@@ -98,7 +118,7 @@ public class SegmentNodeStore implements
>>>         SegmentNodeStoreBranch branch = new SegmentNodeStoreBranch(
>>>                 this, store.getWriter(), head, maximumBackoff);
>>>         branch.setRoot(builder.getNodeState());
>>>-        NodeState merged = branch.merge(commitHook, committed);
>>>+        NodeState merged = branch.merge(commitHook);
>>>         ((SegmentNodeBuilder) builder).reset(merged);
>>>         return merged;
>>>     }
>>>@@ -147,5 +167,4 @@ public class SegmentNodeStore implements
>>>                 new
>>>SegmentNodeState(store.getWriter().getDummySegment(), id);
>>>         return root.getChildNode(ROOT);
>>>     }
>>>-
>>> }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreBranch.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java?rev
>>>=
>>>1
>>>532782&r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreBranch.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreBranch.java Wed Oct 16 14:43:01 2013
>>>@@ -28,7 +28,6 @@ import javax.annotation.Nonnull;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.commons.PathUtils;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import
>>>org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -88,7 +87,7 @@ class SegmentNodeStoreBranch implements
>>>         }
>>>     }
>>>
>>>-    private synchronized long optimisticMerge(CommitHook hook,
>>>PostCommitHook committed)
>>>+    private synchronized long optimisticMerge(CommitHook hook)
>>>             throws CommitFailedException, InterruptedException {
>>>         long timeout = 1;
>>>
>>>@@ -111,10 +110,8 @@ class SegmentNodeStoreBranch implements
>>>                 // someone else has a pessimistic lock on the journal,
>>>                 // so we should not try to commit anything
>>>             } else if (store.setHead(base, newHead)) {
>>>-                NodeState previousBase = base;
>>>                 base = newHead;
>>>                 head = newHead;
>>>-
>>>committed.contentChanged(previousBase.getChildNode(ROOT),
>>>newHead.getChildNode(ROOT));
>>>                 return -1;
>>>             }
>>>
>>>@@ -136,7 +133,7 @@ class SegmentNodeStoreBranch implements
>>>         return MILLISECONDS.convert(timeout, NANOSECONDS);
>>>     }
>>>
>>>-    private synchronized void pessimisticMerge(CommitHook hook,
>>>PostCommitHook committed, long timeout)
>>>+    private synchronized void pessimisticMerge(CommitHook hook, long
>>>timeout)
>>>             throws CommitFailedException {
>>>         while (true) {
>>>             SegmentNodeState before = store.getHead();
>>>@@ -168,10 +165,8 @@ class SegmentNodeStoreBranch implements
>>>                     SegmentNodeState newHead =
>>>                             writer.writeNode(builder.getNodeState());
>>>                     if (store.setHead(after, newHead)) {
>>>-                        NodeState previousBase = base;
>>>                         base = newHead;
>>>                         head = newHead;
>>>-
>>>committed.contentChanged(previousBase.getChildNode(ROOT),
>>>newHead.getChildNode(ROOT));
>>>                         return;
>>>                     } else {
>>>                         // something else happened, perhaps a timeout,
>>>so
>>>@@ -185,13 +180,13 @@ class SegmentNodeStoreBranch implements
>>>     }
>>>
>>>     @Override @Nonnull
>>>-    public synchronized NodeState merge(CommitHook hook, PostCommitHook
>>>committed)
>>>+    public synchronized NodeState merge(CommitHook hook)
>>>             throws CommitFailedException {
>>>         if (base != head) {
>>>             try {
>>>-                long timeout = optimisticMerge(hook, committed);
>>>+                long timeout = optimisticMerge(hook);
>>>                 if (timeout >= 0) {
>>>-                    pessimisticMerge(hook, committed, timeout);
>>>+                    pessimisticMerge(hook, timeout);
>>>                 }
>>>             } catch (InterruptedException e) {
>>>                 throw new CommitFailedException(
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreService.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java?re
>>>v
>>>=
>>>1532782&r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreService.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/pl
>>>u
>>>g
>>>ins/segment/SegmentNodeStoreService.java Wed Oct 16 14:43:01 2013
>>>@@ -24,6 +24,7 @@ import java.util.Dictionary;
>>> import javax.annotation.CheckForNull;
>>> import javax.annotation.Nonnull;
>>>
>>>+import com.google.common.base.Preconditions;
>>> import com.mongodb.Mongo;
>>> import org.apache.felix.scr.annotations.Activate;
>>> import org.apache.felix.scr.annotations.Component;
>>>@@ -33,10 +34,11 @@ import org.apache.felix.scr.annotations.
>>> import org.apache.felix.scr.annotations.Service;
>>> import org.apache.jackrabbit.oak.api.Blob;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>>+import
>>>org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher.Listener;
>>>+import org.apache.jackrabbit.oak.plugins.observation.Observable;
>>> import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
>>> import org.apache.jackrabbit.oak.plugins.segment.mongo.MongoStore;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>@@ -44,7 +46,7 @@ import org.osgi.service.component.Compon
>>>
>>> @Component(policy = ConfigurationPolicy.REQUIRE)
>>> @Service(NodeStore.class)
>>>-public class SegmentNodeStoreService implements NodeStore {
>>>+public class SegmentNodeStoreService implements NodeStore, Observable {
>>>
>>>     @Property(description="The unique name of this instance")
>>>     public static final String NAME = "name";
>>>@@ -145,6 +147,15 @@ public class SegmentNodeStoreService imp
>>>         }
>>>     }
>>>
>>>+    //------------------------------------------------------------<
>>>Observable >---
>>>+
>>>+    @Override
>>>+    public Listener newListener() {
>>>+        Preconditions.checkState(delegate instanceof Observable);
>>>+        return ((Observable) getDelegate()).newListener();
>>>+    }
>>>+
>>>+
>>>     //---------------------------------------------------------<
>>>NodeStore >--
>>>
>>>     @Override @Nonnull
>>>@@ -154,9 +165,9 @@ public class SegmentNodeStoreService imp
>>>
>>>     @Nonnull
>>>     @Override
>>>-    public NodeState merge(@Nonnull NodeBuilder builder, @Nonnull
>>>CommitHook commitHook,
>>>-            PostCommitHook committed) throws CommitFailedException {
>>>-        return getDelegate().merge(builder, commitHook, committed);
>>>+    public NodeState merge(@Nonnull NodeBuilder builder, @Nonnull
>>>CommitHook commitHook)
>>>+            throws CommitFailedException {
>>>+        return getDelegate().merge(builder, commitHook);
>>>     }
>>>
>>>     @Override
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>lifecycle/OakInitializer.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/spi/lifecycle/OakInitializer.java?rev=1532782&r
>>>1
>>>=
>>>1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>lifecycle/OakInitializer.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>lifecycle/OakInitializer.java Wed Oct 16 14:43:01 2013
>>>@@ -21,11 +21,10 @@ package org.apache.jackrabbit.oak.spi.li
>>> import javax.annotation.Nonnull;
>>>
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>>-import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
>>> import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
>>>+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>> import org.apache.jackrabbit.oak.spi.commit.EditorHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>@@ -43,8 +42,7 @@ public final class OakInitializer {
>>>             initializer.initialize(builder);
>>>             store.merge(
>>>                     builder,
>>>-                    new EditorHook(new
>>>IndexUpdateProvider(indexEditor)),
>>>-                    PostCommitHook.EMPTY);
>>>+                    new EditorHook(new
>>>IndexUpdateProvider(indexEditor)));
>>>         } catch (CommitFailedException e) {
>>>             throw new RuntimeException(e);
>>>         }
>>>@@ -63,8 +61,7 @@ public final class OakInitializer {
>>>         try {
>>>             store.merge(
>>>                     builder,
>>>-                    new EditorHook(new
>>>IndexUpdateProvider(indexEditor)),
>>>-                    PostCommitHook.EMPTY);
>>>+                    new EditorHook(new
>>>IndexUpdateProvider(indexEditor)));
>>>         } catch (CommitFailedException e) {
>>>             throw new RuntimeException(e);
>>>         }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStore.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/spi/state/NodeStore.java?rev=1532782&r1=1532781
>>>&
>>>r
>>>2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStore.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStore.java Wed Oct 16 14:43:01 2013
>>>@@ -25,7 +25,6 @@ import javax.annotation.Nonnull;
>>> import org.apache.jackrabbit.oak.api.Blob;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>>
>>> /**
>>>  * Storage abstraction for trees. At any given point in time the stored
>>>@@ -51,15 +50,14 @@ public interface NodeStore {
>>>      *
>>>      * @param builder  the builder whose changes to apply
>>>      * @param commitHook the commit hook to apply while merging changes
>>>-     * @param committed  the post commit hook
>>>      * @return the node state resulting from the merge.
>>>      * @throws CommitFailedException if the merge failed
>>>      * @throws IllegalArgumentException if the builder is not acquired
>>>      *                                  from a root state of this store
>>>      */
>>>     @Nonnull
>>>-    NodeState merge(@Nonnull NodeBuilder builder, @Nonnull CommitHook
>>>commitHook,
>>>-            PostCommitHook committed) throws CommitFailedException;
>>>+    NodeState merge(@Nonnull NodeBuilder builder, @Nonnull CommitHook
>>>commitHook)
>>>+            throws CommitFailedException;
>>>
>>>     /**
>>>      * Rebase the changes in the passed {@code builder} on top of the
>>>current root state.
>>>@@ -114,5 +112,4 @@ public interface NodeStore {
>>>      */
>>>     @CheckForNull
>>>     NodeState retrieve(@Nonnull String checkpoint);
>>>-
>>> }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStoreBranch.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/spi/state/NodeStoreBranch.java?rev=1532782&r1=1
>>>5
>>>3
>>>2781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStoreBranch.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/sp
>>>i
>>>/
>>>state/NodeStoreBranch.java Wed Oct 16 14:43:01 2013
>>>@@ -20,7 +20,6 @@ import javax.annotation.Nonnull;
>>>
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.spi.commit.CommitHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>>
>>> /**
>>>  * An instance of this class represents a private branch of the tree
>>>in
>>>a
>>>@@ -86,13 +85,12 @@ public interface NodeStoreBranch {
>>>      * the current head revision followed by a fast forward merge.
>>>      *
>>>      * @param hook the commit hook to apply while merging changes
>>>-     * @param committed the post commit hook to call after a successful
>>>merge
>>>      * @return the node state resulting from the merge.
>>>      * @throws CommitFailedException if the merge failed
>>>      * @throws IllegalStateException if the branch is already merged
>>>      */
>>>     @Nonnull
>>>-    NodeState merge(@Nonnull CommitHook hook, PostCommitHook committed)
>>>throws CommitFailedException;
>>>+    NodeState merge(@Nonnull CommitHook hook) throws
>>>CommitFailedException;
>>>
>>>     /**
>>>      * Rebase the changes from this branch on top of the current
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeBuilderTest.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/KernelNodeBuilderTest.java?rev=1532782&r
>>>1
>>>=
>>>1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeBuilderTest.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeBuilderTest.java Wed Oct 16 14:43:01 2013
>>>@@ -26,10 +26,8 @@ import org.apache.jackrabbit.mk.core.Mic
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeStore;
>>>-import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
>>> import org.junit.Test;
>>>
>>> public class KernelNodeBuilderTest {
>>>@@ -51,7 +49,7 @@ public class KernelNodeBuilderTest {
>>>     private static void init(NodeStore store) throws
>>>CommitFailedException {
>>>         NodeBuilder builder = store.getRoot().builder();
>>>         builder.child("x").child("y").child("z");
>>>-        store.merge(builder, EmptyHook.INSTANCE, PostCommitHook.EMPTY);
>>>+        store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>>     private static void run(NodeStore store) throws
>>>CommitFailedException {
>>>@@ -73,7 +71,7 @@ public class KernelNodeBuilderTest {
>>>         assertFalse("child node x/y/z not should not be present",
>>>builder
>>>                 .child("x").child("y").hasChildNode("z"));
>>>
>>>-        store.merge(builder, EmptyHook.INSTANCE, PostCommitHook.EMPTY);
>>>+        store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>> }
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStateTest.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/KernelNodeStateTest.java?rev=1532782&r1=
>>>1
>>>5
>>>32781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStateTest.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStateTest.java Wed Oct 16 14:43:01 2013
>>>@@ -33,7 +33,6 @@ import org.apache.jackrabbit.mk.core.Mic
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.api.PropertyState;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -58,7 +57,8 @@ public class KernelNodeStateTest {
>>>         builder.child("y");
>>>         builder.child("z");
>>>
>>>-        state = store.merge(builder, EmptyHook.INSTANCE,
>>>PostCommitHook.EMPTY);
>>>+        state = store.merge(builder, EmptyHook.INSTANCE);
>>>+        state = store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>>     @After
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreCacheTest.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/KernelNodeStoreCacheTest.java?rev=153278
>>>2
>>>&
>>>r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreCacheTest.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/KernelNodeStoreCacheTest.java Wed Oct 16 14:43:01 2013
>>>@@ -29,7 +29,6 @@ import org.apache.jackrabbit.mk.api.Micr
>>> import org.apache.jackrabbit.mk.api.MicroKernelException;
>>> import org.apache.jackrabbit.mk.core.MicroKernelImpl;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -61,7 +60,7 @@ public class KernelNodeStoreCacheTest {
>>>         b.child("c");
>>>         b.child("d");
>>>         b.child("e");
>>>-        store.merge(builder, EmptyHook.INSTANCE, PostCommitHook.EMPTY);
>>>+        store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>>     /**
>>>@@ -138,7 +137,7 @@ public class KernelNodeStoreCacheTest {
>>>     private void modifyContent() throws Exception {
>>>         NodeBuilder builder = store.getRoot().builder();
>>>         builder.child("a").setProperty("foo", "bar");
>>>-        store.merge(builder, EmptyHook.INSTANCE, PostCommitHook.EMPTY);
>>>+        store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>>     private void readTree(NodeState root) {
>>>
>>>Modified:
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/LargeKernelNodeStateTest.java
>>>URL:
>>>http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java
>>>/
>>>o
>>>rg/apache/jackrabbit/oak/kernel/LargeKernelNodeStateTest.java?rev=153278
>>>2
>>>&
>>>r1=1532781&r2=1532782&view=diff
>>>========================================================================
>>>=
>>>=
>>>====
>>>---
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/LargeKernelNodeStateTest.java (original)
>>>+++
>>>jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/ke
>>>r
>>>n
>>>el/LargeKernelNodeStateTest.java Wed Oct 16 14:43:01 2013
>>>@@ -25,7 +25,6 @@ import static junit.framework.Assert.ass
>>> import org.apache.jackrabbit.mk.core.MicroKernelImpl;
>>> import org.apache.jackrabbit.oak.api.CommitFailedException;
>>> import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
>>>-import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
>>> import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
>>> import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
>>> import org.apache.jackrabbit.oak.spi.state.NodeState;
>>>@@ -50,7 +49,7 @@ public class LargeKernelNodeStateTest {
>>>             builder.child("x" + i);
>>>         }
>>>
>>>-        state = store.merge(builder, EmptyHook.INSTANCE,
>>>PostCommitHook.EMPTY);
>>>+        state = store.merge(builder, EmptyHook.INSTANCE);
>>>     }
>>>
>>>     @After
>>>
>>>
>>
>


Mime
View raw message