Clean up DataSchemaContainerTree 10/100210/4
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 21 Mar 2022 17:52:03 +0000 (18:52 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 23 Mar 2022 11:31:27 +0000 (12:31 +0100)
Clean up the class hierarchy and mark things for future improvement,
deprecating unintentionally-public methods and providing guidance.

Change-Id: I9d4a2005714c964880198b9e0bde5e1401c4cb41
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
15 files changed:
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractInteriorContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractMixinContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractOpaqueContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AugmentationContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ChoiceNodeContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataContainerContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextTree.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/LeafContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/LeafListEntryContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ListItemContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/UnkeyedListItemContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/UnkeyedListMixinContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/UnorderedLeafListMixinContextNode.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/UnorderedMapMixinContextNode.java

index 0ec3baf3f5c7219bce0d386562d7fc15d1caed88..ff09288007034caccecb832e840f595ab5f50553 100644 (file)
@@ -10,16 +10,13 @@ package org.opendaylight.yangtools.yang.data.util;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-abstract class AbstractInteriorContextNode<T extends PathArgument> extends
-        DataSchemaContextNode<T> {
-
-    protected AbstractInteriorContextNode(final T identifier, final DataSchemaNode schema) {
+abstract class AbstractInteriorContextNode<T extends PathArgument> extends DataSchemaContextNode<T> {
+    AbstractInteriorContextNode(final T identifier, final DataSchemaNode schema) {
         super(identifier, schema);
     }
 
     @Override
-    public boolean isLeaf() {
+    public final boolean isLeaf() {
         return false;
     }
-
 }
\ No newline at end of file
index 3806612fd9854fe36d2047308417add5e5e9c865..23d28deab1e4aa691bdffb3ed83ec5be82b22e4a 100644 (file)
@@ -10,10 +10,8 @@ package org.opendaylight.yangtools.yang.data.util;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-abstract class AbstractMixinContextNode<T extends PathArgument> extends
-        AbstractInteriorContextNode<T> {
-
-    protected AbstractMixinContextNode(final T identifier, final DataSchemaNode schema) {
+abstract class AbstractMixinContextNode<T extends PathArgument> extends AbstractInteriorContextNode<T> {
+    AbstractMixinContextNode(final T identifier, final DataSchemaNode schema) {
         super(identifier, schema);
     }
 
@@ -21,5 +19,4 @@ abstract class AbstractMixinContextNode<T extends PathArgument> extends
     public final boolean isMixin() {
         return true;
     }
-
 }
\ No newline at end of file
index 857486be0d7faa409bf418ff59a3feacf684e098..12dcf7f653f8ddb460b2fe70c033885c7b1400c1 100644 (file)
@@ -11,7 +11,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
 abstract class AbstractOpaqueContextNode<S extends DataSchemaNode> extends AbstractLeafContextNode<NodeIdentifier, S> {
-    AbstractOpaqueContextNode(S schema) {
+    AbstractOpaqueContextNode(final S schema) {
         super(NodeIdentifier.create(schema.getQName()), schema);
     }
 
index e4c81ece17a8b2bc30d16c83843688a3b5a6d11e..bf3e3a8bad839303c68b69b95efea03fd1cd64ea 100644 (file)
@@ -17,8 +17,8 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 
 final class AugmentationContextNode extends DataContainerContextNode<AugmentationIdentifier> {
-    AugmentationContextNode(final AugmentationSchemaNode augmentation, final DataNodeContainer schema) {
-        super(augmentationIdentifierFrom(augmentation), new EffectiveAugmentationSchema(augmentation, schema), null);
+    AugmentationContextNode(final AugmentationSchemaNode augmentation, final DataNodeContainer target) {
+        super(augmentationIdentifierFrom(augmentation), new EffectiveAugmentationSchema(augmentation, target), null);
     }
 
     @Override
@@ -33,7 +33,7 @@ final class AugmentationContextNode extends DataContainerContextNode<Augmentatio
         if (schema instanceof DataSchemaNode && result.isAugmenting()) {
             return fromAugmentation(schema, (AugmentationTarget) schema, result);
         }
-        return fromDataSchemaNode(result);
+        return lenientOf(result);
     }
 
     @Override
index fee9077aadb534c47a7002aa1ec8bb062bfcca0b..7cd43d7b814de6b7aabf7d8667cac708c6353611 100644 (file)
@@ -15,19 +15,18 @@ import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-class ChoiceNodeContextNode extends AbstractMixinContextNode<NodeIdentifier> {
-
+final class ChoiceNodeContextNode extends AbstractMixinContextNode<NodeIdentifier> {
     private final ImmutableMap<QName, DataSchemaContextNode<?>> byQName;
     private final ImmutableMap<PathArgument, DataSchemaContextNode<?>> byArg;
 
-    protected ChoiceNodeContextNode(final ChoiceSchemaNode schema) {
+    ChoiceNodeContextNode(final ChoiceSchemaNode schema) {
         super(NodeIdentifier.create(schema.getQName()), schema);
         ImmutableMap.Builder<QName, DataSchemaContextNode<?>> byQNameBuilder = ImmutableMap.builder();
         ImmutableMap.Builder<PathArgument, DataSchemaContextNode<?>> byArgBuilder = ImmutableMap.builder();
 
         for (CaseSchemaNode caze : schema.getCases()) {
             for (DataSchemaNode cazeChild : caze.getChildNodes()) {
-                DataSchemaContextNode<?> childOp = fromDataSchemaNode(cazeChild);
+                DataSchemaContextNode<?> childOp = DataSchemaContextNode.of(cazeChild);
                 byArgBuilder.put(childOp.getIdentifier(), childOp);
                 for (QName qname : childOp.getQNameIdentifiers()) {
                     byQNameBuilder.put(qname, childOp);
index 51aa4e284d424e260a75ce9e96fc3d27398d24de..96869c1b8d7a8cd623e3ee32e51e301b3d35928b 100644 (file)
@@ -7,27 +7,24 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
-import java.util.Map;
+import static java.util.Objects.requireNonNull;
+
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 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.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-class DataContainerContextNode<T extends PathArgument> extends
-        AbstractInteriorContextNode<T> {
-
-    private final DataNodeContainer schema;
-    private final Map<QName, DataSchemaContextNode<?>> byQName;
-    private final Map<PathArgument, DataSchemaContextNode<?>> byArg;
+abstract class DataContainerContextNode<T extends PathArgument> extends AbstractInteriorContextNode<T> {
+    private final ConcurrentMap<PathArgument, DataSchemaContextNode<?>> byArg = new ConcurrentHashMap<>();
+    private final ConcurrentMap<QName, DataSchemaContextNode<?>> byQName = new ConcurrentHashMap<>();
+    private final DataNodeContainer container;
 
-    protected DataContainerContextNode(final T identifier, final DataNodeContainer schema,
-            final DataSchemaNode node) {
-        super(identifier, node);
-        this.schema = schema;
-        this.byArg = new ConcurrentHashMap<>();
-        this.byQName = new ConcurrentHashMap<>();
+    DataContainerContextNode(final T identifier, final DataNodeContainer container, final DataSchemaNode schema) {
+        super(identifier, schema);
+        this.container = requireNonNull(container);
     }
 
     @Override
@@ -46,16 +43,16 @@ class DataContainerContextNode<T extends PathArgument> extends
         if (potential != null) {
             return potential;
         }
-        potential = fromLocalSchemaAndQName(schema, child);
+        potential = fromLocalSchemaAndQName(container, child);
         return register(potential);
     }
 
     private DataSchemaContextNode<?> fromLocalSchema(final PathArgument child) {
         if (child instanceof AugmentationIdentifier) {
-            return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
+            return fromSchemaAndQNameChecked(container, ((AugmentationIdentifier) child).getPossibleChildNames()
                     .iterator().next());
         }
-        return fromSchemaAndQNameChecked(schema, child.getNodeType());
+        return fromSchemaAndQNameChecked(container, child.getNodeType());
     }
 
     protected DataSchemaContextNode<?> fromLocalSchemaAndQName(final DataNodeContainer schema2, final QName child) {
@@ -64,6 +61,7 @@ class DataContainerContextNode<T extends PathArgument> extends
 
     private DataSchemaContextNode<?> register(final DataSchemaContextNode<?> potential) {
         if (potential != null) {
+            // FIXME: use putIfAbsent() to make sure we do not perform accidental overrwrites
             byArg.put(potential.getIdentifier(), potential);
             for (QName qname : potential.getQNameIdentifiers()) {
                 byQName.put(qname, potential);
index ec92da849eee15c07bcfaec25580efcb1fdf0c9f..ac6e43e808d3dd6d9e60c8b159d9a56227ab835f 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.data.util;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
-import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -43,25 +42,33 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
  * @param <T> Path Argument type
  */
 public abstract class DataSchemaContextNode<T extends PathArgument> extends AbstractSimpleIdentifiable<T> {
+    // FIXME: this can be null only for AugmentationContextNode and in that case the interior part is handled by a
+    //        separate field in DataContainerContextNode. We need to re-examine our base interface class hierarchy
+    //        so that the underlying (effective in augment's case) SchemaNode is always available.
     private final DataSchemaNode dataSchemaNode;
 
-    protected DataSchemaContextNode(final T identifier, final SchemaNode schema) {
+    DataSchemaContextNode(final T identifier, final DataSchemaNode schema) {
         super(identifier);
-        if (schema instanceof DataSchemaNode) {
-            this.dataSchemaNode = (DataSchemaNode) schema;
-        } else {
-            this.dataSchemaNode = null;
-        }
+        this.dataSchemaNode = schema;
     }
 
+    @Deprecated(forRemoval = true, since = "8.0.2")
+    protected DataSchemaContextNode(final T identifier, final SchemaNode schema) {
+        this(identifier, schema instanceof DataSchemaNode ? (DataSchemaNode) schema : null);
+    }
+
+    // FIXME: document this method
     public boolean isMixin() {
         return false;
     }
 
+    // FIXME: document this method
     public boolean isKeyedEntry() {
         return false;
     }
 
+    // FIXME: this is counter-intuitive: anydata/anyxml are considered non-leaf. This method needs a better name and
+    //        a proper description.
     public abstract boolean isLeaf();
 
     protected Set<QName> getQNameIdentifiers() {
@@ -74,10 +81,13 @@ public abstract class DataSchemaContextNode<T extends PathArgument> extends Abst
      * @param child Child path argument
      * @return A child node, or null if not found
      */
+    // FIXME: document PathArgument type mismatch
     public abstract @Nullable DataSchemaContextNode<?> getChild(PathArgument child);
 
+    // FIXME: document child == null
     public abstract @Nullable DataSchemaContextNode<?> getChild(QName child);
 
+    // FIXME: final
     public @Nullable DataSchemaNode getDataSchemaNode() {
         return dataSchemaNode;
     }
@@ -113,7 +123,7 @@ public abstract class DataSchemaContextNode<T extends PathArgument> extends Abst
         if (result != null && schema instanceof DataSchemaNode && result.isAugmenting()) {
             return fromAugmentation(schema, (AugmentationTarget) schema, result);
         }
-        return fromDataSchemaNode(result);
+        return lenientOf(result);
     }
 
     // FIXME: this looks like it should be a Predicate on a stream with findFirst()
@@ -141,14 +151,53 @@ public abstract class DataSchemaContextNode<T extends PathArgument> extends Abst
             .collect(Collectors.toSet()));
     }
 
+    static @NonNull DataSchemaContextNode<?> of(final @NonNull DataSchemaNode schema) {
+        if (schema instanceof ContainerLike) {
+            return new ContainerContextNode((ContainerLike) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            return fromListSchemaNode((ListSchemaNode) schema);
+        } else if (schema instanceof LeafSchemaNode) {
+            return new LeafContextNode((LeafSchemaNode) schema);
+        } else if (schema instanceof ChoiceSchemaNode) {
+            return new ChoiceNodeContextNode((ChoiceSchemaNode) schema);
+        } else if (schema instanceof LeafListSchemaNode) {
+            return fromLeafListSchemaNode((LeafListSchemaNode) schema);
+        } else if (schema instanceof AnydataSchemaNode) {
+            return new AnydataContextNode((AnydataSchemaNode) schema);
+        } else if (schema instanceof AnyxmlSchemaNode) {
+            return new AnyXmlContextNode((AnyxmlSchemaNode) schema);
+        } else {
+            throw new IllegalStateException("Unhandled schema " + schema);
+        }
+    }
+
+    // FIXME: do we tolerate null argument? do we tolerate unknown subclasses?
+    static @Nullable DataSchemaContextNode<?> lenientOf(final @Nullable DataSchemaNode schema) {
+        if (schema instanceof ContainerLike) {
+            return new ContainerContextNode((ContainerLike) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            return fromListSchemaNode((ListSchemaNode) schema);
+        } else if (schema instanceof LeafSchemaNode) {
+            return new LeafContextNode((LeafSchemaNode) schema);
+        } else if (schema instanceof ChoiceSchemaNode) {
+            return new ChoiceNodeContextNode((ChoiceSchemaNode) schema);
+        } else if (schema instanceof LeafListSchemaNode) {
+            return fromLeafListSchemaNode((LeafListSchemaNode) schema);
+        } else if (schema instanceof AnydataSchemaNode) {
+            return new AnydataContextNode((AnydataSchemaNode) schema);
+        } else if (schema instanceof AnyxmlSchemaNode) {
+            return new AnyXmlContextNode((AnyxmlSchemaNode) schema);
+        } else {
+            return null;
+        }
+    }
+
     /**
      * Returns a DataContextNodeOperation for provided child node
      *
      * <p>
-     * If supplied child is added by Augmentation this operation returns a
-     * DataContextNodeOperation for augmentation, otherwise returns a
-     * DataContextNodeOperation for child as call for
-     * {@link #fromDataSchemaNode(DataSchemaNode)}.
+     * If supplied child is added by Augmentation this operation returns a DataSchemaContextNode for augmentation,
+     * otherwise returns a DataSchemaContextNode for child as call for {@link #lenientOf(DataSchemaNode)}.
      */
     static @Nullable DataSchemaContextNode<?> fromAugmentation(final DataNodeContainer parent,
             final AugmentationTarget parentAug, final DataSchemaNode child) {
@@ -157,47 +206,49 @@ public abstract class DataSchemaContextNode<T extends PathArgument> extends Abst
                 return new AugmentationContextNode(aug, parent);
             }
         }
-        return fromDataSchemaNode(child);
+        return lenientOf(child);
     }
 
+    /**
+     * Get a {@link DataSchemaContextNode} for a particular {@link DataSchemaNode}.
+     *
+     * @param potential Backing DataSchemaNode
+     * @return A {@link DataSchemaContextNode}, or null if the input is {@code null} or of unhandled type
+     */
+    @Deprecated(forRemoval = true, since = "8.0.2")
     public static @Nullable DataSchemaContextNode<?> fromDataSchemaNode(final DataSchemaNode potential) {
-        if (potential instanceof ContainerLike) {
-            return new ContainerContextNode((ContainerLike) potential);
-        } else if (potential instanceof ListSchemaNode) {
-            return fromListSchemaNode((ListSchemaNode) potential);
-        } else if (potential instanceof LeafSchemaNode) {
-            return new LeafContextNode((LeafSchemaNode) potential);
-        } else if (potential instanceof ChoiceSchemaNode) {
-            return new ChoiceNodeContextNode((ChoiceSchemaNode) potential);
-        } else if (potential instanceof LeafListSchemaNode) {
-            return fromLeafListSchemaNode((LeafListSchemaNode) potential);
-        } else if (potential instanceof AnydataSchemaNode) {
-            return new AnydataContextNode((AnydataSchemaNode) potential);
-        } else if (potential instanceof AnyxmlSchemaNode) {
-            return new AnyXmlContextNode((AnyxmlSchemaNode) potential);
-        }
-        return null;
+        return lenientOf(potential);
     }
 
-    private static DataSchemaContextNode<?> fromListSchemaNode(final ListSchemaNode potential) {
-        List<QName> keyDefinition = potential.getKeyDefinition();
-        if (keyDefinition == null || keyDefinition.isEmpty()) {
+    private static @NonNull DataSchemaContextNode<?> fromListSchemaNode(final ListSchemaNode potential) {
+        var keyDefinition = potential.getKeyDefinition();
+        if (keyDefinition.isEmpty()) {
             return new UnkeyedListMixinContextNode(potential);
-        }
-        if (potential.isUserOrdered()) {
+        } else if (potential.isUserOrdered()) {
             return new OrderedMapMixinContextNode(potential);
+        } else {
+            return new UnorderedMapMixinContextNode(potential);
         }
-        return new UnorderedMapMixinContextNode(potential);
     }
 
-    private static DataSchemaContextNode<?> fromLeafListSchemaNode(final LeafListSchemaNode potential) {
+    private static @NonNull DataSchemaContextNode<?> fromLeafListSchemaNode(final LeafListSchemaNode potential) {
         if (potential.isUserOrdered()) {
             return new OrderedLeafListMixinContextNode(potential);
         }
         return new UnorderedLeafListMixinContextNode(potential);
     }
 
-    public static DataSchemaContextNode<?> from(final EffectiveModelContext ctx) {
+    /**
+     * Return a DataSchemaContextNode corresponding to specified {@link EffectiveModelContext}.
+     *
+     * @param ctx EffectiveModelContext
+     * @return A DataSchemaContextNode
+     * @throws NullPointerException if {@code ctx} is null
+     * @deprecated Use {@link DataSchemaContextTree#from(EffectiveModelContext)} and
+     *             {@link DataSchemaContextTree#getRoot()} instead.
+     */
+    @Deprecated(forRemoval = true, since = "8.0.2")
+    public static @NonNull DataSchemaContextNode<?> from(final EffectiveModelContext ctx) {
         return new ContainerContextNode(ctx);
     }
 }
index df3e019b61ec30b8fcb85a3aa0fee966696a127b..1a66488615db13892e747a172ee0225e60b39305 100644 (file)
@@ -24,19 +24,19 @@ import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveModelContextPr
  * @author Robert Varga
  */
 public final class DataSchemaContextTree extends AbstractEffectiveModelContextProvider {
-    private static final LoadingCache<EffectiveModelContext, DataSchemaContextTree> TREES = CacheBuilder.newBuilder()
-            .weakKeys().weakValues().build(new CacheLoader<EffectiveModelContext, DataSchemaContextTree>() {
-                @Override
-                public DataSchemaContextTree load(final EffectiveModelContext key) {
-                    return new DataSchemaContextTree(key);
-                }
-            });
+    private static final LoadingCache<EffectiveModelContext, @NonNull DataSchemaContextTree> TREES =
+        CacheBuilder.newBuilder().weakKeys().weakValues().build(new CacheLoader<>() {
+            @Override
+            public DataSchemaContextTree load(final EffectiveModelContext key) {
+                return new DataSchemaContextTree(key);
+            }
+        });
 
-    private final DataSchemaContextNode<?> root;
+    private final @NonNull ContainerContextNode root;
 
     private DataSchemaContextTree(final EffectiveModelContext ctx) {
         super(ctx);
-        root = DataSchemaContextNode.from(ctx);
+        root = new ContainerContextNode(ctx);
     }
 
     public static @NonNull DataSchemaContextTree from(final @NonNull EffectiveModelContext ctx) {
@@ -51,7 +51,7 @@ public final class DataSchemaContextTree extends AbstractEffectiveModelContextPr
      * @throws NullPointerException if {@code path} is null
      */
     public @NonNull Optional<@NonNull DataSchemaContextNode<?>> findChild(final @NonNull YangInstanceIdentifier path) {
-        return getRoot().findChild(path);
+        return root.findChild(path);
     }
 
     public @NonNull DataSchemaContextNode<?> getRoot() {
index 67cf08af6052195f038c27bec04df6a171d8b4d0..f86f68ee53bbe9cf6450c78807d7af49792a780d 100644 (file)
@@ -11,7 +11,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 
 final class LeafContextNode extends AbstractLeafNodeContext<NodeIdentifier, LeafSchemaNode> {
-    LeafContextNode(final LeafSchemaNode potential) {
-        super(NodeIdentifier.create(potential.getQName()), potential);
+    LeafContextNode(final LeafSchemaNode schema) {
+        super(NodeIdentifier.create(schema.getQName()), schema);
     }
 }
index dc313f4dd5ca940a2f3e71a37335276110b563bf..e86e4741dff3f7d12b57f2aa88d9329f36e4756e 100644 (file)
@@ -12,8 +12,9 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithV
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
 final class LeafListEntryContextNode extends AbstractLeafNodeContext<NodeWithValue<?>, LeafListSchemaNode> {
-    LeafListEntryContextNode(final LeafListSchemaNode potential) {
-        super(new NodeWithValue<>(potential.getQName(), Empty.value()), potential);
+    LeafListEntryContextNode(final LeafListSchemaNode schema) {
+        // FIXME: Empty() here is NOT NICE -- it assumes the list is of such entries...
+        super(new NodeWithValue<>(schema.getQName(), Empty.value()), schema);
     }
 
     @Override
index 3465f5638b553c16cb23863cfad7b6c20d85357a..18cfd0aac18db6a6f0626ef573ee82c6906ffeb1 100644 (file)
@@ -10,11 +10,8 @@ package org.opendaylight.yangtools.yang.data.util;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-final class ListItemContextNode extends
-        DataContainerContextNode<NodeIdentifierWithPredicates> {
-
-
-    protected ListItemContextNode(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
+final class ListItemContextNode extends DataContainerContextNode<NodeIdentifierWithPredicates> {
+    ListItemContextNode(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
         super(identifier, schema, schema);
     }
 
index 0817d5bba272a32e8f347b33fa090088822403ae..a4ffbc1fe90378c9cfca419b3f4504b04621adf3 100644 (file)
@@ -11,9 +11,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
 final class UnkeyedListItemContextNode extends DataContainerContextNode<NodeIdentifier> {
-
-    protected UnkeyedListItemContextNode(final ListSchemaNode schema) {
+    UnkeyedListItemContextNode(final ListSchemaNode schema) {
         super(NodeIdentifier.create(schema.getQName()), schema, schema);
     }
-
 }
index 507d611bd0b65af1f81d022dec4063b397cb142a..00ba8b48109613d9e9c5ba13a9efc98a9c5eb31b 100644 (file)
@@ -7,34 +7,34 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-class UnkeyedListMixinContextNode extends AbstractMixinContextNode<NodeIdentifier> {
-
+final class UnkeyedListMixinContextNode extends AbstractMixinContextNode<NodeIdentifier> {
     private final UnkeyedListItemContextNode innerNode;
 
     UnkeyedListMixinContextNode(final ListSchemaNode list) {
         super(NodeIdentifier.create(list.getQName()), list);
-        this.innerNode = new UnkeyedListItemContextNode(list);
+        innerNode = new UnkeyedListItemContextNode(list);
     }
 
     @Override
     public DataSchemaContextNode<?> getChild(final PathArgument child) {
-        if (child.getNodeType().equals(getIdentifier().getNodeType())) {
-            return innerNode;
-        }
-        return null;
+        // FIXME: 10.0.0: checkArgument() on PathArgument
+        return innerNodeIfMatch(child.getNodeType());
     }
 
     @Override
     public DataSchemaContextNode<?> getChild(final QName child) {
-        if (getIdentifier().getNodeType().equals(child)) {
-            return innerNode;
-        }
-        return null;
+        return innerNodeIfMatch(child);
     }
 
+    // FIXME: dead ringers in other AbstractMixinContextNode subclasses
+    private @Nullable DataSchemaContextNode<?> innerNodeIfMatch(final QName qname) {
+        // FIXME: 10.0.0: requireNonNull(qname)
+        return getIdentifier().getNodeType().equals(qname) ? innerNode : null;
+    }
 }
index c6907f31c1756f0eacffb0a9612eac754a1dbc7c..9d6618c2fac608d28e7c36e28e65143eabd38968 100644 (file)
@@ -14,27 +14,22 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
 class UnorderedLeafListMixinContextNode extends AbstractMixinContextNode<NodeIdentifier> {
+    private final LeafListEntryContextNode innerOp;
 
-    private final DataSchemaContextNode<?> innerOp;
-
-    UnorderedLeafListMixinContextNode(final LeafListSchemaNode potential) {
-        super(NodeIdentifier.create(potential.getQName()), potential);
-        innerOp = new LeafListEntryContextNode(potential);
+    UnorderedLeafListMixinContextNode(final LeafListSchemaNode schema) {
+        super(NodeIdentifier.create(schema.getQName()), schema);
+        innerOp = new LeafListEntryContextNode(schema);
     }
 
     @Override
-    public DataSchemaContextNode<?> getChild(final PathArgument child) {
-        if (child instanceof NodeWithValue) {
-            return innerOp;
-        }
-        return null;
+    public final DataSchemaContextNode<?> getChild(final PathArgument child) {
+        // FIXME: 10.0.0: reject null and invalid
+        return child instanceof NodeWithValue ? innerOp : null;
     }
 
     @Override
-    public DataSchemaContextNode<?> getChild(final QName child) {
-        if (getIdentifier().getNodeType().equals(child)) {
-            return innerOp;
-        }
-        return null;
+    public final DataSchemaContextNode<?> getChild(final QName child) {
+        // FIXME: requireNonNull, common code with UnkeyedListMixinNode
+        return getIdentifier().getNodeType().equals(child) ? innerOp : null;
     }
 }
index 5e36250e1660c812cf192d2a1ac77975de758c40..4b76598303e885efc3c4883c6a6f1cbf7199e790 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -18,22 +19,23 @@ class UnorderedMapMixinContextNode extends AbstractMixinContextNode<NodeIdentifi
 
     UnorderedMapMixinContextNode(final ListSchemaNode list) {
         super(NodeIdentifier.create(list.getQName()), list);
-        this.innerNode = new ListItemContextNode(NodeIdentifierWithPredicates.of(list.getQName()), list);
+        innerNode = new ListItemContextNode(NodeIdentifierWithPredicates.of(list.getQName()), list);
     }
 
     @Override
-    public DataSchemaContextNode<?> getChild(final PathArgument child) {
-        if (child.getNodeType().equals(getIdentifier().getNodeType())) {
-            return innerNode;
-        }
-        return null;
+    public final DataSchemaContextNode<?> getChild(final PathArgument child) {
+        // FIXME: validate PathArgument type
+        return innerNodeIfMatch(child.getNodeType());
     }
 
     @Override
-    public DataSchemaContextNode<?> getChild(final QName child) {
-        if (getIdentifier().getNodeType().equals(child)) {
-            return innerNode;
-        }
-        return null;
+    public final DataSchemaContextNode<?> getChild(final QName child) {
+        return innerNodeIfMatch(child);
+    }
+
+    // FIXME: dead ringers in other AbstractMixinContextNode subclasses
+    private @Nullable DataSchemaContextNode<?> innerNodeIfMatch(final QName qname) {
+        // FIXME: 10.0.0: requireNonNull(qname)
+        return getIdentifier().getNodeType().equals(qname) ? innerNode : null;
     }
 }