You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2013/07/08 15:29:54 UTC

svn commit: r1500715 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java

Author: mduerig
Date: Mon Jul  8 13:29:53 2013
New Revision: 1500715

URL: http://svn.apache.org/r1500715
Log:
OAK-144 Implement observation
Javadoc

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java?rev=1500715&r1=1500714&r2=1500715&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java Mon Jul  8 13:29:53 2013
@@ -28,45 +28,110 @@ import org.apache.jackrabbit.oak.spi.sta
 
 /**
  * Base class for {@code NodeStateDiff} implementations that can be secured.
- * That is its call back methods are only called when its receiver has sufficient
- * rights to access respective items.
+ * That is, its call back methods are only called when its receiver has sufficient
+ * rights to access the respective items.
+ * <p>
+ * Implementors must implement the {@link #create(SecurableNodeStateDiff, String, NodeState, NodeState)}
+ * factory method for creating {@code SecurableNodeStateDiff} instances for child nodes.
+ * Further implementors should override {@link #canRead(PropertyState, PropertyState)} and
+ * {@link #canRead(String, NodeState, NodeState)} and determine whether the passed states are
+ * accessible and the respective callbacks should thus be invoked. Finally implementors should override,
+ * {@link #secureBefore(String, NodeState)}, and {@link #secureAfter(String, NodeState)}} wrapping the
+ * passed node state into a node state that restricts access to accessible child nodes and properties.
  */
 public abstract class SecurableNodeStateDiff implements NodeStateDiff {
+
+    /**
+     * Parent diff
+     */
     private final SecurableNodeStateDiff parent;
 
+    /**
+     * Unsecured diff this secured diff delegates to after it has determined
+     * that the items pertaining to a call back are accessible.
+     */
     private RecursingNodeStateDiff diff;
+
+    /**
+     * Deferred {@link #childNodeChanged(String, NodeState, NodeState)} calls.
+     * Such calls are deferred until an accessible change in the respective sub tree
+     * is detected, as otherwise we might leak information restricted by access control
+     * to the call back.
+     */
     private Deferred deferred = Deferred.EMPTY;
 
     private SecurableNodeStateDiff(SecurableNodeStateDiff parent, RecursingNodeStateDiff diff) {
-        this.diff = diff;
         this.parent = parent;
+        this.diff = diff;
     }
 
+    /**
+     * Create a new child instance
+     * @param parent  parent of this instance
+     */
     protected SecurableNodeStateDiff(SecurableNodeStateDiff parent) {
         this(parent, RecursingNodeStateDiff.EMPTY);
     }
 
+    /**
+     * Create a new instance wrapping a unsecured diff.
+     * @param diff  unsecured diff
+     */
     protected SecurableNodeStateDiff(RecursingNodeStateDiff diff) {
         this(null, diff);
     }
 
+    /**
+     * Factory method for creating {@code SecurableNodeStateDiff} instances for child nodes.
+     * @param parent  parent diff
+     * @param name    name of the child node
+     * @param before  before state of the child node
+     * @param after   after state of the child node
+     * @return  {@code SecurableNodeStateDiff} for the child node {@code name}.
+     */
     @CheckForNull
     protected abstract SecurableNodeStateDiff create(SecurableNodeStateDiff parent,
             String name, NodeState before, NodeState after);
 
+    /**
+     * Determine whether a property is accessible
+     * @param before  before state of the property
+     * @param after   after state of the property
+     * @return  {@code true} if accessible, {@code false} otherwise.
+     */
     protected boolean canRead(PropertyState before, PropertyState after) {
         return true;
     }
 
+    /**
+     * Determine whether a node is accessible
+     * @param before  before state of the node
+     * @param after   after state of the node
+     * @return  {@code true} if accessible, {@code false} otherwise.
+     */
     protected boolean canRead(String name, NodeState before, NodeState after) {
         return true;
     }
 
+    /**
+     * Secure the before state of a child node such that it only provides
+     * accessible child nodes and properties.
+     * @param name       name of the child node
+     * @param nodeState  before state of the child node
+     * @return  secured before state
+     */
     @Nonnull
     protected NodeState secureBefore(String name, NodeState nodeState) {
         return nodeState;
     }
 
+    /**
+     * Secure the after state of a child node such that it only provides
+     * accessible child nodes and properties.
+     * @param name       name of the child node
+     * @param nodeState  after state of the child node
+     * @return  secured after state
+     */
     @Nonnull
     protected NodeState secureAfter(String name, NodeState nodeState) {
         return nodeState;
@@ -119,6 +184,7 @@ public abstract class SecurableNodeState
             return true;
         }
 
+        // Defer call back until accessible changes in the subtree are found
         deferred = new Deferred() {
             @Override
             boolean call() {
@@ -148,6 +214,9 @@ public abstract class SecurableNodeState
 
     //------------------------------------------------------------< Deferred >---
 
+    /**
+     * A deferred method call implementing call by need semantics.
+     */
     private abstract static class Deferred {
         public static final Deferred EMPTY = new Deferred() {
             @Override