Fix space stripping
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / YangModuleInfoTemplate.xtend
index bb532db3a141dfe573537c5ddc00ec7f7e02c6f8..20dccf49311e4e0b0ff39675dc31ebffd541ffaf 100644 (file)
@@ -7,14 +7,16 @@
  */
 package org.opendaylight.mdsal.binding.java.api.generator
 
-import static org.opendaylight.yangtools.yang.binding.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME
-import static org.opendaylight.yangtools.yang.binding.BindingMapping.MODULE_INFO_CLASS_NAME
-import static extension org.opendaylight.yangtools.yang.binding.BindingMapping.getClassName
-import static extension org.opendaylight.yangtools.yang.binding.BindingMapping.getRootPackageName
+import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.getClassName
+import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.getRootPackageName
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.MODULE_INFO_CLASS_NAME
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.MODULE_INFO_QNAMEOF_METHOD_NAME
 
 import com.google.common.base.Preconditions
 import com.google.common.collect.ImmutableSet
 import java.util.Collections
+import java.util.Comparator
 import java.util.HashSet
 import java.util.LinkedHashMap
 import java.util.Map
@@ -23,6 +25,7 @@ import java.util.Set
 import java.util.TreeMap
 import java.util.function.Function
 import org.eclipse.xtend.lib.annotations.Accessors
+import org.gaul.modernizer_maven_annotations.SuppressModernizer
 import org.opendaylight.mdsal.binding.model.api.ParameterizedType
 import org.opendaylight.mdsal.binding.model.api.Type
 import org.opendaylight.mdsal.binding.model.api.WildcardType
@@ -35,7 +38,15 @@ import org.opendaylight.yangtools.yang.common.Revision
 import org.opendaylight.yangtools.yang.model.api.Module
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
 
+/**
+ * Template for {@link YangModuleInfo} implementation for a particular module. Aside from fulfilling that contract,
+ * this class provides a static {@code createQName(String)} method, which is used by co-generated code to initialize
+ * QNAME constants.
+ */
+@SuppressModernizer
 class YangModuleInfoTemplate {
+    static val Comparator<Optional<Revision>> REVISION_COMPARATOR =
+        [ Optional<Revision> first, Optional<Revision> second | Revision.compare(first, second) ]
 
     val Module module
     val SchemaContext ctx
@@ -58,25 +69,33 @@ class YangModuleInfoTemplate {
     }
 
     def String generate() {
+        val Set<Module> submodules = new HashSet
+        collectSubmodules(submodules, module)
+
         val body = '''
             public final class «MODULE_INFO_CLASS_NAME» extends «ResourceYangModuleInfo.importedName» {
-
+                «val rev = module.revision»
+                private static final «QName.importedName» NAME = «QName.importedName».create("«module.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF»"«module.name»").intern();
                 private static final «YangModuleInfo.importedName» INSTANCE = new «MODULE_INFO_CLASS_NAME»();
 
-                «val rev = module.revision»
-                private final «QName.importedName» name = QName.create("«module.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF»"«module.name»").intern();
                 private final «Set.importedName»<«YangModuleInfo.importedName»> importedModules;
 
                 public static «YangModuleInfo.importedName» getInstance() {
                     return INSTANCE;
                 }
 
-                «classBody(module, MODULE_INFO_CLASS_NAME)»
+                public static «QName.importedName» «MODULE_INFO_QNAMEOF_METHOD_NAME»(final «String.importedName» localName) {
+                    return «QName.importedName».create(NAME, localName).intern();
+                }
+
+                «classBody(module, MODULE_INFO_CLASS_NAME, submodules)»
             }
         '''
         return '''
-            package «packageName» ;
+            package «packageName»;
+
             «imports»
+
             «body»
         '''.toString
     }
@@ -86,7 +105,7 @@ class YangModuleInfoTemplate {
             package «packageName»;
 
             public final class «MODEL_BINDING_PROVIDER_CLASS_NAME» implements «YangModelBindingProvider.name» {
-                @Override
+                @«Override.importedName»
                 public «YangModuleInfo.name» getModuleInfo() {
                     return «MODULE_INFO_CLASS_NAME».getInstance();
                 }
@@ -95,9 +114,17 @@ class YangModuleInfoTemplate {
 
     }
 
-    private def CharSequence classBody(Module m, String className) '''
+    private static def void collectSubmodules(Set<Module> dest, Module module) {
+        for (Module submodule : module.submodules) {
+            if (dest.add(submodule)) {
+                collectSubmodules(dest, submodule)
+            }
+        }
+    }
+
+    private def CharSequence classBody(Module m, String className, Set<Module> submodules) '''
         private «className»() {
-            «IF !m.imports.empty || !m.submodules.empty»
+            «IF !m.imports.empty || !submodules.empty»
                 «Set.importedName»<«YangModuleInfo.importedName»> set = new «HashSet.importedName»<>();
             «ENDIF»
             «IF !m.imports.empty»
@@ -106,7 +133,7 @@ class YangModuleInfoTemplate {
                     «val rev = imp.revision»
                     «IF !rev.present»
                         «val Set<Module> modules = ctx.modules»
-                        «val TreeMap<Optional<Revision>, Module> sorted = new TreeMap()»
+                        «val TreeMap<Optional<Revision>, Module> sorted = new TreeMap(REVISION_COMPARATOR
                         «FOR module : modules»
                             «IF module.name.equals(name)»
                                 «sorted.put(module.revision, module)»
@@ -118,35 +145,31 @@ class YangModuleInfoTemplate {
                     «ENDIF»
                 «ENDFOR»
             «ENDIF»
-            «IF !m.submodules.empty»
-                «FOR submodule : m.submodules»
-                    set.add(«submodule.name.className»Info.getInstance());
-                «ENDFOR»
-            «ENDIF»
-            «IF m.imports.empty && m.submodules.empty»
+            «FOR submodule : submodules»
+                set.add(«submodule.name.className»Info.getInstance());
+            «ENDFOR»
+            «IF m.imports.empty && submodules.empty»
                 importedModules = «Collections.importedName».emptySet();
             «ELSE»
                 importedModules = «ImmutableSet.importedName».copyOf(set);
             «ENDIF»
         }
 
-        @Override
+        @«Override.importedName»
         public «QName.importedName» getName() {
-            return name;
+            return NAME;
         }
 
-        @Override
+        @«Override.importedName»
         protected «String.importedName» resourceName() {
             return "«sourcePath(m)»";
         }
 
-        @Override
+        @«Override.importedName»
         public «Set.importedName»<«YangModuleInfo.importedName»> getImportedModules() {
             return importedModules;
         }
-
-        «generateSubInfo(m)»
-
+        «generateSubInfo(submodules)»
     '''
 
     private def sourcePath(Module module) {
@@ -255,22 +278,23 @@ class YangModuleInfoTemplate {
         return builder.toString()
     }
 
-    private def generateSubInfo(Module module) '''
-        «FOR submodule : module.submodules»
+    private def generateSubInfo(Set<Module> submodules) '''
+        «FOR submodule : submodules»
             «val className = submodule.name.className»
-            private static final class «className»Info extends «ResourceYangModuleInfo.importedName» {
 
+            private static final class «className»Info extends «ResourceYangModuleInfo.importedName» {
+                «val rev = submodule.revision»
+                private final «QName.importedName» NAME = «QName.importedName».create("«
+                    submodule.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF»"«submodule.name»").intern();
                 private static final «YangModuleInfo.importedName» INSTANCE = new «className»Info();
 
-                «val rev = submodule.revision»
-                private final «QName.importedName» name = QName.create("«submodule.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF» "«submodule.name»").intern();
                 private final «Set.importedName»<YangModuleInfo> importedModules;
 
                 public static «YangModuleInfo.importedName» getInstance() {
                     return INSTANCE;
                 }
 
-                «classBody(submodule, className + "Info")»
+                «classBody(submodule, className + "Info", Collections.emptySet
             }
         «ENDFOR»
     '''