Yang-maven-plugin refactored and config attributes and spi adjusted. 44/444/6
authorMaros Marsalek <mmarsale@cisco.com>
Fri, 7 Jun 2013 10:20:29 +0000 (12:20 +0200)
committerMaros Marsalek <mmarsale@cisco.com>
Tue, 11 Jun 2013 11:45:08 +0000 (13:45 +0200)
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 <mmarsale@cisco.com>
13 files changed:
opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/yang/mock.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/mock.yang with 100% similarity]
opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml
opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java
opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java

index 1876c68..491cef6 100644 (file)
@@ -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<File> generateSources(SchemaContext context,
-            File outputBaseDir, Set<Module> yangModules, File projectBaseDir)
-            throws IOException {
+            File outputBaseDir, Set<Module> yangModules) throws IOException {
 
         final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
         final List<Type> 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
+    }
+
 }
index 9535468..280284b 100644 (file)
@@ -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;
     }
index b7baa74..8bd2289 100644 (file)
@@ -37,6 +37,7 @@
                                         <nm1>abcd=a.b.c.d</nm1>
                                         <nm2>abcd2=a.b.c.d.2</nm2>
                                     </additionalConfiguration>
+                                    <resourceBaseDir>/target/resourcesGenerated</resourceBaseDir>
                                 </generator>
                                 <generator>
                                     <codeGeneratorClass>
index aaf7080..0df9a63 100644 (file)
@@ -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<String, String> 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<String, String> getAdditionalConfiguration() {
             return additionalConfiguration;
         }
index 653c0bf..7b83af4 100644 (file)
@@ -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<File> 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<File, String>() {
-
-                    @Override
-                    public String apply(File input) {
-                        return input.getPath();
-                    }
-                }).toArray(filesArray);
-    }
-
     private static void toCache(final File rootDir,
             final Collection<File> yangFiles) {
         cache.put(rootDir, yangFiles);
@@ -137,7 +130,7 @@ final class Util {
         return String.format("%s %s", logPrefix, innerMessage);
     }
 
-    public static List<File> getClassPath(MavenProject project) {
+    static List<File> getClassPath(MavenProject project) {
         List<File> 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<String> filter) {
-        for (String f : filter) {
-            if (name.endsWith(f)) {
-                return true;
+    static <T> T checkNotNull(T obj, String paramName) {
+        return Preconditions.checkNotNull(obj, "Parameter " + paramName
+                + " is null");
+    }
+
+    final static class YangsInZipsResult implements Closeable {
+        final List<InputStream> yangStreams;
+        private final List<Closeable> zipInputStreams;
+
+        private YangsInZipsResult(List<InputStream> yangStreams,
+                List<Closeable> 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<InputStream> yangsFromDependencies = new ArrayList<>();
+        List<Closeable> zips = new ArrayList<>();
+        try {
+            List<File> 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<String> 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<? extends ZipEntry> 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<Module> yangModules;
+
+        ContextHolder(SchemaContext context, Set<Module> yangModules) {
+            this.context = context;
+            this.yangModules = yangModules;
+        }
+
+        SchemaContext getContext() {
+            return context;
+        }
+
+        Set<Module> getYangModules() {
+            return yangModules;
+        }
     }
 
 }
index 7dbd856..6e43b30 100644 (file)
@@ -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<CodeGeneratorArg> 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<CodeGeneratorArg> processCodeGenerators(
+            CodeGeneratorArg[] codeGenerators) {
         List<CodeGeneratorArg> 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;
     }
 }
index be92af0..770eeee 100644 (file)
@@ -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<CodeGeneratorArg> codeGenerators;
     private final MavenProject project;
     private final boolean inspectDependencies;
+    private YangProvider yangProvider;
 
+    @VisibleForTesting
     YangToSourcesProcessor(Log log, File yangFilesRootDir,
             List<CodeGeneratorArg> 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> T checkNotNull(T obj, String paramName) {
-        if (obj == null)
-            throw new NullPointerException("Parameter '" + paramName
-                    + "' is null");
-        return obj;
+    YangToSourcesProcessor(Log log, File yangFilesRootDir,
+            List<CodeGeneratorArg> 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<Module> 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<File> 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<InputStream> yangStreams;
-        private final List<Closeable> zipInputStreams;
+        File resourceBaseDir = codeGeneratorCfg.getResourceBaseDir(project);
 
-        private YangsInZipsResult(List<InputStream> yangStreams,
-                List<Closeable> 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<InputStream> yangsFromDependencies = new ArrayList<>();
-        List<Closeable> zips = new ArrayList<>();
-        try {
-            List<File> filesOnCp = Util.getClassPath(project);
-            log.info(Util.message(
-                    "Searching for yang files in following dependencies: %s",
-                    LOG_PREFIX, filesOnCp));
-
-            for (File file : filesOnCp) {
-                List<String> 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<? extends ZipEntry> 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<File> 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<Module> yangModules;
-
-        private ContextHolder(SchemaContext context, Set<Module> yangModules) {
-            this.context = context;
-            this.yangModules = yangModules;
-        }
-
-        public SchemaContext getContext() {
-            return context;
-        }
-
-        public Set<Module> getYangModules() {
-            return yangModules;
-        }
-    }
 }
index 1bfe9d4..14e9d34 100644 (file)
@@ -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<String, String> additionalCfg;
+        private static File resourceBaseDir;
+        private static MavenProject project;
 
         @Override
         public Collection<File> generateSources(SchemaContext context,
-                File outputBaseDir, Set<Module> currentModules,
-                File projectBaseDir) throws IOException {
+                File outputBaseDir, Set<Module> 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<String, String> 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;
         }
     }
 
index 96a4d57..2408254 100644 (file)
@@ -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<File> files = Util.listFiles(new File(yang));
         Collection<File> files2 = Util.listFiles(new File(yang));
index 9c4475c..ae24c18 100644 (file)
             <artifactId>maven-plugin-api</artifactId>
             <version>3.0.5</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>3.0.5</version>
+        </dependency>
     </dependencies>
 
     <build>
index df33d4c..09dcd3e 100644 (file)
@@ -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<File> generateSources(SchemaContext context, File outputBaseDir,
-            Set<Module> currentModules, File projectBaseDir)
-            throws IOException;
+            Set<Module> 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<String, String> 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);
 }
index 172a2f2..3103042 100644 (file)
@@ -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<File> generateSources(SchemaContext context,
-            File outputBaseDir, Set<Module> currentModuleBuilders,
-            File projectMainDir) {
-        // no-op
+            File outputBaseDir, Set<Module> 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<String, String> 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);
     }
 
 }