Add utility wrappers for instantiating builders/nodes 31/80131/2
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 29 Jan 2019 23:38:13 +0000 (00:38 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 4 Feb 2019 13:41:01 +0000 (14:41 +0100)
This removes the need for subclasses of
AbstractNodeContainerModificationStrategy to provide separate
methods, moving through a dispatch class instead. This lowers
the number of potential implementations down to one, with
the functionality being supported by 2 distinct classes.

As it turns out, this refactor actually has no additional overhead,
because the support instance reference can completely supplant
the Class reference we are holding.

JIRA: YANGTOOLS-941
Change-Id: I53a26981d41fb0cc6dd71dffd4e1bd71f9e9387d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit c91afd55c080cf25473767536b4509ae3b5e2603)

18 files changed:
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractLeafSetModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractMapModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractNodeContainerModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AugmentationModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ChoiceModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ContainerModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/DataNodeContainerModificationStrategy.java [moved from yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataNodeContainerModificationStrategy.java with 75% similarity]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/LeafSetModificationStrategy.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ListEntryModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MapModificationStrategy.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NormalizedNodeContainerSupport.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedLeafSetModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedMapModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/SchemaAwareApplyOperation.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnkeyedListItemModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnkeyedListModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedLeafSetModificationStrategy.java [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedMapModificationStrategy.java [deleted file]

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
deleted file mode 100644 (file)
index 5f27050..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 40b808e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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(ListEntryModificationStrategy.of(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 b0b6cecba8c3ec67cc73e1d78c6dea31ba5e1dd1..079b3b36e0265a0e8e754e5198728a775a82b470 100644 (file)
@@ -8,8 +8,10 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
 
-import com.google.common.base.Preconditions;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Verify;
 import java.util.Collection;
 import java.util.Optional;
@@ -29,18 +31,23 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 
 abstract class AbstractNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
-
-    private final Class<? extends NormalizedNode<?, ?>> nodeClass;
+    private final NormalizedNodeContainerSupport<?, ?> support;
     private final boolean verifyChildrenStructure;
 
-    protected AbstractNodeContainerModificationStrategy(final Class<? extends NormalizedNode<?, ?>> nodeClass,
+    AbstractNodeContainerModificationStrategy(final NormalizedNodeContainerSupport<?, ?> support,
             final DataTreeConfiguration treeConfig) {
-        this.nodeClass = Preconditions.checkNotNull(nodeClass , "nodeClass");
+        this.support = requireNonNull(support);
         this.verifyChildrenStructure = treeConfig.getTreeType() == TreeType.CONFIGURATION;
     }
 
+    @Override
+    protected final ChildTrackingPolicy getChildPolicy() {
+        return support.childPolicy;
+    }
+
     @Override
     void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
+        final Class<?> nodeClass = support.requiredClass;
         checkArgument(nodeClass.isInstance(writtenValue), "Node %s is not of type %s", writtenValue, nodeClass);
         checkArgument(writtenValue instanceof NormalizedNodeContainer);
         if (verifyChildrenStructure && verifyChildren) {
@@ -106,7 +113,7 @@ abstract class AbstractNodeContainerModificationStrategy extends SchemaAwareAppl
         mutable.setSubtreeVersion(version);
 
         @SuppressWarnings("rawtypes")
-        final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
+        final NormalizedNodeContainerBuilder dataBuilder = support.createBuilder(newValue);
         final TreeNode result = mutateChildren(mutable, dataBuilder, version, modification.getChildren());
 
         // We are good to go except one detail: this is a single logical write, but
@@ -197,7 +204,7 @@ abstract class AbstractNodeContainerModificationStrategy extends SchemaAwareAppl
                 // order of operation - parent changes are always resolved before
                 // children ones, and having node in TOUCH means children was modified
                 // before.
-                modification.updateValue(LogicalOperation.MERGE, createEmptyValue(value));
+                modification.updateValue(LogicalOperation.MERGE, support.createEmptyValue(value));
                 return;
             case MERGE:
                 // Merging into an existing node. Merge data children modifications (maybe recursively) and mark
@@ -244,7 +251,7 @@ abstract class AbstractNodeContainerModificationStrategy extends SchemaAwareAppl
         final Collection<ModifiedNode> children = modification.getChildren();
         if (!children.isEmpty()) {
             @SuppressWarnings("rawtypes")
-            final NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
+            final NormalizedNodeContainerBuilder dataBuilder = support.createBuilder(currentMeta.getData());
             final MutableTreeNode newMeta = currentMeta.mutable();
             newMeta.setSubtreeVersion(version);
             final TreeNode ret = mutateChildren(newMeta, dataBuilder, version, children);
@@ -319,8 +326,12 @@ abstract class AbstractNodeContainerModificationStrategy extends SchemaAwareAppl
         return verifyChildrenStructure;
     }
 
-    @SuppressWarnings("rawtypes")
-    protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
+    @Override
+    public final String toString() {
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+    }
 
-    protected abstract NormalizedNode<?, ?> createEmptyValue(NormalizedNode<?, ?> original);
+    ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+        return helper.add("support", support).add("verifyChildren", verifyChildrenStructure);
+    }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AugmentationModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AugmentationModificationStrategy.java
deleted file mode 100644 (file)
index 223b92a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkArgument;
-
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-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.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
-
-final class AugmentationModificationStrategy
-        extends AbstractDataNodeContainerModificationStrategy<AugmentationSchemaNode> {
-    AugmentationModificationStrategy(final AugmentationSchemaNode schema, final DataNodeContainer resolved,
-            final DataTreeConfiguration treeConfig) {
-        super(EffectiveAugmentationSchema.create(schema, resolved), AugmentationNode.class, treeConfig);
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof AugmentationNode);
-        return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof AugmentationNode);
-        return ImmutableAugmentationNodeBuilder.create()
-                .withNodeIdentifier(((AugmentationNode) original).getIdentifier()).build();
-    }
-}
index 568bf4c0dc748dcab1a778cdfd5a1ba1b4e6847c..745d1a85f847a99bb905c5c6037dbe4036f134fd 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
 import com.google.common.base.Verify;
@@ -31,21 +29,24 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
 final class ChoiceModificationStrategy extends AbstractNodeContainerModificationStrategy {
-    private final Map<PathArgument, ModificationApplyOperation> childNodes;
+    private static final Single<NodeIdentifier, ChoiceNode> SUPPORT = new Single<>(ChoiceNode.class,
+            ImmutableChoiceNodeBuilder::create, ImmutableChoiceNodeBuilder::create);
+
+    private final ImmutableMap<PathArgument, ModificationApplyOperation> childNodes;
     // FIXME: enforce leaves not coming from two case statements at the same time
-    private final Map<CaseEnforcer, Collection<CaseEnforcer>> exclusions;
-    private final Map<PathArgument, CaseEnforcer> caseEnforcers;
+    private final ImmutableMap<CaseEnforcer, Collection<CaseEnforcer>> exclusions;
+    private final ImmutableMap<PathArgument, CaseEnforcer> caseEnforcers;
 
     ChoiceModificationStrategy(final ChoiceSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
-        super(ChoiceNode.class, treeConfig);
+        super(SUPPORT, treeConfig);
 
         final Builder<PathArgument, ModificationApplyOperation> childBuilder = ImmutableMap.builder();
         final Builder<PathArgument, CaseEnforcer> enforcerBuilder = ImmutableMap.builder();
@@ -58,7 +59,7 @@ final class ChoiceModificationStrategy extends AbstractNodeContainerModification
                 }
                 for (final Entry<AugmentationIdentifier, AugmentationSchemaNode> e
                         : enforcer.getAugmentationEntries()) {
-                    childBuilder.put(e.getKey(), new AugmentationModificationStrategy(e.getValue(), caze, treeConfig));
+                    childBuilder.put(e.getKey(), SchemaAwareApplyOperation.from(e.getValue(), caze, treeConfig));
                     enforcerBuilder.put(e.getKey(), enforcer);
                 }
             }
@@ -79,13 +80,6 @@ final class ChoiceModificationStrategy extends AbstractNodeContainerModification
         return Optional.ofNullable(childNodes.get(child));
     }
 
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof ChoiceNode);
-        return ImmutableChoiceNodeBuilder.create((ChoiceNode) original);
-    }
-
     @Override
     void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
         if (verifyChildrenStructure() && verifyChildren) {
@@ -144,11 +138,5 @@ final class ChoiceModificationStrategy extends AbstractNodeContainerModification
         enforceCases(ret);
         return ret;
     }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof ChoiceNode);
-        return ImmutableChoiceNodeBuilder.create().withNodeIdentifier(((ChoiceNode) original).getIdentifier()).build();
-    }
 }
 
index 361cfcf8f7df2ba8e55be91f7d600c8b30d00d3d..2b299cb1eaa41c1a768be6d3cfba5e26f6e4dd5e 100644 (file)
@@ -7,18 +7,17 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.base.Preconditions;
 import java.util.Optional;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-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.tree.NormalizedNodeContainerSupport.Single;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 
 /**
@@ -26,7 +25,7 @@ import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
  * with mandatory nodes, as it needs to tap into {@link SchemaAwareApplyOperation}'s operations, or subclassed
  * for the purposes of {@link StructuralContainerModificationStrategy}'s automatic lifecycle.
  */
-class ContainerModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ContainerSchemaNode> {
+class ContainerModificationStrategy extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
     private static final class EnforcingMandatory extends ContainerModificationStrategy {
         private final MandatoryLeafEnforcer enforcer;
 
@@ -69,8 +68,11 @@ class ContainerModificationStrategy extends AbstractDataNodeContainerModificatio
         }
     }
 
+    private static final Single<NodeIdentifier, ContainerNode> SUPPORT = new Single<>(ContainerNode.class,
+            ImmutableContainerNodeBuilder::create, ImmutableContainerNodeBuilder::create);
+
     ContainerModificationStrategy(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
-        super(schemaNode, ContainerNode.class, treeConfig);
+        super(SUPPORT, schemaNode, treeConfig);
     }
 
     static ModificationApplyOperation of(final ContainerSchemaNode schema, final DataTreeConfiguration treeConfig) {
@@ -82,18 +84,4 @@ class ContainerModificationStrategy extends AbstractDataNodeContainerModificatio
 
         return new StructuralContainerModificationStrategy(schema, treeConfig);
     }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof ContainerNode);
-        return ImmutableContainerNodeBuilder.create((ContainerNode) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        Preconditions.checkArgument(original instanceof ContainerNode);
-        return ImmutableContainerNodeBuilder.create().withNodeIdentifier(((ContainerNode) original).getIdentifier())
-                .build();
-    }
 }
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
@@ -19,9 +20,7 @@ import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 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.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
@@ -34,9 +33,10 @@ import org.slf4j.LoggerFactory;
  *
  * @param <T> Type of the container node
  */
-abstract class AbstractDataNodeContainerModificationStrategy<T extends DataNodeContainer>
+class DataNodeContainerModificationStrategy<T extends DataNodeContainer>
         extends AbstractNodeContainerModificationStrategy {
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractDataNodeContainerModificationStrategy.class);
+    private static final Logger LOG = LoggerFactory.getLogger(DataNodeContainerModificationStrategy.class);
+
     private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
             .build(new CacheLoader<PathArgument, ModificationApplyOperation>() {
                 @Override
@@ -52,18 +52,15 @@ abstract class AbstractDataNodeContainerModificationStrategy<T extends DataNodeC
                     return SchemaAwareApplyOperation.from(child, treeConfig);
                 }
             });
-    private final T schema;
-    private final DataTreeConfiguration treeConfig;
 
-    protected AbstractDataNodeContainerModificationStrategy(final T schema,
-            final Class<? extends NormalizedNode<?, ?>> nodeClass, final DataTreeConfiguration treeConfig) {
-        super(nodeClass, treeConfig);
-        this.schema = requireNonNull(schema,"schema");
-        this.treeConfig = requireNonNull(treeConfig,"treeConfig");
-    }
+    private final DataTreeConfiguration treeConfig;
+    private final T schema;
 
-    protected final T getSchema() {
-        return schema;
+    DataNodeContainerModificationStrategy(final NormalizedNodeContainerSupport<?, ?> support, final T schema,
+            final DataTreeConfiguration treeConfig) {
+        super(support, treeConfig);
+        this.schema = requireNonNull(schema, "schema");
+        this.treeConfig = requireNonNull(treeConfig, "treeConfig");
     }
 
     @Override
@@ -78,11 +75,7 @@ abstract class AbstractDataNodeContainerModificationStrategy<T extends DataNodeC
     }
 
     @Override
-    @SuppressWarnings("rawtypes")
-    protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + " [" + schema + "]";
+    ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+        return super.addToStringAttributes(helper).add("schema", schema);
     }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/LeafSetModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/LeafSetModificationStrategy.java
new file mode 100644 (file)
index 0000000..d0a836f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.NodeIdentifier;
+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.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+final class LeafSetModificationStrategy extends AbstractNodeContainerModificationStrategy {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private static final Single<NodeIdentifier, OrderedLeafSetNode<?>> ORDERED_SUPPORT =
+            new Single(OrderedLeafSetNode.class, ChildTrackingPolicy.ORDERED,
+                foo -> ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>)foo),
+                ImmutableOrderedLeafSetNodeBuilder::create);
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private static final Single<NodeIdentifier, LeafSetNode<?>> UNORDERED_SUPPORT =
+            new Single(LeafSetNode.class,
+                foo -> ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>)foo),
+                ImmutableLeafSetNodeBuilder::create);
+
+    private final Optional<ModificationApplyOperation> entryStrategy;
+
+    LeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
+        super(schema.isUserOrdered() ? ORDERED_SUPPORT : UNORDERED_SUPPORT, treeConfig);
+        entryStrategy = Optional.of(new LeafSetEntryModificationStrategy(schema));
+    }
+
+    @Override
+    public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+        return identifier instanceof NodeWithValue ? entryStrategy : Optional.empty();
+    }
+}
\ No newline at end of file
index ff7d147090dc933f585e03583898f2810dd36a03..ee9ee85921de2f1a261bb4f589119035122a9bb9 100644 (file)
@@ -7,20 +7,20 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import java.util.Optional;
+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.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-class ListEntryModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ListSchemaNode> {
+class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
     private static final class EnforcingMandatory extends ListEntryModificationStrategy {
         private final MandatoryLeafEnforcer enforcer;
 
@@ -63,8 +63,11 @@ class ListEntryModificationStrategy extends AbstractDataNodeContainerModificatio
         }
     }
 
+    private static final Single<NodeIdentifierWithPredicates, MapEntryNode> SUPPORT = new Single<>(MapEntryNode.class,
+            ImmutableMapEntryNodeBuilder::create, ImmutableMapEntryNodeBuilder::create);
+
     ListEntryModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(schema, MapEntryNode.class, treeConfig);
+        super(SUPPORT, schema, treeConfig);
     }
 
     static ListEntryModificationStrategy of(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
@@ -72,18 +75,4 @@ class ListEntryModificationStrategy extends AbstractDataNodeContainerModificatio
         return enforcer.isPresent() ? new EnforcingMandatory(schema, treeConfig, enforcer.get())
                 : new ListEntryModificationStrategy(schema, treeConfig);
     }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof MapEntryNode);
-        return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof MapEntryNode);
-        return ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(((MapEntryNode) original).getIdentifier())
-                .build();
-    }
-}
\ No newline at end of file
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MapModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MapModificationStrategy.java
new file mode 100644 (file)
index 0000000..6c9c146
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+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.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.MapEntry;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+final class MapModificationStrategy extends AbstractNodeContainerModificationStrategy {
+    private static final MapEntry<OrderedMapNode> ORDERED_SUPPORT = new MapEntry<>(OrderedMapNode.class,
+            ChildTrackingPolicy.ORDERED, ImmutableOrderedMapNodeBuilder::create,
+            ImmutableOrderedMapNodeBuilder::create);
+    private static final MapEntry<MapNode> UNORDERED_SUPPORT = new MapEntry<>(MapNode.class,
+            ChildTrackingPolicy.UNORDERED, ImmutableMapNodeBuilder::create, ImmutableMapNodeBuilder::create);
+
+    private final Optional<ModificationApplyOperation> entryStrategy;
+    private final MapNode emptyNode;
+
+    private MapModificationStrategy(final MapEntry<?> support, final ListSchemaNode schema,
+        final DataTreeConfiguration treeConfig, final MapNode emptyNode) {
+        super(support, treeConfig);
+        this.emptyNode = requireNonNull(emptyNode);
+        entryStrategy = Optional.of(ListEntryModificationStrategy.of(schema, treeConfig));
+    }
+
+    static MapModificationStrategy of(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
+        final MapEntry<?> support;
+        final MapNode emptyNode;
+        if (schema.isUserOrdered()) {
+            support = ORDERED_SUPPORT;
+            emptyNode = ImmutableNodes.orderedMapNode(schema.getQName());
+        } else {
+            support = UNORDERED_SUPPORT;
+            emptyNode = ImmutableNodes.mapNode(schema.getQName());
+        }
+        return new MapModificationStrategy(support, schema, treeConfig, emptyNode);
+    }
+
+    // FIXME: this is a hack, originally introduced in
+    //        Change-Id: I9dc02a1917f38e8a0d62279843974b9869c48693. DataTreeRoot needs to be fixed up to properly
+    //        handle the lookup of through maps.
+    @Override
+    public 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
+    ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+        return super.addToStringAttributes(helper).add("entry", entryStrategy.get());
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NormalizedNodeContainerSupport.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NormalizedNodeContainerSupport.java
new file mode 100644 (file)
index 0000000..fe82ab8
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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 static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+
+abstract class NormalizedNodeContainerSupport<K extends PathArgument, T extends NormalizedNode<K, ?>> {
+    static final class Single<K extends PathArgument, T extends NormalizedNode<K, ?>>
+            extends NormalizedNodeContainerSupport<K, T> {
+        Single(final Class<T> requiredClass,
+                final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
+                final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
+            this(requiredClass, ChildTrackingPolicy.UNORDERED, copyBuilder, emptyBuilder);
+        }
+
+        Single(final Class<T> requiredClass, final ChildTrackingPolicy childPolicy,
+                final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
+                final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
+            super(requiredClass, childPolicy, copyBuilder, emptyBuilder);
+        }
+
+        @Override
+        NormalizedNodeContainerBuilder<?, ?, ?, T> createBuilder(final NormalizedNode<?, ?> original) {
+            return copyBuilder.apply(cast(original));
+        }
+
+        @Override
+        NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
+            return emptyBuilder.get().withNodeIdentifier(cast(original).getIdentifier()).build();
+        }
+
+        private T cast(final NormalizedNode<?, ?> original) {
+            checkArgument(requiredClass.isInstance(original), "Require %s, got %s", requiredClass, original);
+            return requiredClass.cast(original);
+        }
+    }
+
+    // FIXME: MapEntry a refactor of a hack, originally introduced in
+    //        Change-Id: I9dc02a1917f38e8a0d62279843974b9869c48693. DataTreeRoot needs to be fixed up to properly
+    //        handle the lookup of through maps.
+    static final class MapEntry<T extends NormalizedNode<NodeIdentifier, ?>>
+            extends NormalizedNodeContainerSupport<NodeIdentifier, T> {
+        MapEntry(final Class<T> requiredClass, final ChildTrackingPolicy childPolicy,
+                final Function<T, NormalizedNodeContainerBuilder<NodeIdentifier, ?, ?, T>> copyBuilder,
+                final Supplier<NormalizedNodeContainerBuilder<NodeIdentifier, ?, ?, T>> emptyBuilder) {
+            super(requiredClass, childPolicy, copyBuilder, emptyBuilder);
+        }
+
+        @Override
+        NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final NormalizedNode<?, ?> original) {
+            if (requiredClass.isInstance(original)) {
+                return copyBuilder.apply(requiredClass.cast(original));
+            }
+            if (original instanceof MapEntryNode) {
+                return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
+            }
+            throw new IllegalArgumentException("Expected either MapEntryNode or " + requiredClass + ", offending node: "
+                    + original);
+        }
+
+        @Override
+        NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
+            if (requiredClass.isInstance(original)) {
+                return emptyBuilder.get().withNodeIdentifier(requiredClass.cast(original).getIdentifier()).build();
+            }
+            if (original instanceof MapEntryNode) {
+                return ImmutableMapEntryNodeBuilder.create()
+                        .withNodeIdentifier(((MapEntryNode) original).getIdentifier()).build();
+            }
+            throw new IllegalArgumentException("Expected either MapEntryNode or " + requiredClass + ", offending node: "
+                    + original);
+        }
+    }
+
+    final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder;
+    final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder;
+    final ChildTrackingPolicy childPolicy;
+    final Class<T> requiredClass;
+
+    NormalizedNodeContainerSupport(final Class<T> requiredClass, final ChildTrackingPolicy childPolicy,
+            final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
+            final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
+        this.requiredClass = requireNonNull(requiredClass);
+        this.childPolicy = requireNonNull(childPolicy);
+        this.copyBuilder = requireNonNull(copyBuilder);
+        this.emptyBuilder = requireNonNull(emptyBuilder);
+    }
+
+    @SuppressWarnings("rawtypes")
+    abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
+
+    abstract NormalizedNode<?, ?> createEmptyValue(NormalizedNode<?, ?> original);
+
+    @Override
+    public final String toString() {
+        return MoreObjects.toStringHelper(this).add("requiredClass", requiredClass).toString();
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedLeafSetModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedLeafSetModificationStrategy.java
deleted file mode 100644 (file)
index 9928007..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkArgument;
-
-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;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-
-final class OrderedLeafSetModificationStrategy extends AbstractLeafSetModificationStrategy {
-    OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(schema, treeConfig);
-    }
-
-    @Override
-    protected ChildTrackingPolicy getChildPolicy() {
-        return ChildTrackingPolicy.ORDERED;
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof OrderedLeafSetNode<?>);
-        return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof OrderedLeafSetNode<?>);
-        return ImmutableOrderedLeafSetNodeBuilder.create()
-                .withNodeIdentifier(((OrderedLeafSetNode<?>) original).getIdentifier()).build();
-    }
-}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedMapModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OrderedMapModificationStrategy.java
deleted file mode 100644 (file)
index 7e9a6a4..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015 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 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;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-final class OrderedMapModificationStrategy extends AbstractMapModificationStrategy {
-    OrderedMapModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(OrderedMapNode.class, schema, treeConfig);
-    }
-
-    @Override
-    protected ChildTrackingPolicy getChildPolicy() {
-        return ChildTrackingPolicy.ORDERED;
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        return original instanceof OrderedMapNode ? ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original)
-                : super.createBuilder(original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        return original instanceof OrderedMapNode ? ImmutableOrderedMapNodeBuilder.create()
-                .withNodeIdentifier(((OrderedMapNode) original).getIdentifier()).build()
-                : super.createEmptyValue(original);
-    }
-}
index c1546a9bbf11ceaea799923d3adba1ee638bb697..59ae00a48a8f336576d8d68b4717e67618dbd878 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Optional;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
@@ -21,6 +22,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
@@ -30,11 +33,15 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
     private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class);
+    private static final Single<AugmentationIdentifier, AugmentationNode> AUGMENTATION_SUPPORT =
+            new Single<>(AugmentationNode.class, ImmutableAugmentationNodeBuilder::create,
+                    ImmutableAugmentationNodeBuilder::create);
 
     public static ModificationApplyOperation from(final DataSchemaNode schemaNode,
             final DataTreeConfiguration treeConfig) {
@@ -62,7 +69,7 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
         for (final AugmentationSchemaNode potential : augSchemas.getAvailableAugmentations()) {
             for (final DataSchemaNode child : potential.getChildNodes()) {
                 if (identifier.getPossibleChildNames().contains(child.getQName())) {
-                    return new AugmentationModificationStrategy(potential, resolvedTree, treeConfig);
+                    return from(potential, resolvedTree, treeConfig);
                 }
             }
         }
@@ -70,6 +77,12 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
         return null;
     }
 
+    static DataNodeContainerModificationStrategy<AugmentationSchemaNode> from(final AugmentationSchemaNode schema,
+            final DataNodeContainer resolved, final DataTreeConfiguration treeConfig) {
+        return new DataNodeContainerModificationStrategy<>(AUGMENTATION_SUPPORT,
+                EffectiveAugmentationSchema.create(schema, resolved), treeConfig);
+    }
+
     static void checkConflicting(final ModificationPath path, final boolean condition, final String message)
             throws ConflictingModificationAppliedException {
         if (!condition) {
@@ -83,23 +96,15 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
         final SchemaAwareApplyOperation op;
         if (keyDefinition == null || keyDefinition.isEmpty()) {
             op = new UnkeyedListModificationStrategy(schemaNode, treeConfig);
-        } else if (schemaNode.isUserOrdered()) {
-            op = new OrderedMapModificationStrategy(schemaNode, treeConfig);
         } else {
-            op = new UnorderedMapModificationStrategy(schemaNode, treeConfig);
+            op = MapModificationStrategy.of(schemaNode, treeConfig);
         }
         return MinMaxElementsValidation.from(op, schemaNode);
     }
 
     private static ModificationApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode,
             final DataTreeConfiguration treeConfig) {
-        final SchemaAwareApplyOperation op;
-        if (schemaNode.isUserOrdered()) {
-            op = new OrderedLeafSetModificationStrategy(schemaNode, treeConfig);
-        } else {
-            op = new UnorderedLeafSetModificationStrategy(schemaNode, treeConfig);
-        }
-        return MinMaxElementsValidation.from(op, schemaNode);
+        return MinMaxElementsValidation.from(new LeafSetModificationStrategy(schemaNode, treeConfig), schemaNode);
     }
 
     protected static void checkNotConflicting(final ModificationPath path, final TreeNode original,
@@ -186,11 +191,6 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
         }
     }
 
-    @Override
-    protected ChildTrackingPolicy getChildPolicy() {
-        return ChildTrackingPolicy.UNORDERED;
-    }
-
     @Override
     final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta,
             final Version version) {
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnkeyedListItemModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnkeyedListItemModificationStrategy.java
deleted file mode 100644 (file)
index 80a1493..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkArgument;
-
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-final class UnkeyedListItemModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ListSchemaNode> {
-    UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
-        super(schemaNode, UnkeyedListEntryNode.class, treeConfig);
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof UnkeyedListEntryNode);
-        return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof UnkeyedListEntryNode);
-        return ImmutableUnkeyedListEntryNodeBuilder.create()
-                .withNodeIdentifier(((UnkeyedListEntryNode) original).getIdentifier()).build();
-    }
-}
\ No newline at end of file
index 646222cf1b49baf8fb28620ccbf05216b69f6a9e..09d7c66d3c3f7525cb58ac52f58a820717764738 100644 (file)
@@ -20,14 +20,18 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
 final class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
+    private static final Single<NodeIdentifier, UnkeyedListEntryNode> ITEM_SUPPORT =
+            new Single<>(UnkeyedListEntryNode.class, ImmutableUnkeyedListEntryNodeBuilder::create,
+                    ImmutableUnkeyedListEntryNodeBuilder::create);
 
     private final Optional<ModificationApplyOperation> entryStrategy;
 
     UnkeyedListModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        entryStrategy = Optional.of(new UnkeyedListItemModificationStrategy(schema, treeConfig));
+        entryStrategy = Optional.of(new DataNodeContainerModificationStrategy<>(ITEM_SUPPORT, schema, treeConfig));
     }
 
     @Override
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedLeafSetModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedLeafSetModificationStrategy.java
deleted file mode 100644 (file)
index 7628624..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkArgument;
-
-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;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-
-final class UnorderedLeafSetModificationStrategy extends AbstractLeafSetModificationStrategy {
-    UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(schema, treeConfig);
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof LeafSetNode<?>);
-        return ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>) original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        checkArgument(original instanceof LeafSetNode<?>);
-        return ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(((LeafSetNode<?>) original).getIdentifier())
-                .build();
-    }
-}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedMapModificationStrategy.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/UnorderedMapModificationStrategy.java
deleted file mode 100644 (file)
index 48ec895..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 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.ImmutableMapNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-final class UnorderedMapModificationStrategy extends AbstractMapModificationStrategy {
-    UnorderedMapModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
-        super(MapNode.class, schema, treeConfig);
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-        return original instanceof MapNode ? ImmutableMapNodeBuilder.create((MapNode) original)
-                : super.createBuilder(original);
-    }
-
-    @Override
-    protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
-        return original instanceof MapNode ? ImmutableMapNodeBuilder.create()
-                .withNodeIdentifier(((MapNode) original).getIdentifier()).build() : super.createEmptyValue(original);
-    }
-}