Add Abstract{LeafSet,Map}ModificationStrategy 42/80042/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Jan 2019 13:54:51 +0000 (14:54 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Jan 2019 17:43:31 +0000 (18:43 +0100)
This allows us to remove some code duplication in constructor,
but notably share the implementation of getChild().

Furthermore it allows us to make the rooted-at-MapEntry hack work
consistently for ordered map nodes too.

JIRA: YANGTOOLS-946
Change-Id: Id91529c31341afd46a693f24eb1ac4ea0dc4800d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 73740a4c50094c722152883bd333e82961c4dd4c)

yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractLeafSetModificationStrategy.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractMapModificationStrategy.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedLeafSetModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedMapModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedLeafSetModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedMapModificationStrategy.java

diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractLeafSetModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractLeafSetModificationStrategy.java
new file mode 100644 (file)
index 0000000..5f27050
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.tree;
+
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+abstract class AbstractLeafSetModificationStrategy extends AbstractNodeContainerModificationStrategy {
+    private final Optional<ModificationApplyOperation> entryStrategy;
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    AbstractLeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
+        super((Class) LeafSetNode.class, treeConfig);
+        entryStrategy = Optional.of(new LeafSetEntryModificationStrategy(schema));
+    }
+
+    @Override
+    public final Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+        return identifier instanceof NodeWithValue ? entryStrategy : Optional.empty();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractMapModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractMapModificationStrategy.java
new file mode 100644 (file)
index 0000000..b764890
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019 Pantheon Technologies, s.r.o. 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.tree;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.MoreObjects;
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+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.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+// FIXME: createBuilder(), createEmptyValue() and getChild() here are hacks, originally introduced in
+//        Change-Id: I9dc02a1917f38e8a0d62279843974b9869c48693. DataTreeRoot needs to be fixed up to properly
+//        handle the lookup of through maps.
+abstract class AbstractMapModificationStrategy extends AbstractNodeContainerModificationStrategy {
+    final Optional<ModificationApplyOperation> entryStrategy;
+
+    AbstractMapModificationStrategy(final Class<? extends MapNode> nodeClass, final ListSchemaNode schema,
+            final DataTreeConfiguration treeConfig) {
+        super(nodeClass, treeConfig);
+        entryStrategy = Optional.of(new ListEntryModificationStrategy(schema, treeConfig));
+    }
+
+    @Override
+    @SuppressWarnings("rawtypes")
+    protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+        return ImmutableMapEntryNodeBuilder.create(checkCast(original));
+    }
+
+    @Override
+    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
+        return ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(checkCast(original).getIdentifier()).build();
+    }
+
+    @Override
+    public final Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
+        if (identifier instanceof NodeIdentifierWithPredicates) {
+            return entryStrategy;
+        }
+        // In case we already are in a MapEntry node(for example DataTree rooted at MapEntry)
+        // try to retrieve the child that the identifier should be pointing to from our entryStrategy
+        // if we have one. If the entryStrategy cannot find this child we just return the absent
+        // we get from it.
+        return entryStrategy.get().getChild(identifier);
+    }
+
+    @Override
+    public final String toString() {
+        return MoreObjects.toStringHelper(this).add("entry", entryStrategy.get()).toString();
+    }
+
+    private static MapEntryNode checkCast(final NormalizedNode<?, ?> original) {
+        checkArgument(original instanceof MapEntryNode,
+            "MapModification strategy can only handle MapNode or MapEntryNodes, offending node: %s", original);
+        return (MapEntryNode) original;
+    }
+}
index 637b8446dabacd80974bc026a2dc6eb4cc5e65ca..992800755f10d24e33c266d8773b8c12c702ea6d 100644 (file)
@@ -9,10 +9,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
@@ -20,13 +16,9 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
-final class OrderedLeafSetModificationStrategy extends AbstractNodeContainerModificationStrategy {
-    private final Optional<ModificationApplyOperation> entryStrategy;
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+final class OrderedLeafSetModificationStrategy extends AbstractLeafSetModificationStrategy {
     OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super((Class) LeafSetNode.class, treeConfig);
-        entryStrategy = Optional.of(new LeafSetEntryModificationStrategy(schema));
+        super(schema, treeConfig);
     }
 
     @Override
@@ -47,9 +39,4 @@ final class OrderedLeafSetModificationStrategy extends AbstractNodeContainerModi
         return ImmutableOrderedLeafSetNodeBuilder.create()
                 .withNodeIdentifier(((OrderedLeafSetNode<?>) original).getIdentifier()).build();
     }
-
-    @Override
-    public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-        return identifier instanceof NodeWithValue ? entryStrategy : Optional.empty();
-    }
 }
\ No newline at end of file
index 67b3ce6fe5e08ab17328d9aee31bd411add44b24..7e9a6a484a98bd059ab78dc3b2d208c93a82e37a 100644 (file)
@@ -5,14 +5,8 @@
  * 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.tree;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
@@ -20,12 +14,9 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-final class OrderedMapModificationStrategy extends AbstractNodeContainerModificationStrategy {
-    private final Optional<ModificationApplyOperation> entryStrategy;
-
+final class OrderedMapModificationStrategy extends AbstractMapModificationStrategy {
     OrderedMapModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(OrderedMapNode.class, treeConfig);
-        entryStrategy = Optional.of(new ListEntryModificationStrategy(schema, treeConfig));
+        super(OrderedMapNode.class, schema, treeConfig);
     }
 
     @Override
@@ -36,24 +27,14 @@ final class OrderedMapModificationStrategy extends AbstractNodeContainerModifica
     @SuppressWarnings("rawtypes")
     @Override
     protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof OrderedMapNode);
-        return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original);
+        return original instanceof OrderedMapNode ? ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original)
+                : super.createBuilder(original);
     }
 
     @Override
     protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof OrderedMapNode);
-        return ImmutableOrderedMapNodeBuilder.create().withNodeIdentifier(((OrderedMapNode) original).getIdentifier())
-                .build();
-    }
-
-    @Override
-    public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-        return identifier instanceof NodeIdentifierWithPredicates ? entryStrategy : Optional.empty();
-    }
-
-    @Override
-    public String toString() {
-        return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]";
+        return original instanceof OrderedMapNode ? ImmutableOrderedMapNodeBuilder.create()
+                .withNodeIdentifier(((OrderedMapNode) original).getIdentifier()).build()
+                : super.createEmptyValue(original);
     }
-}
\ No newline at end of file
+}
index 6d4ce30cce6ce85e90fa5a3cd4b2a7ff6f235b89..76286240ce12ffed7f61608af272ce97d77dd2ac 100644 (file)
@@ -9,9 +9,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
@@ -19,13 +16,9 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
-final class UnorderedLeafSetModificationStrategy extends AbstractNodeContainerModificationStrategy {
-    private final Optional<ModificationApplyOperation> entryStrategy;
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+final class UnorderedLeafSetModificationStrategy extends AbstractLeafSetModificationStrategy {
     UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super((Class) LeafSetNode.class, treeConfig);
-        entryStrategy = Optional.of(new LeafSetEntryModificationStrategy(schema));
+        super(schema, treeConfig);
     }
 
     @SuppressWarnings("rawtypes")
@@ -41,9 +34,4 @@ final class UnorderedLeafSetModificationStrategy extends AbstractNodeContainerMo
         return ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(((LeafSetNode<?>) original).getIdentifier())
                 .build();
     }
-
-    @Override
-    public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-        return identifier instanceof NodeWithValue ? entryStrategy : Optional.empty();
-    }
 }
\ No newline at end of file
index 0a4ce5a12040ac9a4d4dc606185d9889e7ecae13..48ec895f124109910bc483ba1ac4250b9537b0ad 100644 (file)
@@ -5,70 +5,30 @@
  * 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.tree;
 
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-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.api.schema.tree.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-final class UnorderedMapModificationStrategy extends AbstractNodeContainerModificationStrategy {
-    private final Optional<ModificationApplyOperation> entryStrategy;
-
+final class UnorderedMapModificationStrategy extends AbstractMapModificationStrategy {
     UnorderedMapModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(MapNode.class, treeConfig);
-        entryStrategy = Optional.of(new ListEntryModificationStrategy(schema, treeConfig));
+        super(MapNode.class, schema, treeConfig);
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
+    @SuppressWarnings("rawtypes")
     protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        // If the DataTree is rooted at a MapEntryNode the original value will be MapEntryNode
-        // so make sure we can handle this aswell
-        if (original instanceof MapNode) {
-            return ImmutableMapNodeBuilder.create((MapNode) original);
-        } else if (original instanceof MapEntryNode) {
-            return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
-        }
-        throw new IllegalArgumentException("MapModification strategy can only handle MapNode or MapEntryNode's, "
-                + "offending node: " + original);
+        return original instanceof MapNode ? ImmutableMapNodeBuilder.create((MapNode) original)
+                : super.createBuilder(original);
     }
 
     @Override
     protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        if (original instanceof MapNode) {
-            return ImmutableMapNodeBuilder.create().withNodeIdentifier(((MapNode) original).getIdentifier()).build();
-        } else if (original instanceof MapEntryNode) {
-            return ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(
-                ((MapEntryNode) original).getIdentifier()).build();
-        }
-        throw new IllegalArgumentException("MapModification strategy can only handle MapNode or MapEntryNode's, "
-                + "offending node: " + original);
-    }
-
-    @Override
-    public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
-        if (identifier instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
-            return entryStrategy;
-        } else if (entryStrategy.isPresent()) {
-            // In case we already are in a MapEntry node(for example DataTree rooted at MapEntry)
-            // try to retrieve the child that the identifier should be pointing to from our entryStrategy
-            // if we have one. If the entryStrategy cannot find this child we just return the absent
-            // we get from it.
-            return entryStrategy.get().getChild(identifier);
-        }
-        return Optional.empty();
-    }
-
-    @Override
-    public String toString() {
-        return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]";
+        return original instanceof MapNode ? ImmutableMapNodeBuilder.create()
+                .withNodeIdentifier(((MapNode) original).getIdentifier()).build() : super.createEmptyValue(original);
     }
 }