BUG-7568: refactor yang-maven-plugin 56/52056/34
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 19 Feb 2017 23:49:40 +0000 (00:49 +0100)
committerRobert Varga <nite@hq.sk>
Tue, 5 Sep 2017 12:19:05 +0000 (12:19 +0000)
Refactor the plugin to not use named input streams, but rather
instantiate YangTextSchemaSources. Along with the use of
YangTextSchemaContextResolver this eliminates the need for weird
path-based tricks to get local modules.

Change-Id: I27403270cbacf567ad2182b60f265cc6bb3f83e7
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java
yang/yang-maven-plugin/pom.xml
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFile.java [deleted file]
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFile.java [deleted file]
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java
yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/UtilTest.java
yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFileTest.java [deleted file]
yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFileTest.java [deleted file]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java

index 7cea1e7174983057b9e5cb244f2c6d09b7a6d112..b6f1b55d3b81864610bd8a0ce0fcd932d517bc25 100644 (file)
@@ -62,16 +62,19 @@ public class YangToSourcesPluginTestIT {
             setUp("test-parent/MissingYangInDep/", false);
             fail("Verification exception should have been thrown");
         } catch (VerificationException e) {
-            assertVerificationException(e, "org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException: "
-                    + "Imported module [unknownDep] was not found.");
+            assertVerificationException(e,
+                    "SchemaResolutionException{unsatisfiedImports={RevisionSourceIdentifier"
+                    + " [name=private@2013-02-27]=[ModuleImportImpl"
+                    + " [name=unknownDep, revision=2013-02-27, semanticVersion=0.0.0]]}");
+            return;
         }
     }
 
     static void verifyCorrectLog(final Verifier vrf) throws VerificationException {
         vrf.verifyErrorFreeLog();
-        vrf.verifyTextInLog("[INFO] yang-to-sources: YANG files parsed from");
-        vrf.verifyTextInLog("[INFO] yang-to-sources: Code generator instantiated "
-                + "from org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl");
+        vrf.verifyTextInLog("[INFO] yang-to-sources: Project model files parsed: ");
+        vrf.verifyTextInLog("[INFO] yang-to-sources: Code generator instantiated from "
+                + "org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl");
         vrf.verifyTextInLog("[INFO] yang-to-sources: Sources generated by "
                 + "org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl: null");
     }
index 900e8d92b1be56a60df1e1c6bd0c48ae189ea08e..04ef90d64fc097d70a75f93e41c5dde275b5f1de 100644 (file)
@@ -71,7 +71,7 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>yang-test-util</artifactId>
-            <scope>compile</scope>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
index 000ba17b03da051bed1549df75fd3e31bcecc39e..2941edd4cb643104aec049b41f89a6416b9b6392 100644 (file)
@@ -8,13 +8,17 @@
 package org.opendaylight.yangtools.yang2sources.plugin;
 
 import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import java.io.Closeable;
+import static org.opendaylight.yangtools.yang2sources.plugin.YangToSourcesProcessor.LOG_PREFIX;
+import static org.opendaylight.yangtools.yang2sources.plugin.YangToSourcesProcessor.META_INF_YANG_STRING;
+import static org.opendaylight.yangtools.yang2sources.plugin.YangToSourcesProcessor.META_INF_YANG_STRING_JAR;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteSource;
+import com.google.common.io.ByteStreams;
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -39,6 +43,7 @@ import org.apache.maven.project.MavenProject;
 import org.apache.maven.repository.RepositorySystem;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,8 +62,7 @@ final class Util {
     static Collection<File> listFiles(final File root, final Collection<File> excludedFiles)
             throws FileNotFoundException {
         if (!root.exists()) {
-            LOG.warn("{} YANG source directory {} not found. No code will be generated.", YangToSourcesProcessor
-                    .LOG_PREFIX, root.toString());
+            LOG.warn("{} YANG source directory {} not found. No code will be generated.", LOG_PREFIX, root);
 
             return Collections.emptyList();
         }
@@ -66,8 +70,7 @@ final class Util {
         Collection<File> yangFiles = FileUtils.listFiles(root, new String[] { YANG_SUFFIX }, true);
         for (File f : yangFiles) {
             if (excludedFiles.contains(f)) {
-                LOG.info("{} {} file excluded {}", YangToSourcesProcessor.LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(),
-                        f);
+                LOG.info("{} {} file excluded {}", LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(), f);
             } else {
                 result.add(f);
             }
@@ -104,8 +107,7 @@ final class Util {
             final ArtifactRepository localRepo, final List<ArtifactRepository> remoteRepos) {
         Plugin plugin = project.getPlugin(YangToSourcesMojo.PLUGIN_NAME);
         if (plugin == null) {
-            LOG.warn("{} {} not found, dependencies version check skipped", YangToSourcesProcessor.LOG_PREFIX,
-                    YangToSourcesMojo.PLUGIN_NAME);
+            LOG.warn("{} {} not found, dependencies version check skipped", LOG_PREFIX, YangToSourcesMojo.PLUGIN_NAME);
         } else {
             Map<Artifact, Collection<Artifact>> pluginDependencies = new HashMap<>();
             getPluginTransitiveDependencies(plugin, pluginDependencies, repoSystem, localRepo, remoteRepos);
@@ -168,93 +170,70 @@ final class Util {
         for (org.apache.maven.artifact.Artifact d : dependencies) {
             if (artifact.getGroupId().equals(d.getGroupId()) && artifact.getArtifactId().equals(d.getArtifactId())) {
                 if (!(artifact.getVersion().equals(d.getVersion()))) {
-                    LOG.warn("{} Dependency resolution conflict:", YangToSourcesProcessor.LOG_PREFIX);
+                    LOG.warn("{} Dependency resolution conflict:", LOG_PREFIX);
                     LOG.warn("{} '{}' dependency [{}] has different version than one declared in current project [{}]"
                             + ". It is recommended to fix this problem because it may cause compilation errors.",
-                            YangToSourcesProcessor.LOG_PREFIX, YangToSourcesMojo.PLUGIN_NAME, artifact, d);
+                            LOG_PREFIX, YangToSourcesMojo.PLUGIN_NAME, artifact, d);
                 }
             }
         }
     }
 
-    private static final String JAR_SUFFIX = ".jar";
-
     private static boolean isJar(final File element) {
-        return (element.isFile() && element.getName().endsWith(JAR_SUFFIX));
-    }
-
-    static final class YangsInZipsResult implements Closeable {
-        private final List<YangSourceFromDependency> yangStreams;
-        private final List<Closeable> zipInputStreams;
-
-        private YangsInZipsResult(final List<YangSourceFromDependency> yangStreams,
-                final List<Closeable> zipInputStreams) {
-            this.yangStreams = yangStreams;
-            this.zipInputStreams = zipInputStreams;
-        }
-
-        @Override
-        public void close() throws IOException {
-            for (Closeable is : zipInputStreams) {
-                is.close();
-            }
-        }
-
-        public List<YangSourceFromDependency> getYangStreams() {
-            return this.yangStreams;
-        }
+        return element.isFile() && element.getName().endsWith(".jar");
     }
 
     @SuppressWarnings("checkstyle:illegalCatch")
-    static YangsInZipsResult findYangFilesInDependenciesAsStream(final MavenProject project)
+    static List<YangTextSchemaSource> findYangFilesInDependenciesAsStream(final MavenProject project)
             throws MojoFailureException {
-        List<YangSourceFromDependency> yangsFromDependencies = new ArrayList<>();
-        List<Closeable> zips = new ArrayList<>();
         try {
-            List<File> filesOnCp = Util.getClassPath(project);
-            LOG.info("{} Searching for yang files in following dependencies: {}", YangToSourcesProcessor.LOG_PREFIX,
-                    filesOnCp);
+            final List<File> filesOnCp = Util.getClassPath(project);
+            LOG.info("{} Searching for yang files in following dependencies: {}", LOG_PREFIX, filesOnCp);
 
+            final List<YangTextSchemaSource> yangsFromDependencies = new ArrayList<>();
             for (File file : filesOnCp) {
-                List<String> foundFilesForReporting = new ArrayList<>();
+                final List<String> foundFilesForReporting = new ArrayList<>();
                 // is it jar file or directory?
                 if (file.isDirectory()) {
                     //FIXME: code duplicate
-                    File yangDir = new File(file, YangToSourcesProcessor.META_INF_YANG_STRING);
+                    File yangDir = new File(file, META_INF_YANG_STRING);
                     if (yangDir.exists() && yangDir.isDirectory()) {
                         File[] yangFiles = yangDir.listFiles(
                             (dir, name) -> name.endsWith(RFC6020_YANG_FILE_EXTENSION) && new File(dir, name).isFile());
                         for (final File yangFile : yangFiles) {
-                            yangsFromDependencies.add(new YangSourceFromFile(yangFile));
+                            foundFilesForReporting.add(yangFile.getName());
+                            yangsFromDependencies.add(YangTextSchemaSource.forFile(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_JAR)
-                                && !entry.isDirectory() && entryName.endsWith(RFC6020_YANG_FILE_EXTENSION)) {
-                            foundFilesForReporting.add(entryName);
-                            yangsFromDependencies.add(new YangSourceInZipFile(zip, entry));
+                    try (ZipFile zip = new ZipFile(file)) {
+                        final Enumeration<? extends ZipEntry> entries = zip.entries();
+                        while (entries.hasMoreElements()) {
+                            final ZipEntry entry = entries.nextElement();
+                            final String entryName = entry.getName();
+
+                            if (entryName.startsWith(META_INF_YANG_STRING_JAR) && !entry.isDirectory()
+                                    && entryName.endsWith(RFC6020_YANG_FILE_EXTENSION)) {
+                                foundFilesForReporting.add(entryName);
+
+                                yangsFromDependencies.add(YangTextSchemaSource.delegateForByteSource(
+                                    entryName.substring(entryName.lastIndexOf('/') + 1),
+                                    ByteSource.wrap(ByteStreams.toByteArray(zip.getInputStream(entry)))));
+                            }
                         }
                     }
                 }
                 if (foundFilesForReporting.size() > 0) {
-                    LOG.info("{} Found {} yang files in {}: {}", YangToSourcesProcessor.LOG_PREFIX,
-                            foundFilesForReporting.size(), file, foundFilesForReporting);
+                    LOG.info("{} Found {} yang files in {}: {}", LOG_PREFIX, foundFilesForReporting.size(), file,
+                        foundFilesForReporting);
                 }
 
             }
+
+            return yangsFromDependencies;
         } catch (Exception e) {
             throw new MojoFailureException(e.getMessage(), e);
         }
-        return new YangsInZipsResult(yangsFromDependencies, zips);
     }
 
     /**
@@ -267,21 +246,20 @@ final class Util {
     static Collection<File> findYangFilesInDependencies(final MavenProject project) throws MojoFailureException {
         final List<File> yangsFilesFromDependencies = new ArrayList<>();
 
-        List<File> filesOnCp;
+        final List<File> filesOnCp;
         try {
             filesOnCp = Util.getClassPath(project);
         } catch (Exception e) {
             throw new MojoFailureException("Failed to scan for YANG files in dependencies", e);
         }
-        LOG.info("{} Searching for yang files in following dependencies: {}", YangToSourcesProcessor.LOG_PREFIX,
-            filesOnCp);
+        LOG.info("{} Searching for yang files in following dependencies: {}", LOG_PREFIX, filesOnCp);
 
         for (File file : filesOnCp) {
             try {
                 // is it jar file or directory?
                 if (file.isDirectory()) {
                     //FIXME: code duplicate
-                    File yangDir = new File(file, YangToSourcesProcessor.META_INF_YANG_STRING);
+                    File yangDir = new File(file, META_INF_YANG_STRING);
                     if (yangDir.exists() && yangDir.isDirectory()) {
                         File[] yangFiles = yangDir.listFiles(
                             (dir, name) -> name.endsWith(RFC6020_YANG_FILE_EXTENSION) && new File(dir, name).isFile());
@@ -296,10 +274,9 @@ final class Util {
                             ZipEntry entry = entries.nextElement();
                             String entryName = entry.getName();
 
-                            if (entryName.startsWith(YangToSourcesProcessor.META_INF_YANG_STRING_JAR)
+                            if (entryName.startsWith(META_INF_YANG_STRING_JAR)
                                     && !entry.isDirectory() && entryName.endsWith(RFC6020_YANG_FILE_EXTENSION)) {
-                                LOG.debug("{} Found a YANG file in {}: {}", YangToSourcesProcessor.LOG_PREFIX, file,
-                                        entryName);
+                                LOG.debug("{} Found a YANG file in {}: {}", LOG_PREFIX, file, entryName);
                                 yangsFilesFromDependencies.add(file);
                                 break;
                             }
@@ -314,16 +291,14 @@ final class Util {
     }
 
     static final class ContextHolder {
-        private static final Splitter SEP_SPLITTER = Splitter.on(File.separator);
-
         private final SchemaContext context;
         private final Set<Module> yangModules;
-        private final Set<Module> yangFiles;
+        private final Map<Module, String> yangFiles;
 
-        ContextHolder(final SchemaContext context, final Set<Module> yangModules, final Set<Module> yangFiles) {
-            this.context = context;
-            this.yangModules = yangModules;
-            this.yangFiles = yangFiles;
+        ContextHolder(final SchemaContext context, final Set<Module> yangModules, final Map<Module, String> yangFiles) {
+            this.context = Preconditions.checkNotNull(context);
+            this.yangModules = ImmutableSet.copyOf(yangModules);
+            this.yangFiles = ImmutableMap.copyOf(yangFiles);
         }
 
         SchemaContext getContext() {
@@ -334,17 +309,13 @@ final class Util {
             return yangModules;
         }
 
-        Set<Module> getYangFiles() {
-            return yangFiles;
-        }
-
         Optional<String> moduleToResourcePath(final Module mod) {
-            if (!yangFiles.contains(mod)) {
+            final String fileName = yangFiles.get(mod);
+            if (fileName == null) {
                 return Optional.empty();
             }
 
-            return Optional.of("/" + YangToSourcesProcessor.META_INF_YANG_STRING_JAR + "/"
-                    + Iterables.getLast(SEP_SPLITTER.split(mod.getModuleSourcePath())));
+            return Optional.of("/" + YangToSourcesProcessor.META_INF_YANG_STRING_JAR + "/" + fileName);
         }
     }
 }
diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFile.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFile.java
deleted file mode 100644 (file)
index 523ae55..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang2sources.plugin;
-
-import com.google.common.base.Preconditions;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
-
-class YangSourceFromFile extends YangSourceFromDependency {
-
-    private final File source;
-
-    YangSourceFromFile(File source) {
-        this.source = Preconditions.checkNotNull(source);
-    }
-
-    @Override
-    public InputStream openStream() throws IOException {
-
-        return new NamedFileInputStream(source, YangToSourcesProcessor.META_INF_YANG_STRING + File.separator
-                + source.getName());
-    }
-
-    @Override
-    public long size() throws IOException {
-        return source.length();
-    }
-
-    @Override
-    String getDescription() {
-        return source.getAbsolutePath();
-    }
-}
diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFile.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFile.java
deleted file mode 100644 (file)
index 72ba67d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang2sources.plugin;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-class YangSourceInZipFile extends YangSourceFromDependency {
-
-    private final ZipFile file;
-    private final ZipEntry entry;
-
-    YangSourceInZipFile(ZipFile file, ZipEntry entry) {
-        this.file = Preconditions.checkNotNull(file);
-        this.entry = Preconditions.checkNotNull(entry);
-    }
-
-    @Override
-    public long size() {
-        return entry.getSize();
-    }
-
-    @Override
-    public InputStream openStream() throws IOException {
-        return file.getInputStream(entry);
-    }
-
-    @Override
-    String getDescription() {
-        return file.getName() + "::" + entry.getName();
-    }
-}
index bb820517da207cd8a023d453120e48b0077e2db1..97c810d751130b8a843cf8021f05a18b949b4409 100644 (file)
@@ -8,19 +8,21 @@
 package org.opendaylight.yangtools.yang2sources.plugin;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.io.CharStreams;
-import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.Reader;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -30,14 +32,17 @@ import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.util.FileUtils;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
-import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaSourceRegistration;
 import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
 import org.opendaylight.yangtools.yang2sources.plugin.Util.ContextHolder;
-import org.opendaylight.yangtools.yang2sources.plugin.Util.YangsInZipsResult;
 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
 import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
@@ -50,9 +55,12 @@ class YangToSourcesProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(YangToSourcesProcessor.class);
 
     static final String LOG_PREFIX = "yang-to-sources:";
-    static final String META_INF_YANG_STRING = "META-INF" + File.separator + "yang";
-    static final String META_INF_YANG_STRING_JAR = "META-INF" + "/" + "yang";
-    static final String META_INF_YANG_SERVICES_STRING_JAR = "META-INF" + "/" + "services";
+    private static final String META_INF_STR = "META-INF";
+    private static final String YANG_STR = "yang";
+
+    static final String META_INF_YANG_STRING = META_INF_STR + File.separator + YANG_STR;
+    static final String META_INF_YANG_STRING_JAR = META_INF_STR + "/" + YANG_STR;
+    static final String META_INF_YANG_SERVICES_STRING_JAR = META_INF_STR + "/" + "services";
 
     private final File yangFilesRootDir;
     private final Set<File> excludedFiles;
@@ -61,7 +69,6 @@ class YangToSourcesProcessor {
     private final boolean inspectDependencies;
     private final BuildContext buildContext;
     private final YangProvider yangProvider;
-    private final YangTextSchemaContextResolver resolver;
 
     @VisibleForTesting
     YangToSourcesProcessor(final File yangFilesRootDir, final Collection<File> excludedFiles,
@@ -81,7 +88,6 @@ class YangToSourcesProcessor {
         this.project = Preconditions.checkNotNull(project);
         this.inspectDependencies = inspectDependencies;
         this.yangProvider = yangProvider;
-        this.resolver = YangTextSchemaContextResolver.create("maven-plugin");
     }
 
     YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir,
@@ -120,8 +126,6 @@ class YangToSourcesProcessor {
 
     @SuppressWarnings("checkstyle:illegalCatch")
     private ContextHolder processYang() throws MojoExecutionException {
-        SchemaContext resolveSchemaContext;
-        List<Closeable> closeables = new ArrayList<>();
         LOG.info("{} Inspecting {}", LOG_PREFIX, yangFilesRootDir);
         try {
             /*
@@ -159,15 +163,15 @@ class YangToSourcesProcessor {
                 return null;
             }
 
-            final List<NamedFileInputStream> yangsInProject = new ArrayList<>();
+            final Builder<SourceIdentifier, String> b = ImmutableMap.builder();
+            final YangTextSchemaContextResolver resolver = YangTextSchemaContextResolver.create("maven-plugin");
             for (final File f : yangFilesInProject) {
-                // FIXME: This is hack - normal path should be reported.
-                yangsInProject.add(new NamedFileInputStream(f, META_INF_YANG_STRING + File.separator + f.getName()));
+                final YangTextSchemaSourceRegistration reg = resolver.registerSource(YangTextSchemaSource.forFile(f));
+                // Registration has an accurate identifier
+                b.put(reg.getInstance().getIdentifier(), f.getName());
             }
 
-            List<InputStream> all = new ArrayList<>();
-            all.addAll(yangsInProject);
-            closeables.addAll(yangsInProject);
+            final Map<SourceIdentifier, String> sourcesInProject = b.build();
 
             /**
              * Set contains all modules generated from input sources. Number of
@@ -175,50 +179,44 @@ class YangToSourcesProcessor {
              * (parsed submodule's data are added to its parent module). Set
              * cannot contains null values.
              */
-            final Set<Module> projectYangModules = new HashSet<>();
-            final Set<Module> projectYangFiles = new HashSet<>();
-            try {
-                if (inspectDependencies) {
-                    YangsInZipsResult dependentYangResult = Util.findYangFilesInDependenciesAsStream(project);
-                    Closeable dependentYangResult1 = dependentYangResult;
-                    closeables.add(dependentYangResult1);
-                    List<InputStream> yangStreams = toStreamsWithoutDuplicates(dependentYangResult.getYangStreams());
-                    all.addAll(yangStreams);
-                    closeables.addAll(yangStreams);
+            if (inspectDependencies) {
+                final List<YangTextSchemaSource> sourcesInDependencies = Util.findYangFilesInDependenciesAsStream(
+                    project);
+                for (YangTextSchemaSource s : toUniqueSources(sourcesInDependencies)) {
+                    resolver.registerSource(s);
                 }
+            }
 
-                resolveSchemaContext = YangParserTestUtils.parseYangStreams(all);
-
-                Set<Module> parsedAllYangModules = resolveSchemaContext.getModules();
-                for (Module module : parsedAllYangModules) {
-                    if (containedInFiles(yangsInProject, module)) {
-                        LOG.debug("Module {} belongs to current project", module);
-                        projectYangModules.add(module);
-                        projectYangFiles.add(module);
-
-                        for (Module sub : module.getSubmodules()) {
-                            if (containedInFiles(yangsInProject, sub)) {
-                                LOG.debug("Submodule {} belongs to current project", sub);
-                                projectYangFiles.add(sub);
-                            } else {
-                                LOG.warn("Submodule {} not found in input files", sub);
-                            }
+            final SchemaContext schemaContext = resolver.trySchemaContext();
+            final Set<Module> projectYangModules = new HashSet<>();
+            final Map<Module, String> projectYangFiles = new HashMap<>();
+            for (Module module : schemaContext.getModules()) {
+                final SourceIdentifier modId = moduleToIdentifier(module);
+                LOG.debug("Looking for source {}", modId);
+                final String file = sourcesInProject.get(modId);
+                if (file != null) {
+                    LOG.debug("Module {} belongs to current project", module);
+                    projectYangModules.add(module);
+                    projectYangFiles.put(module, file);
+
+                    for (Module sub : module.getSubmodules()) {
+                        final SourceIdentifier subId = moduleToIdentifier(sub);
+                        final String subFile = sourcesInProject.get(subId);
+                        if (subFile != null) {
+                            LOG.debug("Submodule {} belongs to current project", sub);
+                            projectYangFiles.put(sub, subFile);
+                        } else {
+                            LOG.warn("Submodule {} not found in input files", sub);
                         }
                     }
                 }
-            } finally {
-                for (AutoCloseable closeable : closeables) {
-                    closeable.close();
-                }
             }
 
-            LOG.info("{} {} files parsed from {}", LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(), yangsInProject);
-            LOG.debug("Project YANG files: {}", projectYangFiles);
-
-            return new ContextHolder(resolveSchemaContext, projectYangModules, projectYangFiles);
-
-            // MojoExecutionException is thrown since execution cannot continue
+            LOG.debug("Processed project files: {}", yangFilesInProject);
+            LOG.info("{} Project model files parsed: {}", LOG_PREFIX, yangFilesInProject.size());
+            return new ContextHolder(schemaContext, projectYangModules, projectYangFiles);
         } catch (Exception e) {
+            // MojoExecutionException is thrown since execution cannot continue
             LOG.error("{} Unable to parse {} files from {}", LOG_PREFIX, Util.YANG_SUFFIX, yangFilesRootDir, e);
             Throwable rootCause = Throwables.getRootCause(e);
             throw new MojoExecutionException(LOG_PREFIX + " Unable to parse " + Util.YANG_SUFFIX + " files from "
@@ -226,39 +224,29 @@ class YangToSourcesProcessor {
         }
     }
 
-    private static boolean containedInFiles(final List<NamedFileInputStream> files, final Module module) {
-        final String path = module.getModuleSourcePath();
-        if (path != null) {
-            LOG.debug("Looking for source {}", path);
-            for (NamedFileInputStream is : files) {
-                LOG.debug("In project destination {}", is.getFileDestination());
-                if (path.equals(is.getFileDestination())) {
-                    return true;
-                }
-            }
+    private static SourceIdentifier moduleToIdentifier(final Module module) {
+        final QNameModule mod = module.getQNameModule();
+        final Date rev = mod.getRevision();
+        final Optional<String> optRev;
+        if (!SimpleDateFormatUtil.DEFAULT_DATE_REV.equals(rev)) {
+            optRev = Optional.of(mod.getFormattedRevision());
+        } else {
+            optRev = Optional.absent();
         }
 
-        return false;
+        return RevisionSourceIdentifier.create(module.getName(), optRev);
     }
 
-    private static List<InputStream> toStreamsWithoutDuplicates(final List<YangSourceFromDependency> list)
+    private static Collection<YangTextSchemaSource> toUniqueSources(final Collection<YangTextSchemaSource> sources)
             throws IOException {
-        final Map<String, YangSourceFromDependency> byContent = new HashMap<>();
-
-        for (YangSourceFromDependency yangFromDependency : list) {
-            try (Reader reader = yangFromDependency.asCharSource(StandardCharsets.UTF_8).openStream()) {
+        final Map<String, YangTextSchemaSource> byContent = new HashMap<>();
+        for (YangTextSchemaSource s : sources) {
+            try (Reader reader = s.asCharSource(StandardCharsets.UTF_8).openStream()) {
                 final String contents = CharStreams.toString(reader);
-                byContent.putIfAbsent(contents, yangFromDependency);
-            } catch (IOException e) {
-                throw new IOException("Exception when reading from: " + yangFromDependency.getDescription(), e);
+                byContent.putIfAbsent(contents, s);
             }
-
-        }
-        List<InputStream> inputs = new ArrayList<>(byContent.size());
-        for (YangSourceFromDependency entry : byContent.values()) {
-            inputs.add(entry.openStream());
         }
-        return inputs;
+        return byContent.values();
     }
 
     /**
index e5fd2e6bf1a136a9b95a4d99f2fff74ddba67ec9..5380b8b488d4d36298328f4a15d2ca3fd7d8a9e0 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.yangtools.yang2sources.plugin;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -18,8 +26,10 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
@@ -33,53 +43,51 @@ import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.repository.RepositorySystem;
-import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 import org.opendaylight.yangtools.yang2sources.plugin.Util.ContextHolder;
-import org.opendaylight.yangtools.yang2sources.plugin.Util.YangsInZipsResult;
 
 @RunWith(MockitoJUnitRunner.class)
 public class UtilTest {
 
     @Test
     public void getClassPathTest() {
-        final MavenProject project = Mockito.mock(MavenProject.class);
-        final File file = Mockito.mock(File.class);
-        final File file2 = Mockito.mock(File.class);
-        final Artifact artifact = Mockito.mock(Artifact.class);
-        final Artifact artifact2 = Mockito.mock(Artifact.class);
+        final MavenProject project = mock(MavenProject.class);
+        final File file = mock(File.class);
+        final File file2 = mock(File.class);
+        final Artifact artifact = mock(Artifact.class);
+        final Artifact artifact2 = mock(Artifact.class);
 
         final Set<Artifact> artifacts = new HashSet<>();
         artifacts.add(artifact);
         artifacts.add(artifact2);
 
-        Mockito.when(project.getArtifacts()).thenReturn(artifacts);
-        Mockito.when(artifact.getFile()).thenReturn(file);
-        Mockito.when(file.isFile()).thenReturn(true);
-        Mockito.when(file.getName()).thenReturn("iamjar.jar");
-        Mockito.when(artifact2.getFile()).thenReturn(file2);
-        Mockito.when(file2.isDirectory()).thenReturn(true);
+        when(project.getArtifacts()).thenReturn(artifacts);
+        when(artifact.getFile()).thenReturn(file);
+        when(file.isFile()).thenReturn(true);
+        when(file.getName()).thenReturn("iamjar.jar");
+        when(artifact2.getFile()).thenReturn(file2);
+        when(file2.isDirectory()).thenReturn(true);
 
         final List<File> files = Util.getClassPath(project);
-        Assert.assertEquals(2, files.size());
-        Assert.assertTrue(files.contains(file) && files.contains(file2));
+        assertEquals(2, files.size());
+        assertTrue(files.contains(file) && files.contains(file2));
     }
 
     @Test
     public void checkClasspathTest() throws Exception {
-        final MavenProject project = Mockito.mock(MavenProject.class);
-        final Plugin plugin = Mockito.mock(Plugin.class);
-        final RepositorySystem repoSystem = Mockito.mock(RepositorySystem.class);
-        final ArtifactRepository localRepo = Mockito.mock(ArtifactRepository.class);
-        final ArtifactResolutionResult artifactResolResult = Mockito.mock(ArtifactResolutionResult.class);
-        final Artifact artifact = Mockito.mock(Artifact.class);
-        final Dependency dep = Mockito.mock(Dependency.class);
+        final MavenProject project = mock(MavenProject.class);
+        final Plugin plugin = mock(Plugin.class);
+        final RepositorySystem repoSystem = mock(RepositorySystem.class);
+        final ArtifactRepository localRepo = mock(ArtifactRepository.class);
+        final ArtifactResolutionResult artifactResolResult = mock(ArtifactResolutionResult.class);
+        final Artifact artifact = mock(Artifact.class);
+        final Dependency dep = mock(Dependency.class);
 
         final List<ArtifactRepository> remoteRepos = new ArrayList<>();
         remoteRepos.add(localRepo);
@@ -90,41 +98,40 @@ public class UtilTest {
         final List<Dependency> listDepcy = new ArrayList<>();
         listDepcy.add(dep);
 
-        Mockito.when(project.getPlugin(Mockito.anyString())).thenReturn(plugin);
-        Mockito.when(plugin.getDependencies()).thenReturn(listDepcy);
-        Mockito.when(artifact.getArtifactId()).thenReturn("artifactId");
-        Mockito.when(artifact.getGroupId()).thenReturn("groupId");
-        Mockito.when(artifact.getVersion()).thenReturn("SNAPSHOT");
-        Mockito.when(repoSystem.createDependencyArtifact(dep)).thenReturn(artifact);
-        Mockito.when(repoSystem.resolve(Mockito.any(ArtifactResolutionRequest.class))).thenReturn(artifactResolResult);
-        Mockito.when(artifactResolResult.getArtifacts()).thenReturn(artifacts);
-        Mockito.when(project.getDependencyArtifacts()).thenReturn(artifacts);
+        when(project.getPlugin(anyString())).thenReturn(plugin);
+        when(plugin.getDependencies()).thenReturn(listDepcy);
+        when(artifact.getArtifactId()).thenReturn("artifactId");
+        when(artifact.getGroupId()).thenReturn("groupId");
+        when(artifact.getVersion()).thenReturn("SNAPSHOT");
+        when(repoSystem.createDependencyArtifact(dep)).thenReturn(artifact);
+        when(repoSystem.resolve(any(ArtifactResolutionRequest.class))).thenReturn(artifactResolResult);
+        when(artifactResolResult.getArtifacts()).thenReturn(artifacts);
+        when(project.getDependencyArtifacts()).thenReturn(artifacts);
 
         Util.checkClasspath(project, repoSystem, localRepo, remoteRepos);
-        Assert.assertEquals(1, artifacts.size());
-        Assert.assertEquals(1, remoteRepos.size());
-        Assert.assertEquals(1, listDepcy.size());
+        assertEquals(1, artifacts.size());
+        assertEquals(1, remoteRepos.size());
+        assertEquals(1, listDepcy.size());
     }
 
     @Test
     public void findYangFilesInDependenciesAsStream() throws Exception {
-        final MavenProject project = Mockito.mock(MavenProject.class);
+        final MavenProject project = mock(MavenProject.class);
         prepareProject(project);
 
-        final YangsInZipsResult yangzip = Util.findYangFilesInDependenciesAsStream(project);
-        Assert.assertNotNull(yangzip);
-        Assert.assertEquals(2, yangzip.getYangStreams().size());
-        yangzip.close();
+        final List<YangTextSchemaSource> yangzip = Util.findYangFilesInDependenciesAsStream(project);
+        assertNotNull(yangzip);
+        assertEquals(2, yangzip.size());
     }
 
     @Test
     public void findYangFilesInDependencies() throws Exception {
-        final MavenProject project = Mockito.mock(MavenProject.class);
+        final MavenProject project = mock(MavenProject.class);
         prepareProject(project);
 
         final Collection<File> files = Util.findYangFilesInDependencies(project);
-        Assert.assertNotNull(files);
-        Assert.assertEquals(2, files.size());
+        assertNotNull(files);
+        assertEquals(2, files.size());
     }
 
     @Test
@@ -132,18 +139,18 @@ public class UtilTest {
         final File testYang1 = new File(getClass().getResource("/test.yang").toURI());
         final File testYang2 = new File(getClass().getResource("/test2.yang").toURI());
         final SchemaContext context = YangParserTestUtils.parseYangSources(testYang1, testYang2);
-        final Set<Module> yangModules = new HashSet<>();
-        final Util.ContextHolder cxH = new ContextHolder(context, yangModules, yangModules);
-        Assert.assertEquals(context, cxH.getContext());
-        Assert.assertEquals(yangModules, cxH.getYangModules());
+        final Map<Module, String> yangModules = new HashMap<>();
+        final Util.ContextHolder cxH = new ContextHolder(context, yangModules.keySet(), yangModules);
+        assertEquals(context, cxH.getContext());
+        assertEquals(yangModules.keySet(), cxH.getYangModules());
     }
 
     private URL makeMetaInf() throws Exception {
         final String path = getClass().getResource("/").getPath();
         final String metaInfPath = path + "tests/META-INF/yang";
         final Path createDirectories = Files.createDirectories(Paths.get(metaInfPath));
-        Assert.assertNotNull(createDirectories);
-        Assert.assertEquals(metaInfPath, createDirectories.toString());
+        assertNotNull(createDirectories);
+        assertEquals(metaInfPath, createDirectories.toString());
         Runtime.getRuntime().exec("cp " + path + "/test.yang " + metaInfPath + "/");
         Runtime.getRuntime().exec("cp " + path + "/test2.yang " + metaInfPath + "/");
         return getClass().getResource("/tests");
@@ -154,7 +161,7 @@ public class UtilTest {
         if (url == null) {
             url = makeMetaInf();
         }
-        Assert.assertNotNull(url);
+        assertNotNull(url);
         final File testFile = new File(getClass().getResource("/tests").toURI());
         File testFile2 = new File(getClass().getResource("/").getPath(), "test.jar");
         testFile2.createNewFile();
@@ -166,16 +173,16 @@ public class UtilTest {
         addSourceFileToTargetJar(new File(getClass().getResource("/tests/META-INF").getPath()), target);
         target.close();
 
-        final Artifact artifact = Mockito.mock(Artifact.class);
-        final Artifact artifact2 = Mockito.mock(Artifact.class);
+        final Artifact artifact = mock(Artifact.class);
+        final Artifact artifact2 = mock(Artifact.class);
 
         final Set<Artifact> artifacts = new HashSet<>();
         artifacts.add(artifact);
         artifacts.add(artifact2);
 
-        Mockito.when(project.getArtifacts()).thenReturn(artifacts);
-        Mockito.when(artifact.getFile()).thenReturn(testFile);
-        Mockito.when(artifact2.getFile()).thenReturn(testFile2);
+        when(project.getArtifacts()).thenReturn(artifacts);
+        when(artifact.getFile()).thenReturn(testFile);
+        when(artifact2.getFile()).thenReturn(testFile2);
     }
 
     private void addSourceFileToTargetJar(final File source, final JarOutputStream target) throws IOException {
diff --git a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFileTest.java b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFileTest.java
deleted file mode 100644 (file)
index 5286855..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang2sources.plugin;
-
-import java.io.File;
-import java.io.InputStream;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class YangSourceFromFileTest {
-
-    @Test
-    public void yangSourceFromFileTest() throws Exception {
-        final File source = new File(getClass().getResource("/yang-source-from-file.yang").getFile());
-        final YangSourceFromFile yangSource = new YangSourceFromFile(source);
-        final InputStream openStream = yangSource.openStream();
-        Assert.assertNotNull(openStream);
-        Assert.assertEquals(541, yangSource.size());
-    }
-
-}
diff --git a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFileTest.java b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFileTest.java
deleted file mode 100644 (file)
index d0e65d5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang2sources.plugin;
-
-import java.io.InputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class YangSourceInZipFileTest {
-
-    @Test
-    public void yangSourceInZipFileTest() throws Exception {
-        final ZipFile file = Mockito.mock(ZipFile.class);
-        final ZipEntry entry = Mockito.mock(ZipEntry.class);
-        Mockito.when(entry.getSize()).thenReturn(519L);
-        final InputStream inputStream = Mockito.mock(InputStream.class);
-        Mockito.when(file.getInputStream(entry)).thenReturn(inputStream);
-        final YangSourceInZipFile yangSource = new YangSourceInZipFile(file, entry);
-        Assert.assertEquals(519, yangSource.size());
-        Assert.assertNotNull(yangSource.openStream());
-    }
-
-}
index 2dd566bf17c7b8047b30f3a1f030bcbfdbd0f742..cf5e75f8c03180981102bdfe8af29a659ada94de 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.parser.repo;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -252,6 +253,18 @@ public final class YangTextSchemaContextResolver implements AutoCloseable, Schem
         return sc;
     }
 
+    @Beta
+    public SchemaContext trySchemaContext() throws SchemaResolutionException {
+        return trySchemaContext(StatementParserMode.DEFAULT_MODE);
+    }
+
+    @Beta
+    public SchemaContext trySchemaContext(final StatementParserMode statementParserMode)
+            throws SchemaResolutionException {
+        final SchemaContextFactory factory = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+        return factory.createSchemaContext(ImmutableSet.copyOf(requiredSources), statementParserMode).checkedGet();
+    }
+
     @Override
     public synchronized CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(
             final SourceIdentifier sourceIdentifier) {