From 62b1e511c8e7a219134e74c3bad8e4ab83e93512 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Tue, 18 Mar 2014 18:06:26 +0100 Subject: [PATCH] Added NormalizedNodeContainerBuilder and helpers. - 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 --- .../yang/data/impl/schema/Builders.java | 58 ++++++--- .../yang/data/impl/schema/ImmutableNodes.java | 63 ++++++++++ .../data/impl/schema/NormalizedNodeUtils.java | 66 ++++++++++ .../builder/api/CollectionNodeBuilder.java | 6 +- .../builder/api/DataContainerNodeBuilder.java | 4 +- .../schema/builder/api/ListNodeBuilder.java | 7 +- .../api/NormalizedNodeContainerBuilder.java | 18 +++ ...ractImmutableDataContainerNodeBuilder.java | 15 ++- .../ImmutableAugmentationNodeBuilder.java | 7 +- .../impl/ImmutableChoiceNodeBuilder.java | 9 +- .../impl/ImmutableContainerNodeBuilder.java | 8 +- .../impl/ImmutableLeafSetNodeBuilder.java | 42 ++++--- .../impl/ImmutableMapEntryNodeBuilder.java | 13 +- .../builder/impl/ImmutableMapNodeBuilder.java | 29 +++-- .../AbstractImmutableDataContainerNode.java | 18 +-- .../schema/test/NormalizedNodeUtilsTest.java | 119 ++++++++++++++++++ 16 files changed, 405 insertions(+), 77 deletions(-) create mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java create mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeUtils.java create mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/NormalizedNodeContainerBuilder.java create mode 100644 yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/test/NormalizedNodeUtilsTest.java diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/Builders.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/Builders.java index 0982382363..6c4b6a1f00 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/Builders.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/Builders.java @@ -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 NormalizedNodeBuilder> leafBuilder() { return ImmutableLeafNodeBuilder.create(); } public static NormalizedNodeBuilder> leafBuilder( - LeafSchemaNode schema) { + final LeafSchemaNode schema) { return ImmutableLeafNodeSchemaAwareBuilder.create(schema); } @@ -33,16 +61,16 @@ public class Builders { } public static NormalizedNodeBuilder> leafSetEntryBuilder( - LeafListSchemaNode schema) { + final LeafListSchemaNode schema) { return ImmutableLeafSetEntryNodeSchemaAwareBuilder.create(schema); } - public static ListNodeBuilder> leafSetBuilder() { + public static ListNodeBuilder> leafSetBuilder() { return ImmutableLeafSetNodeBuilder.create(); } - public static ListNodeBuilder> leafSetBuilder(LeafListSchemaNode schema) { - return ImmutableLeafSetNodeSchemaAwareBuilder.create(schema); + public static ListNodeBuilder> leafSetBuilder(final LeafListSchemaNode schema) { + return ImmutableLeafSetNodeSchemaAwareBuilder.create(schema); } public static DataContainerNodeBuilder containerBuilder() { @@ -50,7 +78,7 @@ public class Builders { } public static DataContainerNodeBuilder containerBuilder( - ContainerSchemaNode schema) { + final ContainerSchemaNode schema) { return ImmutableContainerNodeSchemaAwareBuilder.create(schema); } @@ -59,7 +87,7 @@ public class Builders { } public static DataContainerNodeBuilder mapEntryBuilder( - ListSchemaNode schema) { + final ListSchemaNode schema) { return ImmutableMapEntryNodeSchemaAwareBuilder.create(schema); } @@ -67,7 +95,7 @@ public class Builders { return ImmutableMapNodeBuilder.create(); } - public static CollectionNodeBuilder mapBuilder(ListSchemaNode schema) { + public static CollectionNodeBuilder mapBuilder(final ListSchemaNode schema) { return ImmutableMapNodeSchemaAwareBuilder.create(schema); } @@ -75,7 +103,7 @@ public class Builders { return ImmutableAugmentationNodeBuilder.create(); } - public static DataContainerNodeBuilder augmentationBuilder(AugmentationSchema schema) { + public static DataContainerNodeBuilder augmentationBuilder(final AugmentationSchema schema) { return ImmutableAugmentationNodeSchemaAwareBuilder.create(schema); } @@ -83,7 +111,7 @@ public class Builders { return ImmutableChoiceNodeBuilder.create(); } - public static DataContainerNodeBuilder choiceBuilder(org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) { + public static DataContainerNodeBuilder 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 index 0000000000..21e2792dde --- /dev/null +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java @@ -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 mapNodeBuilder() { + return ImmutableMapNodeBuilder.create(); + } + + public static final CollectionNodeBuilder mapNodeBuilder(final QName name) { + return ImmutableMapNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(name)); + } + + public static final LeafNode leafNode(final QName name,final T value) { + return ImmutableLeafNodeBuilder.create() + .withNodeIdentifier(new NodeIdentifier(name)) + .withValue(value) + .build(); + } + + public static DataContainerNodeBuilder 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 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 index 0000000000..2e9b90e066 --- /dev/null +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeUtils.java @@ -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> 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> findNode(final NormalizedNode tree, final InstanceIdentifier path) { + checkNotNull(tree, "Tree must not be null"); + checkNotNull(path, "Path must not be null"); + + Optional> currentNode = Optional.> of(tree); + Iterator pathIterator = path.getPath().iterator(); + while (currentNode.isPresent() && pathIterator.hasNext()) { + currentNode = getDirectChild(currentNode.get(), pathIterator.next()); + } + return currentNode; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Optional> 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(); + } +} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/CollectionNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/CollectionNodeBuilder.java index 2dc68a9a82..fbe6bb350f 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/CollectionNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/CollectionNodeBuilder.java @@ -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> - extends NormalizedNodeBuilder, R> { +public interface CollectionNodeBuilder, R extends NormalizedNode> + extends NormalizedNodeContainerBuilder { //TODO might be list to keep ordering and map internal @Override diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/DataContainerNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/DataContainerNodeBuilder.java index 9c39b871d7..9adf6c60f8 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/DataContainerNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/DataContainerNodeBuilder.java @@ -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> - extends NormalizedNodeBuilder>, R> { + extends NormalizedNodeContainerBuilder, R> { @Override DataContainerNodeBuilder withValue(List> value); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/ListNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/ListNodeBuilder.java index 41aeae367a..f11704a737 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/ListNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/ListNodeBuilder.java @@ -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 - extends CollectionNodeBuilder> { + extends CollectionNodeBuilder, LeafSetNode> { @Override ListNodeBuilder withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier); @Override - ListNodeBuilder withValue(List value); + ListNodeBuilder withValue(List> value); @Override - ListNodeBuilder withChild(V child); + ListNodeBuilder withChild(LeafSetEntryNode child); ListNodeBuilder 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 index 0000000000..17d9ae8c52 --- /dev/null +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/api/NormalizedNodeContainerBuilder.java @@ -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,P extends NormalizedNode> +extends NormalizedNodeBuilder,P>{ + + @Override + public NormalizedNodeContainerBuilder withNodeIdentifier(K nodeIdentifier); + + @Override + public NormalizedNodeContainerBuilder withValue(List value); + + public NormalizedNodeContainerBuilder addChild(CV child); +} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java index 39032ad78e..af71a675c1 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java @@ -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> implements DataContainerNodeBuilder { - protected Map> value; + protected final Map> value; protected I nodeIdentifier; protected AbstractImmutableDataContainerNodeBuilder() { @@ -28,7 +29,7 @@ abstract class AbstractImmutableDataContainerNodeBuilder withValue(List> value) { + public DataContainerNodeBuilder withValue(final List> value) { // TODO Replace or putAll ? for (DataContainerChild dataContainerChild : value) { withChild(dataContainerChild); @@ -37,15 +38,21 @@ abstract class AbstractImmutableDataContainerNodeBuilder withChild(DataContainerChild child) { + public DataContainerNodeBuilder withChild(final DataContainerChild child) { this.value.put(child.getIdentifier(), child); return this; } @Override - public DataContainerNodeBuilder withNodeIdentifier(I nodeIdentifier) { + public DataContainerNodeBuilder withNodeIdentifier(final I nodeIdentifier) { this.nodeIdentifier = nodeIdentifier; return this; } + + @Override + public DataContainerNodeBuilder addChild( + final DataContainerChild child) { + return withChild(child); + } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableAugmentationNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableAugmentationNodeBuilder.java index 481ddb09ff..3ead4a6edc 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableAugmentationNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableAugmentationNodeBuilder.java @@ -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 { @@ -26,7 +27,7 @@ public class ImmutableAugmentationNodeBuilder @Override public DataContainerNodeBuilder 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 implements AugmentationNode { - ImmutableAugmentationNode(InstanceIdentifier.AugmentationIdentifier nodeIdentifier, Map> children) { - super(children, nodeIdentifier); + ImmutableAugmentationNode(final InstanceIdentifier.AugmentationIdentifier nodeIdentifier, final Map> children) { + super(ImmutableMap.copyOf(children), nodeIdentifier); } } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableChoiceNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableChoiceNodeBuilder.java index 674ebbaddc..a5c2d03180 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableChoiceNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableChoiceNodeBuilder.java @@ -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 { public static DataContainerNodeBuilder create() { return new ImmutableChoiceNodeBuilder(); } + @Override public ChoiceNode build() { return new ImmutableChoiceNode(nodeIdentifier, value); } @@ -29,9 +32,9 @@ public class ImmutableChoiceNodeBuilder extends AbstractImmutableDataContainerNo extends AbstractImmutableDataContainerNode implements ChoiceNode { - ImmutableChoiceNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, - Map> children) { - super(children, nodeIdentifier); + ImmutableChoiceNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier, + final Map> children) { + super(ImmutableMap.copyOf(children), nodeIdentifier); } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableContainerNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableContainerNodeBuilder.java index c3cbf34779..f657e81dd1 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableContainerNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableContainerNodeBuilder.java @@ -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 { public static DataContainerNodeBuilder create() { @@ -31,9 +33,9 @@ public class ImmutableContainerNodeBuilder extends AbstractImmutableDataContaine implements ContainerNode { ImmutableContainerNode( - InstanceIdentifier.NodeIdentifier nodeIdentifier, - Map> children) { - super(children, nodeIdentifier); + final InstanceIdentifier.NodeIdentifier nodeIdentifier, + final Map> children) { + super(ImmutableMap.copyOf(children), nodeIdentifier); } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java index f352b984c7..f3dd9d0c9b 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java @@ -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 - implements ListNodeBuilder> { +public class ImmutableLeafSetNodeBuilder implements ListNodeBuilder> { - protected Map> value; + protected Map> value = Maps.newLinkedHashMap(); protected InstanceIdentifier.NodeIdentifier nodeIdentifier; public static ListNodeBuilder> create() { return new ImmutableLeafSetNodeBuilder<>(); } - public ListNodeBuilder> withChild(LeafSetEntryNode child) { - if(this.value == null) { - this.value = Maps.newLinkedHashMap(); - } - + @Override + public ListNodeBuilder> withChild(final LeafSetEntryNode child) { this.value.put(child.getIdentifier(), child); return this; } @@ -45,13 +44,14 @@ public class ImmutableLeafSetNodeBuilder } @Override - public ListNodeBuilder> withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) { + public ListNodeBuilder> withNodeIdentifier( + final InstanceIdentifier.NodeIdentifier nodeIdentifier) { this.nodeIdentifier = nodeIdentifier; return this; } @Override - public ListNodeBuilder> withValue(List> value) { + public ListNodeBuilder> withValue(final List> value) { for (LeafSetEntryNode leafSetEntry : value) { withChild(leafSetEntry); } @@ -60,21 +60,25 @@ public class ImmutableLeafSetNodeBuilder } @Override - public ListNodeBuilder> withChildValue(T value) { - return withChild(new ImmutableLeafSetEntryNodeBuilder.ImmutableLeafSetEntryNode<>(new InstanceIdentifier.NodeWithValue(nodeIdentifier.getNodeType(), value), value)); + public ListNodeBuilder> withChildValue(final T value) { + return withChild(new ImmutableLeafSetEntryNodeBuilder.ImmutableLeafSetEntryNode<>( + new InstanceIdentifier.NodeWithValue(nodeIdentifier.getNodeType(), value), value)); } - final class ImmutableLeafSetNode extends AbstractImmutableNormalizedNode>> implements LeafSetNode { + private final static class ImmutableLeafSetNode extends + AbstractImmutableNormalizedNode>> implements + Immutable, LeafSetNode { private final Map> mappedChildren; - ImmutableLeafSetNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, Map> children) { + ImmutableLeafSetNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier, + final Map> children) { super(nodeIdentifier, children.values()); this.mappedChildren = children; } @Override - public Optional> getChild(InstanceIdentifier.NodeWithValue child) { + public Optional> getChild(final InstanceIdentifier.NodeWithValue child) { return Optional.fromNullable(mappedChildren.get(child)); } @@ -88,4 +92,10 @@ public class ImmutableLeafSetNodeBuilder } } + @Override + public NormalizedNodeContainerBuilder, LeafSetNode> addChild( + final LeafSetEntryNode child) { + return withChild(child); + } + } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java index 90e36f736a..896ff642d0 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java @@ -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 withValue(List> value) { + public DataContainerNodeBuilder withValue(final List> value) { for (DataContainerChild childId : value) { this.childrenQNamesToPaths.put(childId.getNodeType(), childId.getIdentifier()); } @@ -45,11 +45,12 @@ public class ImmutableMapEntryNodeBuilder } @Override - public DataContainerNodeBuilder withChild(DataContainerChild child) { + public DataContainerNodeBuilder 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 implements MapEntryNode { - ImmutableMapEntryNode(InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier, - Map> children) { - super(children, nodeIdentifier); + ImmutableMapEntryNode(final InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier, + final Map> children) { + super(ImmutableMap.copyOf(children), nodeIdentifier); } } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java index 08380c76f0..b149abca01 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java @@ -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 { - protected Map value; + protected Map value = Maps.newLinkedHashMap(); protected InstanceIdentifier.NodeIdentifier nodeIdentifier; public static CollectionNodeBuilder create() { return new ImmutableMapNodeBuilder(); } - public CollectionNodeBuilder withChild(MapEntryNode child) { - if(this.value == null) { - this.value = Maps.newLinkedHashMap(); - } - + @Override + public CollectionNodeBuilder withChild(final MapEntryNode child) { this.value.put(child.getIdentifier(), child); return this; } @Override - public CollectionNodeBuilder withValue(List value) { + public CollectionNodeBuilder withValue(final List value) { // TODO replace or putAll ? for (MapEntryNode mapEntryNode : value) { withChild(mapEntryNode); @@ -48,7 +46,8 @@ public class ImmutableMapNodeBuilder return this; } - public CollectionNodeBuilder withNodeIdentifier(InstanceIdentifier.NodeIdentifier nodeIdentifier) { + @Override + public CollectionNodeBuilder 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> implements MapNode { + @Override + public CollectionNodeBuilder addChild( + final MapEntryNode child) { + return withChild(child); + } + + static final class ImmutableMapNode extends AbstractImmutableNormalizedNode> implements Immutable,MapNode { private final Map mappedChildren; - ImmutableMapNode(InstanceIdentifier.NodeIdentifier nodeIdentifier, - Map children) { + ImmutableMapNode(final InstanceIdentifier.NodeIdentifier nodeIdentifier, + final Map children) { super(nodeIdentifier, children.values()); this.mappedChildren = children; } @Override - public Optional getChild(InstanceIdentifier.NodeIdentifierWithPredicates child) { + public Optional getChild(final InstanceIdentifier.NodeIdentifierWithPredicates child) { return Optional.fromNullable(mappedChildren.get(child)); } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java index 7954d56344..f914484831 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java @@ -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 - extends AbstractImmutableNormalizedNode>> - implements DataContainerNode { +public abstract class AbstractImmutableDataContainerNode // + extends AbstractImmutableNormalizedNode>> // + implements Immutable, DataContainerNode { - protected Map> children; + protected final Map> children; - public AbstractImmutableDataContainerNode(Map> children, K nodeIdentifier) { + public AbstractImmutableDataContainerNode( + final Map> children, final K nodeIdentifier) { super(nodeIdentifier, children.values()); this.children = children; } @Override - public Optional> getChild(InstanceIdentifier.PathArgument child) { - return Optional.>fromNullable(children.get(child)); + public final Optional> getChild(final PathArgument child) { + return Optional.> 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 index 0000000000..36d6067cf1 --- /dev/null +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/test/NormalizedNodeUtilsTest.java @@ -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 + * + *
+ * 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;
+ *              }
+ *      }
+ * }
+ * 
+ * + */ +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 + * + *
+     * root
+     *     list-a
+     *          leaf-a "foo"
+     *     list-a
+     *          leaf-a "bar"
+     *          list-b
+     *                  leaf-b "one"
+     *          list-b
+     *                  leaf-b "two"
+     *
+     * 
+ * + * @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> listFooResult = NormalizedNodeUtils.findNode(tree, LIST_A_FOO_PATH); + assertTrue(listFooResult.isPresent()); + + Optional> listTwoResult = NormalizedNodeUtils.findNode(tree, LIST_B_TWO_PATH); + assertTrue(listTwoResult.isPresent()); + } + +} -- 2.36.6