Refactor yang-jmx-generator and -plugin to support list of dependencies. 23/3523/4
authorTomas Olvecky <tolvecky@cisco.com>
Thu, 5 Dec 2013 16:22:16 +0000 (17:22 +0100)
committerTomas Olvecky <tolvecky@cisco.com>
Fri, 6 Dec 2013 13:26:05 +0000 (14:26 +0100)
Change-Id: I87aec9e234588d12ac5ea2dd26509de1c625bbb2
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
24 files changed:
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java
opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/DependencyAttribute.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListAttribute.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/SchemaContextTest.java
opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang
opendaylight/config/yang-test/src/main/yang/config-test-impl.yang
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml

index b0b6f3d..f721895 100644 (file)
@@ -7,19 +7,9 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Pattern;
-
+import com.google.common.annotations.VisibleForTesting;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.AnnotationsDirective;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.ConstructorsDirective;
@@ -33,11 +23,18 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
 
 public class FtlFilePersister {
     private static final Logger logger = LoggerFactory
@@ -56,7 +53,7 @@ public class FtlFilePersister {
                         ftlFile.getFtlTempleteLocation());
                 try {
                     template.process(ftlFile, writer);
-                } catch (TemplateException e) {
+                } catch (Throwable e) {
                     throw new IllegalStateException(
                             "Template error while generating " + ftlFile, e);
                 }
index 3a6ff18..6da6801 100644 (file)
@@ -21,13 +21,13 @@ import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute.Dependency;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter;
@@ -39,6 +39,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Meth
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 
 import javax.management.openmbean.SimpleType;
@@ -112,8 +113,8 @@ public class TemplateFactory {
 
             // convert attributes to getters
             for (AttributeIfc attributeIfc : entry.getAttributes()) {
-                String returnType = null;
-                returnType = getReturnType(entry, attributeIfc);
+                String returnType;
+                returnType = getReturnType(attributeIfc);
                 String getterName = "get"
                         + attributeIfc.getUpperCaseCammelCase();
                 MethodDeclaration getter = new MethodDeclaration(returnType,
@@ -132,7 +133,7 @@ public class TemplateFactory {
                     fields.add(field);
                 }
                 MethodDeclaration operation = new MethodDeclaration(
-                        getReturnType(entry, rpc.getReturnType()), rpc.getName(), fields);
+                        getReturnType(rpc.getReturnType()), rpc.getName(), fields);
                 methods.add(operation);
             }
 
@@ -150,28 +151,35 @@ public class TemplateFactory {
         return result;
     }
 
-    private static String getReturnType(RuntimeBeanEntry entry, AttributeIfc attributeIfc) {
+    // FIXME: put into Type.toString
+    static String serializeType(Type type) {
+        if (type instanceof ParameterizedType){
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            StringBuffer sb = new StringBuffer();
+            sb.append(parameterizedType.getRawType().getFullyQualifiedName());
+            sb.append("<");
+            boolean first = true;
+            for(Type parameter: parameterizedType.getActualTypeArguments()) {
+                if (first) {
+                    first = false;
+                } else {
+                    sb.append(",");
+                }
+                sb.append(serializeType(parameter));
+            }
+            sb.append(">");
+            return sb.toString();
+        } else {
+            return type.getFullyQualifiedName();
+        }
+    }
+
+
+    private static String getReturnType(AttributeIfc attributeIfc) {
         String returnType;
         if (attributeIfc instanceof TypedAttribute) {
-            returnType = ((TypedAttribute) attributeIfc).getType()
-                    .getFullyQualifiedName();
-        } else if (attributeIfc instanceof TOAttribute) {
-            String fullyQualifiedName = FullyQualifiedNameHelper
-                    .getFullyQualifiedName(entry.getPackageName(),
-                            attributeIfc.getUpperCaseCammelCase());
-
-            returnType = fullyQualifiedName;
-        } else if (attributeIfc instanceof ListAttribute) {
-            AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
-                    .getInnerAttribute();
-
-            String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr)
-                    .getType().getFullyQualifiedName()
-                    : FullyQualifiedNameHelper.getFullyQualifiedName(
-                            entry.getPackageName(),
-                            attributeIfc.getUpperCaseCammelCase());
-
-            returnType = "java.util.List<" + innerTpe + ">";
+            Type type = ((TypedAttribute) attributeIfc).getType();
+            returnType = serializeType(type);
         } else if (attributeIfc == VoidAttribute.getInstance()) {
             return "void";
         } else {
@@ -292,8 +300,7 @@ public class TemplateFactory {
     public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe(
             ModuleMXBeanEntry mbe) {
         MXBeanInterfaceAttributesProcessor attrProcessor = new MXBeanInterfaceAttributesProcessor();
-        attrProcessor.processAttributes(mbe.getAttributes(),
-                mbe.getPackageName());
+        attrProcessor.processAttributes(mbe.getAttributes());
         GeneralInterfaceTemplate ifcTemplate = new GeneralInterfaceTemplate(
                 getHeaderFromEntry(mbe), mbe.getPackageName(),
                 mbe.getMXBeanInterfaceName(), Lists.<String> newArrayList(),
@@ -306,7 +313,7 @@ public class TemplateFactory {
             ModuleMXBeanEntry mbe) {
         Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
         TOAttributesProcessor processor = new TOAttributesProcessor();
-        processor.processAttributes(mbe.getAttributes(), mbe.getPackageName());
+        processor.processAttributes(mbe.getAttributes());
         for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
                 .getTOs()) {
             List<Constructor> constructors = Lists.newArrayList();
@@ -345,7 +352,7 @@ public class TemplateFactory {
             yangPropertiesToTypesMap.put(returnType.getAttributeYangName(), returnType);
         }
 
-        processor.processAttributes(yangPropertiesToTypesMap, rbe.getPackageName());
+        processor.processAttributes(yangPropertiesToTypesMap);
         for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
                 .getTOs()) {
             List<Constructor> constructors = Lists.newArrayList();
@@ -372,36 +379,29 @@ public class TemplateFactory {
 
         private final List<TOInternal> tos = Lists.newArrayList();
 
-        void processAttributes(Map<String, AttributeIfc> attributes,
-                String packageName) {
+        void processAttributes(Map<String, AttributeIfc> attributes) {
             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
                 AttributeIfc attributeIfc = attrEntry.getValue();
                 if (attributeIfc instanceof TOAttribute) {
-                    createTOInternal(packageName, attributeIfc);
+                    createTOInternal((TOAttribute) attributeIfc);
                 }
                 if (attributeIfc instanceof ListAttribute) {
                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
                             .getInnerAttribute();
                     if (innerAttr instanceof TOAttribute) {
-                        createTOInternal(packageName, innerAttr);
+                        createTOInternal((TOAttribute) innerAttr);
                     }
                 }
             }
         }
 
-        private void createTOInternal(String packageName,
-                AttributeIfc attributeIfc) {
-            String fullyQualifiedName = FullyQualifiedNameHelper
-                    .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
+        private void createTOInternal(TOAttribute toAttribute) {
 
-            String type = fullyQualifiedName;
-            String name = attributeIfc.getUpperCaseCammelCase();
-            Map<String, AttributeIfc> attrs = ((TOAttribute) attributeIfc)
-                    .getCapitalizedPropertiesToTypesMap();
-            // recursive processing
-            processAttributes(attrs, packageName);
+            Map<String, AttributeIfc> attrs = toAttribute.getCapitalizedPropertiesToTypesMap();
+            // recursive processing of TO's attributes
+            processAttributes(attrs);
 
-            tos.add(new TOInternal(type, name, attrs, packageName));
+            tos.add(new TOInternal(toAttribute.getType(), attrs));
         }
 
         List<TOInternal> getTOs() {
@@ -409,20 +409,22 @@ public class TemplateFactory {
         }
 
         private static class TOInternal {
-            private final String type, name;
+            private final String fullyQualifiedName, name;
             private List<Field> fields;
             private List<MethodDefinition> methods;
 
-            public TOInternal(String type, String name,
+            public TOInternal(Type type, Map<String, AttributeIfc> attrs) {
+                this(type.getFullyQualifiedName(), type.getName(), attrs, type.getPackageName());
+            }
+
+            public TOInternal(String fullyQualifiedName, String name,
                     Map<String, AttributeIfc> attrs, String packageName) {
-                super();
-                this.type = type;
+                this.fullyQualifiedName = fullyQualifiedName;
                 this.name = name;
                 processAttrs(attrs, packageName);
             }
 
-            private void processAttrs(Map<String, AttributeIfc> attrs,
-                    String packageName) {
+            private void processAttrs(Map<String, AttributeIfc> attrs, String packageName) {
                 fields = Lists.newArrayList();
                 methods = Lists.newArrayList();
 
@@ -431,25 +433,14 @@ public class TemplateFactory {
                     String varName = BindingGeneratorUtil
                             .parseToValidParamName(attrEntry.getKey());
 
-                    String fullyQualifiedName = null;
+                    String fullyQualifiedName;
                     if (attrEntry.getValue() instanceof TypedAttribute) {
-                        Type innerType = ((TypedAttribute) attrEntry.getValue())
-                                .getType();
-                        fullyQualifiedName = innerType.getFullyQualifiedName();
-                    } else if (attrEntry.getValue() instanceof ListAttribute) {
-                        AttributeIfc innerAttr = ((ListAttribute) attrEntry
-                                .getValue()).getInnerAttribute();
-
-                        String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr)
-                                .getType().getFullyQualifiedName()
-                                : FullyQualifiedNameHelper
-                                        .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
-
-                        fullyQualifiedName = "java.util.List<" + innerTpe + ">";
-                    } else
+                        Type type = ((TypedAttribute) attrEntry.getValue()).getType();
+                        fullyQualifiedName = serializeType(type);
+                    } else {
                         fullyQualifiedName = FullyQualifiedNameHelper
                                 .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
-
+                    }
                     fields.add(new Field(fullyQualifiedName, varName));
 
                     String getterName = "get" + innerName;
@@ -470,7 +461,7 @@ public class TemplateFactory {
             }
 
             String getType() {
-                return type;
+                return fullyQualifiedName;
             }
 
             String getName() {
@@ -488,38 +479,16 @@ public class TemplateFactory {
     }
 
     private static class MXBeanInterfaceAttributesProcessor {
-        private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List";
         private final List<MethodDeclaration> methods = Lists.newArrayList();
 
-        void processAttributes(Map<String, AttributeIfc> attributes,
-                String packageName) {
+        void processAttributes(Map<String, AttributeIfc> attributes) {
             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
                 String returnType;
                 AttributeIfc attributeIfc = attrEntry.getValue();
 
                 if (attributeIfc instanceof TypedAttribute) {
-                    returnType = ((TypedAttribute) attributeIfc).getType()
-                            .getFullyQualifiedName();
-                } else if (attributeIfc instanceof TOAttribute) {
-                    String fullyQualifiedName = FullyQualifiedNameHelper
-                            .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
-
-                    returnType = fullyQualifiedName;
-                } else if (attributeIfc instanceof ListAttribute) {
-                    String fullyQualifiedName = null;
-
-                    AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
-                            .getInnerAttribute();
-                    if (innerAttr instanceof JavaAttribute) {
-                        fullyQualifiedName = ((JavaAttribute) innerAttr)
-                                .getType().getFullyQualifiedName();
-                    } else if (innerAttr instanceof TOAttribute) {
-                        fullyQualifiedName = FullyQualifiedNameHelper
-                                .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
-                    }
-
-                    returnType = STRING_FULLY_QUALIFIED_NAME.concat("<")
-                            .concat(fullyQualifiedName).concat(">");
+                    TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
+                    returnType = serializeType(typedAttribute.getType());
                 } else {
                     throw new UnsupportedOperationException(
                             "Attribute not supported: "
@@ -565,14 +534,14 @@ public class TemplateFactory {
                 AttributeIfc attributeIfc = attrEntry.getValue();
 
                 if (attributeIfc instanceof TypedAttribute) {
-                    type = ((TypedAttribute) attributeIfc).getType()
-                            .getFullyQualifiedName();
+                    TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
+                    type = serializeType(typedAttribute.getType());
                 } else if (attributeIfc instanceof TOAttribute) {
                     String fullyQualifiedName = FullyQualifiedNameHelper
                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
 
                     type = fullyQualifiedName;
-                } else if (attributeIfc instanceof ListAttribute) {
+                } else if (attributeIfc instanceof ListAttribute) {  //FIXME: listAttribute might extend TypedAttribute
                     String fullyQualifiedName = null;
                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
                             .getInnerAttribute();
@@ -617,8 +586,8 @@ public class TemplateFactory {
                 AttributeIfc attributeIfc = attrEntry.getValue();
 
                 if (attributeIfc instanceof TypedAttribute) {
-                    type = ((TypedAttribute) attributeIfc).getType()
-                            .getFullyQualifiedName();
+                    TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
+                    type = serializeType(typedAttribute.getType());
                 } else if (attributeIfc instanceof TOAttribute) {
                     String fullyQualifiedName = FullyQualifiedNameHelper
                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
@@ -651,9 +620,9 @@ public class TemplateFactory {
                 List<Annotation> annotations = Lists
                         .newArrayList(overrideAnnotation);
 
-                if (attributeIfc instanceof DependencyAttribute) {
+                if (attributeIfc instanceof AbstractDependencyAttribute) {
                     isDependency = true;
-                    dependency = ((DependencyAttribute) attributeIfc)
+                    dependency = ((AbstractDependencyAttribute) attributeIfc)
                             .getDependency();
                     annotations.add(Annotation
                             .createRequireIfcAnnotation(dependency.getSie()));
index 293696d..5624e16 100644 (file)
@@ -7,11 +7,13 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model;
 
+
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency;
+
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute.Dependency;
-
 public class ModuleField extends Field {
 
     private final String nullableDefault, attributeName;
@@ -22,10 +24,14 @@ public class ModuleField extends Field {
             String attributeName, String nullableDefault, boolean isDependency,
             Dependency dependency) {
         super(modifiers, type, name);
-        this.nullableDefault = nullableDefault;
         this.dependent = isDependency;
         this.dependency = dependency;
         this.attributeName = attributeName;
+        if (type.startsWith(List.class.getName()) && nullableDefault == null) {
+            String generics = type.substring(List.class.getName().length());
+            nullableDefault = "new " + ArrayList.class.getName() + generics + "()";
+        }
+        this.nullableDefault = nullableDefault;
     }
 
     public ModuleField(String type, String name, String attributeName,
@@ -49,4 +55,5 @@ public class ModuleField extends Field {
     public String getAttributeName() {
         return attributeName;
     }
+
 }
index d0646f4..f7197d1 100644 (file)
@@ -52,8 +52,14 @@ package ${packageName};
     public void validate(){
     <#list moduleFields as field>
         <#if field.dependent==true && field.dependency.mandatory==true>
+        <#if field.type?starts_with("java.util.List")>
+        for(javax.management.ObjectName dep : ${field.name}) {
+            dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute);
+        }
+        <#else>
         dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute);
         </#if>
+        </#if>
     </#list>
         customValidation();
     }
@@ -65,10 +71,17 @@ package ${packageName};
     // caches of resolved dependencies
     <#list moduleFields as field>
     <#if field.dependent==true>
+        <#if field.type?starts_with("java.util.List")>
+        private java.util.List<${field.dependency.sie.exportedOsgiClassName}> ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
+        protected final java.util.List<${field.dependency.sie.exportedOsgiClassName}> get${field.attributeName}Dependency(){
+            return ${field.name}Dependency;
+        }
+        <#else>
         private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency;
         protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){
             return ${field.name}Dependency;
         }
+        </#if>
     </#if>
     </#list>
 
@@ -79,12 +92,18 @@ package ${packageName};
 
             <#list moduleFields as field>
                 <#if field.dependent==true>
-
                     <#if field.dependency.mandatory==false>
                         if(${field.name}!=null) {
                     </#if>
 
-                    ${field.name}Dependency = dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, ${field.name}, ${field.name}JmxAttribute);
+                    <#if field.type?starts_with("java.util.List")>
+            ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
+            for(javax.management.ObjectName dep : ${field.name}) {
+                ${field.name}Dependency.add(dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, dep, ${field.name}JmxAttribute));
+            }
+                    <#else>
+            ${field.name}Dependency = dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, ${field.name}, ${field.name}JmxAttribute);
+                    </#if>
 
                     <#if field.dependency.mandatory==false>
                         }
index 0d6ec3c..2f14374 100644 (file)
@@ -75,6 +75,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 
+//TODO: refactor
 public class JMXGeneratorTest extends AbstractGeneratorTest {
 
     JMXGenerator jmxGenerator;
@@ -84,19 +85,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
     File generatedResourcesDir;
 
     private static final List<String> expectedModuleFileNames = ServiceInterfaceEntryTest
-            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " +
-                    "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " +
-                    "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " +
-                    "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " +
-                    "AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " +
-                    "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " +
-                    "AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, " +
-                    "DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, " +
-                    "DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, " +
-                    "DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, " +
-                    "EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " +
-                    "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " +
-                    "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
+            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
 
     private static final List<String> expectedBGPNames = ServiceInterfaceEntryTest
             .toFileNames("[AbstractBgpListenerImplModule.java, " + "AbstractBgpListenerImplModuleFactory.java, " +
@@ -119,38 +108,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                     "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " +
                     "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java]");
     private static final List<String> expectedAllFileNames = ServiceInterfaceEntryTest
-            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " +
-                    "AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, " +
-                    "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " +
-                    "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " +
-                    "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " +
-                    "AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, " +
-                    "AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, " +
-                    "AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, " +
-                    "AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, " +
-                    "AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, " +
-                    "AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AsyncEventBusModule.java, " +
-                    "AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " +
-                    "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " +
-                    "AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, " +
-                    "BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java," +
-                    " BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, " +
-                    "BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, " +
-                    "DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, " +
-                    "DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, " +
-                    "DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, " +
-                    "DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, " +
-                    "EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, " +
-                    "EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " +
-                    "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " +
-                    "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, " +
-                    "NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, " +
-                    "NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, " +
-                    "NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, " +
-                    "NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, " +
-                    "NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, " +
-                    "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " +
-                    "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
+            .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
     private static final List<String> expectedGenerateMBEsListNames = ServiceInterfaceEntryTest
             .toFileNames("[AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java]");
 
@@ -381,7 +339,11 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
                         + ".threads.java.DynamicThreadPoolModuleFactory",//
                 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
-                        + ".threads.java.NamingThreadFactoryModuleFactory");
+                        + ".threads.java.NamingThreadFactoryModuleFactory", //
+                PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
+                        + ".threads.java.ThreadPoolRegistryImplModuleFactory");
+
+
         assertThat(lines, equalTo(expectedLines));
 
     }
index 70a4edd..a7110b8 100644 (file)
@@ -8,11 +8,14 @@
 package org.opendaylight.controller.config.yangjmxgenerator;
 
 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;
@@ -21,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;
@@ -338,7 +342,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
                                 moduleLocalNameFromXPath);
                         yangToAttributes = fillConfiguration(choiceCaseNode,
                                 currentModule, typeProviderWrapper,
-                                qNamesToSIEs, schemaContext);
+                                qNamesToSIEs, schemaContext, packageName);
                         checkUniqueAttributesWithGeneratedClass(
                                 uniqueGeneratedClassesNames, when.getQName(),
                                 yangToAttributes);
@@ -484,12 +488,12 @@ 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);
         }
@@ -549,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;
     }
@@ -561,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
@@ -570,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,
index 9b82f12..f19a46d 100644 (file)
@@ -67,7 +67,7 @@ public class RuntimeBeanEntry {
     private final Set<Rpc> rpcs;
 
     @VisibleForTesting
-    public RuntimeBeanEntry(String packageName,
+    RuntimeBeanEntry(String packageName,
             DataSchemaNode nodeForReporting, String yangName,
             String javaNamePrefix, boolean isRoot,
             Optional<String> keyYangName, List<AttributeIfc> attributes,
@@ -228,7 +228,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)) {
@@ -239,7 +239,7 @@ public class RuntimeBeanEntry {
                     runtimeBeanEntries.add(hierarchicalChild);
                 } else /* ordinary list attribute */{
                     ListAttribute listAttribute = ListAttribute.create(
-                            (ListSchemaNode) child, typeProviderWrapper);
+                            (ListSchemaNode) child, typeProviderWrapper, packageName);
                     attributes.add(listAttribute);
                 }
 
@@ -280,7 +280,7 @@ public class RuntimeBeanEntry {
                     } else if (rpcDefinition.getOutput().getChildNodes().size() == 1) {
                         DataSchemaNode returnDSN = rpcDefinition.getOutput()
                                 .getChildNodes().iterator().next();
-                        returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper);
+                        returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper, packageName);
 
                     } else {
                         throw new IllegalArgumentException(
@@ -311,16 +311,17 @@ public class RuntimeBeanEntry {
                 attributes, rpcs);
     }
 
-    private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper) {
+    private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper,
+                                                       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);
+            TOAttribute toAttribute = TOAttribute.create(container, typeProviderWrapper, packageName);
             return toAttribute;
         } else if (child instanceof ListSchemaNode) {
-            return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper);
+            return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper, packageName);
         } else if (child instanceof LeafListSchemaNode) {
             return ListAttribute.create((LeafListSchemaNode) child, typeProviderWrapper);
         } else {
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java
new file mode 100644 (file)
index 0000000..eb1c9e4
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator.attribute;
+
+import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+public abstract class AbstractDependencyAttribute extends AbstractAttribute  implements TypedAttribute  {
+
+    protected final Dependency dependency;
+    protected final String nullableDescription, nullableDefault;
+
+    public AbstractDependencyAttribute(DataSchemaNode attrNode,
+                                       ServiceInterfaceEntry sie, boolean mandatory,
+                                       String nullableDescription) {
+        super(attrNode);
+        dependency = new Dependency(sie, mandatory);
+        this.nullableDescription = nullableDescription;
+        nullableDefault = null;
+    }
+
+    public Dependency getDependency() {
+        return dependency;
+    }
+
+    @Override
+    public String getNullableDescription() {
+        return nullableDescription;
+    }
+
+    @Override
+    public String getNullableDefault() {
+        return nullableDefault;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        if (!super.equals(o))
+            return false;
+
+        AbstractDependencyAttribute that = (AbstractDependencyAttribute) o;
+
+        if (dependency != null ? !dependency.equals(that.dependency)
+                : that.dependency != null)
+            return false;
+        if (nullableDefault != null ? !nullableDefault
+                .equals(that.nullableDefault) : that.nullableDefault != null)
+            return false;
+        if (nullableDescription != null ? !nullableDescription
+                .equals(that.nullableDescription)
+                : that.nullableDescription != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (dependency != null ? dependency.hashCode() : 0);
+        result = 31
+                * result
+                + (nullableDescription != null ? nullableDescription.hashCode()
+                        : 0);
+        result = 31 * result
+                + (nullableDefault != null ? nullableDefault.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName() + "{" + getAttributeYangName() + ","
+                + "dependency=" + dependency + '}';
+    }
+
+
+}
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java
new file mode 100644 (file)
index 0000000..38de6e1
--- /dev/null
@@ -0,0 +1,45 @@
+package org.opendaylight.controller.config.yangjmxgenerator.attribute;
+
+import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
+
+public class Dependency {
+        private final ServiceInterfaceEntry sie;
+        private final boolean mandatory;
+
+        public Dependency(ServiceInterfaceEntry sie, boolean mandatory) {
+            this.sie = sie;
+            this.mandatory = mandatory;
+        }
+
+        public ServiceInterfaceEntry getSie() {
+            return sie;
+        }
+
+        public boolean isMandatory() {
+            return mandatory;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            Dependency that = (Dependency) o;
+
+            if (mandatory != that.mandatory)
+                return false;
+            if (!sie.equals(that.sie))
+                return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = sie.hashCode();
+            result = 31 * result + (mandatory ? 1 : 0);
+            return result;
+        }
+    }
index 1912b75..d8df78a 100644 (file)
@@ -15,19 +15,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import javax.management.ObjectName;
 import javax.management.openmbean.SimpleType;
 
-public class DependencyAttribute extends AbstractAttribute implements
-        TypedAttribute {
+public class DependencyAttribute extends AbstractDependencyAttribute {
 
-    private final Dependency dependency;
-    private final String nullableDescription, nullableDefault;
 
     public DependencyAttribute(DataSchemaNode attrNode,
             ServiceInterfaceEntry sie, boolean mandatory,
             String nullableDescription) {
-        super(attrNode);
-        dependency = new Dependency(sie, mandatory);
-        this.nullableDescription = nullableDescription;
-        nullableDefault = null;
+        super(attrNode, sie, mandatory, nullableDescription);
     }
 
     @Override
@@ -35,109 +29,9 @@ public class DependencyAttribute extends AbstractAttribute implements
         return Types.typeForClass(ObjectName.class);
     }
 
-    public Dependency getDependency() {
-        return dependency;
-    }
-
-    @Override
-    public String getNullableDescription() {
-        return nullableDescription;
-    }
-
-    @Override
-    public String getNullableDefault() {
-        return nullableDefault;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        if (!super.equals(o))
-            return false;
-
-        DependencyAttribute that = (DependencyAttribute) o;
-
-        if (dependency != null ? !dependency.equals(that.dependency)
-                : that.dependency != null)
-            return false;
-        if (nullableDefault != null ? !nullableDefault
-                .equals(that.nullableDefault) : that.nullableDefault != null)
-            return false;
-        if (nullableDescription != null ? !nullableDescription
-                .equals(that.nullableDescription)
-                : that.nullableDescription != null)
-            return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = super.hashCode();
-        result = 31 * result + (dependency != null ? dependency.hashCode() : 0);
-        result = 31
-                * result
-                + (nullableDescription != null ? nullableDescription.hashCode()
-                        : 0);
-        result = 31 * result
-                + (nullableDefault != null ? nullableDefault.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "DependencyAttribute{" + getAttributeYangName() + ","
-                + "dependency=" + dependency + '}';
-    }
-
     @Override
     public SimpleType<?> getOpenType() {
         return SimpleType.OBJECTNAME;
     }
 
-    public static class Dependency {
-        private final ServiceInterfaceEntry sie;
-        private final boolean mandatory;
-
-        public Dependency(ServiceInterfaceEntry sie, boolean mandatory) {
-            this.sie = sie;
-            this.mandatory = mandatory;
-        }
-
-        public ServiceInterfaceEntry getSie() {
-            return sie;
-        }
-
-        public boolean isMandatory() {
-            return mandatory;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o)
-                return true;
-            if (o == null || getClass() != o.getClass())
-                return false;
-
-            Dependency that = (Dependency) o;
-
-            if (mandatory != that.mandatory)
-                return false;
-            if (!sie.equals(that.sie))
-                return false;
-
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = sie.hashCode();
-            result = 31 * result + (mandatory ? 1 : 0);
-            return result;
-        }
-    }
-
 }
index 083b0b5..73b557e 100644 (file)
@@ -7,24 +7,27 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.attribute;
 
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
+import org.opendaylight.yangtools.binding.generator.util.Types;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
-public class ListAttribute extends AbstractAttribute {
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import java.util.List;
+
+public class ListAttribute extends AbstractAttribute implements TypedAttribute {
 
     private final String nullableDescription, nullableDefault;
-    private final AttributeIfc innerAttribute;
+    private final TypedAttribute innerAttribute;
 
     public static ListAttribute create(ListSchemaNode node,
-            TypeProviderWrapper typeProvider) {
+            TypeProviderWrapper typeProvider, String packageName) {
 
-        AttributeIfc innerAttribute = TOAttribute.create(node, typeProvider);
+        TOAttribute innerAttribute = TOAttribute.create(node, typeProvider, packageName);
 
         return new ListAttribute(node, innerAttribute, node.getDescription());
     }
@@ -32,12 +35,12 @@ public class ListAttribute extends AbstractAttribute {
     public static ListAttribute create(LeafListSchemaNode node,
             TypeProviderWrapper typeProvider) {
 
-        AttributeIfc innerAttribute = new JavaAttribute(node, typeProvider);
+        JavaAttribute innerAttribute = new JavaAttribute(node, typeProvider);
 
         return new ListAttribute(node, innerAttribute, node.getDescription());
     }
 
-    ListAttribute(DataSchemaNode attrNode, AttributeIfc innerAttribute,
+    ListAttribute(DataSchemaNode attrNode, TypedAttribute innerAttribute,
             String description) {
         super(attrNode);
         this.nullableDescription = description;
@@ -99,14 +102,24 @@ public class ListAttribute extends AbstractAttribute {
         return true;
     }
 
+
+    @Override
+    public Type getType() {
+        return Types.parameterizedTypeFor(Types.typeForClass(List.class), innerAttribute.getType());
+    }
+
     @Override
     public ArrayType<?> getOpenType() {
-        OpenType<?> inerOpenType = innerAttribute.getOpenType();
+        OpenType<?> innerOpenType = innerAttribute.getOpenType();
+        return constructArrayType(innerOpenType);
+    }
+
+    static ArrayType<?> constructArrayType(OpenType<?> innerOpenType){
         try {
-            return new ArrayType<>(1, inerOpenType);
+            return new ArrayType<>(1, innerOpenType);
         } catch (OpenDataException e) {
             throw new RuntimeException("Unable to create " + ArrayType.class
-                    + " with inner element of type " + inerOpenType, e);
+                    + " with inner element of type " + innerOpenType, e);
         }
     }
 
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java
new file mode 100644 (file)
index 0000000..641099a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator.attribute;
+
+import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
+import org.opendaylight.yangtools.binding.generator.util.Types;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+import javax.management.ObjectName;
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import java.util.List;
+
+public class ListDependenciesAttribute extends AbstractDependencyAttribute {
+
+    public ListDependenciesAttribute(DataSchemaNode attrNode, ServiceInterfaceEntry sie, boolean mandatory, String nullableDescription) {
+        super(attrNode, sie, mandatory, nullableDescription);
+    }
+
+    @Override
+    public Type getType() {
+        return Types.parameterizedTypeFor(Types.typeForClass(List.class), Types.typeForClass(ObjectName.class));
+    }
+
+    @Override
+    public ArrayType<?> getOpenType() {
+        OpenType<?> innerOpenType = SimpleType.OBJECTNAME;
+        return ListAttribute.constructArrayType(innerOpenType);
+    }
+
+}
index 9665633..6a540b5 100644 (file)
@@ -13,6 +13,8 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
+import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -29,11 +31,12 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-public class TOAttribute extends AbstractAttribute {
+public class TOAttribute extends AbstractAttribute implements TypedAttribute {
 
     private final String nullableDescription, nullableDefault;
     private final Map<String, AttributeIfc> yangNameToAttributeMap;
     private final Map<String, String> attributeNameMap;
+    private final String packageName;
 
     private static final Set<Class<? extends DataSchemaNode>> ALLOWED_CHILDREN = Sets
             .newHashSet();
@@ -45,7 +48,7 @@ public class TOAttribute extends AbstractAttribute {
     }
 
     public static <T extends DataNodeContainer & AugmentationTarget & DataSchemaNode> TOAttribute create(
-            T containerSchemaNode, TypeProviderWrapper typeProviderWrapper) {
+            T containerSchemaNode, TypeProviderWrapper typeProviderWrapper, String packageName) {
         // Transfer Object: get the leaves
         Map<String, AttributeIfc> map = new HashMap<>();
         Map<String, String> attributeNameMap = new HashMap<>();
@@ -55,18 +58,18 @@ public class TOAttribute extends AbstractAttribute {
                 String yangName = dataSchemaNode.getQName().getLocalName();
                 map.put(yangName,
                         createInnerAttribute(dataSchemaNode,
-                                typeProviderWrapper));
+                                typeProviderWrapper, packageName));
             } catch (IllegalArgumentException e) {
                 throw new IllegalStateException("Unable to create TO", e);
             }
         }
         return new TOAttribute(containerSchemaNode, map, attributeNameMap,
-                containerSchemaNode.getDescription());
+                containerSchemaNode.getDescription(), packageName);
     }
 
     private static AttributeIfc createInnerAttribute(
             DataSchemaNode dataSchemaNode,
-            TypeProviderWrapper typeProviderWrapper) {
+            TypeProviderWrapper typeProviderWrapper, String packageName) {
         Class<? extends DataSchemaNode> type = isAllowedType(dataSchemaNode);
 
         if (type.equals(LeafSchemaNode.class))
@@ -74,13 +77,13 @@ public class TOAttribute extends AbstractAttribute {
                     typeProviderWrapper);
         else if (type.equals(ListSchemaNode.class))
             return ListAttribute.create((ListSchemaNode) dataSchemaNode,
-                    typeProviderWrapper);
+                    typeProviderWrapper, packageName);
         else if (type.equals(LeafListSchemaNode.class))
             return ListAttribute.create((LeafListSchemaNode) dataSchemaNode,
                     typeProviderWrapper);
         else if (type.equals(ContainerSchemaNode.class))
             return TOAttribute.create((ContainerSchemaNode) dataSchemaNode,
-                    typeProviderWrapper);
+                    typeProviderWrapper, packageName);
 
         throw new IllegalStateException("This should never happen");
     }
@@ -98,12 +101,13 @@ public class TOAttribute extends AbstractAttribute {
 
     private TOAttribute(DataSchemaNode attrNode,
             Map<String, AttributeIfc> transferObject,
-            Map<String, String> attributeNameMap, String nullableDescription) {
+            Map<String, String> attributeNameMap, String nullableDescription, String packageName) {
         super(attrNode);
         yangNameToAttributeMap = transferObject;
         this.attributeNameMap = attributeNameMap;
         this.nullableDescription = nullableDescription;
         nullableDefault = null;
+        this.packageName = packageName;
     }
 
     public Map<String, String> getAttributeNameMap() {
@@ -197,6 +201,12 @@ public class TOAttribute extends AbstractAttribute {
                 + yangNameToAttributeMap + '}';
     }
 
+    @Override
+    public Type getType() {
+        // TODO: ReferencedTypeImpl from Types
+        return new ReferencedTypeImpl(packageName, getUpperCaseCammelCase());
+    }
+
     @Override
     public CompositeType getOpenType() {
         String description = getNullableDescription() == null ? getAttributeYangName()
@@ -222,6 +232,10 @@ public class TOAttribute extends AbstractAttribute {
         }
     }
 
+    public String getPackageName() {
+        return packageName;
+    }
+
     private static final class FunctionImpl implements
             Function<Entry<String, AttributeIfc>, OpenType<?>> {
         private final String[] itemNames;
index 661dbd7..e86c876 100644 (file)
@@ -7,38 +7,14 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.SimpleType;
-
+import com.google.common.collect.Sets;
 import org.junit.Before;
 import org.junit.Test;
 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.attribute.TypedAttribute;
 import org.opendaylight.yangtools.binding.generator.util.Types;
@@ -48,13 +24,37 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 
-import com.google.common.collect.Sets;
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.SimpleType;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class ModuleMXBeanEntryTest extends AbstractYangTest {
     public static final String EVENTBUS_MXB_NAME = "eventbus";
     public static final String ASYNC_EVENTBUS_MXB_NAME = "async-eventbus";
     public static final String THREADFACTORY_NAMING_MXB_NAME = "threadfactory-naming";
     public static final String THREADPOOL_DYNAMIC_MXB_NAME = "threadpool-dynamic";
+    public static final String THREADPOOL_REGISTRY_IMPL_NAME = "threadpool-registry-impl";
 
     public static final String BGP_LISTENER_IMPL_MXB_NAME = "bgp-listener-impl";
 
@@ -87,7 +87,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
         assertNotNull(namesToMBEs);
         Set<String> expectedMXBeanNames = Sets.newHashSet(EVENTBUS_MXB_NAME,
                 ASYNC_EVENTBUS_MXB_NAME, THREADFACTORY_NAMING_MXB_NAME,
-                THREADPOOL_DYNAMIC_MXB_NAME);
+                THREADPOOL_DYNAMIC_MXB_NAME, THREADPOOL_REGISTRY_IMPL_NAME);
         assertThat(namesToMBEs.keySet(), is(expectedMXBeanNames));
         return namesToMBEs;
     }
@@ -299,6 +299,15 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
             }
 
         }
+        { // test multiple dependencies
+            ModuleMXBeanEntry threadPoolRegistry = namesToMBEs.get(THREADPOOL_REGISTRY_IMPL_NAME);
+            Map<String, AttributeIfc> attributes = threadPoolRegistry.getAttributes();
+            assertEquals(1, attributes.size());
+            AttributeIfc threadpoolsAttr = attributes.get("threadpools");
+            assertNotNull(threadpoolsAttr);
+            assertTrue(threadpoolsAttr instanceof ListDependenciesAttribute);
+            ListDependenciesAttribute threadpools = (ListDependenciesAttribute) threadpoolsAttr;
+        }
     }
 
 }
index 24c0257..14ec7e0 100644 (file)
@@ -100,10 +100,15 @@ public class SchemaContextTest extends AbstractYangTest {
 
     @Test
     public void testReadingIdentities_threadsJavaModule() {
-        Map<String /* identity name */, Optional<QName>> expectedIdentitiesToBases = ImmutableMap
-                .of("eventbus", Optional.of(MODULE_TYPE_Q_NAME), "async-eventbus", Optional.of(MODULE_TYPE_Q_NAME),
-                        "threadfactory-naming", Optional.of(MODULE_TYPE_Q_NAME), "threadpool-dynamic",
-                        Optional.of(MODULE_TYPE_Q_NAME), "thread-rpc-context", Optional.<QName>absent());
+        Map<String /* identity name */, Optional<QName>> expectedIdentitiesToBases = new HashMap(){{
+            put(ModuleMXBeanEntryTest.EVENTBUS_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME));
+            put(ModuleMXBeanEntryTest.ASYNC_EVENTBUS_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME));
+            put(ModuleMXBeanEntryTest.THREADFACTORY_NAMING_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME));
+            put(ModuleMXBeanEntryTest.THREADPOOL_DYNAMIC_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME));
+            put("thread-rpc-context", Optional.absent());
+            put(ModuleMXBeanEntryTest.THREADPOOL_REGISTRY_IMPL_NAME, Optional.of(MODULE_TYPE_Q_NAME));
+        }};
+
         assertAllIdentitiesAreExpected(threadsJavaModule,
                 expectedIdentitiesToBases);
     }
index 2972cec..4af5b95 100644 (file)
@@ -241,4 +241,25 @@ module config-threads-java {
             }
         }
     }
+
+    identity threadpool-registry-impl {
+        base config:module-type;
+        config:java-name-prefix ThreadPoolRegistryImpl;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case threadpool-registry-impl {
+            when "/config:modules/config:module/config:type = 'threadpool-registry-impl'";
+
+            // list of dependencies:
+            list threadpools {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity th2:threadpool;
+                    }
+                }
+            }
+        }
+    }
 }
index ba5021e..bd83a4c 100644 (file)
@@ -242,6 +242,15 @@ module config-test-impl {
                     }
                 }
             }
+
+            list testing-deps {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity test:testing;
+                    }
+                }
+            }
         }
     }
 
index 4b6dcfd..2b6f862 100644 (file)
@@ -12,6 +12,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIf
 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 javax.management.openmbean.ArrayType;
@@ -37,7 +38,9 @@ public abstract class AttributeIfcSwitchStatement<T> {
         } else if (attributeIfc instanceof DependencyAttribute) {
             return caseDependencyAttribute(((DependencyAttribute) attributeIfc).getOpenType());
         } else if (attributeIfc instanceof ListAttribute) {
-            return caseListAttribute(((ListAttribute) attributeIfc).getOpenType());
+            return caseListAttribute((ArrayType<?>) attributeIfc.getOpenType());
+        } else if (attributeIfc instanceof ListDependenciesAttribute) {
+            return caseListDependeciesAttribute((ArrayType<?>) attributeIfc.getOpenType());
         } else if (attributeIfc instanceof TOAttribute) {
             return caseTOAttribute(((TOAttribute) attributeIfc).getOpenType());
         }
@@ -45,6 +48,7 @@ public abstract class AttributeIfcSwitchStatement<T> {
         throw getIllegalArgumentException(attributeIfc);
     }
 
+
     private IllegalArgumentException getIllegalArgumentException(AttributeIfc attributeIfc) {
         return new IllegalArgumentException("Unknown attribute type " + attributeIfc.getClass() + ", " + attributeIfc
                 + " with open type:" + attributeIfc.getOpenType());
@@ -74,6 +78,7 @@ public abstract class AttributeIfcSwitchStatement<T> {
 
     protected abstract T caseListAttribute(ArrayType<?> openType);
 
+    protected abstract T caseListDependeciesAttribute(ArrayType<?> openType);
 
     private static class UnknownOpenTypeException extends RuntimeException {
         public UnknownOpenTypeException(String message) {
index bc3c74a..e2ea404 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 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.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
 
@@ -86,4 +87,11 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadin
         return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
     }
 
+    @Override
+    protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
+        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
+        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+    }
+
 }
index 853197c..6e5bd0d 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
 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.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
@@ -121,4 +122,10 @@ public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingSt
                 prepareStrategy(((ListAttribute) lastAttribute).getInnerAttribute()));
     }
 
+    @Override
+    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
+        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME));
+    }
+
 }
index c321164..f5a2511 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 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.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
@@ -109,4 +110,10 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
         return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType);
     }
 
+    @Override
+    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
+        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType);
+    }
+
 }
index 99e9699..ad587ea 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 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.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
 import org.w3c.dom.Document;
@@ -96,4 +97,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
         return new ArrayAttributeWritingStrategy(innerStrategy);
     }
 
+    @Override
+    protected AttributeWritingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
+        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
+        return new ArrayAttributeWritingStrategy(innerStrategy);
+    }
+
 }
index d91e38d..1e01a9f 100644 (file)
@@ -136,6 +136,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         checkBinaryLeafEdited(response);
         checkTypeConfigAttribute(response);
         checkTypedefs(response);
+        checkTestingDeps(response);
         checkEnum(response);
         checkBigDecimal(response);
 
@@ -163,11 +164,6 @@ public class NetconfMappingTest extends AbstractConfigTest {
         verifyNoMoreInteractions(netconfOperationRouter);
     }
 
-    private void checkBigDecimal(Element response) {
-        int size = response.getElementsByTagName("sleep-factor").getLength();
-        assertEquals(1, size);
-    }
-
     private void closeSession() throws NetconfDocumentedException, ParserConfigurationException, SAXException,
             IOException {
         DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID);
@@ -394,6 +390,17 @@ public class NetconfMappingTest extends AbstractConfigTest {
         fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response));
     }
 
+    private void checkTestingDeps(Element response) {
+        int testingDepsSize = response.getElementsByTagName("testing-deps").getLength();
+        assertEquals(2, testingDepsSize);
+    }
+
+    private void checkBigDecimal(Element response) {
+        int size = response.getElementsByTagName("sleep-factor").getLength();
+        assertEquals(1, size);
+    }
+
+
     private void checkTypeConfigAttribute(Element response) {
 
         XmlElement modulesElement = XmlElement.fromDomElement(response).getOnlyChildElement("data")
index caa0094..9bf0042 100644 (file)
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
                         <name>ref_dep</name>
                     </testing-dep>
+
+                    <testing-deps>
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+                        <name>ref_dep</name>
+                    </testing-deps>
+                    <testing-deps>
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+                        <name>ref_dep_2</name>
+                    </testing-deps>
                 </module>
 
                 <module>

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.