You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/12/27 23:26:58 UTC

svn commit: r1225034 - in /jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state: ChangeTree.java TransientSpace.java

Author: mduerig
Date: Tue Dec 27 22:26:58 2011
New Revision: 1225034

URL: http://svn.apache.org/viewvc?rev=1225034&view=rev
Log:
Microkernel based prototype of JCR implementation (WIP)
- javadoc
- minor improvement

Modified:
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java?rev=1225034&r1=1225033&r2=1225034&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java Tue Dec 27 22:26:58 2011
@@ -61,6 +61,12 @@ public class ChangeTree {
     private final NodeDelta root;
     private final Function1<Path, Boolean> nodeExists;
 
+    /**
+     * Create a new change tree rooted at {@code rootPath}.
+     * @param rootPath  root path for this change tree
+     * @param nodeExists  predicate which determines whether a path exists on the
+     *                    persistent layer.
+     */
     public ChangeTree(final Path rootPath, Function1<Path, Boolean> nodeExists) {
         this.nodeExists = nodeExists;
 
@@ -72,10 +78,20 @@ public class ChangeTree {
         };
     }
 
+    /**
+     * @return {@code true} iff {@code path} exists either transiently or on
+     * the persistence layer.
+     */
     public boolean nodeExists(Path path) {
         return getNodeOrNull(path) != null;
     }
 
+    /**
+     * @param path
+     * @return a {@code NodeDelta} instance for the given {@code path}.
+     * @throws PathNotFoundException  if {@code path} does not exist transiently nor
+     * on the persistence layer.
+     */
     public NodeDelta getNode(Path path) throws PathNotFoundException {
         NodeDelta delta = getNodeOrNull(path);
         if (delta == null) {
@@ -85,14 +101,24 @@ public class ChangeTree {
         return delta;
     }
 
+    /**
+     * Collect all transient changes made to this change tree.
+     * @param listener
+     */
     public void collectChanges(Listener listener) {
         root.accept(new ChangeVisitor(listener));
     }
 
+    /**
+     * Clear all transient changes made to this change tree.
+     */
     public void clear() {
         root.clear();
     }
 
+    /**
+     * @return  {@code true} iff this change tree has transient changes.
+     */
     public boolean hasChanges() {
         return root.hasChanges();
     }
@@ -108,6 +134,9 @@ public class ChangeTree {
         return delta;
     }
 
+    /**
+     * Visitor for traversing a change tree.
+     */
     public interface Visitor {
         void visit(Existing delta);
         void visit(Added delta);
@@ -115,11 +144,43 @@ public class ChangeTree {
         void visit(Moved delta);
     }
 
+    /**
+     * Listener for collecting changes in a change tree.
+     * @see ChangeTree#collectChanges(org.apache.jackrabbit.state.ChangeTree.Listener)
+     */
     public interface Listener {
+
+        /**
+         * Record addition of a node at {@code path}.
+         * @param path
+         */
         void addNode(Path path);
+
+        /**
+         * Record removal of a node at {@code path}.
+         * @param path
+         */
         void removeNode(Path path);
+
+        /**
+         * Record a move from {@code sourcePath} to {@code destPath}.
+         * @param sourcePath
+         * @param destinationPath
+         */
         void moveNode(Path sourcePath, Path destinationPath);
+
+        /**
+         * Record setting a property value at {@code path}.
+         * @param path
+         * @param value
+         */
         void setProperty(Path path, JsonValue value);
+
+        /**
+         * Record removal of a property at {@code path}.
+         * @param path
+         */
+        void removeProperty(Path path);
     }
 
     private class ChangeVisitor implements Visitor {
@@ -160,7 +221,12 @@ public class ChangeTree {
             for (Entry<String, JsonValue> property : delta.properties.entrySet()) {
                 String name = property.getKey();
                 JsonValue value = property.getValue();
-                listener.setProperty(path.concat(name), value);
+                if (value == null) {
+                    listener.removeProperty(path.concat(name));
+                }
+                else {
+                    listener.setProperty(path.concat(name), value);
+                }
             }
         }
 
@@ -171,6 +237,22 @@ public class ChangeTree {
         }
     }
 
+    /**
+     * {@code NodeDelta} instances record changes to a node. {@code NodeDelta}'s
+     * subclasses correspond to these changes:
+     *
+     * <ul>
+     * <li>{@link org.apache.jackrabbit.state.ChangeTree.Added} represents a transiently
+     *      added node.</li>
+     * <li>{@link org.apache.jackrabbit.state.ChangeTree.Removed} represents a transiently
+     *      removed node.</li>
+     * <li>{@link org.apache.jackrabbit.state.ChangeTree.Moved} represents a transiently
+     *      moved node.</li>
+     * <li>{@link org.apache.jackrabbit.state.ChangeTree.Existing} represents a node which
+     *      is otherwise touched. That is, which either has property modifications or a has a
+     *      child node which is touched. </li>
+     * </ul>
+     */
     public abstract class NodeDelta {
         private final Map<String, NodeDelta> childNodes = new HashMap<String, NodeDelta>();
         private final Map<String, JsonValue> properties = new HashMap<String, JsonValue>();
@@ -182,28 +264,63 @@ public class ChangeTree {
             this.name = name;
         }
 
+        /**
+         * @return transient path to this node
+         */
         public Path getPath() {
             return parent.getPath().concat(name);
         }
 
+        /**
+         * @return persistent path to this node or {@code null} if this node is neither
+         * an {@link org.apache.jackrabbit.state.ChangeTree.Existing existing} node nor a
+         * {@link org.apache.jackrabbit.state.ChangeTree.Moved moved} node and this does
+         * not have a persistent path.
+         */
         public Path getPersistentPath() {
             return null;
         }
 
+        /**
+         * @return {@code true} iff this is node has been transiently removed. This is
+         * either the result of a remove or a move operation.
+         */
         public abstract boolean isRemoved();
+
+        /**
+         * @return {@code true} iff this node is moved. If at the same time {@link #isRemoved()}
+         * is {@code true}, this is the source node of the move operation. Otherwise this is
+         * the target node of the move operation.
+         */
         public abstract boolean isMoved();
+
+        /**
+         * @return {@code true} iff this node is transient.
+         */
         public abstract boolean isTransient();
 
         public abstract void accept(Visitor visitor);
 
+        /**
+         * @return {@code true} iff this node has either changed child nodes or changed
+         * properties. 
+         */
         public boolean hasChanges() {
             return !childNodes.isEmpty() || !properties.isEmpty();
         }
 
+        /**
+         * @param name
+         * @return  {@code true} iff this node has a child node with the given {@code name}.
+         */
         public final boolean hasNode(String name) {
             return getNode(name) != null;
         }
 
+        /**
+         * @param name
+         * @return  the child node with the given {@code name} or {@code null} if none.
+         */
         public abstract NodeDelta getNode(String name);
 
         public Iterator<Entry<String, NodeDelta>> getNodes() {
@@ -216,14 +333,27 @@ public class ChangeTree {
             });
         }
 
+        /**
+         * @param name
+         * @return {@code true} iff this node has a property with the given {@code name}.
+         */
         public boolean hasProperty(String name) {
             return properties.containsKey(name);
         }
 
+        /**
+         * @param name
+         * @return  the property with the given {@code name} or {@code null} if the property
+         * has been removed ({@link #hasProperty(String)} {@code true}) or does not exist
+         * ({@link #hasProperty(String)} {@code false}).
+         */
         public JsonValue getProperty(String name) {
             return properties.get(name);
         }
 
+        /**
+         * @return  an iterator of all added properties.
+         */
         public Iterator<Entry<String, JsonValue>> getProperties() {
             return Iterators.filterIterator(properties.entrySet().iterator(), new Predicate<Entry<String, JsonValue>>() {
                 @Override
@@ -233,6 +363,12 @@ public class ChangeTree {
             });
         }
 
+        /**
+         * Add a node with the given {@code name}.
+         * @param name
+         * @return  the added node
+         * @throws ItemExistsException
+         */
         public NodeDelta addNode(String name) throws ItemExistsException {
             if (hasNode(name)) {
                 throw new ItemExistsException(name);
@@ -241,6 +377,12 @@ public class ChangeTree {
             return addChild(new Added(this, name));
         }
 
+        /**
+         * Remove the node with the given {@code name}.
+         * @param name
+         * @return  the removed node
+         * @throws ItemNotFoundException
+         */
         public NodeDelta removeNode(String name) throws ItemNotFoundException {
             NodeDelta delta = getNode(name);
             if (delta == null) {
@@ -250,6 +392,14 @@ public class ChangeTree {
             return delta.remove();
         }
 
+        /**
+         * Move the node with the given {@code name} to {@code destination}.
+         * @param name
+         * @param destination
+         * @throws ItemNotFoundException
+         * @throws ItemExistsException
+         * @throws PathNotFoundException
+         */
         public void moveNode(String name, Path destination) throws ItemNotFoundException, ItemExistsException,
                 PathNotFoundException {
 
@@ -280,6 +430,12 @@ public class ChangeTree {
             source.moveTo(destParent, destination.getName());
         }
 
+        /**
+         * Set the property with the given {@code name} to {@code value} or remove the
+         * property if {@code value} is {@code null}.
+         * @param name
+         * @param value
+         */
         public void setValue(String name, JsonValue value) {
             if (value == null && properties.containsKey(name) && properties.get(name) != null) {
                 properties.remove(name);
@@ -334,6 +490,9 @@ public class ChangeTree {
         }
     }
 
+    /**
+     * Represents an existing node. That is, a node which exists on the persistence layer.
+     */
     public class Existing extends NodeDelta {
         Existing(NodeDelta parent, String name) {
             super(parent, name);
@@ -395,6 +554,9 @@ public class ChangeTree {
         }
     }
 
+    /**
+     * Represents a transiently added node.
+     */
     public class Added extends NodeDelta {
         Added(NodeDelta parent, String name) {
             super(parent, name);
@@ -438,6 +600,9 @@ public class ChangeTree {
         }
     }
 
+    /**
+     * Represents a moved node.
+     */
     public class Moved extends NodeDelta {
         private final NodeDelta source;
 
@@ -446,7 +611,10 @@ public class ChangeTree {
             this.source = source;
         }
 
-        Path getSourcePath() {
+        /**
+         * @return  path to the source node of the move operation.
+         */
+        public Path getSourcePath() {
             return source.getPath();
         }
 
@@ -518,6 +686,9 @@ public class ChangeTree {
         }
     }
 
+    /**
+     * Represents a transiently removed node.
+     */
     public class Removed extends NodeDelta {
         private final boolean moved;
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java?rev=1225034&r1=1225033&r2=1225034&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java Tue Dec 27 22:26:58 2011
@@ -68,7 +68,15 @@ public class TransientSpace {
                 public void setProperty(Path path, JsonValue value) {
                     jsop.append("^\"")
                             .append(path.getMkPath())
-                            .append("\":").append(value == null ? "null" : value.toJson());
+                            .append("\":")
+                            .append(value.toJson());
+                }
+
+                @Override
+                public void removeProperty(Path path) {
+                    jsop.append("^\"")
+                            .append(path.getMkPath())
+                            .append("\":null");
                 }
             });