Added NormalizedNodeContainerBuilder and helpers. 46/5646/5
authorTony Tkacik <ttkacik@cisco.com>
Tue, 18 Mar 2014 17:06:26 +0000 (18:06 +0100)
committerRobert Varga <rovarga@cisco.com>
Wed, 19 Mar 2014 10:11:51 +0000 (11:11 +0100)
   - NormalizedNodeContainerBuilder is common root
     to builders which produces NormalizedNodeContainer,
     this allows to write more generic code using builders.

   - NormalizedNodeUtils - provides helper functions to process
     normalized date tree, such as findNode which look up
     subtree based on provided InstanceIdentifier.

   - Added Immutable marker interface to existing builders.

Change-Id: Id842742432c48d76cdf78dab40352af27e10360f
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
16 files changed:
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/Builders.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeUtils.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/CollectionNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/DataContainerNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/ListNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/NormalizedNodeContainerBuilder.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableAugmentationNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableChoiceNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableContainerNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/test/NormalizedNodeUtilsTest.java [new file with mode: 0644]

index 09823823630f7b4ca9e52b57d8c0c4886b099fca..6c4b6a1f0074aa8247f6b7614c974d3670e713fb 100644 (file)
@@ -8,23 +8,51 @@
 package org.opendaylight.yangtools.yang.data.impl.schema;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.*;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.*;
-import org.opendaylight.yangtools.yang.model.api.*;
-
-public class Builders {
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeSchemaAwareBuilder;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+public final class Builders {
+
+    private Builders() {
+        throw new UnsupportedOperationException("Utilities class should not be instantiated");
+    }
 
     public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> leafBuilder() {
         return ImmutableLeafNodeBuilder.create();
     }
 
     public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, T, LeafNode<T>> leafBuilder(
-            LeafSchemaNode schema) {
+            final LeafSchemaNode schema) {
         return ImmutableLeafNodeSchemaAwareBuilder.create(schema);
     }
 
@@ -33,16 +61,16 @@ public class Builders {
     }
 
     public static <T> NormalizedNodeBuilder<InstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> leafSetEntryBuilder(
-            LeafListSchemaNode schema) {
+            final LeafListSchemaNode schema) {
         return ImmutableLeafSetEntryNodeSchemaAwareBuilder.create(schema);
     }
 
-    public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> leafSetBuilder() {
+    public static <T> ListNodeBuilder<T,LeafSetEntryNode<T>> leafSetBuilder() {
         return ImmutableLeafSetNodeBuilder.create();
     }
 
-    public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> leafSetBuilder(LeafListSchemaNode schema) {
-        return ImmutableLeafSetNodeSchemaAwareBuilder.create(schema);
+    public static <T> ListNodeBuilder<T,LeafSetEntryNode<T>> leafSetBuilder(final LeafListSchemaNode schema) {
+        return ImmutableLeafSetNodeSchemaAwareBuilder.<T>create(schema);
     }
 
     public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> containerBuilder() {
@@ -50,7 +78,7 @@ public class Builders {
     }
 
     public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> containerBuilder(
-            ContainerSchemaNode schema) {
+            final ContainerSchemaNode schema) {
         return ImmutableContainerNodeSchemaAwareBuilder.create(schema);
     }
 
@@ -59,7 +87,7 @@ public class Builders {
     }
 
     public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder(
-            ListSchemaNode schema) {
+            final ListSchemaNode schema) {
         return ImmutableMapEntryNodeSchemaAwareBuilder.create(schema);
     }
 
@@ -67,7 +95,7 @@ public class Builders {
         return ImmutableMapNodeBuilder.create();
     }
 
-    public static CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder(ListSchemaNode schema) {
+    public static CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder(final ListSchemaNode schema) {
         return ImmutableMapNodeSchemaAwareBuilder.create(schema);
     }
 
@@ -75,7 +103,7 @@ public class Builders {
         return ImmutableAugmentationNodeBuilder.create();
     }
 
-    public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> augmentationBuilder(AugmentationSchema schema) {
+    public static DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> augmentationBuilder(final AugmentationSchema schema) {
         return ImmutableAugmentationNodeSchemaAwareBuilder.create(schema);
     }
 
@@ -83,7 +111,7 @@ public class Builders {
         return ImmutableChoiceNodeBuilder.create();
     }
 
-    public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> choiceBuilder(org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+    public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> choiceBuilder(final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
         return ImmutableChoiceNodeSchemaAwareBuilder.create(schema);
     }
 
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java
new file mode 100644 (file)
index 0000000..21e2792
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+
+public final class ImmutableNodes {
+
+    private ImmutableNodes() {
+        throw new UnsupportedOperationException("Utilities class should not be instantiated");
+    }
+
+    public static final CollectionNodeBuilder<MapEntryNode, MapNode> mapNodeBuilder() {
+        return ImmutableMapNodeBuilder.create();
+    }
+
+    public static final CollectionNodeBuilder<MapEntryNode, MapNode> mapNodeBuilder(final QName name) {
+        return ImmutableMapNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(name));
+    }
+
+    public static final <T> LeafNode<T> leafNode(final QName name,final T value) {
+        return ImmutableLeafNodeBuilder.<T>create()
+                .withNodeIdentifier(new NodeIdentifier(name))
+                .withValue(value)
+                .build();
+    }
+
+    public static DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder(final QName nodeName,final QName keyName,final Object keyValue) {
+        return ImmutableMapEntryNodeBuilder.create()
+                .withNodeIdentifier(new NodeIdentifierWithPredicates(nodeName, keyName,keyValue))
+                .withChild(leafNode(keyName, keyValue));
+    }
+
+    public static MapEntryNode mapEntry(final QName nodeName,final QName keyName,final Object keyValue) {
+        return mapEntryBuilder(nodeName, keyName, keyValue).build();
+    }
+
+    public static DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder() {
+        return ImmutableMapEntryNodeBuilder.create();
+    }
+
+    public static NormalizedNode<?, ?> containerNode(final QName name) {
+        return ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(name)).build();
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeUtils.java
new file mode 100644 (file)
index 0000000..2e9b90e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Iterator;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Optional;
+
+public final class NormalizedNodeUtils {
+    private NormalizedNodeUtils() {
+        throw new UnsupportedOperationException("Utilities class should not be instantiated");
+    }
+
+    public static Optional<NormalizedNode<?, ?>> findNode(final InstanceIdentifier rootPath, final NormalizedNode<?, ?> rootNode, final InstanceIdentifier childPath) {
+        if(rootPath.contains(childPath)) {
+            int common = rootPath.getPath().size();
+            InstanceIdentifier relativePath = new InstanceIdentifier(childPath.getPath().subList(common, childPath.getPath().size()));
+            return findNode(rootNode, relativePath);
+        }
+        return Optional.absent();
+    }
+
+    public static Optional<NormalizedNode<?, ?>> findNode(final NormalizedNode<?, ?> tree, final InstanceIdentifier path) {
+        checkNotNull(tree, "Tree must not be null");
+        checkNotNull(path, "Path must not be null");
+
+        Optional<NormalizedNode<?, ?>> currentNode = Optional.<NormalizedNode<?, ?>> of(tree);
+        Iterator<PathArgument> pathIterator = path.getPath().iterator();
+        while (currentNode.isPresent() && pathIterator.hasNext()) {
+            currentNode = getDirectChild(currentNode.get(), pathIterator.next());
+        }
+        return currentNode;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static Optional<NormalizedNode<?, ?>> getDirectChild(final NormalizedNode<?, ?> node, final PathArgument pathArg) {
+        if (node instanceof LeafNode<?> || node instanceof LeafSetEntryNode<?>) {
+            return Optional.absent();
+        } else if (node instanceof DataContainerNode<?>) {
+            return (Optional) ((DataContainerNode<?>) node).getChild(pathArg);
+        } else if (node instanceof MapNode && pathArg instanceof NodeIdentifierWithPredicates) {
+            return (Optional) ((MapNode) node).getChild((NodeIdentifierWithPredicates) pathArg);
+        } else if (node instanceof LeafSetNode<?>) {
+            return (Optional) ((LeafSetNode<?>) node).getChild((NodeWithValue) pathArg);
+        }
+        return Optional.absent();
+    }
+}
index 2dc68a9a828daafa18c473f3f6f4f749761ab044..fbe6bb350ff1f12a97e74575814c5c1a5e9ae267 100644 (file)
@@ -10,10 +10,12 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.api;
 import java.util.List;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-public interface CollectionNodeBuilder<V, R extends NormalizedNode<InstanceIdentifier.NodeIdentifier, ?>>
-        extends NormalizedNodeBuilder<InstanceIdentifier.NodeIdentifier, List<V>, R> {
+public interface CollectionNodeBuilder<V extends NormalizedNode<?, ?>, R extends NormalizedNode<InstanceIdentifier.NodeIdentifier, ?>>
+        extends NormalizedNodeContainerBuilder<NodeIdentifier,PathArgument, V, R> {
 
     //TODO might be list to keep ordering and map internal
     @Override
index 9c39b871d7e16a90622f5fcf80a96fcf12f8f036..9adf6c60f8cb5ef2c491cc6379836b08a8a97eb2 100644 (file)
@@ -8,14 +8,14 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.builder.api;
 
 import java.util.List;
-import java.util.Map;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 
 public interface DataContainerNodeBuilder<I extends InstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
-        extends NormalizedNodeBuilder<I, List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>, R> {
+        extends NormalizedNodeContainerBuilder<I, PathArgument, DataContainerChild<? extends PathArgument, ?>, R> {
 
     @Override
     DataContainerNodeBuilder<I, R> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value);
index 41aeae367a79f1242d5b2d7d543706e0b82a0d83..f11704a737cf7f82342e10bedad3dabaf9c2aca7 100644 (file)
@@ -10,19 +10,20 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.api;
 import java.util.List;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 
 public interface ListNodeBuilder<T, V>
-        extends CollectionNodeBuilder<V, LeafSetNode<T>> {
+        extends CollectionNodeBuilder<LeafSetEntryNode<T>, LeafSetNode<T>> {
 
     @Override
     ListNodeBuilder<T, V> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier);
 
     @Override
-    ListNodeBuilder<T, V> withValue(List<V> value);
+    ListNodeBuilder<T, V> withValue(List<LeafSetEntryNode<T>> value);
 
     @Override
-    ListNodeBuilder<T, V> withChild(V child);
+    ListNodeBuilder<T, V> withChild(LeafSetEntryNode<T> child);
 
     ListNodeBuilder<T, V> withChildValue(T child);
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/NormalizedNodeContainerBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/NormalizedNodeContainerBuilder.java
new file mode 100644 (file)
index 0000000..17d9ae8
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yangtools.yang.data.impl.schema.builder.api;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface NormalizedNodeContainerBuilder<K extends PathArgument,CK extends PathArgument,CV extends NormalizedNode<? extends CK, ?>,P extends NormalizedNode<K, ?>>
+extends NormalizedNodeBuilder<K,List<CV>,P>{
+
+    @Override
+    public NormalizedNodeContainerBuilder<K,CK,CV,P> withNodeIdentifier(K nodeIdentifier);
+
+    @Override
+    public NormalizedNodeContainerBuilder<K,CK,CV,P> withValue(List<CV> value);
+
+    public NormalizedNodeContainerBuilder<K,CK,CV,P> addChild(CV child);
+}
index 39032ad78e9408faf5b4cdd252b04d6f64d8d71a..af71a675c1c7e56674f2f1fad1e659ead8695a83 100644 (file)
@@ -11,6 +11,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
@@ -20,7 +21,7 @@ import com.google.common.collect.Maps;
 abstract class AbstractImmutableDataContainerNodeBuilder<I extends InstanceIdentifier.PathArgument, R extends DataContainerNode<I>>
         implements DataContainerNodeBuilder<I, R> {
 
-    protected Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value;
+    protected final Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value;
     protected I nodeIdentifier;
 
     protected AbstractImmutableDataContainerNodeBuilder() {
@@ -28,7 +29,7 @@ abstract class AbstractImmutableDataContainerNodeBuilder<I extends InstanceIdent
     }
 
     @Override
-    public DataContainerNodeBuilder<I, R> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
+    public DataContainerNodeBuilder<I, R> withValue(final List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
         // TODO Replace or putAll ?
         for (DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> dataContainerChild : value) {
             withChild(dataContainerChild);
@@ -37,15 +38,21 @@ abstract class AbstractImmutableDataContainerNodeBuilder<I extends InstanceIdent
     }
 
     @Override
-    public DataContainerNodeBuilder<I, R> withChild(DataContainerChild<?, ?> child) {
+    public DataContainerNodeBuilder<I, R> withChild(final DataContainerChild<?, ?> child) {
         this.value.put(child.getIdentifier(), child);
         return this;
     }
 
 
     @Override
-    public DataContainerNodeBuilder<I, R> withNodeIdentifier(I nodeIdentifier) {
+    public DataContainerNodeBuilder<I, R> withNodeIdentifier(final I nodeIdentifier) {
         this.nodeIdentifier = nodeIdentifier;
         return this;
     }
+
+    @Override
+    public DataContainerNodeBuilder<I, R> addChild(
+            final DataContainerChild<? extends PathArgument, ?> child) {
+        return withChild(child);
+    }
 }
index 481ddb09ff181a5fec4ea2271e24d846b066b526..3ead4a6edc9bc6eea300ea604a2d6dc77b814632 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContaine
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
 
 public class ImmutableAugmentationNodeBuilder
         extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> {
@@ -26,7 +27,7 @@ public class ImmutableAugmentationNodeBuilder
 
     @Override
     public DataContainerNodeBuilder<InstanceIdentifier.AugmentationIdentifier, AugmentationNode> withChild(
-            DataContainerChild<?, ?> child) {
+            final DataContainerChild<?, ?> child) {
         // Check nested augments
         Preconditions.checkArgument(child instanceof AugmentationNode == false,
                 "Unable to add: %s, as a child for: %s, Nested augmentations are not permitted", child.getNodeType(),
@@ -44,8 +45,8 @@ public class ImmutableAugmentationNodeBuilder
             extends AbstractImmutableDataContainerNode<InstanceIdentifier.AugmentationIdentifier>
             implements AugmentationNode {
 
-        ImmutableAugmentationNode(InstanceIdentifier.AugmentationIdentifier nodeIdentifier, Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
-            super(children, nodeIdentifier);
+        ImmutableAugmentationNode(final InstanceIdentifier.AugmentationIdentifier nodeIdentifier, final Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+            super(ImmutableMap.copyOf(children), nodeIdentifier);
         }
     }
 }
index 674ebbaddc048dca748799494db70744545f57fa..a5c2d031805e35014197b518f43b8b6817b57bc0 100644 (file)
@@ -15,12 +15,15 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
 
+import com.google.common.collect.ImmutableMap;
+
 public class ImmutableChoiceNodeBuilder extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> {
 
     public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ChoiceNode> create() {
         return new ImmutableChoiceNodeBuilder();
     }
 
+    @Override
     public ChoiceNode build() {
         return new ImmutableChoiceNode(nodeIdentifier, value);
     }
@@ -29,9 +32,9 @@ public class ImmutableChoiceNodeBuilder extends AbstractImmutableDataContainerNo
             extends AbstractImmutableDataContainerNode<InstanceIdentifier.NodeIdentifier>
             implements ChoiceNode {
 
-        ImmutableChoiceNode(InstanceIdentifier.NodeIdentifier nodeIdentifier,
-                            Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
-            super(children, nodeIdentifier);
+        ImmutableChoiceNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier,
+                            final Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+            super(ImmutableMap.copyOf(children), nodeIdentifier);
         }
 
     }
index c3cbf3477973d7ed78eb3ed13956104047867a1f..f657e81dd182512250a19f4101d967b8d24e7068 100644 (file)
@@ -15,6 +15,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
 
+import com.google.common.collect.ImmutableMap;
+
 public class ImmutableContainerNodeBuilder extends AbstractImmutableDataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> {
 
     public static DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> create() {
@@ -31,9 +33,9 @@ public class ImmutableContainerNodeBuilder extends AbstractImmutableDataContaine
             implements ContainerNode {
 
         ImmutableContainerNode(
-                InstanceIdentifier.NodeIdentifier nodeIdentifier,
-                Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
-            super(children, nodeIdentifier);
+                final InstanceIdentifier.NodeIdentifier nodeIdentifier,
+                final Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+            super(ImmutableMap.copyOf(children), nodeIdentifier);
         }
 
     }
index f352b984c7ab348693b5e083b89ac1c712106e7e..f3dd9d0c9b1fb73a004e60f5af19263b8aa53195 100644 (file)
@@ -10,31 +10,30 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 import java.util.List;
 import java.util.Map;
 
+import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
-public class ImmutableLeafSetNodeBuilder<T>
-        implements ListNodeBuilder<T, LeafSetEntryNode<T>> {
+public class ImmutableLeafSetNodeBuilder<T> implements ListNodeBuilder<T, LeafSetEntryNode<T>> {
 
-    protected Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> value;
+    protected Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> value = Maps.newLinkedHashMap();
     protected InstanceIdentifier.NodeIdentifier nodeIdentifier;
 
     public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create() {
         return new ImmutableLeafSetNodeBuilder<>();
     }
 
-    public ListNodeBuilder<T, LeafSetEntryNode<T>> withChild(LeafSetEntryNode<T> child) {
-        if(this.value == null) {
-            this.value = Maps.newLinkedHashMap();
-        }
-
+    @Override
+    public ListNodeBuilder<T, LeafSetEntryNode<T>> withChild(final LeafSetEntryNode<T> child) {
         this.value.put(child.getIdentifier(), child);
         return this;
     }
@@ -45,13 +44,14 @@ public class ImmutableLeafSetNodeBuilder<T>
     }
 
     @Override
-    public ListNodeBuilder<T, LeafSetEntryNode<T>> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+    public ListNodeBuilder<T, LeafSetEntryNode<T>> withNodeIdentifier(
+            final InstanceIdentifier.NodeIdentifier nodeIdentifier) {
         this.nodeIdentifier = nodeIdentifier;
         return this;
     }
 
     @Override
-    public ListNodeBuilder<T, LeafSetEntryNode<T>> withValue(List<LeafSetEntryNode<T>> value) {
+    public ListNodeBuilder<T, LeafSetEntryNode<T>> withValue(final List<LeafSetEntryNode<T>> value) {
         for (LeafSetEntryNode<T> leafSetEntry : value) {
             withChild(leafSetEntry);
         }
@@ -60,21 +60,25 @@ public class ImmutableLeafSetNodeBuilder<T>
     }
 
     @Override
-    public ListNodeBuilder<T, LeafSetEntryNode<T>> withChildValue(T value) {
-        return withChild(new ImmutableLeafSetEntryNodeBuilder.ImmutableLeafSetEntryNode<>(new InstanceIdentifier.NodeWithValue(nodeIdentifier.getNodeType(), value), value));
+    public ListNodeBuilder<T, LeafSetEntryNode<T>> withChildValue(final T value) {
+        return withChild(new ImmutableLeafSetEntryNodeBuilder.ImmutableLeafSetEntryNode<>(
+                new InstanceIdentifier.NodeWithValue(nodeIdentifier.getNodeType(), value), value));
     }
 
-    final class ImmutableLeafSetNode<T> extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<LeafSetEntryNode<T>>> implements LeafSetNode<T> {
+    private final static class ImmutableLeafSetNode<T> extends
+            AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<LeafSetEntryNode<T>>> implements
+            Immutable, LeafSetNode<T> {
 
         private final Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> mappedChildren;
 
-        ImmutableLeafSetNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> children) {
+        ImmutableLeafSetNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier,
+                final Map<InstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> children) {
             super(nodeIdentifier, children.values());
             this.mappedChildren = children;
         }
 
         @Override
-        public Optional<LeafSetEntryNode<T>> getChild(InstanceIdentifier.NodeWithValue child) {
+        public Optional<LeafSetEntryNode<T>> getChild(final InstanceIdentifier.NodeWithValue child) {
             return Optional.fromNullable(mappedChildren.get(child));
         }
 
@@ -88,4 +92,10 @@ public class ImmutableLeafSetNodeBuilder<T>
         }
     }
 
+    @Override
+    public NormalizedNodeContainerBuilder<NodeIdentifier, PathArgument, LeafSetEntryNode<T>, LeafSetNode<T>> addChild(
+            final LeafSetEntryNode<T> child) {
+        return withChild(child);
+    }
+
 }
index 90e36f736a11cb1b3c4e546b67a3aef1f4f4c522..896ff642d098f453e5b490571b513c743d656c6a 100644 (file)
@@ -15,10 +15,10 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 
 public class ImmutableMapEntryNodeBuilder
@@ -37,7 +37,7 @@ public class ImmutableMapEntryNodeBuilder
     // FIXME, find better solution than 2 maps (map from QName to Child ?)
 
     @Override
-    public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withValue(List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
+    public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withValue(final List<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> value) {
         for (DataContainerChild<? extends InstanceIdentifier.PathArgument, ?> childId : value) {
             this.childrenQNamesToPaths.put(childId.getNodeType(), childId.getIdentifier());
         }
@@ -45,11 +45,12 @@ public class ImmutableMapEntryNodeBuilder
     }
 
     @Override
-    public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withChild(DataContainerChild<?, ?> child) {
+    public DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> withChild(final DataContainerChild<?, ?> child) {
         childrenQNamesToPaths.put(child.getNodeType(), child.getIdentifier());
         return super.withChild(child);
     }
 
+    @Override
     public MapEntryNode build() {
         checkKeys();
         return new ImmutableMapEntryNode(nodeIdentifier, value);
@@ -72,9 +73,9 @@ public class ImmutableMapEntryNodeBuilder
 
     static final class ImmutableMapEntryNode extends AbstractImmutableDataContainerNode<InstanceIdentifier.NodeIdentifierWithPredicates> implements MapEntryNode {
 
-        ImmutableMapEntryNode(InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier,
-                              Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
-            super(children, nodeIdentifier);
+        ImmutableMapEntryNode(final InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier,
+                              final Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children) {
+            super(ImmutableMap.copyOf(children), nodeIdentifier);
         }
     }
 }
index 08380c76f0a5de0afea3d8406fd3261dd3eea441..b149abca017b9e8a065acd5f019157559c08c473 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 import java.util.List;
 import java.util.Map;
 
+import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
@@ -22,24 +23,21 @@ import com.google.common.collect.Maps;
 public class ImmutableMapNodeBuilder
         implements CollectionNodeBuilder<MapEntryNode, MapNode> {
 
-    protected Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
+    protected Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value = Maps.newLinkedHashMap();
     protected InstanceIdentifier.NodeIdentifier nodeIdentifier;
 
     public static CollectionNodeBuilder<MapEntryNode, MapNode> create() {
         return new ImmutableMapNodeBuilder();
     }
 
-    public CollectionNodeBuilder<MapEntryNode, MapNode> withChild(MapEntryNode child) {
-        if(this.value == null) {
-            this.value = Maps.newLinkedHashMap();
-        }
-
+    @Override
+    public CollectionNodeBuilder<MapEntryNode, MapNode> withChild(final MapEntryNode child) {
         this.value.put(child.getIdentifier(), child);
         return this;
     }
 
     @Override
-    public CollectionNodeBuilder<MapEntryNode, MapNode> withValue(List<MapEntryNode> value) {
+    public CollectionNodeBuilder<MapEntryNode, MapNode> withValue(final List<MapEntryNode> value) {
         // TODO replace or putAll ?
         for (MapEntryNode mapEntryNode : value) {
             withChild(mapEntryNode);
@@ -48,7 +46,8 @@ public class ImmutableMapNodeBuilder
         return this;
     }
 
-    public CollectionNodeBuilder<MapEntryNode, MapNode> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) {
+    @Override
+    public CollectionNodeBuilder<MapEntryNode, MapNode> withNodeIdentifier(final InstanceIdentifier.NodeIdentifier nodeIdentifier) {
         this.nodeIdentifier = nodeIdentifier;
         return this;
     }
@@ -58,18 +57,24 @@ public class ImmutableMapNodeBuilder
         return new ImmutableMapNode(nodeIdentifier, value);
     }
 
-    static final class ImmutableMapNode extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<MapEntryNode>> implements MapNode {
+    @Override
+    public CollectionNodeBuilder<MapEntryNode, MapNode> addChild(
+            final MapEntryNode child) {
+        return withChild(child);
+    }
+
+    static final class ImmutableMapNode extends AbstractImmutableNormalizedNode<InstanceIdentifier.NodeIdentifier, Iterable<MapEntryNode>> implements Immutable,MapNode {
 
         private final Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mappedChildren;
 
-        ImmutableMapNode(InstanceIdentifier.NodeIdentifier nodeIdentifier,
-                         Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> children) {
+        ImmutableMapNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier,
+                         final Map<InstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> children) {
             super(nodeIdentifier, children.values());
             this.mappedChildren = children;
         }
 
         @Override
-        public Optional<MapEntryNode> getChild(InstanceIdentifier.NodeIdentifierWithPredicates child) {
+        public Optional<MapEntryNode> getChild(final InstanceIdentifier.NodeIdentifierWithPredicates child) {
             return Optional.fromNullable(mappedChildren.get(child));
         }
 
index 7954d56344bc1b729e9bad31c82b2e089c84a550..f914484831b120066529ed6696c8a58e5f099081 100644 (file)
@@ -9,26 +9,28 @@ package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
 
 import java.util.Map;
 
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 
 import com.google.common.base.Optional;
 
-public abstract class AbstractImmutableDataContainerNode<K extends InstanceIdentifier.PathArgument>
-        extends AbstractImmutableNormalizedNode<K, Iterable<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>>
-        implements DataContainerNode<K> {
+public abstract class AbstractImmutableDataContainerNode<K extends PathArgument> //
+        extends AbstractImmutableNormalizedNode<K, Iterable<DataContainerChild<? extends PathArgument, ?>>> //
+        implements Immutable, DataContainerNode<K> {
 
-    protected Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children;
+    protected final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children;
 
-    public AbstractImmutableDataContainerNode(Map<InstanceIdentifier.PathArgument, DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> children, K nodeIdentifier) {
+    public AbstractImmutableDataContainerNode(
+            final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children, final K nodeIdentifier) {
         super(nodeIdentifier, children.values());
         this.children = children;
     }
 
     @Override
-    public Optional<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>> getChild(InstanceIdentifier.PathArgument child) {
-        return Optional.<DataContainerChild<? extends InstanceIdentifier.PathArgument, ?>>fromNullable(children.get(child));
+    public final Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
+        return Optional.<DataContainerChild<? extends PathArgument, ?>> fromNullable(children.get(child));
     }
 
     @Override
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/test/NormalizedNodeUtilsTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/test/NormalizedNodeUtilsTest.java
new file mode 100644 (file)
index 0000000..36d6067
--- /dev/null
@@ -0,0 +1,119 @@
+package org.opendaylight.yangtools.yang.data.impl.schema.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+
+import com.google.common.base.Optional;
+
+/**
+ *
+ * Schema structure of document is
+ *
+ * <pre>
+ * container root { 
+ *      list list-a {
+ *              key leaf-a;
+ *              leaf leaf-a;
+ *              choice choice-a {
+ *                      case one {
+ *                              leaf one;
+ *                      }
+ *                      case two-three {
+ *                              leaf two;
+ *                              leaf three;
+ *                      }
+ *              }
+ *              list list-b {
+ *                      key leaf-b;
+ *                      leaf leaf-b;
+ *              }
+ *      }
+ * }
+ * </pre>
+ *
+ */
+public class NormalizedNodeUtilsTest {
+
+    private static final QName ROOT_QNAME = QName.create("urn:opendalight:controller:sal:dom:store:test", "2014-03-13",
+            "root");
+    private static final QName LIST_A_QNAME = QName.create(ROOT_QNAME, "list-a");
+    private static final QName LIST_B_QNAME = QName.create(ROOT_QNAME, "list-b");
+    private static final QName CHOICE_A_QNAME = QName.create(ROOT_QNAME, "choice-a");
+    private static final QName LEAF_A_QNAME = QName.create(ROOT_QNAME, "leaf-a");
+    private static final QName LEAF_B_QNAME = QName.create(ROOT_QNAME, "leaf-b");
+    private static final String FOO = "foo";
+    private static final String BAR = "bar";
+    private static final String ONE = "one";
+    private static final String TWO = "two";
+
+    private static final InstanceIdentifier LIST_A_FOO_PATH = InstanceIdentifier.builder()
+                //.node(ROOT_QNAME)
+                .node(LIST_A_QNAME)
+                .nodeWithKey(LIST_A_QNAME, LEAF_A_QNAME, FOO)
+                .build();
+    private static final InstanceIdentifier LIST_B_TWO_PATH = InstanceIdentifier.builder()
+                //.node(ROOT_QNAME)
+                .node(LIST_A_QNAME)
+                .nodeWithKey(LIST_A_QNAME, LEAF_A_QNAME, BAR)
+                .node(LIST_B_QNAME)
+                .nodeWithKey(LIST_B_QNAME,LEAF_B_QNAME,TWO)
+                .build();
+
+    /**
+     * Returns a test document
+     *
+     * <pre>
+     * root
+     *     list-a
+     *          leaf-a "foo"
+     *     list-a
+     *          leaf-a "bar"
+     *          list-b
+     *                  leaf-b "one"
+     *          list-b
+     *                  leaf-b "two"
+     *
+     * </pre>
+     *
+     * @return
+     */
+    public NormalizedNode<?, ?> createDocumentOne() {
+        return ImmutableContainerNodeBuilder
+                .create()
+                .withNodeIdentifier(new NodeIdentifier(ROOT_QNAME))
+                .withChild(
+                        mapNodeBuilder(LIST_A_QNAME)
+                                .withChild(mapEntry(LIST_A_QNAME, LEAF_A_QNAME, FOO))
+                                .withChild(
+                                        mapEntryBuilder(LIST_A_QNAME, LEAF_A_QNAME, BAR).withChild(
+                                                mapNodeBuilder(LIST_B_QNAME)
+                                                        .withChild(mapEntry(LIST_B_QNAME, LEAF_B_QNAME, ONE))
+                                                        .withChild(mapEntry(LIST_B_QNAME, LEAF_B_QNAME, TWO)).build())
+                                                .build()).build()).build();
+
+    }
+
+    @Test
+    public void findNodeTest() {
+        NormalizedNode<?, ?> tree = createDocumentOne();
+        assertNotNull(tree);
+
+        Optional<NormalizedNode<?, ?>> listFooResult = NormalizedNodeUtils.findNode(tree, LIST_A_FOO_PATH);
+        assertTrue(listFooResult.isPresent());
+
+        Optional<NormalizedNode<?, ?>> listTwoResult = NormalizedNodeUtils.findNode(tree, LIST_B_TWO_PATH);
+        assertTrue(listTwoResult.isPresent());
+    }
+
+}