BUG-509: cleanup datastore interafaces 16/7516/2
authorRobert Varga <rovarga@cisco.com>
Thu, 29 May 2014 13:04:30 +0000 (15:04 +0200)
committerRobert Varga <rovarga@cisco.com>
Thu, 29 May 2014 14:51:25 +0000 (16:51 +0200)
This removes unused methods and adds interface contract documentation.

Change-Id: I7bc57d034da1d0503d76afa6f4c09ce6a6bfe669
Signed-off-by: Robert Varga <rovarga@cisco.com>
19 files changed:
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataPreconditionFailedException.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidateNode.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java

index 00df6580effda8da33e80a648653935049010c47..7b799661afbdc60b1b523b7d39fc3e984fdf46b9 100644 (file)
@@ -257,7 +257,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
             ready = true;
 
             LOG.debug("Store transaction: {} : Ready", getIdentifier());
             ready = true;
 
             LOG.debug("Store transaction: {} : Ready", getIdentifier());
-            mutableTree.seal();
+            mutableTree.ready();
             return store.submit(this);
         }
 
             return store.submit(this);
         }
 
index b36ef3dd7c16250bfcc101ab4567be3feaaadbc4..2a163d8dbc7334c95a24481d1a1835ffa8496586 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder;
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder;
-import static org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils.append;
 
 import java.util.Collection;
 import java.util.Collections;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -46,23 +45,10 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 
 /**
 import com.google.common.collect.Multimap;
 
 /**
- *
  * Resolve Data Change Events based on modifications and listeners
  *
  * Computes data change events for all affected registered listeners in data
  * tree.
  * Resolve Data Change Events based on modifications and listeners
  *
  * Computes data change events for all affected registered listeners in data
  * tree.
- *
- * Prerequisites for computation is to set all parameters properly:
- * <ul>
- * <li>{@link #setRootPath(InstanceIdentifier)} - Root path of datastore
- * <li>{@link #setListenerRoot(ListenerTree)} - Root of listener registration
- * tree, which contains listeners to be notified
- * <li>{@link #setModificationRoot(NodeModification)} - Modification root, for
- * which events should be computed
- * <li>{@link #setBeforeRoot(Optional)} - State of before modification occurred
- * <li>{@link #setAfterRoot(Optional)} - State of after modification occurred
- * </ul>
- *
  */
 final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListenerNotifyTask>> {
     private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class);
  */
 final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListenerNotifyTask>> {
     private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class);
@@ -72,7 +58,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
     private final DataTreeCandidate candidate;
     private final ListenerTree listenerRoot;
 
     private final DataTreeCandidate candidate;
     private final ListenerTree listenerRoot;
 
-    public ResolveDataChangeEventsTask(DataTreeCandidate candidate, ListenerTree listenerTree) {
+    public ResolveDataChangeEventsTask(final DataTreeCandidate candidate, final ListenerTree listenerTree) {
         this.candidate = Preconditions.checkNotNull(candidate);
         this.listenerRoot = Preconditions.checkNotNull(listenerTree);
     }
         this.candidate = Preconditions.checkNotNull(candidate);
         this.listenerRoot = Preconditions.checkNotNull(listenerTree);
     }
@@ -83,7 +69,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
      * Implementation of done as Map-Reduce with two steps: 1. resolving events
      * and their mapping to listeners 2. merging events affecting same listener
      *
      * Implementation of done as Map-Reduce with two steps: 1. resolving events
      * and their mapping to listeners 2. merging events affecting same listener
      *
-     * @return Iterable of Notification Tasks which needs to be executed in
+     * @return An {@link Iterable} of Notification Tasks which needs to be executed in
      *         order to delivery data change events.
      */
     @Override
      *         order to delivery data change events.
      */
     @Override
@@ -329,7 +315,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         for (NormalizedNode<PathArgument, ?> beforeChild : beforeCont.getValue()) {
             PathArgument childId = beforeChild.getIdentifier();
             alreadyProcessed.add(childId);
         for (NormalizedNode<PathArgument, ?> beforeChild : beforeCont.getValue()) {
             PathArgument childId = beforeChild.getIdentifier();
             alreadyProcessed.add(childId);
-            InstanceIdentifier childPath = append(path, childId);
+            InstanceIdentifier childPath = path.node(childId);
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
             Optional<NormalizedNode<PathArgument, ?>> afterChild = afterCont.getChild(childId);
             DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners,
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
             Optional<NormalizedNode<PathArgument, ?>> afterChild = afterCont.getChild(childId);
             DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners,
@@ -348,7 +334,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
                 // and it was not present in previous loop, that means it is
                 // created.
                 Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
                 // and it was not present in previous loop, that means it is
                 // created.
                 Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
-                InstanceIdentifier childPath = append(path,childId);
+                InstanceIdentifier childPath = path.node(childId);
                 childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild,
                         DOMImmutableDataChangeEvent.getCreateEventFactory()));
             }
                 childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild,
                         DOMImmutableDataChangeEvent.getCreateEventFactory()));
             }
@@ -432,7 +418,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
                 PathArgument childId = child.getIdentifier();
                 LOG.trace("Resolving event for child {}", childId);
                 Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
                 PathArgument childId = child.getIdentifier();
                 LOG.trace("Resolving event for child {}", childId);
                 Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
-                eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory));
+                eventBuilder.merge(resolveSameEventRecursivelly(path.node(childId), childListeners, child, eventFactory));
             }
             propagateEvent = eventBuilder.build();
         } else {
             }
             propagateEvent = eventBuilder.build();
         } else {
@@ -460,7 +446,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
 
         for (DataTreeCandidateNode childMod : modification.getChildNodes()) {
             PathArgument childId = childMod.getIdentifier();
 
         for (DataTreeCandidateNode childMod : modification.getChildNodes()) {
             PathArgument childId = childMod.getIdentifier();
-            InstanceIdentifier childPath = append(path, childId);
+            InstanceIdentifier childPath = path.node(childId);
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
 
             switch (childMod.getModificationType()) {
             Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
 
             switch (childMod.getModificationType()) {
@@ -522,7 +508,7 @@ final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListe
         }
     }
 
         }
     }
 
-    public static ResolveDataChangeEventsTask create(DataTreeCandidate candidate, ListenerTree listenerTree) {
+    public static ResolveDataChangeEventsTask create(final DataTreeCandidate candidate, final ListenerTree listenerTree) {
         return new ResolveDataChangeEventsTask(candidate, listenerTree);
     }
 }
         return new ResolveDataChangeEventsTask(candidate, listenerTree);
     }
 }
index bb2111e6a08882b71656e28c96758ccfe19f178e..bd24ac5fcfd3c670b2677531eb485cba3a9e7d4c 100644 (file)
@@ -11,20 +11,42 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 import com.google.common.base.Preconditions;
 
 
 import com.google.common.base.Preconditions;
 
+/**
+ * Exception thrown when a proposed change fails validation before being
+ * applied into the datastore. This can have multiple reasons, for example
+ * the datastore has been concurrently modified such that a conflicting
+ * node is present, or the modification is structurally incorrect.
+ */
 public class DataPreconditionFailedException extends Exception {
     private static final long serialVersionUID = 1L;
     private final InstanceIdentifier path;
 
 public class DataPreconditionFailedException extends Exception {
     private static final long serialVersionUID = 1L;
     private final InstanceIdentifier path;
 
+    /**
+     * Create a new instance.
+     *
+     * @param path Object path which caused this exception
+     * @param message Specific message describing the failure
+     */
     public DataPreconditionFailedException(final InstanceIdentifier path, final String message) {
     public DataPreconditionFailedException(final InstanceIdentifier path, final String message) {
-        super(message);
-        this.path = Preconditions.checkNotNull(path);
+        this(path, message, null);
     }
     }
-
+    /**
+     * Create a new instance, initializing
+     *
+     * @param path Object path which caused this exception
+     * @param message Specific message describing the failure
+     * @param cause Exception which triggered this failure, may be null
+     */
     public DataPreconditionFailedException(final InstanceIdentifier path, final String message, final Throwable cause) {
         super(message, cause);
         this.path = Preconditions.checkNotNull(path);
     }
 
     public DataPreconditionFailedException(final InstanceIdentifier path, final String message, final Throwable cause) {
         super(message, cause);
         this.path = Preconditions.checkNotNull(path);
     }
 
+    /**
+     * Returns the offending object path.
+     *
+     * @return Path of the offending object
+     */
     public InstanceIdentifier getPath() {
         return path;
     }
     public InstanceIdentifier getPath() {
         return path;
     }
index 906e2844291fc502bae2a2534fe71bf1cb1d02a6..d860dfc064cbbbb6420b39dc47840ad3f78040bf 100644 (file)
@@ -9,7 +9,27 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
+/**
+ * An encapsulation of a validated data tree modification. This candidate
+ * is ready for atomic commit to the datastore. It allows access to before-
+ * and after-state as it will be seen in to subsequent commit. This capture
+ * can be accessed for reference, but cannot be modified and the content
+ * is limited to nodes which were affected by the modification from which
+ * this instance originated.
+ */
 public interface DataTreeCandidate {
 public interface DataTreeCandidate {
+    /**
+     * Get the candidate tree root node.
+     *
+     * @return Candidate tree root node
+     */
     DataTreeCandidateNode getRootNode();
     DataTreeCandidateNode getRootNode();
+
+    /**
+     * Get the candidate tree root path. This is the path of the root node
+     * relative to the root of InstanceIdentifier namespace.
+     *
+     * @return Relative path of the root node
+     */
     InstanceIdentifier getRootPath();
 }
     InstanceIdentifier getRootPath();
 }
index b1ca45b53e3320e18a6ce7bdc761420e01c4b033..528419d235033ec8d85d43cfb36229bd477b13e6 100644 (file)
@@ -12,11 +12,47 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
 
 
 import com.google.common.base.Optional;
 
+/**
+ * A single node within a {@link DataTreeCandidate}. The nodes are organized
+ * in tree hierarchy, reflecting the modification from which this candidate
+ * was created. The node itself exposes the before- and after-image of the
+ * tree restricted to the modified nodes.
+ */
 public interface DataTreeCandidateNode {
 public interface DataTreeCandidateNode {
+    /**
+     * Get the node identifier.
+     *
+     * @return The node identifier.
+     */
     PathArgument getIdentifier();
     PathArgument getIdentifier();
+
+    /**
+     * Get an unmodifiable iterable of modified child nodes.
+     *
+     * @return Unmodifiable iterable of modified child nodes.
+     */
     Iterable<DataTreeCandidateNode> getChildNodes();
 
     Iterable<DataTreeCandidateNode> getChildNodes();
 
+    /**
+     * Return the type of modification this node is undergoing.
+     *
+     * @return Node modification type.
+     */
     ModificationType getModificationType();
     ModificationType getModificationType();
+
+    /**
+     * Return the before-image of data corresponding to the node.
+     *
+     * @return Node data as they were present in the tree before
+     *         the modification was applied.
+     */
     Optional<NormalizedNode<?, ?>> getDataAfter();
     Optional<NormalizedNode<?, ?>> getDataAfter();
+
+    /**
+     * Return the after-image of data corresponding to the node.
+     *
+     * @return Node data as they will be present in the tree after
+     *         the modification is applied.
+     */
     Optional<NormalizedNode<?, ?>> getDataBefore();
 }
     Optional<NormalizedNode<?, ?>> getDataBefore();
 }
index cff90a4aefd2079915af4fb327ae48d5ef609a29..e4370c46a04fbc2539796672abc2baf9abeeae1f 100644 (file)
@@ -16,8 +16,35 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  * has the ability to rebase itself to a new snapshot.
  */
 public interface DataTreeModification extends DataTreeSnapshot {
  * has the ability to rebase itself to a new snapshot.
  */
 public interface DataTreeModification extends DataTreeSnapshot {
-       void delete(InstanceIdentifier path);
-       void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
-       void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
-       void seal();
+    /**
+     * Delete the node at specified path.
+     *
+     * @param path Node path
+     */
+    void delete(InstanceIdentifier path);
+
+    /**
+     * Merge the specified data with the currently-present data
+     * at specified path.
+     *
+     * @param path Node path
+     * @param data Data to be merged
+     */
+    void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
+
+    /**
+     * Replace the data at specified path with supplied data.
+     *
+     * @param path Node path
+     * @param data New node data
+     */
+    void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
+
+    /**
+     * Finish creation of a modification, making it ready for application
+     * to the data tree. Any calls to this object's methods will result
+     * in undefined behavior, possibly with an
+     * {@link IllegalStateException} being thrown.
+     */
+    void ready();
 }
 }
index f93f40a9cc1f5b9bd85e00543be0497fde16d4de..0d73143de2aad021ee17f7577d95eaabdc0af24e 100644 (file)
@@ -33,15 +33,24 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
+/**
+ * A set of listeners organized as a tree by node to which they listen. This class
+ * allows for efficient lookup of listeners when we walk the DataTreeCandidate.
+ */
 public final class ListenerTree {
     private static final Logger LOG = LoggerFactory.getLogger(ListenerTree.class);
     private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
     private final Node rootNode = new Node(null, null);
 
     private ListenerTree() {
 public final class ListenerTree {
     private static final Logger LOG = LoggerFactory.getLogger(ListenerTree.class);
     private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
     private final Node rootNode = new Node(null, null);
 
     private ListenerTree() {
-
+        // Private to disallow direct instantiation
     }
 
     }
 
+    /**
+     * Create a new empty instance of the listener tree.
+     *
+     * @return An empty instance.
+     */
     public static ListenerTree create() {
         return new ListenerTree();
     }
     public static ListenerTree create() {
         return new ListenerTree();
     }
@@ -110,6 +119,14 @@ public final class ListenerTree {
         }
     }
 
         }
     }
 
+    /**
+     * Obtain a tree walking context. This context ensures a consistent view of
+     * the listener registrations. The context should be closed as soon as it
+     * is not required, because each unclosed instance blocks modification of
+     * the listener tree.
+     *
+     * @return A walker instance.
+     */
     public Walker getWalker() {
         /*
          * TODO: The only current user of this method is local to the datastore.
     public Walker getWalker() {
         /*
          * TODO: The only current user of this method is local to the datastore.
@@ -124,6 +141,10 @@ public final class ListenerTree {
         return ret;
     }
 
         return ret;
     }
 
+    /**
+     * A walking context, pretty much equivalent to an iterator, but it
+     * exposes the undelying tree structure.
+     */
     public static final class Walker implements AutoCloseable {
         private final Lock lock;
         private final Node node;
     public static final class Walker implements AutoCloseable {
         private final Lock lock;
         private final Node node;
index b16e907120ac098ee81a3f9fec4dd83469971f69..b9a26f5c00be0b6cf45775e141d22728b1d22ee2 100644 (file)
@@ -7,37 +7,39 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
+/**
+ * Enumeration of all possible node modification states. These are used in
+ * data tree modification context to quickly assess what sort of modification
+ * the node is undergoing.
+ */
 public enum ModificationType {
 public enum ModificationType {
-
     /**
     /**
-     *
-     * Node is unmodified
-     *
-     *
+     * Node is currently unmodified.
      */
     UNMODIFIED,
      */
     UNMODIFIED,
+
     /**
     /**
-     *
-     * Child of tree node was modified
-     *
+     * A child node, either direct or indirect, has been modified. This means
+     * that the data representation of this node has potentially changed.
      */
     SUBTREE_MODIFIED,
      */
     SUBTREE_MODIFIED,
+
     /**
     /**
-     * Tree node was replaced with new value / subtree
-     *
+     * This node has been placed into the tree, potentially completely replacing
+     * pre-existing contents.
      */
     WRITE,
      */
     WRITE,
+
     /**
     /**
-     *
-     * Tree node is to be deleted.
-     *
+     * This node has been deleted along with any of its child nodes.
      */
     DELETE,
 
     /**
      */
     DELETE,
 
     /**
-     *
-     * Tree node is to be merged with existing one.
-     *
+     * Node has been written into the tree, but instead of replacing pre-existing
+     * contents, it has been merged. This means that any incoming nodes which
+     * were present in the tree have been replaced, but their child nodes have
+     * been retained.
      */
      */
-    MERGE
+    MERGE,
 }
 }
index 52beaa7c616d046ea9793aa712b37f860c2d03cc..d714f1cc85449d60967c0d87cc05c4282ec3d880 100644 (file)
@@ -10,17 +10,17 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import com.google.common.base.Optional;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import com.google.common.base.Optional;
+
 /**
 /**
- *
- * Tree node which contains references to it's leafs
+ * A tree node which has references to its child leaves. This are typically
+ * internal non-data leaves, such as containers, lists, etc.
  *
  * @param <C> Final node type
  */
 public interface StoreTreeNode<C extends StoreTreeNode<C>> {
 
     /**
  *
  * @param <C> Final node type
  */
 public interface StoreTreeNode<C extends StoreTreeNode<C>> {
 
     /**
-     *
-     * Returns direct child of the node
+     * Returns a direct child of the node
      *
      * @param child Identifier of child
      * @return Optional with node if the child is existing, {@link Optional#absent()} otherwise.
      *
      * @param child Identifier of child
      * @return Optional with node if the child is existing, {@link Optional#absent()} otherwise.
index 7e783f927d95d9be9f92041074cf6769ef582bac..b634866856b11e810c17bba036bece830a887ba5 100644 (file)
@@ -7,60 +7,32 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree;
 
-import java.util.Set;
-
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 
-import com.google.common.base.Function;
 import com.google.common.base.Strings;
 import com.google.common.base.Strings;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.UnsignedLong;
 
 
+/**
+ * Data store tree manipulation utilities.
+ */
 public final class StoreUtils {
     private static final int STRINGTREE_INDENT = 4;
 
 public final class StoreUtils {
     private static final int STRINGTREE_INDENT = 4;
 
-    private final static Function<Identifiable<Object>, Object> EXTRACT_IDENTIFIER = new Function<Identifiable<Object>, Object>() {
-        @Override
-        public Object apply(final Identifiable<Object> input) {
-            return input.getIdentifier();
-        }
-    };
-
     private StoreUtils() {
         throw new UnsupportedOperationException("Utility class should not be instantiated");
     }
 
     private StoreUtils() {
         throw new UnsupportedOperationException("Utility class should not be instantiated");
     }
 
-    /*
-     * Suppressing warnings here allows us to fool the compiler enough
-     * such that we can reuse a single function for all applicable types
-     * and present it in a type-safe manner to our users.
+    /**
+     * Convert a data subtree under a node into a human-readable string format.
+     *
+     * @param node Data subtree root
+     * @return String containing a human-readable form of the subtree.
      */
      */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static <V> Function<Identifiable<V>, V> identifierExtractor() {
-        return (Function) EXTRACT_IDENTIFIER;
-    }
-
-    public static final UnsignedLong increase(final UnsignedLong original) {
-        return original.plus(UnsignedLong.ONE);
-    }
-
-    public static final InstanceIdentifier append(final InstanceIdentifier parent, final PathArgument arg) {
-        return new InstanceIdentifier(ImmutableList.<PathArgument> builder().addAll(parent.getPath()).add(arg).build());
-    }
-
-    public static <V> Set<V> toIdentifierSet(final Iterable<? extends Identifiable<V>> children) {
-        return FluentIterable.from(children).transform(StoreUtils.<V> identifierExtractor()).toSet();
-    }
-
     public static String toStringTree(final NormalizedNode<?, ?> node) {
     public static String toStringTree(final NormalizedNode<?, ?> node) {
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder builder = new StringBuilder();
         toStringTree(builder, node, 0);
         return builder.toString();
     }
         toStringTree(builder, node, 0);
         return builder.toString();
     }
index 732352dd34bbf974b6d897984d9b731c72e5e591..99982d318cf5487699d2db60549e4ee194ed0540 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import java.util.List;
 import java.util.Map;
 
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
@@ -21,6 +22,9 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 
+/**
+ * A set of utility methods for interacting with {@link TreeNode} objects.
+ */
 public final class TreeNodeUtils {
     private TreeNodeUtils() {
         throw new UnsupportedOperationException("Utility class should not be instantiated");
 public final class TreeNodeUtils {
     private TreeNodeUtils() {
         throw new UnsupportedOperationException("Utility class should not be instantiated");
@@ -32,7 +36,6 @@ public final class TreeNodeUtils {
      * @param tree Data Tree
      * @param path Path to the node
      * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise.
      * @param tree Data Tree
      * @param path Path to the node
      * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise.
-     *
      */
     public static <T extends StoreTreeNode<T>> Optional<T> findNode(final T tree, final InstanceIdentifier path) {
         Optional<T> current = Optional.<T> of(tree);
      */
     public static <T extends StoreTreeNode<T>> Optional<T> findNode(final T tree, final InstanceIdentifier path) {
         Optional<T> current = Optional.<T> of(tree);
index c05ed4b442d0fa964fa94d88fb9526a5c88673c6..f7e95b84bd4df38c214c32f10c1b01df61fb4798 100644 (file)
@@ -131,7 +131,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
     }
 
     @Override
-    public synchronized void seal() {
+    public synchronized void ready() {
         Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
         sealed = true;
         rootNode.seal();
         Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
         sealed = true;
         rootNode.seal();
index 2639d050efe28b8b0903636e987b5c134e79c922..e7e79f891687592db4ac45a14eb558dae20c085b 100644 (file)
@@ -14,8 +14,31 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import com.google.common.base.Optional;
 
 
 import com.google.common.base.Optional;
 
+/**
+ * Internal interface representing a modification action of a particular node.
+ * It is used by the validation code to allow for a read-only view of the
+ * modification tree as we should never modify that during validation.
+ */
 interface NodeModification extends Identifiable<PathArgument> {
 interface NodeModification extends Identifiable<PathArgument> {
+    /**
+     * Get the type of modification.
+     *
+     * @return Modification type.
+     */
     ModificationType getType();
     ModificationType getType();
+
+    /**
+     * Get the original tree node to which the modification is to be applied.
+     *
+     * @return The original node, or {@link Optional#absent()} if the node is
+     *         a new node.
+     */
     Optional<TreeNode> getOriginal();
     Optional<TreeNode> getOriginal();
+
+    /**
+     * Get a read-only view of children nodes.
+     *
+     * @return Iterable of all children nodes.
+     */
     Iterable<? extends NodeModification> getChildren();
 }
     Iterable<? extends NodeModification> getChildren();
 }
index 2ef85cbcb7e548cb6fa1ccd932e7dddbb651ace3..227684ae35ee1f6bdbc8685df670c9cc157881af 100644 (file)
@@ -18,6 +18,11 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
+/**
+ * Internal utility class for an empty candidate. We instantiate this class
+ * for empty modifications, saving memory and processing speed. Instances
+ * of this class are explicitly recognized and processing of them is skipped.
+ */
 final class NoopDataTreeCandidate extends AbstractDataTreeCandidate {
     private static final DataTreeCandidateNode ROOT = new DataTreeCandidateNode() {
         @Override
 final class NoopDataTreeCandidate extends AbstractDataTreeCandidate {
     private static final DataTreeCandidateNode ROOT = new DataTreeCandidateNode() {
         @Override
index b70c5d18dc58a6c30c36864678d4c725dc6fd0b9..5c6aeace569aabd1020a1b67e4572e428dbf2da1 100644 (file)
@@ -13,7 +13,6 @@ import java.util.Map;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode;
@@ -178,7 +177,7 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp
             final PathArgument childId = childMod.getIdentifier();
             final Optional<TreeNode> childMeta = currentMeta.getChild(childId);
 
             final PathArgument childId = childMod.getIdentifier();
             final Optional<TreeNode> childMeta = currentMeta.getChild(childId);
 
-            InstanceIdentifier childPath = StoreUtils.append(path, childId);
+            InstanceIdentifier childPath = path.node(childId);
             resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta);
         }
     }
             resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta);
         }
     }
index 1444f0c6a859c43bfc39c39c8b1ad26e3374bc63..522bf3c84dd350344ad4ac65defadf5f1181d5e7 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Preconditions;
 
 
 import com.google.common.base.Preconditions;
 
-/*
+/**
  * A very basic data tree node.
  */
 abstract class AbstractTreeNode implements TreeNode {
  * A very basic data tree node.
  */
 abstract class AbstractTreeNode implements TreeNode {
index 7ab309607b908e84e0603840b9aa6bc31a7c61c5..087f4de666155217722bca1407eb168efa069eed 100644 (file)
@@ -17,9 +17,43 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  * any interactions with it will result in undefined behavior.
  */
 public interface MutableTreeNode extends StoreTreeNode<TreeNode> {
  * any interactions with it will result in undefined behavior.
  */
 public interface MutableTreeNode extends StoreTreeNode<TreeNode> {
+    /**
+     * Set the data component of the node.
+     *
+     * @param data New data component, may not be null.
+     */
     void setData(NormalizedNode<?, ?> data);
     void setData(NormalizedNode<?, ?> data);
+
+    /**
+     * Set the new subtree version. This is typically invoked when the user
+     * has modified some of this node's children.
+     *
+     * @param subtreeVersion New subtree version.
+     */
     void setSubtreeVersion(Version subtreeVersion);
     void setSubtreeVersion(Version subtreeVersion);
+
+    /**
+     * Add a new child node. This acts as add-or-replace operation, e.g. it
+     * succeeds even if a conflicting child is already present.
+     *
+     * @param child New child node.
+     */
     void addChild(TreeNode child);
     void addChild(TreeNode child);
+
+    /**
+     * Remove a child node. This acts as delete-or-nothing operation, e.g. it
+     * succeeds even if the corresponding child is not present.
+     *
+     * @param id Child identificator.
+     */
     void removeChild(PathArgument id);
     void removeChild(PathArgument id);
+
+    /**
+     * Finish node modification and return a read-only view of this node. After
+     * this method is invoked, any further calls to this object's method result
+     * in undefined behavior.
+     *
+     * @return Read-only view of this node.
+     */
     TreeNode seal();
 }
     TreeNode seal();
 }
index b0beb8168befede9c70bdee711ec05084997887a..def1958123c951419faeecab6d5cee5654903a3e 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-/*
+/**
  * A very basic data tree node. It has a version (when it was last modified),
  * a subtree version (when any of its children were modified) and some read-only
  * data.
  * A very basic data tree node. It has a version (when it was last modified),
  * a subtree version (when any of its children were modified) and some read-only
  * data.
index 7194faadf650a73b7cdd0cd6434592254889ec93..d89928b51e7f35dd19e2d386744a9b5fa9408bdf 100644 (file)
@@ -14,6 +14,11 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 
 
 import com.google.common.base.Optional;
 
+/**
+ * Concretization of AbstractTreeNode for leaf nodes which only contain data.
+ * Instances of this class report all children as absent, subtree version
+ * equal to this node's version and do not support mutable view.
+ */
 final class ValueNode extends AbstractTreeNode {
     private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class);
 
 final class ValueNode extends AbstractTreeNode {
     private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class);