Merge "Yang-maven-plugin refactored and config attributes and spi adjusted."
authorGiovanni Meo <gmeo@cisco.com>
Wed, 12 Jun 2013 16:25:22 +0000 (16:25 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 12 Jun 2013 16:25:22 +0000 (16:25 +0000)
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 1876c689c0e5a10b44f554f51905e4f9b4a6ad0f..491cef6bcc3caf99bfb61e83f10d1aa678cc7332 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 9535468ed52fefedaa58fb0aca0860337aa9d74e..280284bcba38d9378a54c225d53a69f7ad02dc5a 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 b7baa743388986fcac742805d54f0ff256b09f3c..8bd2289b116e37f0523f993028525e293113031c 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 aaf7080a6234c8e6a4155b42ec8dc20d3c7cc58f..0df9a6345ee9384b316f3d71093fa19a9796a658 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 653c0bff6d5b6c1fca52c9ff891df60be1385ba2..7b83af42428d9e6ebbda79b301e80f1672c114fd 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 7dbd8568240b802d0c105a309eaca270ab5d1eae..6e43b306cd44d82b1cdcaa32b5b54c976fc41a71 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 be92af0126cb07aed0027a831287767091ad1c25..770eeee964895bd0714cdc00eb0e08d7850923cf 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 1bfe9d4d0c01e0522fb48799d38c2a947cdc1a07..14e9d34b2aeec672c4f3ff15b26ec2a57b8bd5d0 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 96a4d57a00d97f3a8ec9e36b0bccd84e13c551f0..240825409fcc8459209c1d3a407aea4a0acd6e1a 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 9c4475cd40b966f3ab4ba3596c464d8bddbafac4..ae24c1848e5de587089796141056178da0d8b5af 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 df33d4c5919e81070c8947d2d30b01182fd85a3a..09dcd3e8e9ca2cafc18d5745bcafb6016c64eedb 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 172a2f25b67dcd03ed540bda966593e68bd0d367..3103042f9970c4d2d24ab606f709322f8daa85e4 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);
     }
 
 }