Author: jukka
Date: Mon Feb 10 22:30:39 2014
New Revision: 1566769

URL: http://svn.apache.org/r1566769
Log:
OAK-1387: Pass CommitInfo to commit hooks, editors and validators

Extract ItemSaveValidator away from AbstractRoot by adding CommitInfo.path

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java
   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.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/delegate/SessionDelegate.java

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1566769&r1=1566768&r2=1566769&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Mon Feb 10 22:30:39 2014
@@ -58,6 +58,7 @@
               org.apache.jackrabbit.oak.plugins.index.nodetype,
               org.apache.jackrabbit.oak.plugins.index.property,
               org.apache.jackrabbit.oak.plugins.index.reference,
+              org.apache.jackrabbit.oak.plugins.itemsave,
               org.apache.jackrabbit.oak.plugins.memory,
               org.apache.jackrabbit.oak.plugins.name,
               org.apache.jackrabbit.oak.plugins.nodetype,

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java?rev=1566769&r1=1566768&r2=1566769&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/AbstractRoot.java
 Mon Feb 10 22:30:39 2014
@@ -29,7 +29,6 @@ import javax.security.auth.Subject;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.ContentSession;
-import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.QueryEngine;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -40,15 +39,10 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
 import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
-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.EmptyHook;
-import org.apache.jackrabbit.oak.spi.commit.FailingValidator;
 import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
 import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
-import org.apache.jackrabbit.oak.spi.commit.SubtreeExcludingValidator;
-import org.apache.jackrabbit.oak.spi.commit.Validator;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.Context;
@@ -63,7 +57,6 @@ import org.apache.jackrabbit.oak.util.La
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Lists.newArrayList;
-import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
 import static org.apache.jackrabbit.oak.commons.PathUtils.isAncestor;
@@ -232,17 +225,18 @@ abstract class AbstractRoot implements R
 
     @Override
     public void commit() throws CommitFailedException {
-        commit(null, null);
+        commit(null, "/");
     }
 
     @Override
-    public void commit(@Nullable String message, @Nullable String path)
+    public void commit(@Nullable String message, @Nonnull String path)
             throws CommitFailedException {
         checkLive();
         ContentSession session = getContentSession();
         CommitInfo info = new CommitInfo(
-                session.toString(), session.getAuthInfo().getUserID(), 
message);
-        store.merge(builder, getCommitHook(path), info);
+                session.toString(), session.getAuthInfo().getUserID(),
+                message, path);
+        store.merge(builder, getCommitHook(), info);
         secureBuilder.baseChanged();
         modCount = 0;
         if (permissionProvider.hasValue()) {
@@ -253,28 +247,14 @@ abstract class AbstractRoot implements R
 
     /**
      * Combine the globally defined commit hook(s) and the hooks and 
validators defined by the
-     * various security related configurations. In addition a commit hook is 
added to check
-     * that the {@code path} to commit contains all unpersisted changes and to 
fail the
-     * commit otherwise.
+     * various security related configurations.
      *
-     * @param path path to commit
      * @return A commit hook combining repository global commit hook(s) with 
the pluggable hooks
      *         defined with the security modules and the padded {@code hooks}.
      */
-    private CommitHook getCommitHook(@Nullable final String path) {
+    private CommitHook getCommitHook() {
         List<CommitHook> hooks = newArrayList();
 
-        if (path != null) {
-            hooks.add(new EditorHook(new EditorProvider() {
-                @Override
-                public Editor getRootEditor(
-                        NodeState before, NodeState after,
-                        NodeBuilder builder, CommitInfo info) {
-                    return new ItemSaveValidator(path);
-                }
-            }));
-        }
-
         hooks.add(hook);
 
         List<CommitHook> postValidationHooks = new ArrayList<CommitHook>();
@@ -438,52 +418,4 @@ abstract class AbstractRoot implements R
         }
     }
 
-    //------------------------------------------------------------< 
ItemSaveValidator >---
-
-    /**
-     * This validator checks that all changes are contained within the subtree
-     * rooted at a given path.
-     */
-    private static class ItemSaveValidator extends SubtreeExcludingValidator {
-
-        /**
-         * Name of the property whose {@link 
#propertyChanged(org.apache.jackrabbit.oak.api.PropertyState, 
org.apache.jackrabbit.oak.api.PropertyState)} to
-         * ignore or {@code null} if no property should be ignored.
-         */
-        private final String ignorePropertyChange;
-
-        /**
-         * Create a new validator that only throws a {@link 
CommitFailedException} whenever
-         * there are changes not contained in the subtree rooted at {@code 
path}.
-         * @param path
-         */
-        public ItemSaveValidator(String path) {
-            this(new FailingValidator(CommitFailedException.UNSUPPORTED, 0,
-                    "Failed to save subtree at " + path + ". There are " +
-                            "transient modifications outside that subtree."),
-                    newArrayList(elements(path)));
-        }
-
-        private ItemSaveValidator(Validator validator, List<String> path) {
-            super(validator, path);
-            // Ignore property changes if this is the head of the path.
-            // This allows for calling save on a changed property.
-            ignorePropertyChange = path.size() == 1 ? path.get(0) : null;
-        }
-
-        @Override
-        public void propertyChanged(PropertyState before, PropertyState after)
-                throws CommitFailedException {
-            if (!before.getName().equals(ignorePropertyChange)) {
-                super.propertyChanged(before, after);
-            }
-        }
-
-        @Override
-        protected SubtreeExcludingValidator createValidator(
-                Validator validator, final List<String> path) {
-            return new ItemSaveValidator(validator, path);
-        }
-    }
-
 }

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java?rev=1566769&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java
 Mon Feb 10 22:30:39 2014
@@ -0,0 +1,77 @@
+/*
+ * 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.itemsave;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
+
+import java.util.List;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.commit.FailingValidator;
+import org.apache.jackrabbit.oak.spi.commit.SubtreeExcludingValidator;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+
+/**
+ * This validator checks that all changes are contained within the subtree
+ * rooted at a given path.
+ */
+class ItemSaveValidator extends SubtreeExcludingValidator {
+
+    /**
+     * Name of the property whose {@link 
#propertyChanged(org.apache.jackrabbit.oak.api.PropertyState, 
org.apache.jackrabbit.oak.api.PropertyState)} to
+     * ignore or {@code null} if no property should be ignored.
+     */
+    private final String ignorePropertyChange;
+
+    /**
+     * Create a new validator that only throws a {@link CommitFailedException} 
whenever
+     * there are changes not contained in the subtree rooted at {@code path}.
+     * @param path
+     */
+    public ItemSaveValidator(String path) {
+        this(new FailingValidator(CommitFailedException.UNSUPPORTED, 0,
+                "Failed to save subtree at " + path + ". There are " +
+                        "transient modifications outside that subtree."),
+                newArrayList(elements(path)));
+    }
+
+    private ItemSaveValidator(Validator validator, List<String> path) {
+        super(validator, path);
+        // Ignore property changes if this is the head of the path.
+        // This allows for calling save on a changed property.
+        ignorePropertyChange = path.size() == 1 ? path.get(0) : null;
+    }
+
+    @Override
+    public void propertyChanged(PropertyState before, PropertyState after)
+            throws CommitFailedException {
+        if (!before.getName().equals(ignorePropertyChange)) {
+            super.propertyChanged(before, after);
+        }
+    }
+
+    @Override
+    protected SubtreeExcludingValidator createValidator(
+            Validator validator, final List<String> path) {
+        return new ItemSaveValidator(validator, path);
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java?rev=1566769&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java
 Mon Feb 10 22:30:39 2014
@@ -0,0 +1,49 @@
+/*
+ * 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.itemsave;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * This validator checks that all changes are contained within the subtree
+ * rooted at a given path.
+ */
+@Component
+@Service(EditorProvider.class)
+public class ItemSaveValidatorProvider extends ValidatorProvider {
+
+    @Override
+    protected Validator getRootValidator(
+            NodeState before, NodeState after, CommitInfo info) {
+        String path = info.getPath();
+        if (PathUtils.denotesRoot(path)) {
+            return null; // no need to check saves of the whole transient space
+        } else {
+            return new ItemSaveValidator(path);
+        }
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/itemsave/ItemSaveValidatorProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java?rev=1566769&r1=1566768&r2=1566769&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
 Mon Feb 10 22:30:39 2014
@@ -49,6 +49,8 @@ public final class CommitInfo {
 
     private final long date = System.currentTimeMillis();
 
+    private final String path;
+
     /**
      * Creates a commit info for the given session and user.
      *
@@ -56,10 +58,19 @@ public final class CommitInfo {
      * @param userId The user id.
      * @param message message attached to this commit, or {@code null}
      */
-    public CommitInfo(@Nonnull String sessionId, @Nullable String userId, 
@Nullable String message) {
+    public CommitInfo(
+            @Nonnull String sessionId, @Nullable String userId,
+            @Nullable String message) {
+        this(sessionId, userId, message, "/");
+    }
+
+    public CommitInfo(
+            @Nonnull String sessionId, @Nullable String userId,
+            @Nullable String message, @Nonnull String path) {
         this.sessionId = checkNotNull(sessionId);
         this.userId = (userId == null) ? OAK_UNKNOWN : userId;
         this.message = message;
+        this.path = checkNotNull(path);
     }
 
     /**
@@ -93,6 +104,10 @@ public final class CommitInfo {
         return date;
     }
 
+    public String getPath() {
+        return path;
+    }
+
     //------------------------------------------------------------< Object >--
 
     @Override
@@ -104,7 +119,8 @@ public final class CommitInfo {
             return sessionId.equals(that.sessionId)
                     && userId.equals(that.userId)
                     && Objects.equal(this.message, that.message)
-                    && this.date == that.date;
+                    && this.date == that.date
+                    && path.equals(that.path);
         } else {
             return false;
         }
@@ -112,7 +128,7 @@ public final class CommitInfo {
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(sessionId, userId, message, date);
+        return Objects.hashCode(sessionId, userId, message, date, path);
     }
 
     @Override
@@ -122,6 +138,7 @@ public final class CommitInfo {
                 .add("userId", userId)
                 .add("userData", message)
                 .add("date", date)
+                .add("path", path)
                 .toString();
     }
 

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=1566769&r1=1566768&r2=1566769&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
 Mon Feb 10 22:30:39 2014
@@ -35,6 +35,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexProvider;
 import 
org.apache.jackrabbit.oak.plugins.index.reference.ReferenceEditorProvider;
 import 
org.apache.jackrabbit.oak.plugins.index.reference.ReferenceIndexProvider;
+import org.apache.jackrabbit.oak.plugins.itemsave.ItemSaveValidatorProvider;
 import org.apache.jackrabbit.oak.plugins.name.NameValidatorProvider;
 import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
@@ -67,6 +68,7 @@ public class Jcr {
 
         with(new SecurityProviderImpl());
 
+        with(new ItemSaveValidatorProvider());
         with(new NameValidatorProvider());
         with(new NamespaceEditorProvider());
         with(new TypeEditorProvider());

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1566769&r1=1566768&r2=1566769&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
 Mon Feb 10 22:30:39 2014
@@ -250,7 +250,7 @@ public class SessionDelegate {
      * @throws CommitFailedException if the commit failed
      */
     public void commit(Root root) throws CommitFailedException {
-        root.commit(userData, null);
+        root.commit(userData, "/");
     }
 
     public void checkProtectedNode(String path) throws RepositoryException {


Reply via email to