BUG-1513: introduce ChoiceSchemaNode
[mdsal.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingSchemaContextUtils.java
index 6645aba5741a64d4deb339ad2f1cd92dcffb15c2..4f8b5acb1821184260b1e670bb3313adf6ef96d3 100644 (file)
@@ -1,9 +1,10 @@
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
@@ -16,17 +17,20 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+public final class BindingSchemaContextUtils {
 
-public class BindingSchemaContextUtils {
+    private BindingSchemaContextUtils() {
+        throw new UnsupportedOperationException("Utility class should not be instantiated");
+    }
 
     // FIXME: THis method does not search in case augmentations.
     public static Optional<DataNodeContainer> findDataNodeContainer(final SchemaContext ctx,
@@ -55,7 +59,7 @@ public class BindingSchemaContextUtils {
                 if(pathArguments.hasNext()) {
                     currentArg = pathArguments.next();
                 } else {
-                    return Optional.absent();
+                    return currentContainer;
                 }
             }
             if(ChildOf.class.isAssignableFrom(currentArg.getType()) && BindingReflections.isAugmentationChild(currentArg.getType())) {
@@ -86,8 +90,8 @@ public class BindingSchemaContextUtils {
             final QName targetQName) {
 
         for (DataSchemaNode child : ctx.getChildNodes()) {
-            if (child instanceof ChoiceNode) {
-                DataNodeContainer potential = findInCases(((ChoiceNode) child), targetQName);
+            if (child instanceof ChoiceSchemaNode) {
+                DataNodeContainer potential = findInCases(((ChoiceSchemaNode) child), targetQName);
                 if (potential != null) {
                     return Optional.of(potential);
                 }
@@ -103,7 +107,7 @@ public class BindingSchemaContextUtils {
         return Optional.absent();
     }
 
-    private static DataNodeContainer findInCases(final ChoiceNode choiceNode, final QName targetQName) {
+    private static DataNodeContainer findInCases(final ChoiceSchemaNode choiceNode, final QName targetQName) {
         for (ChoiceCaseNode caze : choiceNode.getCases()) {
             Optional<DataNodeContainer> potential = findDataNodeContainer(caze, targetQName);
             if (potential.isPresent()) {
@@ -161,4 +165,48 @@ public class BindingSchemaContextUtils {
         return augmentations;
     }
 
+    public static Optional<ChoiceSchemaNode> findInstantiatedChoice(final DataNodeContainer parent, final Class<?> choiceClass) {
+        return findInstantiatedChoice(parent, BindingReflections.findQName(choiceClass));
+    }
+
+    public static Optional<ChoiceSchemaNode> findInstantiatedChoice(final DataNodeContainer ctxNode, final QName choiceName) {
+        DataSchemaNode potential = ctxNode.getDataChildByName(choiceName);
+        if (potential == null) {
+            potential = ctxNode.getDataChildByName(choiceName.getLocalName());
+        }
+
+        if (potential instanceof ChoiceSchemaNode) {
+            return Optional.of((ChoiceSchemaNode) potential);
+        }
+
+        return Optional.absent();
+    }
+
+    public static Optional<ChoiceCaseNode> findInstantiatedCase(final ChoiceSchemaNode instantiatedChoice, final ChoiceCaseNode originalDefinition) {
+        ChoiceCaseNode potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName());
+        if(originalDefinition.equals(potential)) {
+            return Optional.of(potential);
+        }
+        if (potential != null) {
+            SchemaNode potentialRoot = SchemaNodeUtils.getRootOriginalIfPossible(potential);
+            if (originalDefinition.equals(potentialRoot)) {
+                return Optional.of(potential);
+            }
+        }
+        // We try to find case by name, then lookup its root definition
+        // and compare it with original definition
+        // This solves case, if choice was inside grouping
+        // which was used in different module and thus namespaces are
+        // different, but local names are still same.
+        //
+        // Still we need to check equality of definition, because local name is not
+        // sufficient to uniquelly determine equality of cases
+        //
+        potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName().getLocalName());
+        if(potential != null && (originalDefinition.equals(SchemaNodeUtils.getRootOriginalIfPossible(potential)))) {
+            return Optional.of(potential);
+        }
+        return Optional.absent();
+    }
+
 }