BUG-1513: introduce ChoiceSchemaNode
[mdsal.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingSchemaContextUtils.java
index 078c090d27b37cea49cf8b9957eee9f641ffcba3..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()) {
@@ -115,20 +119,23 @@ public class BindingSchemaContextUtils {
 
     private static Optional<DataNodeContainer> findFirstDataNodeContainerInRpc(final SchemaContext ctx,
             final Class<? extends DataObject> targetType) {
+        final YangModuleInfo moduleInfo;
         try {
-            YangModuleInfo moduleInfo = BindingReflections.getModuleInfo(targetType);
-            for(RpcDefinition rpc : ctx.getOperations()) {
-                String rpcNamespace = rpc.getQName().getNamespace().toString();
-                String rpcRevision = rpc.getQName().getFormattedRevision();
-                if(moduleInfo.getNamespace().equals(rpcNamespace) && moduleInfo.getRevision().equals(rpcRevision)) {
-                    Optional<DataNodeContainer> potential = findInputOutput(rpc,targetType.getSimpleName());
-                    if(potential.isPresent()) {
-                        return potential;
-                    }
+            moduleInfo = BindingReflections.getModuleInfo(targetType);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    String.format("Failed to load module information for class %s", targetType), e);
+        }
+
+        for(RpcDefinition rpc : ctx.getOperations()) {
+            String rpcNamespace = rpc.getQName().getNamespace().toString();
+            String rpcRevision = rpc.getQName().getFormattedRevision();
+            if(moduleInfo.getNamespace().equals(rpcNamespace) && moduleInfo.getRevision().equals(rpcRevision)) {
+                Optional<DataNodeContainer> potential = findInputOutput(rpc,targetType.getSimpleName());
+                if(potential.isPresent()) {
+                    return potential;
                 }
             }
-        } catch (Exception e) {
-            // FIXME: Add logging
         }
         return Optional.absent();
     }
@@ -158,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();
+    }
+
 }