jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1574896 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/main/java/org/apac...
Date Thu, 06 Mar 2014 14:32:34 GMT
Author: mduerig
Date: Thu Mar  6 14:32:33 2014
New Revision: 1574896

URL: http://svn.apache.org/r1574896
Log:
OAK-1514: Support for Sling JcrResourceListener
- Add EventHandler.enter and EventHandler.leave
- Slight tighten the EventHandler contract
- Add injectors for Observers to Oak and Jcr

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/DefaultEventHandler.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/NodeObserver.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventHandler.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteredHandler.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java Thu Mar
 6 14:32:33 2014
@@ -43,8 +43,8 @@ import javax.security.auth.login.LoginEx
 
 import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 import com.google.common.io.Closer;
-
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.Root;
@@ -112,6 +112,8 @@ public class Oak {
 
     private final List<CommitHook> commitHooks = newArrayList();
 
+    private final List<Observer> observers = Lists.newArrayList();
+
     private List<EditorProvider> editorProviders = newArrayList();
 
     private SecurityProvider securityProvider;
@@ -448,6 +450,12 @@ public class Oak {
         return this;
     }
 
+    @Nonnull
+    public Oak with(@Nonnull Observer observer) {
+        observers.add(checkNotNull(observer));
+        return this;
+    }
+
     /**
      * Enable the asynchronous (background) indexing behavior.
      * 
@@ -502,6 +510,12 @@ public class Oak {
         // add index hooks later to prevent the OakInitializer to do excessive indexing
         with(new IndexUpdateProvider(indexEditors));
         withEditorHook();
+
+        // Register observer last to prevent sending events while initialising
+        for (Observer observer : observers) {
+            WhiteboardUtils.registerObserver(whiteboard, observer);
+        }
+
         CommitHook commitHook = CompositeHook.compose(commitHooks);
         return new ContentRepositoryImpl(
                 store,

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/DefaultEventHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/DefaultEventHandler.java?rev=1574896&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/DefaultEventHandler.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/DefaultEventHandler.java
Thu Mar  6 14:32:33 2014
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.observation;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Default implementation of {@code EventHandler} that
+ * does nothing.
+ */
+public class DefaultEventHandler implements EventHandler {
+    public static EventHandler INSTANCE = new DefaultEventHandler();
+
+    @Override
+    public void enter(NodeState before, NodeState after) {
+        // do nothing
+    }
+
+    @Override
+    public void leave(NodeState before, NodeState after) {
+        // do nothing
+    }
+
+    /**
+     * @return  {@code this}
+     */
+    @Override
+    public EventHandler getChildHandler(String name, NodeState before, NodeState after) {
+        return this;
+    }
+
+    @Override
+    public void propertyAdded(PropertyState after) {
+        // do nothing
+    }
+
+    @Override
+    public void propertyChanged(PropertyState before, PropertyState after) {
+        // do nothing
+    }
+
+    @Override
+    public void propertyDeleted(PropertyState before) {
+        // do nothing
+    }
+
+    @Override
+    public void nodeAdded(String name, NodeState after) {
+        // do nothing
+    }
+
+    @Override
+    public void nodeDeleted(String name, NodeState before) {
+        // do nothing
+    }
+
+    @Override
+    public void nodeMoved(String sourcePath, String name, NodeState moved) {
+        // do nothing
+    }
+
+    @Override
+    public void nodeReordered(String destName, String name, NodeState reordered) {
+        // do nothing
+    }
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
Thu Mar  6 14:32:33 2014
@@ -143,7 +143,16 @@ public class EventGenerator {
          */
         @Override
         public void run() {
-            after.compareAgainstBaseState(before, this);
+            if (skip == 0) {
+                // Only call enter if this is not a continuation that hit
+                // the MAX_CHANGES_PER_CONTINUATION limit before
+                handler.enter(before, after);
+            }
+            if (after.compareAgainstBaseState(before, this)) {
+                // Only call leave if this continuation exists normally and not
+                // as a result of hitting the MAX_CHANGES_PER_CONTINUATION limit
+                handler.leave(before, after);
+            }
         }
 
         //-------------------------------------------------< NodeStateDiff >--

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventHandler.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventHandler.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventHandler.java
Thu Mar  6 14:32:33 2014
@@ -36,11 +36,34 @@ import org.apache.jackrabbit.oak.spi.sta
  * information like the path or identifier of the current node based on
  * the sequence of those specialization calls.
  * <p>
+ * The events belonging to this instance <em>should</em> be delivered
+ * before events to other instance deeper down the tree are delivered.
+ * <p>
  * All names and paths passed to handler methods use unmapped Oak names.
  */
 public interface EventHandler {
 
     /**
+     * Called before the given before and after states are compared.
+     * The implementation can use this method to initialize any internal
+     * state needed for processing the results of the comparison.
+     *
+     * @param before before state, non-existent if this node was added
+     * @param after after state, non-existent if this node was removed
+     */
+    void enter(NodeState before, NodeState after);
+
+    /**
+     * Called after the given before and after states are compared.
+     * The implementation can use this method to post-process information
+     * collected during the content diff.
+     *
+     * @param before before state, non-existent if this node was added
+     * @param after after state, non-existent if this node was removed
+     */
+    void leave(NodeState before, NodeState after);
+
+    /**
      * Returns a handler of events within the given child node, or
      * {@code null} if changes within that child are not to be processed.
      *

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteredHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteredHandler.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteredHandler.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteredHandler.java
Thu Mar  6 14:32:33 2014
@@ -29,7 +29,7 @@ import org.apache.jackrabbit.oak.spi.sta
  * on all detected changes, and forwards the filtered change events to a given
  * delegate handler.
  */
-public class FilteredHandler implements EventHandler {
+public class FilteredHandler extends DefaultEventHandler {
 
     private final EventFilter filter;
 
@@ -40,6 +40,17 @@ public class FilteredHandler implements 
         this.handler = handler;
     }
 
+
+    @Override
+    public void enter(NodeState before, NodeState after) {
+        handler.enter(before, after);
+    }
+
+    @Override
+    public void leave(NodeState before, NodeState after) {
+        handler.leave(before, after);
+    }
+
     @Override @CheckForNull
     public EventHandler getChildHandler(
             String name, NodeState before, NodeState after) {

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/NodeObserver.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/NodeObserver.java?rev=1574896&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/NodeObserver.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/NodeObserver.java
Thu Mar  6 14:32:33 2014
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.observation;
+
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.ImmutableRoot;
+import org.apache.jackrabbit.oak.namepath.GlobalNameMapper;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
+import org.apache.jackrabbit.oak.plugins.observation.filter.VisibleFilter;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Base class for {@code Observer} instances that group changes
+ * by node instead of tracking them down to individual properties.
+ */
+public abstract class NodeObserver implements Observer {
+    private final String path;
+
+    private NodeState previousRoot;
+
+    /**
+     * Create a new instance for observing the given path.
+     * @param path
+     */
+    protected NodeObserver(String path) {
+        this.path = path;
+    }
+
+    /**
+     * A node at {@code path} has been added.
+     * @param path       Path of the added node.
+     * @param added      Names of the added properties.
+     * @param deleted    Names of the deleted properties.
+     * @param changed    Names of the changed properties.
+     * @param commitInfo commit info associated with this change.
+     */
+    protected abstract void added(
+            @Nonnull String path,
+            @Nonnull Set<String> added,
+            @Nonnull Set<String> deleted,
+            @Nonnull Set<String> changed,
+            @Nonnull CommitInfo commitInfo);
+
+    /**
+     * A node at {@code path} has been deleted.
+     * @param path       Path of the deleted node.
+     * @param added      Names of the added properties.
+     * @param deleted    Names of the deleted properties.
+     * @param changed    Names of the changed properties.
+     * @param commitInfo commit info associated with this change.
+     */
+    protected abstract void deleted(
+            @Nonnull String path,
+            @Nonnull Set<String> added,
+            @Nonnull Set<String> deleted,
+            @Nonnull Set<String> changed,
+            @Nonnull CommitInfo commitInfo);
+
+    /**
+     * A node at {@code path} has been changed.
+     * @param path       Path of the changed node.
+     * @param added      Names of the added properties.
+     * @param deleted    Names of the deleted properties.
+     * @param changed    Names of the changed properties.
+     * @param commitInfo commit info associated with this change.
+     */
+    protected abstract void changed(
+            @Nonnull String path,
+            @Nonnull Set<String> added,
+            @Nonnull Set<String> deleted,
+            @Nonnull Set<String> changed,
+            @Nonnull CommitInfo commitInfo);
+
+    @Override
+    public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
+        if (previousRoot != null) {
+            NamePathMapper namePathMapper = new NamePathMapperImpl(
+                    new GlobalNameMapper(new ImmutableRoot(root)));
+
+            NodeState before = previousRoot;
+            NodeState after = root;
+            EventHandler handler = new FilteredHandler(
+                    new VisibleFilter(),
+                    new NodeEventHandler("/", info, namePathMapper));
+            for (String name : PathUtils.elements(path)) {
+                before = before.getChildNode(name);
+                after = after.getChildNode(name);
+                handler = handler.getChildHandler(name, before, after);
+            }
+
+            EventGenerator generator = new EventGenerator(previousRoot, root, handler);
+            while (!generator.isDone()) {
+                generator.generate();
+            }
+        }
+
+        previousRoot = root;
+    }
+
+    private enum EventType {ADDED, DELETED, CHANGED}
+
+    private class NodeEventHandler extends DefaultEventHandler {
+        private final String path;
+        private final CommitInfo commitInfo;
+        private final NamePathMapper namePathMapper;
+        private final EventType eventType;
+        private final Set<String> added = Sets.newHashSet();
+        private final Set<String> deleted = Sets.newHashSet();
+        private final Set<String> changed = Sets.newHashSet();
+
+        public NodeEventHandler(String path, CommitInfo commitInfo, NamePathMapper namePathMapper)
{
+            this.path = path;
+            this.commitInfo = commitInfo == null ? CommitInfo.EMPTY : commitInfo;
+            this.namePathMapper = namePathMapper;
+            this.eventType = EventType.CHANGED;
+        }
+
+        private NodeEventHandler(NodeEventHandler parent, String name, EventType eventType)
{
+            this.path = "/".equals(parent.path) ? '/' + name : parent.path + '/' + name;
+            this.commitInfo = parent.commitInfo;
+            this.namePathMapper = parent.namePathMapper;
+            this.eventType = eventType;
+        }
+
+        @Override
+        public void leave(NodeState before, NodeState after) {
+            switch (eventType) {
+                case ADDED:
+                    added(namePathMapper.getJcrPath(path), added, deleted, changed, commitInfo);
+                    break;
+                case DELETED:
+                    deleted(namePathMapper.getJcrPath(path), added, deleted, changed, commitInfo);
+                    break;
+                case CHANGED:
+                    if (!added.isEmpty() || ! deleted.isEmpty() || !changed.isEmpty()) {
+                        changed(namePathMapper.getJcrPath(path), added, deleted, changed,
commitInfo);
+                    }
+                    break;
+            }
+        }
+
+        @Override
+        public EventHandler getChildHandler(String name, NodeState before, NodeState after)
{
+            if (!before.exists()) {
+                return new NodeEventHandler(this, name, EventType.ADDED);
+            } else if (!after.exists()) {
+                return new NodeEventHandler(this, name, EventType.DELETED);
+            } else {
+                return new NodeEventHandler(this, name, EventType.CHANGED);
+            }
+        }
+
+        @Override
+        public void propertyAdded(PropertyState after) {
+            added.add(namePathMapper.getJcrName(after.getName()));
+        }
+
+        @Override
+        public void propertyChanged(PropertyState before, PropertyState after) {
+            changed.add(namePathMapper.getJcrName(after.getName()));
+        }
+
+        @Override
+        public void propertyDeleted(PropertyState before) {
+            deleted.add(namePathMapper.getJcrName(before.getName()));
+        }
+
+    }
+}

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java Thu
Mar  6 14:32:33 2014
@@ -47,6 +47,7 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.commit.Editor;
 import org.apache.jackrabbit.oak.spi.commit.EditorHook;
 import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
 import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
@@ -153,6 +154,12 @@ public class Jcr {
         return this;
     }
 
+    @Nonnull
+    public final Jcr with(@Nonnull Observer observer) {
+        oak.with(checkNotNull(observer));
+        return this;
+    }
+
     public Jcr withAsyncIndexing() {
         oak.withAsyncIndexing();
         return this;

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java?rev=1574896&r1=1574895&r2=1574896&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java
Thu Mar  6 14:32:33 2014
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.jcr.ob
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.namepath.PathTracker;
 import org.apache.jackrabbit.oak.plugins.identifier.IdentifierTracker;
+import org.apache.jackrabbit.oak.plugins.observation.DefaultEventHandler;
 import org.apache.jackrabbit.oak.plugins.observation.EventHandler;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
@@ -29,7 +30,7 @@ import org.apache.jackrabbit.oak.spi.sta
  * and identifier information to translate change callbacks to corresponding
  * JCR events that are then placed in the given {@link EventQueue}.
  */
-class QueueingHandler implements EventHandler {
+class QueueingHandler extends DefaultEventHandler {
 
     private final EventQueue queue;
 



Mime
View raw message