BUG-868: remove deprecated use of QName constructors
[controller.git] / opendaylight / config / yang-jmx-generator / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / RuntimeBeanEntry.java
index 6d1eca11933cea8216588d6a94fab9955b173c49..23b071c817022ac0103f7cc01c4cc5f5482ba995 100644 (file)
@@ -10,9 +10,14 @@ package org.opendaylight.controller.config.yangjmxgenerator;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -20,19 +25,21 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -41,10 +48,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-
 /**
  * Holds information about runtime bean to be generated. There are two kinds of
  * RuntimeBeanEntry instances: if isRoot flag is set to true, this bean
@@ -64,11 +67,11 @@ public class RuntimeBeanEntry {
     private final Set<Rpc> rpcs;
 
     @VisibleForTesting
-    public RuntimeBeanEntry(String packageName,
-            DataSchemaNode nodeForReporting, String yangName,
-            String javaNamePrefix, boolean isRoot,
-            Optional<String> keyYangName, List<AttributeIfc> attributes,
-            List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
+    RuntimeBeanEntry(final String packageName,
+            final DataNodeContainer nodeForReporting, final String yangName,
+            final String javaNamePrefix, final boolean isRoot,
+            final Optional<String> keyYangName, final List<AttributeIfc> attributes,
+            final List<RuntimeBeanEntry> children, final Set<Rpc> rpcs) {
 
         checkArgument(isRoot == false || keyYangName.isPresent() == false,
                 "Root RuntimeBeanEntry must not have key " + "set");
@@ -85,7 +88,7 @@ public class RuntimeBeanEntry {
         for (AttributeIfc a : attributes) {
             checkState(map.containsKey(a.getAttributeYangName()) == false,
                     "Attribute already defined: " + a.getAttributeYangName()
-                            + " in " + nodeForReporting);
+                    + " in " + nodeForReporting);
             map.put(a.getAttributeYangName(), a);
         }
 
@@ -109,9 +112,9 @@ public class RuntimeBeanEntry {
      *         not contain special configuration for it.
      */
     public static Map<String, RuntimeBeanEntry> extractClassNameToRuntimeBeanMap(
-            String packageName, ChoiceCaseNode container,
-            String moduleYangName, TypeProviderWrapper typeProviderWrapper,
-            String javaNamePrefix, Module currentModule) {
+            final String packageName, final DataNodeContainer container,
+            final String moduleYangName, final TypeProviderWrapper typeProviderWrapper,
+            final String javaNamePrefix, final Module currentModule) {
 
         Map<QName, Set<RpcDefinition>> identitiesToRpcs = getIdentitiesToRpcs(currentModule);
 
@@ -150,7 +153,7 @@ public class RuntimeBeanEntry {
     }
 
     private static Map<QName/* of identity */, Set<RpcDefinition>> getIdentitiesToRpcs(
-            Module currentModule) {
+            final Module currentModule) {
         // currently only looks for local identities (found in currentModule)
         Map<QName, Set<RpcDefinition>> result = new HashMap<>();
         for (IdentitySchemaNode identity : currentModule.getIdentities()) {
@@ -160,41 +163,44 @@ public class RuntimeBeanEntry {
 
         for (RpcDefinition rpc : currentModule.getRpcs()) {
             ContainerSchemaNode input = rpc.getInput();
-            for (UsesNode uses : input.getUses()) {
-
-                if (uses.getGroupingPath().getPath().size() != 1)
-                    continue;
-
-                // check grouping path
-                QName qname = uses.getGroupingPath().getPath().get(0);
-                if (false == qname
-                        .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME))
-                    continue;
-
-                for (SchemaNode refinedNode : uses.getRefines().values()) {
-
-                    for (UnknownSchemaNode unknownSchemaNode : refinedNode
-                            .getUnknownSchemaNodes()) {
-                        if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
-                                .equals(unknownSchemaNode.getNodeType())) {
-                            String localIdentityName = unknownSchemaNode
-                                    .getNodeParameter();
-                            QName identityQName = new QName(
-                                    currentModule.getNamespace(),
-                                    currentModule.getRevision(),
-                                    localIdentityName);
-                            Set<RpcDefinition> rpcDefinitions = result
-                                    .get(identityQName);
-                            if (rpcDefinitions == null) {
-                                throw new IllegalArgumentException(
-                                        "Identity referenced by rpc not found. Identity:"
-                                                + localIdentityName + " , rpc "
-                                                + rpc);
+            if (input != null) {
+                for (UsesNode uses : input.getUses()) {
+
+                    if (uses.getGroupingPath().getPath().size() != 1) {
+                        continue;
+                    }
+
+                    // check grouping path
+                    QName qname = uses.getGroupingPath().getPath().get(0);
+                    if (false == qname
+                            .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME)) {
+                        continue;
+                    }
+
+                    for (SchemaNode refinedNode : uses.getRefines().values()) {
+
+                        for (UnknownSchemaNode unknownSchemaNode : refinedNode
+                                .getUnknownSchemaNodes()) {
+                            if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
+                                    .equals(unknownSchemaNode.getNodeType())) {
+                                String localIdentityName = unknownSchemaNode
+                                        .getNodeParameter();
+                                QName identityQName = QName.create(
+                                        currentModule.getNamespace(),
+                                        currentModule.getRevision(),
+                                        localIdentityName);
+                                Set<RpcDefinition> rpcDefinitions = result
+                                        .get(identityQName);
+                                if (rpcDefinitions == null) {
+                                    throw new IllegalArgumentException(
+                                            "Identity referenced by rpc not found. Identity:"
+                                                    + localIdentityName + " , rpc "
+                                                    + rpc);
+                                }
+                                rpcDefinitions.add(rpc);
                             }
-                            rpcDefinitions.add(rpc);
                         }
                     }
-
                 }
             }
         }
@@ -206,9 +212,9 @@ public class RuntimeBeanEntry {
      * in subtree.
      */
     private static AttributesRpcsAndRuntimeBeans extractSubtree(
-            String packageName, DataNodeContainer subtree,
-            TypeProviderWrapper typeProviderWrapper, Module currentModule,
-            Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
+            final String packageName, final DataNodeContainer subtree,
+            final TypeProviderWrapper typeProviderWrapper, final Module currentModule,
+            final Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
 
         List<AttributeIfc> attributes = Lists.newArrayList();
         // List<JavaAttribute> javaAttributes = new ArrayList<>();
@@ -225,7 +231,7 @@ public class RuntimeBeanEntry {
                 ContainerSchemaNode container = (ContainerSchemaNode) child;
                 // this can be either TO or hierarchical RB
                 TOAttribute toAttribute = TOAttribute.create(container,
-                        typeProviderWrapper);
+                        typeProviderWrapper, packageName);
                 attributes.add(toAttribute);
             } else if (child instanceof ListSchemaNode) {
                 if (isInnerStateBean(child)) {
@@ -236,13 +242,17 @@ public class RuntimeBeanEntry {
                     runtimeBeanEntries.add(hierarchicalChild);
                 } else /* ordinary list attribute */{
                     ListAttribute listAttribute = ListAttribute.create(
-                            (ListSchemaNode) child, typeProviderWrapper);
+                            (ListSchemaNode) child, typeProviderWrapper, packageName);
                     attributes.add(listAttribute);
                 }
 
+            } else if (child instanceof LeafListSchemaNode) {
+                ListAttribute listAttribute = ListAttribute.create(
+                        (LeafListSchemaNode) child, typeProviderWrapper);
+                attributes.add(listAttribute);
             } else {
-                throw new IllegalStateException("Unknown running-data node "
-                        + child + " , " + "" + "expected leaf or container");
+                throw new IllegalStateException("Unexpected running-data node "
+                        + child);
             }
         }
         Set<Rpc> rpcs = new HashSet<>();
@@ -252,7 +262,7 @@ public class RuntimeBeanEntry {
             if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME
                     .equals(unknownSchemaNode.getNodeType())) {
                 String localIdentityName = unknownSchemaNode.getNodeParameter();
-                QName identityQName = new QName(currentModule.getNamespace(),
+                QName identityQName = QName.create(currentModule.getNamespace(),
                         currentModule.getRevision(), localIdentityName);
                 Set<RpcDefinition> rpcDefinitions = identitiesToRpcs
                         .get(identityQName);
@@ -264,42 +274,28 @@ public class RuntimeBeanEntry {
                 }
                 // convert RpcDefinition to Rpc
                 for (RpcDefinition rpcDefinition : rpcDefinitions) {
-                    String name = ModuleMXBeanEntry
+                    String name = TypeProviderWrapper
                             .findJavaParameter(rpcDefinition);
-                    String returnType;
+                    AttributeIfc returnType;
                     if (rpcDefinition.getOutput() == null
                             || rpcDefinition.getOutput().getChildNodes().size() == 0) {
-                        returnType = "void";
+                        returnType = VoidAttribute.getInstance();
                     } else if (rpcDefinition.getOutput().getChildNodes().size() == 1) {
                         DataSchemaNode returnDSN = rpcDefinition.getOutput()
                                 .getChildNodes().iterator().next();
-                        checkArgument(
-                                returnDSN instanceof LeafSchemaNode,
-                                "Unexpected type of rpc return type. "
-                                        + "Currently only leafs and empty output nodes are supported, got "
-                                        + returnDSN);
-                        LeafSchemaNode returnLeaf = (LeafSchemaNode) returnDSN;
-                        // We currently expect leaf defined in output element in yang to be named result
-                        // FIXME: value of result is fully qualified name - should be extended to accept TOs
-                        String localName = returnLeaf.getQName().getLocalName();
-                        checkArgument(
-                                localName.equals("result"),
-                                "Unexpected name of leaf in output element, expected leaf named result, was %s at %s",
-                                localName, currentModule.getName());
-
-                        returnType = typeProviderWrapper.getType(returnLeaf)
-                                .getFullyQualifiedName();
+                        returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper, packageName);
+
                     } else {
                         throw new IllegalArgumentException(
                                 "More than one child node in rpc output is not supported. "
                                         + "Error occured in " + rpcDefinition);
                     }
                     List<JavaAttribute> parameters = new ArrayList<>();
-                    for (DataSchemaNode childNode : rpcDefinition.getInput()
-                            .getChildNodes()) {
+                    for (DataSchemaNode childNode : sortAttributes(rpcDefinition.getInput()
+                            .getChildNodes())) {
                         if (childNode.isAddedByUses() == false) { // skip
-                                                                  // refined
-                                                                  // context-instance
+                            // refined
+                            // context-instance
                             checkArgument(childNode instanceof LeafSchemaNode, "Unexpected type of rpc input type. "
                                     + "Currently only leafs and empty output nodes are supported, got " + childNode);
                             JavaAttribute javaAttribute = new JavaAttribute(
@@ -318,20 +314,50 @@ public class RuntimeBeanEntry {
                 attributes, rpcs);
     }
 
-    private static boolean isInnerStateBean(DataSchemaNode child) {
+    private static AttributeIfc getReturnTypeAttribute(final DataSchemaNode child, final TypeProviderWrapper typeProviderWrapper,
+            final String packageName) {
+        if (child instanceof LeafSchemaNode) {
+            LeafSchemaNode leaf = (LeafSchemaNode) child;
+            return new JavaAttribute(leaf, typeProviderWrapper);
+        } else if (child instanceof ContainerSchemaNode) {
+            ContainerSchemaNode container = (ContainerSchemaNode) child;
+            TOAttribute toAttribute = TOAttribute.create(container, typeProviderWrapper, packageName);
+            return toAttribute;
+        } else if (child instanceof ListSchemaNode) {
+            return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper, packageName);
+        } else if (child instanceof LeafListSchemaNode) {
+            return ListAttribute.create((LeafListSchemaNode) child, typeProviderWrapper);
+        } else {
+            throw new IllegalStateException("Unknown output data node " + child + " for rpc");
+        }
+    }
+
+    private static Collection<DataSchemaNode> sortAttributes(final Set<DataSchemaNode> childNodes) {
+        final TreeSet<DataSchemaNode> dataSchemaNodes = new TreeSet<>(new Comparator<DataSchemaNode>() {
+            @Override
+            public int compare(final DataSchemaNode o1, final DataSchemaNode o2) {
+                return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
+            }
+        });
+        dataSchemaNodes.addAll(childNodes);
+        return dataSchemaNodes;
+    }
+
+    private static boolean isInnerStateBean(final DataSchemaNode child) {
         for (UnknownSchemaNode unknownSchemaNode : child
                 .getUnknownSchemaNodes()) {
             if (unknownSchemaNode.getNodeType().equals(
-                    ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME))
+                    ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME)) {
                 return true;
+            }
         }
         return false;
     }
 
-    private static RuntimeBeanEntry createHierarchical(String packageName,
-            ListSchemaNode listSchemaNode,
-            TypeProviderWrapper typeProviderWrapper, Module currentModule,
-            Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
+    private static RuntimeBeanEntry createHierarchical(final String packageName,
+            final ListSchemaNode listSchemaNode,
+            final TypeProviderWrapper typeProviderWrapper, final Module currentModule,
+            final Map<QName, Set<RpcDefinition>> identitiesToRpcs) {
 
         // supported are numeric types, strings, enums
         // get all attributes
@@ -353,7 +379,7 @@ public class RuntimeBeanEntry {
                     "More than one key is not supported in " + listSchemaNode);
         }
 
-        String javaNamePrefix = ModuleMXBeanEntry
+        String javaNamePrefix = TypeProviderWrapper
                 .findJavaNamePrefix(listSchemaNode);
 
         RuntimeBeanEntry rbFromAttributes = new RuntimeBeanEntry(packageName,
@@ -366,10 +392,10 @@ public class RuntimeBeanEntry {
         return rbFromAttributes;
     }
 
-    private static RuntimeBeanEntry createRoot(String packageName,
-            DataSchemaNode nodeForReporting, String attributeYangName,
-            List<AttributeIfc> attributes, String javaNamePrefix,
-            List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
+    private static RuntimeBeanEntry createRoot(final String packageName,
+            final DataNodeContainer nodeForReporting, final String attributeYangName,
+            final List<AttributeIfc> attributes, final String javaNamePrefix,
+            final List<RuntimeBeanEntry> children, final Set<Rpc> rpcs) {
         return new RuntimeBeanEntry(packageName, nodeForReporting,
                 attributeYangName, javaNamePrefix, true,
                 Optional.<String> absent(), attributes, children, rpcs);
@@ -421,8 +447,8 @@ public class RuntimeBeanEntry {
         private final Set<Rpc> rpcs;
 
         public AttributesRpcsAndRuntimeBeans(
-                List<RuntimeBeanEntry> runtimeBeanEntries,
-                List<AttributeIfc> attributes, Set<Rpc> rpcs) {
+                final List<RuntimeBeanEntry> runtimeBeanEntries,
+                final List<AttributeIfc> attributes, final Set<Rpc> rpcs) {
             this.runtimeBeanEntries = runtimeBeanEntries;
             this.attributes = attributes;
             this.rpcs = rpcs;
@@ -448,11 +474,11 @@ public class RuntimeBeanEntry {
     public static class Rpc {
         private final String name;
         private final List<JavaAttribute> parameters;
-        private final String returnType;
+        private final AttributeIfc returnType;
         private final String yangName;
 
-        Rpc(String returnType, String name, String yangName,
-                List<JavaAttribute> parameters) {
+        Rpc(final AttributeIfc returnType, final String name, final String yangName,
+                final List<JavaAttribute> parameters) {
             this.returnType = returnType;
             this.name = name;
             this.parameters = parameters;
@@ -471,7 +497,7 @@ public class RuntimeBeanEntry {
             return parameters;
         }
 
-        public String getReturnType() {
+        public AttributeIfc getReturnType() {
             return returnType;
         }
     }
@@ -482,12 +508,12 @@ public class RuntimeBeanEntry {
         return getJavaNameOfRuntimeMXBean(javaNamePrefix);
     }
 
-    public String getFullyQualifiedName(String typeName) {
+    public String getFullyQualifiedName(final String typeName) {
         return FullyQualifiedNameHelper.getFullyQualifiedName(packageName,
                 typeName);
     }
 
-    private static String getJavaNameOfRuntimeMXBean(String javaNamePrefix) {
+    private static String getJavaNameOfRuntimeMXBean(final String javaNamePrefix) {
         return javaNamePrefix + MXBEAN_SUFFIX;
     }