Yang-maven-plugin refactored and config attributes and spi adjusted.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / maven-yang-plugin / src / main / java / org / opendaylight / controller / yang2sources / plugin / YangToSourcesMojo.java
index 05d9c0cd2c54488e5815b4701ec862c7744f89f3..6e43b306cd44d82b1cdcaa32b5b54c976fc41a71 100644 (file)
@@ -8,11 +8,9 @@
 package org.opendaylight.controller.yang2sources.plugin;
 
 import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -22,15 +20,11 @@ import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
-import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
-import org.opendaylight.controller.yang.model.parser.impl.YangParserImpl;
 import org.opendaylight.controller.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
 import org.opendaylight.controller.yang2sources.spi.CodeGenerator;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
 
 /**
  * Generate sources from yang files using user provided set of
@@ -48,144 +42,80 @@ import com.google.common.collect.Maps;
 @Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = true)
 public final class YangToSourcesMojo extends AbstractMojo {
 
-    private static final String LOG_PREFIX = "yang-to-sources:";
-
     /**
      * Classes implementing {@link CodeGenerator} interface. An instance will be
-     * created out of every class using default constructor. Method
-     * {@link CodeGenerator#generateSources(SchemaContext, File)} will be called
-     * on every instance.
+     * created out of every class using default constructor. Method {@link
+     * CodeGenerator#generateSources(SchemaContext, File, Set<String>
+     * yangModulesNames)} will be called on every instance.
      */
-    @Parameter(required = true)
+    @Parameter(required = false)
     private CodeGeneratorArg[] codeGenerators;
 
     /**
      * Source directory that will be recursively searched for yang files (ending
      * with .yang suffix).
      */
-    @Parameter(required = true)
-    private String yangFilesRootDir;
+    @Parameter(required = false)
+    private String yangFilesRootDir; // defaults to ${basedir}/src/main/yang
 
     @Parameter(property = "project", required = true, readonly = true)
     protected MavenProject project;
 
-    private transient final YangModelParser parser;
+    @Parameter(property = "inspectDependencies", required = true, readonly = true)
+    private boolean inspectDependencies;
 
-    @VisibleForTesting
-    YangToSourcesMojo(CodeGeneratorArg[] codeGeneratorArgs,
-            YangModelParser parser, String yangFilesRootDir) {
-        super();
-        this.codeGenerators = codeGeneratorArgs;
-        this.yangFilesRootDir = yangFilesRootDir;
-        this.parser = parser;
-    }
+    private YangToSourcesProcessor yangToSourcesProcessor;
 
     public YangToSourcesMojo() {
-        super();
-        parser = new YangParserImpl();
-    }
 
-    @Override
-    public void execute() throws MojoExecutionException, MojoFailureException {
-        SchemaContext context = processYang();
-        generateSources(context);
     }
 
-    /**
-     * Generate {@link SchemaContext} with {@link YangModelParserImpl}
-     */
-    private SchemaContext processYang() throws MojoExecutionException {
-        try {
-            Collection<File> yangFiles = Util.listFiles(yangFilesRootDir);
-
-            if (yangFiles.isEmpty()) {
-                getLog().warn(
-                        Util.message("No %s file found in %s", LOG_PREFIX,
-                                Util.YANG_SUFFIX, yangFilesRootDir));
-                return null;
-            }
-
-            Set<Module> parsedYang = parser
-                    .parseYangModels(new ArrayList<File>(yangFiles));
-            SchemaContext resolveSchemaContext = parser
-                    .resolveSchemaContext(parsedYang);
-            getLog().info(
-                    Util.message("%s files parsed from %s", LOG_PREFIX,
-                            Util.YANG_SUFFIX, yangFiles));
-            return resolveSchemaContext;
-
-            // MojoExecutionException is thrown since execution cannot continue
-        } catch (Exception e) {
-            String message = Util.message("Unable to parse %s files from %s",
-                    LOG_PREFIX, Util.YANG_SUFFIX, yangFilesRootDir);
-            getLog().error(message, e);
-            throw new MojoExecutionException(message, e);
-        }
+    @VisibleForTesting
+    YangToSourcesMojo(YangToSourcesProcessor processor) {
+        this.yangToSourcesProcessor = processor;
     }
 
-    /**
-     * Call generate on every generator from plugin configuration
-     */
-    private void generateSources(SchemaContext context)
-            throws MojoFailureException {
-        if (codeGenerators.length == 0) {
-            getLog().warn(
-                    Util.message("No code generators provided", LOG_PREFIX));
-            return;
-        }
-
-        Map<String, String> thrown = Maps.newHashMap();
-
-        for (CodeGeneratorArg codeGenerator : codeGenerators) {
-            try {
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (yangToSourcesProcessor == null) {
+            List<CodeGeneratorArg> codeGeneratorArgs = processCodeGenerators(codeGenerators);
 
-                generateSourcesWithOneGenerator(context, codeGenerator);
+            // defaults to ${basedir}/src/main/yang
+            File yangFilesRootFile = processYangFilesRootDir(yangFilesRootDir,
+                    project.getBasedir());
 
-            } catch (Exception e) {
-                // try other generators, exception will be thrown after
-                getLog().error(
-                        Util.message(
-                                "Unable to generate sources with %s generator",
-                                LOG_PREFIX,
-                                codeGenerator.getCodeGeneratorClass()), e);
-                thrown.put(codeGenerator.getCodeGeneratorClass(), e.getClass()
-                        .getCanonicalName());
-            }
+            yangToSourcesProcessor = new YangToSourcesProcessor(getLog(),
+                    yangFilesRootFile, codeGeneratorArgs, project,
+                    inspectDependencies);
         }
+        yangToSourcesProcessor.execute();
+    }
 
-        if (!thrown.isEmpty()) {
-            String message = Util
-                    .message(
-                            "One or more code generators failed, including failed list(generatorClass=exception) %s",
-                            LOG_PREFIX, thrown.toString());
-            getLog().error(message);
-            throw new MojoFailureException(message);
+    private static List<CodeGeneratorArg> processCodeGenerators(
+            CodeGeneratorArg[] codeGenerators) {
+        List<CodeGeneratorArg> codeGeneratorArgs;
+        if (codeGenerators == null) {
+            codeGeneratorArgs = Collections.emptyList();
+        } else {
+            codeGeneratorArgs = Arrays.asList(codeGenerators);
         }
+        return codeGeneratorArgs;
     }
 
-    /**
-     * Instantiate generator from class and call required method
-     */
-    private void generateSourcesWithOneGenerator(SchemaContext context,
-            CodeGeneratorArg codeGeneratorCfg) throws ClassNotFoundException,
-            InstantiationException, IllegalAccessException, IOException {
-
-        codeGeneratorCfg.check();
-
-        CodeGenerator g = Util.getInstance(
-                codeGeneratorCfg.getCodeGeneratorClass(), CodeGenerator.class);
-        getLog().info(
-                Util.message("Code generator instantiated from %s", LOG_PREFIX,
-                        codeGeneratorCfg.getCodeGeneratorClass()));
-
-        File outputDir = codeGeneratorCfg.getOutputBaseDir();
-        if (project != null && outputDir != null) {
-            project.addCompileSourceRoot(outputDir.getPath());
+    private static File processYangFilesRootDir(String yangFilesRootDir,
+            File baseDir) {
+        File yangFilesRootFile;
+        if (yangFilesRootDir == null) {
+            yangFilesRootFile = new File(baseDir, "src" + File.separator
+                    + "main" + File.separator + "yang");
+        } else {
+            File file = new File(yangFilesRootDir);
+            if (file.isAbsolute()) {
+                yangFilesRootFile = file;
+            } else {
+                yangFilesRootFile = new File(baseDir, file.getPath());
+            }
         }
-        Collection<File> generated = g.generateSources(context, outputDir);
-        getLog().info(
-                Util.message("Sources generated by %s: %s", LOG_PREFIX,
-                        codeGeneratorCfg.getCodeGeneratorClass(), generated));
+        return yangFilesRootFile;
     }
-
 }