Deprecate YangInstanceIdentifier.EMPTY
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / InstanceIdToNodes.java
index d288b000a8ede26a9c47705d64482e473554f4aa..a944452d54a284e09737be6c7f9a856ce280a71e 100644 (file)
@@ -10,25 +10,24 @@ package org.opendaylight.yangtools.yang.data.impl.schema;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.Optional;
 import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.yangtools.concepts.Identifiable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 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.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AnydataNode;
 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.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
@@ -45,16 +44,9 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  * Base strategy for converting an instance identifier into a normalized node structure.
  * Use provided static methods for generic YangInstanceIdentifier -> NormalizedNode translation in ImmutableNodes.
  */
-abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable<T> {
-    private final T identifier;
-
+abstract class InstanceIdToNodes<T extends PathArgument> extends AbstractIdentifiable<T> {
     InstanceIdToNodes(final T identifier) {
-        this.identifier = identifier;
-    }
-
-    @Override
-    public final T getIdentifier() {
-        return identifier;
+        super(identifier);
     }
 
     /**
@@ -73,19 +65,11 @@ abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable
      * @param operation Optional modify operation to be set on the last child
      * @return NormalizedNode structure corresponding to submitted instance ID
      */
-    abstract NormalizedNode<?, ?> create(PathArgument first, Iterator<PathArgument> others,
-            Optional<NormalizedNode<?, ?>> deepestChild, Optional<Entry<QName, ModifyAction>> operation);
+    abstract @NonNull NormalizedNode<?, ?> create(PathArgument first, Iterator<PathArgument> others,
+            Optional<NormalizedNode<?, ?>> deepestChild);
 
     abstract boolean isMixin();
 
-    static void addModifyOpIfPresent(final Optional<Entry<QName, ModifyAction>> operation,
-            final AttributesBuilder<?> builder) {
-        if (operation.isPresent()) {
-            final Entry<QName, ModifyAction> entry = operation.get();
-            builder.withAttributes(ImmutableMap.of(entry.getKey(), entry.getValue().name().toLowerCase()));
-        }
-    }
-
     private static final class UnkeyedListMixinNormalization extends InstanceIdToCompositeNodes<NodeIdentifier> {
         private final UnkeyedListItemNormalization innerNode;
 
@@ -110,44 +94,66 @@ abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable
         }
     }
 
-    private static final class AnyXmlNormalization extends InstanceIdToNodes<NodeIdentifier> {
-        AnyXmlNormalization(final AnyXmlSchemaNode schema) {
+    private abstract static class AbstractOpaqueNormalization extends InstanceIdToNodes<NodeIdentifier> {
+        AbstractOpaqueNormalization(final DataSchemaNode schema) {
             super(NodeIdentifier.create(schema.getQName()));
         }
 
         @Override
-        InstanceIdToNodes<?> getChild(final PathArgument child) {
+        final InstanceIdToNodes<?> getChild(final PathArgument child) {
             return null;
         }
 
+        @Override
+        final boolean isMixin() {
+            return false;
+        }
+    }
+
+    private static final class AnydataNormalization extends AbstractOpaqueNormalization {
+        AnydataNormalization(final AnyDataSchemaNode schema) {
+            super(schema);
+        }
+
         @Override
         NormalizedNode<?, ?> create(final PathArgument first, final Iterator<PathArgument> others,
-                final Optional<NormalizedNode<?, ?>> deepestChild,
-                final Optional<Entry<QName,ModifyAction>> operation) {
-            final NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> builder = Builders.anyXmlBuilder()
+                final Optional<NormalizedNode<?, ?>> deepestChild) {
+            checkState(deepestChild.isPresent(), "Cannot instantiate anydata node without a value");
+            final NormalizedNode<?, ?> child = deepestChild.get();
+            checkState(child instanceof AnydataNode, "Invalid child %s", child);
+            return createAnydata((AnydataNode<?>) child);
+        }
+
+        private <T> AnydataNode<T> createAnydata(final AnydataNode<T> child) {
+            return Builders.anydataBuilder(child.getValueObjectModel()).withValue(child.getValue())
+            .withNodeIdentifier(getIdentifier()).build();
+        }
+    }
+
+    private static final class AnyXmlNormalization extends AbstractOpaqueNormalization {
+        AnyXmlNormalization(final AnyXmlSchemaNode schema) {
+            super(schema);
+        }
+
+        @Override
+        NormalizedNode<?, ?> create(final PathArgument first, final Iterator<PathArgument> others,
+                final Optional<NormalizedNode<?, ?>> deepestChild) {
+            final NormalizedNodeBuilder<NodeIdentifier, DOMSource, AnyXmlNode> builder = Builders.anyXmlBuilder()
                     .withNodeIdentifier(getIdentifier());
             if (deepestChild.isPresent()) {
                 final NormalizedNode<?, ?> child = deepestChild.get();
-                checkState(child instanceof AnyXmlNode);
+                checkState(child instanceof AnyXmlNode, "Invalid child %s", child);
                 builder.withValue(((AnyXmlNode) child).getValue());
             }
 
-            addModifyOpIfPresent(operation, builder);
             return builder.build();
         }
-
-        @Override
-        boolean isMixin() {
-            return false;
-        }
     }
 
     private static Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent, final QName child) {
-        DataSchemaNode potential = parent.getDataChildByName(child);
-        if (potential == null) {
-            potential = findChoice(Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class), child);
-        }
-        return Optional.ofNullable(potential);
+        final Optional<DataSchemaNode> potential = parent.findDataChildByName(child);
+        return potential.isPresent() ? potential : Optional.ofNullable(
+            findChoice(Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class), child));
     }
 
     static InstanceIdToNodes<?> fromSchemaAndQNameChecked(final DataNodeContainer schema, final QName child) {
@@ -186,8 +192,8 @@ abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable
     private static InstanceIdToNodes<?> fromAugmentation(final DataNodeContainer parent,
             final AugmentationTarget parentAug, final DataSchemaNode child) {
         for (final AugmentationSchemaNode aug : parentAug.getAvailableAugmentations()) {
-            final DataSchemaNode potential = aug.getDataChildByName(child.getQName());
-            if (potential != null) {
+            final Optional<DataSchemaNode> potential = aug.findDataChildByName(child.getQName());
+            if (potential.isPresent()) {
                 return new InstanceIdToCompositeNodes.AugmentationNormalization(aug, parent);
             }
         }
@@ -205,6 +211,8 @@ abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable
             return new InstanceIdToCompositeNodes.ChoiceNodeNormalization((ChoiceSchemaNode) potential);
         } else if (potential instanceof LeafListSchemaNode) {
             return fromLeafListSchemaNode((LeafListSchemaNode) potential);
+        } else if (potential instanceof AnyDataSchemaNode) {
+            return new AnydataNormalization((AnyDataSchemaNode) potential);
         } else if (potential instanceof AnyXmlSchemaNode) {
             return new AnyXmlNormalization((AnyXmlSchemaNode) potential);
         }