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;
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
@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;
}
-
}