Merge "Corrected response status codes from restconf"
[controller.git] / opendaylight / config / yang-jmx-generator / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / ModuleMXBeanEntry.java
index fdc573f9757b1acb2c32162c9f1be757916a3e58..a7110b874c829e00cfaccf4386abf97fb9c7b556 100644 (file)
@@ -7,25 +7,15 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException;
@@ -34,6 +24,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 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;
@@ -50,8 +41,20 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Sets;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
 
 /**
  * Represents part of yang model that describes a module.
@@ -129,13 +132,13 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     private final String nullableDescription, packageName, javaNamePrefix,
             namespace;
 
-    private final Map<String /* java fully qualified name */, String/* identity local name */> providedServices;
+    private final Map<String, QName> providedServices;
 
     private Collection<RuntimeBeanEntry> runtimeBeans;
 
     public ModuleMXBeanEntry(IdentitySchemaNode id,
             Map<String, AttributeIfc> yangToAttributes, String packageName,
-            Map<String, String> providedServices2, String javaNamePrefix,
+            Map<String, QName> providedServices2, String javaNamePrefix,
             String namespace, Collection<RuntimeBeanEntry> runtimeBeans) {
         this.globallyUniqueName = id.getQName().getLocalName();
         this.yangToAttributes = yangToAttributes;
@@ -184,7 +187,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
      * @return services implemented by this module. Keys are fully qualified java names of generated
      * ServiceInterface classes, values are identity local names.
      */
-    public Map<String, String> getProvidedServices() {
+    public Map<String, QName> getProvidedServices() {
         return providedServices;
     }
 
@@ -317,7 +320,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
                     checkState(moduleIdentity != null, "Cannot find identity "
                             + moduleLocalNameFromXPath
                             + " matching augmentation " + augmentation);
-                    Map<String, String> providedServices = findProvidedServices(
+                    Map<String, QName> providedServices = findProvidedServices(
                             moduleIdentity, currentModule, qNamesToSIEs,
                             schemaContext);
 
@@ -339,7 +342,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
                                 moduleLocalNameFromXPath);
                         yangToAttributes = fillConfiguration(choiceCaseNode,
                                 currentModule, typeProviderWrapper,
-                                qNamesToSIEs, schemaContext);
+                                qNamesToSIEs, schemaContext, packageName);
                         checkUniqueAttributesWithGeneratedClass(
                                 uniqueGeneratedClassesNames, when.getQName(),
                                 yangToAttributes);
@@ -485,23 +488,23 @@ public class ModuleMXBeanEntry extends AbstractEntry {
             ChoiceCaseNode choiceCaseNode, Module currentModule,
             TypeProviderWrapper typeProviderWrapper,
             Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext) {
+            SchemaContext schemaContext, String packageName) {
         Map<String, AttributeIfc> yangToAttributes = new HashMap<>();
         for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) {
             AttributeIfc attributeValue = getAttributeValue(attrNode,
                     currentModule, qNamesToSIEs, typeProviderWrapper,
-                    schemaContext);
+                    schemaContext, packageName);
             yangToAttributes.put(attributeValue.getAttributeYangName(),
                     attributeValue);
         }
         return yangToAttributes;
     }
 
-    private static Map<String, String> findProvidedServices(
+    private static Map<String, QName> findProvidedServices(
             IdentitySchemaNode moduleIdentity, Module currentModule,
             Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
             SchemaContext schemaContext) {
-        Map<String, String> result = new HashMap<>();
+        Map<String, QName> result = new HashMap<>();
         for (UnknownSchemaNode unknownNode : moduleIdentity
                 .getUnknownSchemaNodes()) {
             if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME
@@ -510,8 +513,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
                         .getNodeParameter();
                 ServiceInterfaceEntry sie = findSIE(prefixAndIdentityLocalName,
                         currentModule, qNamesToSIEs, schemaContext);
-                result.put(sie.getFullyQualifiedName(), sie.getQName()
-                        .getLocalName());
+                result.put(sie.getFullyQualifiedName(), sie.getQName());
             }
         }
         return result;
@@ -551,11 +553,12 @@ public class ModuleMXBeanEntry extends AbstractEntry {
         }
     }
 
-    private static int getChildNodeSizeWithoutUses(ContainerSchemaNode csn) {
+    private static int getChildNodeSizeWithoutUses(DataNodeContainer csn) {
         int result = 0;
         for (DataSchemaNode dsn : csn.getChildNodes()) {
-            if (dsn.isAddedByUses() == false)
+            if (dsn.isAddedByUses() == false) {
                 result++;
+            }
         }
         return result;
     }
@@ -563,7 +566,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     private static AttributeIfc getAttributeValue(DataSchemaNode attrNode,
             Module currentModule,
             Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            TypeProviderWrapper typeProviderWrapper, SchemaContext schemaContext) {
+            TypeProviderWrapper typeProviderWrapper, SchemaContext schemaContext, String packageName) {
 
         if (attrNode instanceof LeafSchemaNode) {
             // simple type
@@ -572,49 +575,75 @@ public class ModuleMXBeanEntry extends AbstractEntry {
         } else if (attrNode instanceof ContainerSchemaNode) {
             // reference or TO
             ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) attrNode;
-            if (containerSchemaNode.getUses().size() == 1
-                    && getChildNodeSizeWithoutUses(containerSchemaNode) == 0) {
-                // reference
-                UsesNode usesNode = containerSchemaNode.getUses().iterator()
-                        .next();
-                checkState(usesNode.getRefines().size() == 1,
-                        "Unexpected 'refine' child node size of "
-                                + containerSchemaNode);
-                LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines()
-                        .values().iterator().next();
-                checkState(refine.getUnknownSchemaNodes().size() == 1,
-                        "Unexpected unknown schema node size of " + refine);
-                UnknownSchemaNode requiredIdentity = refine
-                        .getUnknownSchemaNodes().iterator().next();
-                checkState(
-                        ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity
-                                .getNodeType()),
-                        "Unexpected language extension " + requiredIdentity);
-                String prefixAndIdentityLocalName = requiredIdentity
-                        .getNodeParameter();
-                // import should point to a module
-                ServiceInterfaceEntry serviceInterfaceEntry = findSIE(
-                        prefixAndIdentityLocalName, currentModule,
-                        qNamesToSIEs, schemaContext);
-                boolean mandatory = refine.getConstraints().isMandatory();
-                return new DependencyAttribute(attrNode, serviceInterfaceEntry,
-                        mandatory, attrNode.getDescription());
+            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(containerSchemaNode,
+                    attrNode, currentModule, qNamesToSIEs, schemaContext);
+            if (dependencyAttributeOptional.isPresent()) {
+                return dependencyAttributeOptional.get();
             } else {
-                return TOAttribute.create(containerSchemaNode,
-                        typeProviderWrapper);
+                return TOAttribute.create(containerSchemaNode, typeProviderWrapper, packageName);
             }
+
         } else if (attrNode instanceof LeafListSchemaNode) {
             return ListAttribute.create((LeafListSchemaNode) attrNode,
                     typeProviderWrapper);
         } else if (attrNode instanceof ListSchemaNode) {
-            return ListAttribute.create((ListSchemaNode) attrNode,
-                    typeProviderWrapper);
+            ListSchemaNode listSchemaNode = (ListSchemaNode) attrNode;
+            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(listSchemaNode,
+                    attrNode, currentModule, qNamesToSIEs, schemaContext);
+            if (dependencyAttributeOptional.isPresent()) {
+                return dependencyAttributeOptional.get();
+            } else {
+                return ListAttribute.create(listSchemaNode, typeProviderWrapper, packageName);
+            }
         } else {
             throw new UnsupportedOperationException(
                     "Unknown configuration node " + attrNode.toString());
         }
     }
 
+    private static Optional<? extends AbstractDependencyAttribute> extractDependency(DataNodeContainer dataNodeContainer,
+                                                            DataSchemaNode attrNode,
+                                                            Module currentModule,
+                                                            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
+                                                            SchemaContext schemaContext) {
+        if (dataNodeContainer.getUses().size() == 1
+                && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) {
+            // reference
+            UsesNode usesNode = dataNodeContainer.getUses().iterator()
+                    .next();
+            checkState(usesNode.getRefines().size() == 1,
+                    "Unexpected 'refine' child node size of "
+                            + dataNodeContainer);
+            LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines()
+                    .values().iterator().next();
+            checkState(refine.getUnknownSchemaNodes().size() == 1,
+                    "Unexpected unknown schema node size of " + refine);
+            UnknownSchemaNode requiredIdentity = refine
+                    .getUnknownSchemaNodes().iterator().next();
+            checkState(
+                    ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity
+                            .getNodeType()),
+                    "Unexpected language extension " + requiredIdentity);
+            String prefixAndIdentityLocalName = requiredIdentity
+                    .getNodeParameter();
+            // import should point to a module
+            ServiceInterfaceEntry serviceInterfaceEntry = findSIE(
+                    prefixAndIdentityLocalName, currentModule,
+                    qNamesToSIEs, schemaContext);
+            boolean mandatory = refine.getConstraints().isMandatory();
+            AbstractDependencyAttribute reference;
+            if (dataNodeContainer instanceof ContainerSchemaNode ){
+                reference = new DependencyAttribute(attrNode, serviceInterfaceEntry,
+                    mandatory, attrNode.getDescription());
+            } else {
+                reference = new ListDependenciesAttribute(attrNode, serviceInterfaceEntry,
+                        mandatory, attrNode.getDescription());
+            }
+            return Optional.of(reference);
+        }
+        return Optional.absent();
+    }
+
     private static ServiceInterfaceEntry findSIE(
             String prefixAndIdentityLocalName, Module currentModule,
             Map<QName, ServiceInterfaceEntry> qNamesToSIEs,