From e2dff6dc15408745a6f5988e6874be2a768c6c97 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Fri, 7 Jun 2013 12:20:29 +0200 Subject: [PATCH] Yang-maven-plugin refactored and config attributes and spi adjusted. Removed project base dir parameter from CodeGenerator since it can be acquired via additionalConfiguration. Added resourceBaseDir config attribute that allows resources to be added to packaged jar. Added mavenProject config attribute that provides any additional configuration to code generators if necessary. Adjusted log levels for the plugin. Plugin refactored and generate sources test fixed. Change-Id: Ic3cc1342bb8eb8d6cc374da8af28fa9905ee8fcf Signed-off-by: Maros Marsalek --- .../sal/api/gen/plugin/CodeGeneratorImpl.java | 18 +- .../plugin/it/YangToSourcesPluginTestIT.java | 7 +- .../test/resources/AdditionalConfig/pom.xml | 1 + .../yang2sources/plugin/ConfigArg.java | 18 ++ .../controller/yang2sources/plugin/Util.java | 147 ++++++++++--- .../plugin/YangToSourcesMojo.java | 39 +++- .../plugin/YangToSourcesProcessor.java | 204 ++++++------------ .../plugin/GenerateSourcesTest.java | 52 +++-- .../yang2sources/plugin/UtilTest.java | 7 +- .../src/test/resources/{ => yang}/mock.yang | 0 .../code-generator/maven-yang/pom.xml | 5 + .../yang2sources/spi/CodeGenerator.java | 31 ++- .../spi/CodeGeneratorTestImpl.java | 38 +++- 13 files changed, 363 insertions(+), 204 deletions(-) rename opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/{ => yang}/mock.yang (100%) diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java b/opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java index 1876c689c0..491cef6bcc 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.Set; import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator; import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl; import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; @@ -30,8 +31,7 @@ public class CodeGeneratorImpl implements CodeGenerator { @Override public Collection generateSources(SchemaContext context, - File outputBaseDir, Set yangModules, File projectBaseDir) - throws IOException { + File outputBaseDir, Set yangModules) throws IOException { final BindingGenerator bindingGenerator = new BindingGeneratorImpl(); final List types = bindingGenerator.generateTypes(context); @@ -49,9 +49,7 @@ public class CodeGeneratorImpl implements CodeGenerator { final GeneratorJavaFile generator = new GeneratorJavaFile( typesToGenerate, tosToGenerate); - return generator.generateToFile(outputBaseDir.getPath().startsWith( - projectBaseDir.getPath()) ? outputBaseDir : new File( - projectBaseDir, outputBaseDir.getPath())); + return generator.generateToFile(outputBaseDir); } @Override @@ -65,4 +63,14 @@ public class CodeGeneratorImpl implements CodeGenerator { // no additional config utilized } + @Override + public void setResourceBaseDir(File resourceBaseDir) { + // no resource processing necessary + } + + @Override + public void setMavenProject(MavenProject project) { + // no additional information needed + } + } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java index 9535468ed5..280284bcba 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java @@ -45,8 +45,10 @@ public class YangToSourcesPluginTestIT { @Test public void testAdditionalConfiguration() throws VerificationException { Verifier v = setUp("AdditionalConfig/", false); - v.verifyTextInLog("[INFO] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}"); - v.verifyTextInLog("[INFO] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}"); + v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}"); + v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}"); + v.verifyTextInLog("../files marked as resources: META-INF/yang"); + v.verifyTextInLog("target/generated-resources marked as resources for generator: org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl"); } @Test @@ -106,6 +108,7 @@ public class YangToSourcesPluginTestIT { + project).getAbsolutePath()); if (ignoreF) verifier.addCliOption("-fn"); + verifier.setMavenDebug(true); verifier.executeGoal("generate-sources"); return verifier; } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml index b7baa74338..8bd2289b11 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml @@ -37,6 +37,7 @@ abcd=a.b.c.d abcd2=a.b.c.d.2 + /target/resourcesGenerated diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java index aaf7080a62..0df9a6345e 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java @@ -42,7 +42,10 @@ public abstract class ConfigArg { public static final class CodeGeneratorArg extends ConfigArg { private static final String CODE_GEN_DEFAULT_DIR = "target" + File.separator + "generated-sources"; + private static final String CODE_GEN_DEFAULT_RESOURCE_DIR = "target" + + File.separator + "generated-resources"; private String codeGeneratorClass; + private File resourceBaseDir = new File(CODE_GEN_DEFAULT_RESOURCE_DIR); private Map additionalConfiguration = Maps.newHashMap(); @@ -59,6 +62,13 @@ public abstract class ConfigArg { this.codeGeneratorClass = codeGeneratorClass; } + public CodeGeneratorArg(String codeGeneratorClass, + String outputBaseDir, String resourceBaseDir) { + super(outputBaseDir); + this.codeGeneratorClass = codeGeneratorClass; + this.resourceBaseDir = new File(resourceBaseDir); + } + @Override public void check() { Preconditions.checkNotNull(codeGeneratorClass, @@ -69,6 +79,14 @@ public abstract class ConfigArg { return codeGeneratorClass; } + public File getResourceBaseDir(MavenProject project) { + if (resourceBaseDir.isAbsolute()) { + return resourceBaseDir; + } else { + return new File(project.getBasedir(), resourceBaseDir.getPath()); + } + } + public Map getAdditionalConfiguration() { return additionalConfiguration; } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java index 653c0bff6d..7b83af4242 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java @@ -7,21 +7,31 @@ */ package org.opendaylight.controller.yang2sources.plugin; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; +import org.opendaylight.controller.yang.model.api.Module; +import org.opendaylight.controller.yang.model.api.SchemaContext; -import com.google.common.base.Function; -import com.google.common.collect.Collections2; +import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -81,23 +91,6 @@ final class Util { } } - static String[] listFilesAsArrayOfPaths(File rootDir) - throws FileNotFoundException { - String[] filesArray = new String[] {}; - Collection yangFiles = listFiles(rootDir); - - // If collection is empty, return empty array [] rather then [null] - // array, that is created by default - return yangFiles.isEmpty() ? filesArray : Collections2.transform( - yangFiles, new Function() { - - @Override - public String apply(File input) { - return input.getPath(); - } - }).toArray(filesArray); - } - private static void toCache(final File rootDir, final Collection yangFiles) { cache.put(rootDir, yangFiles); @@ -137,7 +130,7 @@ final class Util { return String.format("%s %s", logPrefix, innerMessage); } - public static List getClassPath(MavenProject project) { + static List getClassPath(MavenProject project) { List dependencies = Lists.newArrayList(); for (Artifact element : project.getArtifacts()) { File asFile = element.getFile(); @@ -155,13 +148,117 @@ final class Util { : false; } - public static boolean acceptedFilter(String name, List filter) { - for (String f : filter) { - if (name.endsWith(f)) { - return true; + static T checkNotNull(T obj, String paramName) { + return Preconditions.checkNotNull(obj, "Parameter " + paramName + + " is null"); + } + + final static class YangsInZipsResult implements Closeable { + final List yangStreams; + private final List zipInputStreams; + + private YangsInZipsResult(List yangStreams, + List zipInputStreams) { + this.yangStreams = yangStreams; + this.zipInputStreams = zipInputStreams; + } + + @Override + public void close() throws IOException { + for (InputStream is : yangStreams) { + is.close(); + } + for (Closeable is : zipInputStreams) { + is.close(); } } - return false; + } + + static YangsInZipsResult findYangFilesInDependenciesAsStream(Log log, + MavenProject project) + throws MojoFailureException { + List yangsFromDependencies = new ArrayList<>(); + List zips = new ArrayList<>(); + try { + List filesOnCp = Util.getClassPath(project); + log.info(Util.message( + "Searching for yang files in following dependencies: %s", + YangToSourcesProcessor.LOG_PREFIX, filesOnCp)); + + for (File file : filesOnCp) { + List foundFilesForReporting = new ArrayList<>(); + // is it jar file or directory? + if (file.isDirectory()) { + File yangDir = new File(file, + YangToSourcesProcessor.META_INF_YANG_STRING); + if (yangDir.exists() && yangDir.isDirectory()) { + File[] yangFiles = yangDir + .listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".yang") + && new File(dir, name).isFile(); + } + }); + for (File yangFile : yangFiles) { + yangsFromDependencies.add(new NamedFileInputStream( + yangFile)); + } + } + + } else { + ZipFile zip = new ZipFile(file); + zips.add(zip); + + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String entryName = entry.getName(); + + if (entryName + .startsWith(YangToSourcesProcessor.META_INF_YANG_STRING)) { + if (entry.isDirectory() == false + && entryName.endsWith(".yang")) { + foundFilesForReporting.add(entryName); + // This will be closed after all strams are + // parsed. + InputStream entryStream = zip + .getInputStream(entry); + yangsFromDependencies.add(entryStream); + } + } + } + } + if (foundFilesForReporting.size() > 0) { + log.info(Util.message("Found %d yang files in %s: %s", + YangToSourcesProcessor.LOG_PREFIX, + foundFilesForReporting.size(), file, + foundFilesForReporting)); + } + + } + } catch (Exception e) { + throw new MojoFailureException(e.getMessage(), e); + } + return new YangsInZipsResult(yangsFromDependencies, zips); + } + + final static class ContextHolder { + private final SchemaContext context; + private final Set yangModules; + + ContextHolder(SchemaContext context, Set yangModules) { + this.context = context; + this.yangModules = yangModules; + } + + SchemaContext getContext() { + return context; + } + + Set getYangModules() { + return yangModules; + } } } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java index 7dbd856824..6e43b306cd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java @@ -64,41 +64,58 @@ public final class YangToSourcesMojo extends AbstractMojo { @Parameter(property = "inspectDependencies", required = true, readonly = true) private boolean inspectDependencies; + private YangToSourcesProcessor yangToSourcesProcessor; + public YangToSourcesMojo() { } @VisibleForTesting - YangToSourcesMojo(CodeGeneratorArg[] codeGeneratorArgs, - String yangFilesRootDir) { - this.codeGenerators = codeGeneratorArgs; - this.yangFilesRootDir = yangFilesRootDir; + YangToSourcesMojo(YangToSourcesProcessor processor) { + this.yangToSourcesProcessor = processor; } @Override public void execute() throws MojoExecutionException, MojoFailureException { + if (yangToSourcesProcessor == null) { + List codeGeneratorArgs = processCodeGenerators(codeGenerators); + + // defaults to ${basedir}/src/main/yang + File yangFilesRootFile = processYangFilesRootDir(yangFilesRootDir, + project.getBasedir()); + + yangToSourcesProcessor = new YangToSourcesProcessor(getLog(), + yangFilesRootFile, codeGeneratorArgs, project, + inspectDependencies); + } + yangToSourcesProcessor.execute(); + } + + private static List processCodeGenerators( + CodeGeneratorArg[] codeGenerators) { List codeGeneratorArgs; if (codeGenerators == null) { codeGeneratorArgs = Collections.emptyList(); } else { codeGeneratorArgs = Arrays.asList(codeGenerators); } + return codeGeneratorArgs; + } - // defaults to ${basedir}/src/main/yang + private static File processYangFilesRootDir(String yangFilesRootDir, + File baseDir) { File yangFilesRootFile; if (yangFilesRootDir == null) { - yangFilesRootFile = new File(project.getBasedir(), "src" - + File.separator + "main" + File.separator + "yang"); + 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(project.getBasedir(), - file.getPath()); + yangFilesRootFile = new File(baseDir, file.getPath()); } } - new YangToSourcesProcessor(getLog(), yangFilesRootFile, - codeGeneratorArgs, project, inspectDependencies).execute(); + return yangFilesRootFile; } } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java index be92af0126..770eeee964 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java @@ -9,19 +9,15 @@ package org.opendaylight.controller.yang2sources.plugin; import java.io.Closeable; import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; @@ -33,46 +29,51 @@ import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.parser.impl.YangParserImpl; import org.opendaylight.controller.yang2sources.plugin.ConfigArg.CodeGeneratorArg; -import org.opendaylight.controller.yang2sources.plugin.Util.NamedFileInputStream; +import org.opendaylight.controller.yang2sources.plugin.Util.ContextHolder; +import org.opendaylight.controller.yang2sources.plugin.Util.YangsInZipsResult; import org.opendaylight.controller.yang2sources.spi.CodeGenerator; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; class YangToSourcesProcessor { - private static final String LOG_PREFIX = "yang-to-sources:"; - private static final String META_INF_YANG_STRING = "META-INF" - + File.separator + "yang"; - private static final File META_INF_YANG_DIR = new File(META_INF_YANG_STRING); + static final String LOG_PREFIX = "yang-to-sources:"; + static final String META_INF_YANG_STRING = "META-INF" + File.separator + + "yang"; + static final File META_INF_YANG_DIR = new File(META_INF_YANG_STRING); private final Log log; private final File yangFilesRootDir; private final List codeGenerators; private final MavenProject project; private final boolean inspectDependencies; + private YangProvider yangProvider; + @VisibleForTesting YangToSourcesProcessor(Log log, File yangFilesRootDir, List codeGenerators, MavenProject project, - boolean inspectDependencies) { - this.log = checkNotNull(log, "log"); - this.yangFilesRootDir = checkNotNull(yangFilesRootDir, + boolean inspectDependencies, YangProvider yangProvider) { + this.log = Util.checkNotNull(log, "log"); + this.yangFilesRootDir = Util.checkNotNull(yangFilesRootDir, "yangFilesRootDir"); - this.codeGenerators = Collections.unmodifiableList(checkNotNull( + this.codeGenerators = Collections.unmodifiableList(Util.checkNotNull( codeGenerators, "codeGenerators")); - this.project = checkNotNull(project, "project"); + this.project = Util.checkNotNull(project, "project"); this.inspectDependencies = inspectDependencies; + this.yangProvider = yangProvider; } - private static T checkNotNull(T obj, String paramName) { - if (obj == null) - throw new NullPointerException("Parameter '" + paramName - + "' is null"); - return obj; + YangToSourcesProcessor(Log log, File yangFilesRootDir, + List codeGenerators, MavenProject project, + boolean inspectDependencies) { + this(log, yangFilesRootDir, codeGenerators, project, + inspectDependencies, new YangProvider()); } public void execute() throws MojoExecutionException, MojoFailureException { ContextHolder context = processYang(); generateSources(context); - addYangsToMETA_INF(); + yangProvider.addYangsToMETA_INF(log, project, yangFilesRootDir); } private ContextHolder processYang() throws MojoExecutionException { @@ -88,7 +89,8 @@ class YangToSourcesProcessor { Set projectYangModules; try { if (inspectDependencies) { - YangsInZipsResult dependentYangResult = findYangFilesInDependenciesAsStream(); + YangsInZipsResult dependentYangResult = Util + .findYangFilesInDependenciesAsStream(log, project); Closeable dependentYangResult1 = dependentYangResult; closeables.add(dependentYangResult1); all.addAll(dependentYangResult.yangStreams); @@ -124,20 +126,38 @@ class YangToSourcesProcessor { } } - private void addYangsToMETA_INF() throws MojoFailureException { - Resource res = new Resource(); + static class YangProvider { - File targetYangDir = new File(project.getBasedir(), "target" - + File.separator + "yang"); - res.setDirectory(targetYangDir.getPath()); + private static final String yangResourceDir = "target" + File.separator + + "yang"; - res.setTargetPath(META_INF_YANG_DIR.getPath()); - try { - FileUtils.copyDirectory(yangFilesRootDir, targetYangDir); - } catch (IOException e) { - throw new MojoFailureException(e.getMessage(), e); + void addYangsToMETA_INF(Log log, MavenProject project, + File yangFilesRootDir) throws MojoFailureException { + File targetYangDir = new File(project.getBasedir(), yangResourceDir); + + try { + FileUtils.copyDirectory(yangFilesRootDir, targetYangDir); + } catch (IOException e) { + String message = "Unable to copy yang files into resource folder"; + log.warn(message, e); + throw new MojoFailureException(message, e); + } + + setResource(targetYangDir, META_INF_YANG_DIR.getPath(), project); + + log.debug(Util.message( + "Yang files from: %s marked as resources: %s", LOG_PREFIX, + yangFilesRootDir, META_INF_YANG_DIR.getPath())); + } + + private static void setResource(File targetYangDir, String targetPath, + MavenProject project) { + Resource res = new Resource(); + res.setDirectory(targetYangDir.getPath()); + if (targetPath != null) + res.setTargetPath(targetPath); + project.addResource(res); } - project.addResource(res); } /** @@ -192,122 +212,30 @@ class YangToSourcesProcessor { log.info(Util.message("Sources will be generated to %s", LOG_PREFIX, outputDir)); - log.info(Util.message("Project root dir is %s", LOG_PREFIX, + log.debug(Util.message("Project root dir is %s", LOG_PREFIX, project.getBasedir())); - log.info(Util.message( + log.debug(Util.message( "Additional configuration picked up for : %s: %s", LOG_PREFIX, codeGeneratorCfg.getCodeGeneratorClass(), codeGeneratorCfg.getAdditionalConfiguration())); + project.addCompileSourceRoot(outputDir.getAbsolutePath()); g.setLog(log); + g.setMavenProject(project); g.setAdditionalConfig(codeGeneratorCfg.getAdditionalConfiguration()); - Collection generated = g.generateSources(context.getContext(), - outputDir, context.getYangModules(), project.getBasedir()); - log.info(Util.message("Sources generated by %s: %s", LOG_PREFIX, - codeGeneratorCfg.getCodeGeneratorClass(), generated)); - } - - private class YangsInZipsResult implements Closeable { - private final List yangStreams; - private final List zipInputStreams; + File resourceBaseDir = codeGeneratorCfg.getResourceBaseDir(project); - private YangsInZipsResult(List yangStreams, - List zipInputStreams) { - this.yangStreams = yangStreams; - this.zipInputStreams = zipInputStreams; - } + YangProvider.setResource(resourceBaseDir, null, project); + g.setResourceBaseDir(resourceBaseDir); + log.debug(Util.message( + "Folder: %s marked as resources for generator: %s", LOG_PREFIX, + resourceBaseDir, codeGeneratorCfg.getCodeGeneratorClass())); - @Override - public void close() throws IOException { - for (InputStream is : yangStreams) { - is.close(); - } - for (Closeable is : zipInputStreams) { - is.close(); - } - } - } - - private YangsInZipsResult findYangFilesInDependenciesAsStream() - throws MojoFailureException { - List yangsFromDependencies = new ArrayList<>(); - List zips = new ArrayList<>(); - try { - List filesOnCp = Util.getClassPath(project); - log.info(Util.message( - "Searching for yang files in following dependencies: %s", - LOG_PREFIX, filesOnCp)); - - for (File file : filesOnCp) { - List foundFilesForReporting = new ArrayList<>(); - // is it jar file or directory? - if (file.isDirectory()) { - File yangDir = new File(file, META_INF_YANG_STRING); - if (yangDir.exists() && yangDir.isDirectory()) { - File[] yangFiles = yangDir - .listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".yang") - && new File(dir, name).isFile(); - } - }); - for (File yangFile : yangFiles) { - yangsFromDependencies.add(new NamedFileInputStream( - yangFile)); - } - } - - } else { - ZipFile zip = new ZipFile(file); - zips.add(zip); - - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - String entryName = entry.getName(); - - if (entryName.startsWith(META_INF_YANG_STRING)) { - if (entry.isDirectory() == false - && entryName.endsWith(".yang")) { - foundFilesForReporting.add(entryName); - // This will be closed after all strams are - // parsed. - InputStream entryStream = zip - .getInputStream(entry); - yangsFromDependencies.add(entryStream); - } - } - } - } - if (foundFilesForReporting.size() > 0) { - log.info(Util.message("Found %d yang files in %s: %s", - LOG_PREFIX, foundFilesForReporting.size(), file, - foundFilesForReporting)); - } + Collection generated = g.generateSources(context.getContext(), + outputDir, context.getYangModules()); - } - } catch (Exception e) { - throw new MojoFailureException(e.getMessage(), e); - } - return new YangsInZipsResult(yangsFromDependencies, zips); + log.info(Util.message("Sources generated by %s: %s", LOG_PREFIX, + codeGeneratorCfg.getCodeGeneratorClass(), generated)); } - private class ContextHolder { - private final SchemaContext context; - private final Set yangModules; - - private ContextHolder(SchemaContext context, Set yangModules) { - this.context = context; - this.yangModules = yangModules; - } - - public SchemaContext getContext() { - return context; - } - - public Set getYangModules() { - return yangModules; - } - } } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java index 1bfe9d4d0c..14e9d34b2a 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java @@ -7,9 +7,11 @@ */ package org.opendaylight.controller.yang2sources.plugin; -import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.Is.*; import static org.junit.Assert.*; -import static org.mockito.Mockito.doReturn; +import static org.junit.matchers.JUnitMatchers.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; import java.io.File; import java.io.IOException; @@ -17,16 +19,17 @@ import java.util.Collection; import java.util.Map; import java.util.Set; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang2sources.plugin.ConfigArg.CodeGeneratorArg; +import org.opendaylight.controller.yang2sources.plugin.YangToSourcesProcessor.YangProvider; import org.opendaylight.controller.yang2sources.spi.CodeGenerator; import com.google.common.collect.Lists; @@ -40,27 +43,37 @@ public class GenerateSourcesTest { private MavenProject project; @Before - public void setUp() { + public void setUp() throws MojoFailureException { MockitoAnnotations.initMocks(this); - yang = new File(getClass().getResource("/mock.yang").getFile()) + yang = new File(getClass().getResource("/yang/mock.yang").getFile()) .getParent(); outDir = new File("/outputDir"); - mojo = new YangToSourcesMojo( - new CodeGeneratorArg[] { new CodeGeneratorArg( - GeneratorMock.class.getName(), "outputDir") }, yang); + YangProvider mock = mock(YangProvider.class); + doNothing().when(mock).addYangsToMETA_INF(any(Log.class), + any(MavenProject.class), any(File.class)); + + YangToSourcesProcessor processor = new YangToSourcesProcessor( + mock(Log.class), new File(yang), + Lists.newArrayList(new CodeGeneratorArg(GeneratorMock.class + .getName(), "outputDir")), project, false, + mock); + mojo = new YangToSourcesMojo(processor); doReturn(new File("")).when(project).getBasedir(); mojo.project = project; } - @Ignore @Test public void test() throws Exception { mojo.execute(); assertThat(GeneratorMock.called, is(1)); assertThat(GeneratorMock.outputDir, is(outDir)); + assertThat(GeneratorMock.project, is(project)); assertNotNull(GeneratorMock.log); assertTrue(GeneratorMock.additionalCfg.isEmpty()); + assertThat(GeneratorMock.resourceBaseDir.toString(), + containsString("target" + File.separator + + "generated-resources")); } public static class GeneratorMock implements CodeGenerator { @@ -69,11 +82,13 @@ public class GenerateSourcesTest { private static File outputDir; private static Log log; private static Map additionalCfg; + private static File resourceBaseDir; + private static MavenProject project; @Override public Collection generateSources(SchemaContext context, - File outputBaseDir, Set currentModules, - File projectBaseDir) throws IOException { + File outputBaseDir, Set currentModules) + throws IOException { called++; outputDir = outputBaseDir; return Lists.newArrayList(); @@ -81,13 +96,24 @@ public class GenerateSourcesTest { @Override public void setLog(Log log) { - this.log = log; + GeneratorMock.log = log; } @Override public void setAdditionalConfig( Map additionalConfiguration) { - this.additionalCfg = additionalConfiguration; + GeneratorMock.additionalCfg = additionalConfiguration; + } + + @Override + public void setResourceBaseDir(File resourceBaseDir) { + GeneratorMock.resourceBaseDir = resourceBaseDir; + + } + + @Override + public void setMavenProject(MavenProject project) { + GeneratorMock.project = project; } } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java index 96a4d57a00..240825409f 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java @@ -7,19 +7,20 @@ */ package org.opendaylight.controller.yang2sources.plugin; -import org.junit.Test; +import static org.junit.Assert.*; import java.io.File; import java.io.FileNotFoundException; import java.util.Collection; -import static org.junit.Assert.assertTrue; +import org.junit.Test; public class UtilTest { @Test public void testCache() throws FileNotFoundException { - String yang = new File(getClass().getResource("/mock.yang").getFile()) + String yang = new File(getClass().getResource("/yang/mock.yang") + .getFile()) .getParent(); Collection files = Util.listFiles(new File(yang)); Collection files2 = Util.listFiles(new File(yang)); diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/mock.yang b/opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/yang/mock.yang similarity index 100% rename from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/mock.yang rename to opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/yang/mock.yang diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml b/opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml index 9c4475cd40..ae24c1848e 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml @@ -19,6 +19,11 @@ maven-plugin-api 3.0.5 + + org.apache.maven + maven-core + 3.0.5 + diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java index df33d4c591..09dcd3e8e9 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Set; import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.SchemaContext; @@ -39,10 +40,36 @@ public interface CodeGenerator { * @throws IOException */ Collection generateSources(SchemaContext context, File outputBaseDir, - Set currentModules, File projectBaseDir) - throws IOException; + Set currentModules) throws IOException; + /** + * Utilize maven logging if necessary + * + * @param log + */ void setLog(Log log); + /** + * Provided map contains all configuration that was set in pom for code + * generator in additionalConfiguration tag + * + * @param additionalConfiguration + */ void setAdditionalConfig(Map additionalConfiguration); + + /** + * Provided folder is marked as resources and its content will be packaged + * in resulting jar. Feel free to add necessary resources + * + * @param resourceBaseDir + */ + void setResourceBaseDir(File resourceBaseDir); + + /** + * Provided maven project object. Any additional information about current + * maven project can be accessed from it. + * + * @param resourceBaseDir + */ + void setMavenProject(MavenProject project); } diff --git a/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java b/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java index 172a2f25b6..3103042f99 100644 --- a/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java @@ -13,27 +13,55 @@ import java.util.Map; import java.util.Set; import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.SchemaContext; public class CodeGeneratorTestImpl implements CodeGenerator { + private Log log; + @Override public Collection generateSources(SchemaContext context, - File outputBaseDir, Set currentModuleBuilders, - File projectMainDir) { - // no-op + File outputBaseDir, Set currentModuleBuilders) { + if (log != null) { + log.debug(getClass().getCanonicalName() + + " generateSources:context: " + context); + log.debug(getClass().getCanonicalName() + + " generateSources:outputBaseDir: " + outputBaseDir); + log.debug(getClass().getCanonicalName() + + " generateSources:currentModuleBuilders: " + + currentModuleBuilders); + + } return null; } @Override public void setLog(Log log) { - // no-op + this.log = log; } @Override public void setAdditionalConfig(Map additionalConfiguration) { - // no-op + if (log != null) + log.debug(getClass().getCanonicalName() + " additionalConfig: " + + additionalConfiguration); + } + + + @Override + public void setResourceBaseDir(File resourceBaseDir) { + if (log != null) + log.debug(getClass().getCanonicalName() + " resourceBaseDir: " + + resourceBaseDir); + } + + @Override + public void setMavenProject(MavenProject project) { + if (log != null) + log.debug(getClass().getCanonicalName() + " maven project: " + + project); } } -- 2.36.6