Clean up DataSchemaContext{Node,Tree}
[yangtools.git] / yang / yang-data-util / src / main / java / org / opendaylight / yangtools / yang / data / util / DataSchemaContextNode.java
index e51f1a60619b02356126354aec06411b9d9f8f25..22b93d8621aca0727d02a63c8da448a1593fcff2 100644 (file)
@@ -9,13 +9,15 @@ package org.opendaylight.yangtools.yang.data.util;
 
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.AnyXmlSchemaNode;
@@ -34,23 +36,15 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 
 /**
- * Schema derived data providing necessary information for mapping
- * between {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode}
- * and serialization format defined in RFC6020, since the mapping
- * is not one-to-one.
+ * Schema derived data providing necessary information for mapping between
+ * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and serialization format defined in RFC6020,
+ * since the mapping is not one-to-one.
  *
  * @param <T> Path Argument type
- *
  */
 public abstract class DataSchemaContextNode<T extends PathArgument> implements Identifiable<T> {
-
-    private final T identifier;
     private final DataSchemaNode dataSchemaNode;
-
-    @Override
-    public T getIdentifier() {
-        return identifier;
-    }
+    private final T identifier;
 
     protected DataSchemaContextNode(final T identifier, final SchemaNode schema) {
         this.identifier = identifier;
@@ -61,6 +55,11 @@ public abstract class DataSchemaContextNode<T extends PathArgument> implements I
         }
     }
 
+    @Override
+    public T getIdentifier() {
+        return identifier;
+    }
+
     public boolean isMixin() {
         return false;
     }
@@ -69,21 +68,45 @@ public abstract class DataSchemaContextNode<T extends PathArgument> implements I
         return false;
     }
 
+    public abstract boolean isLeaf();
+
     protected Set<QName> getQNameIdentifiers() {
-        return Collections.singleton(identifier.getNodeType());
+        return ImmutableSet.of(identifier.getNodeType());
     }
 
+    /**
+     * Find a child node identifier by its {@link PathArgument}.
+     *
+     * @param child Child path argument
+     * @return
+     */
     @Nullable public abstract DataSchemaContextNode<?> getChild(PathArgument child);
 
     @Nullable public abstract DataSchemaContextNode<?> getChild(QName child);
 
-    public abstract boolean isLeaf();
-
-
     @Nullable public DataSchemaNode getDataSchemaNode() {
         return dataSchemaNode;
     }
 
+    /**
+     * Find a child node as identified by a {@link YangInstanceIdentifier} relative to this node.
+     *
+     * @param path Path towards the child node
+     * @return Child node if present, or empty when corresponding child is not found.
+     * @throws NullPointerException if {@code path} is null
+     */
+    public final @NonNull Optional<@NonNull DataSchemaContextNode<?>> findChild(
+            final @NonNull YangInstanceIdentifier path) {
+        DataSchemaContextNode<?> currentOp = this;
+        for (PathArgument arg : path.getPathArguments()) {
+            currentOp = currentOp.getChild(arg);
+            if (currentOp == null) {
+                return Optional.empty();
+            }
+        }
+        return Optional.of(currentOp);
+    }
+
     static DataSchemaNode findChildSchemaNode(final DataNodeContainer parent, final QName child) {
         DataSchemaNode potential = parent.getDataChildByName(child);
         if (potential == null) {