Bug 6859 - Binding generator v1 refactoring
[controller.git] / opendaylight / config / yang-jmx-generator-plugin / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / plugin / JMXGenerator.java
index c8356274f8144095581e504e8b45680051be319d..34480b9d1086e77a0bc99295f199781f4767c9ff 100644 (file)
@@ -12,110 +12,118 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.plugin.logging.Log;
+import com.google.common.io.Files;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.apache.maven.project.MavenProject;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
-import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
+import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.slf4j.impl.StaticLoggerBinder;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * This class interfaces with yang-maven-plugin. Gets parsed yang modules in
  * {@link SchemaContext}, and parameters form the plugin configuration, and
  * writes service interfaces and/or modules.
  */
-public class JMXGenerator implements CodeGenerator {
+public class JMXGenerator implements BasicCodeGenerator, MavenProjectAware {
+    private static final class NamespaceMapping {
+        private final String namespace, packageName;
+
+        public NamespaceMapping(final String namespace, final String packagename) {
+            this.namespace = namespace;
+            this.packageName = packagename;
+        }
+    }
 
+    @VisibleForTesting
     static final String NAMESPACE_TO_PACKAGE_DIVIDER = "==";
+    @VisibleForTesting
     static final String NAMESPACE_TO_PACKAGE_PREFIX = "namespaceToPackage";
+    @VisibleForTesting
     static final String MODULE_FACTORY_FILE_BOOLEAN = "moduleFactoryFile";
 
-    private PackageTranslator packageTranslator;
+    private static final Logger LOG = LoggerFactory.getLogger(JMXGenerator.class);
+    private static final Pattern NAMESPACE_MAPPING_PATTERN = Pattern.compile("(.+)" + NAMESPACE_TO_PACKAGE_DIVIDER + "(.+)");
+
     private final CodeWriter codeWriter;
-    private static final Logger LOGGER = LoggerFactory
-            .getLogger(JMXGenerator.class);
     private Map<String, String> namespaceToPackageMapping;
     private File resourceBaseDir;
     private File projectBaseDir;
     private boolean generateModuleFactoryFile = true;
 
     public JMXGenerator() {
-        this.codeWriter = new CodeWriter();
+        this(new CodeWriter());
     }
 
-    public JMXGenerator(CodeWriter codeWriter) {
+    public JMXGenerator(final CodeWriter codeWriter) {
         this.codeWriter = codeWriter;
     }
 
     @Override
-    public Collection<File> generateSources(SchemaContext context,
-                                            File outputBaseDir, Set<Module> yangModulesInCurrentMavenModule) {
+    public Collection<File> generateSources(final SchemaContext context,
+                                            final File outputBaseDir, final Set<Module> yangModulesInCurrentMavenModule) {
 
         Preconditions.checkArgument(context != null, "Null context received");
         Preconditions.checkArgument(outputBaseDir != null,
                 "Null outputBaseDir received");
 
         Preconditions
-                .checkArgument(namespaceToPackageMapping != null && !namespaceToPackageMapping.isEmpty(),
+                .checkArgument((this.namespaceToPackageMapping != null) && !this.namespaceToPackageMapping.isEmpty(),
                         "No namespace to package mapping provided in additionalConfiguration");
 
-        packageTranslator = new PackageTranslator(namespaceToPackageMapping);
+        final PackageTranslator packageTranslator = new PackageTranslator(this.namespaceToPackageMapping);
 
         if (!outputBaseDir.exists()) {
             outputBaseDir.mkdirs();
         }
 
-        GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
+        final GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
         // create SIE structure qNamesToSIEs
-        Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
+        final Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
 
 
-        Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
-        for (Module module : context.getModules()) {
-            String packageName = packageTranslator.getPackageName(module);
-            Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
+        final Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
+        for (final Module module : context.getModules()) {
+            final String packageName = packageTranslator.getPackageName(module);
+            final Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
                     .create(module, packageName, knownSEITracker);
 
-            for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
+            for (final Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
                     .entrySet()) {
                 // merge value into qNamesToSIEs
-                if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
-                    qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
-                } else {
+                if (qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue()) != null) {
                     throw new IllegalStateException(
-                        "Cannot add two SIE  with same qname "
+                        "Cannot add two SIE with same qname "
                                 + sieEntry.getValue());
                 }
             }
             if (yangModulesInCurrentMavenModule.contains(module)) {
                 // write this sie to disk
-                for (ServiceInterfaceEntry sie : namesToSIEntries.values()) {
+                for (final ServiceInterfaceEntry sie : namesToSIEntries.values()) {
                     try {
-                        generatedFiles.addFile(codeWriter.writeSie(sie,
+                        generatedFiles.addFile(this.codeWriter.writeSie(sie,
                                 outputBaseDir));
-                    } catch (Exception e) {
+                    } catch (final Exception e) {
                         throw new RuntimeException(
                                 "Error occurred during SIE source generate phase",
                                 e);
@@ -124,26 +132,26 @@ public class JMXGenerator implements CodeGenerator {
             }
         }
 
-        File mainBaseDir = concatFolders(projectBaseDir, "src", "main", "java");
-        Preconditions.checkNotNull(resourceBaseDir,
+        final File mainBaseDir = concatFolders(this.projectBaseDir, "src", "main", "java");
+        Preconditions.checkNotNull(this.resourceBaseDir,
                 "resource base dir attribute was null");
 
-        StringBuilder fullyQualifiedNamesOfFactories = new StringBuilder();
+        final StringBuilder fullyQualifiedNamesOfFactories = new StringBuilder();
         // create MBEs
-        for (Module module : yangModulesInCurrentMavenModule) {
-            String packageName = packageTranslator.getPackageName(module);
-            Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
+        for (final Module module : yangModulesInCurrentMavenModule) {
+            final String packageName = packageTranslator.getPackageName(module);
+            final Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
                     .create(module, qNamesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context)),
                             packageName);
 
-            for (Entry<String, ModuleMXBeanEntry> mbeEntry : namesToMBEs
+            for (final Entry<String, ModuleMXBeanEntry> mbeEntry : namesToMBEs
                     .entrySet()) {
-                ModuleMXBeanEntry mbe = mbeEntry.getValue();
+                final ModuleMXBeanEntry mbe = mbeEntry.getValue();
                 try {
-                    List<File> files1 = codeWriter.writeMbe(mbe, outputBaseDir,
+                    final List<File> files1 = this.codeWriter.writeMbe(mbe, outputBaseDir,
                             mainBaseDir);
                     generatedFiles.addFile(files1);
-                } catch (Exception e) {
+                } catch (final Exception e) {
                     throw new RuntimeException(
                             "Error occurred during MBE source generate phase",
                             e);
@@ -154,70 +162,53 @@ public class JMXGenerator implements CodeGenerator {
             }
         }
         // create ModuleFactory file if needed
-        if (fullyQualifiedNamesOfFactories.length() > 0
-                && generateModuleFactoryFile) {
-            File serviceLoaderFile = JMXGenerator.concatFolders(
-                    resourceBaseDir, "META-INF", "services",
+        if ((fullyQualifiedNamesOfFactories.length() > 0)
+                && this.generateModuleFactoryFile) {
+            final File serviceLoaderFile = JMXGenerator.concatFolders(
+                    this.resourceBaseDir, "META-INF", "services",
                     ModuleFactory.class.getName());
             // if this file does not exist, create empty file
             serviceLoaderFile.getParentFile().mkdirs();
             try {
                 serviceLoaderFile.createNewFile();
-                FileUtils.write(serviceLoaderFile,
-                        fullyQualifiedNamesOfFactories.toString());
-            } catch (IOException e) {
-                String message = "Cannot write to " + serviceLoaderFile;
-                LOGGER.error(message);
+                Files.write(fullyQualifiedNamesOfFactories.toString(), serviceLoaderFile, StandardCharsets.UTF_8);
+            } catch (final IOException e) {
+                final String message = "Cannot write to " + serviceLoaderFile;
+                LOG.error(message, e);
                 throw new RuntimeException(message, e);
             }
         }
         return generatedFiles.getFiles();
     }
 
-    static File concatFolders(File projectBaseDir, String... folderNames) {
-        StringBuilder b = new StringBuilder();
-        for (String folder : folderNames) {
-            b.append(folder);
-            b.append(File.separator);
+    @VisibleForTesting
+    static File concatFolders(final File projectBaseDir, final String... folderNames) {
+        File result = projectBaseDir;
+        for (final String folder: folderNames) {
+            result = new File(result, folder);
         }
-        return new File(projectBaseDir, b.toString());
+        return result;
     }
 
     @Override
-    public void setAdditionalConfig(Map<String, String> additionalCfg) {
-        if (LOGGER != null) {
-            LOGGER.debug(getClass().getCanonicalName(),
-                    ": Additional configuration received: ",
-                    additionalCfg.toString());
-        }
+    public void setAdditionalConfig(final Map<String, String> additionalCfg) {
+        LOG.debug("{}: Additional configuration received: {}", getClass().getCanonicalName(), additionalCfg);
         this.namespaceToPackageMapping = extractNamespaceMapping(additionalCfg);
         this.generateModuleFactoryFile = extractModuleFactoryBoolean(additionalCfg);
     }
 
-    private boolean extractModuleFactoryBoolean(
-            Map<String, String> additionalCfg) {
-        String bool = additionalCfg.get(MODULE_FACTORY_FILE_BOOLEAN);
-        if (bool == null) {
-            return true;
-        }
-        if ("false".equals(bool)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public void setLog(Log log) {
-        StaticLoggerBinder.getSingleton().setMavenLog(log);
+    private static boolean extractModuleFactoryBoolean(final Map<String, String> additionalCfg) {
+        final String bool = additionalCfg.get(MODULE_FACTORY_FILE_BOOLEAN);
+        return !"false".equals(bool);
     }
 
     private static Map<String, String> extractNamespaceMapping(
-            Map<String, String> additionalCfg) {
-        Map<String, String> namespaceToPackage = Maps.newHashMap();
-        for (String key : additionalCfg.keySet()) {
+            final Map<String, String> additionalCfg) {
+        final Map<String, String> namespaceToPackage = Maps.newHashMap();
+        for (final String key : additionalCfg.keySet()) {
             if (key.startsWith(NAMESPACE_TO_PACKAGE_PREFIX)) {
-                String mapping = additionalCfg.get(key);
-                NamespaceMapping mappingResolved = extractNamespaceMapping(mapping);
+                final String mapping = additionalCfg.get(key);
+                final NamespaceMapping mappingResolved = extractNamespaceMapping(mapping);
                 namespaceToPackage.put(mappingResolved.namespace,
                         mappingResolved.packageName);
             }
@@ -225,54 +216,39 @@ public class JMXGenerator implements CodeGenerator {
         return namespaceToPackage;
     }
 
-    static Pattern namespaceMappingPattern = Pattern.compile("(.+)"
-            + NAMESPACE_TO_PACKAGE_DIVIDER + "(.+)");
-
-    private static NamespaceMapping extractNamespaceMapping(String mapping) {
-        Matcher matcher = namespaceMappingPattern.matcher(mapping);
-        Preconditions
-                .checkArgument(matcher.matches(), String.format("Namespace to package mapping:%s is in invalid " +
-                        "format, requested format is: %s", mapping, namespaceMappingPattern));
+    private static NamespaceMapping extractNamespaceMapping(final String mapping) {
+        final Matcher matcher = NAMESPACE_MAPPING_PATTERN.matcher(mapping);
+        Preconditions.checkArgument(matcher.matches(),
+            "Namespace to package mapping:%s is in invalid format, requested format is: %s",
+            mapping, NAMESPACE_MAPPING_PATTERN);
         return new NamespaceMapping(matcher.group(1), matcher.group(2));
     }
 
-    private static class NamespaceMapping {
-        public NamespaceMapping(String namespace, String packagename) {
-            this.namespace = namespace;
-            this.packageName = packagename;
-        }
-
-        private final String namespace, packageName;
-    }
-
     @Override
-    public void setResourceBaseDir(File resourceDir) {
+    public void setResourceBaseDir(final File resourceDir) {
         this.resourceBaseDir = resourceDir;
     }
 
     @Override
-    public void setMavenProject(MavenProject project) {
+    public void setMavenProject(final MavenProject project) {
         this.projectBaseDir = project.getBasedir();
-
-        if (LOGGER != null)
-            LOGGER.debug(getClass().getCanonicalName(), " project base dir: ",
-                    projectBaseDir);
+        LOG.debug("{}: project base dir: {}", getClass().getCanonicalName(), this.projectBaseDir);
     }
 
     @VisibleForTesting
     static class GeneratedFilesTracker {
         private final Set<File> files = Sets.newHashSet();
 
-        void addFile(File file) {
-            if (files.contains(file)) {
-                List<File> undeletedFiles = Lists.newArrayList();
-                for (File presentFile : files) {
-                    if (presentFile.delete() == false) {
+        void addFile(final File file) {
+            if (this.files.contains(file)) {
+                final List<File> undeletedFiles = Lists.newArrayList();
+                for (final File presentFile : this.files) {
+                    if (!presentFile.delete()) {
                         undeletedFiles.add(presentFile);
                     }
                 }
-                if (undeletedFiles.isEmpty() == false) {
-                    LOGGER.error(
+                if (!undeletedFiles.isEmpty()) {
+                    LOG.error(
                             "Illegal state occurred: Unable to delete already generated files, undeleted files: {}",
                             undeletedFiles);
                 }
@@ -280,17 +256,17 @@ public class JMXGenerator implements CodeGenerator {
                         "Name conflict in generated files, file" + file
                                 + " present twice");
             }
-            files.add(file);
+            this.files.add(file);
         }
 
-        void addFile(Collection<File> files) {
-            for (File file : files) {
+        void addFile(final Collection<File> files) {
+            for (final File file : files) {
                 addFile(file);
             }
         }
 
         public Set<File> getFiles() {
-            return files;
+            return this.files;
         }
     }
 }