From f271e68461d10a30f2a9fd2b89aa37204a720688 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 5 Sep 2017 16:14:31 +0200 Subject: [PATCH] Revert "BUG-7568: refactor yang-maven-plugin" This reverts commit ab09dfe2691b4ab5d5937b124ae3afc199a561b7. Change-Id: Idb128323149613fae8d06298b39cdcf40b0ca690 Signed-off-by: Robert Varga --- .../plugin/it/YangToSourcesPluginTestIT.java | 13 +- yang/yang-maven-plugin/pom.xml | 2 +- .../yangtools/yang2sources/plugin/Util.java | 139 ++++++++++------- .../plugin/YangSourceFromFile.java | 40 +++++ .../plugin/YangSourceInZipFile.java | 40 +++++ .../plugin/YangToSourcesProcessor.java | 146 ++++++++++-------- .../yang2sources/plugin/UtilTest.java | 117 +++++++------- .../plugin/YangSourceFromFileTest.java | 26 ++++ .../plugin/YangSourceInZipFileTest.java | 34 ++++ .../repo/YangTextSchemaContextResolver.java | 13 -- 10 files changed, 364 insertions(+), 206 deletions(-) create mode 100644 yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFile.java create mode 100644 yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFile.java create mode 100644 yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFileTest.java create mode 100644 yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFileTest.java diff --git a/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java b/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java index b6f1b55d3b..7cea1e7174 100644 --- a/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java +++ b/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java @@ -62,19 +62,16 @@ public class YangToSourcesPluginTestIT { setUp("test-parent/MissingYangInDep/", false); fail("Verification exception should have been thrown"); } catch (VerificationException e) { - assertVerificationException(e, - "SchemaResolutionException{unsatisfiedImports={RevisionSourceIdentifier" - + " [name=private@2013-02-27]=[ModuleImportImpl" - + " [name=unknownDep, revision=2013-02-27, semanticVersion=0.0.0]]}"); - return; + assertVerificationException(e, "org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException: " + + "Imported module [unknownDep] was not found."); } } static void verifyCorrectLog(final Verifier vrf) throws VerificationException { vrf.verifyErrorFreeLog(); - 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: 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: Sources generated by " + "org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl: null"); } diff --git a/yang/yang-maven-plugin/pom.xml b/yang/yang-maven-plugin/pom.xml index 04ef90d64f..900e8d92b1 100644 --- a/yang/yang-maven-plugin/pom.xml +++ b/yang/yang-maven-plugin/pom.xml @@ -71,7 +71,7 @@ ${project.groupId} yang-test-util - test + compile ${project.groupId} diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java index 2941edd4cb..000ba17b03 100644 --- a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java @@ -8,17 +8,13 @@ package org.opendaylight.yangtools.yang2sources.plugin; import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION; -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 com.google.common.base.Splitter; +import com.google.common.collect.Iterables; +import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -43,7 +39,6 @@ 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; @@ -62,7 +57,8 @@ final class Util { static Collection listFiles(final File root, final Collection excludedFiles) throws FileNotFoundException { if (!root.exists()) { - LOG.warn("{} YANG source directory {} not found. No code will be generated.", LOG_PREFIX, root); + LOG.warn("{} YANG source directory {} not found. No code will be generated.", YangToSourcesProcessor + .LOG_PREFIX, root.toString()); return Collections.emptyList(); } @@ -70,7 +66,8 @@ final class Util { Collection yangFiles = FileUtils.listFiles(root, new String[] { YANG_SUFFIX }, true); for (File f : yangFiles) { if (excludedFiles.contains(f)) { - LOG.info("{} {} file excluded {}", LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(), f); + LOG.info("{} {} file excluded {}", YangToSourcesProcessor.LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(), + f); } else { result.add(f); } @@ -107,7 +104,8 @@ final class Util { final ArtifactRepository localRepo, final List remoteRepos) { Plugin plugin = project.getPlugin(YangToSourcesMojo.PLUGIN_NAME); if (plugin == null) { - LOG.warn("{} {} not found, dependencies version check skipped", LOG_PREFIX, YangToSourcesMojo.PLUGIN_NAME); + LOG.warn("{} {} not found, dependencies version check skipped", YangToSourcesProcessor.LOG_PREFIX, + YangToSourcesMojo.PLUGIN_NAME); } else { Map> pluginDependencies = new HashMap<>(); getPluginTransitiveDependencies(plugin, pluginDependencies, repoSystem, localRepo, remoteRepos); @@ -170,70 +168,93 @@ 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:", LOG_PREFIX); + LOG.warn("{} Dependency resolution conflict:", YangToSourcesProcessor.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.", - LOG_PREFIX, YangToSourcesMojo.PLUGIN_NAME, artifact, d); + YangToSourcesProcessor.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"); + return (element.isFile() && element.getName().endsWith(JAR_SUFFIX)); + } + + static final class YangsInZipsResult implements Closeable { + private final List yangStreams; + private final List zipInputStreams; + + private YangsInZipsResult(final List yangStreams, + final List zipInputStreams) { + this.yangStreams = yangStreams; + this.zipInputStreams = zipInputStreams; + } + + @Override + public void close() throws IOException { + for (Closeable is : zipInputStreams) { + is.close(); + } + } + + public List getYangStreams() { + return this.yangStreams; + } } @SuppressWarnings("checkstyle:illegalCatch") - static List findYangFilesInDependenciesAsStream(final MavenProject project) + static YangsInZipsResult findYangFilesInDependenciesAsStream(final MavenProject project) throws MojoFailureException { + List yangsFromDependencies = new ArrayList<>(); + List zips = new ArrayList<>(); try { - final List filesOnCp = Util.getClassPath(project); - LOG.info("{} Searching for yang files in following dependencies: {}", LOG_PREFIX, filesOnCp); + List filesOnCp = Util.getClassPath(project); + LOG.info("{} Searching for yang files in following dependencies: {}", YangToSourcesProcessor.LOG_PREFIX, + filesOnCp); - final List yangsFromDependencies = new ArrayList<>(); for (File file : filesOnCp) { - final List foundFilesForReporting = new ArrayList<>(); + List foundFilesForReporting = new ArrayList<>(); // is it jar file or directory? if (file.isDirectory()) { //FIXME: code duplicate - File yangDir = new File(file, META_INF_YANG_STRING); + File yangDir = new File(file, YangToSourcesProcessor.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) { - foundFilesForReporting.add(yangFile.getName()); - yangsFromDependencies.add(YangTextSchemaSource.forFile(yangFile)); + yangsFromDependencies.add(new YangSourceFromFile(yangFile)); } } - } else { - try (ZipFile zip = new ZipFile(file)) { - final Enumeration 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))))); - } + } else { + ZipFile zip = new ZipFile(file); + zips.add(zip); + + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String entryName = entry.getName(); + + if (entryName.startsWith(YangToSourcesProcessor.META_INF_YANG_STRING_JAR) + && !entry.isDirectory() && entryName.endsWith(RFC6020_YANG_FILE_EXTENSION)) { + foundFilesForReporting.add(entryName); + yangsFromDependencies.add(new YangSourceInZipFile(zip, entry)); } } } if (foundFilesForReporting.size() > 0) { - LOG.info("{} Found {} yang files in {}: {}", LOG_PREFIX, foundFilesForReporting.size(), file, - foundFilesForReporting); + LOG.info("{} Found {} yang files in {}: {}", YangToSourcesProcessor.LOG_PREFIX, + foundFilesForReporting.size(), file, foundFilesForReporting); } } - - return yangsFromDependencies; } catch (Exception e) { throw new MojoFailureException(e.getMessage(), e); } + return new YangsInZipsResult(yangsFromDependencies, zips); } /** @@ -246,20 +267,21 @@ final class Util { static Collection findYangFilesInDependencies(final MavenProject project) throws MojoFailureException { final List yangsFilesFromDependencies = new ArrayList<>(); - final List filesOnCp; + List 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: {}", LOG_PREFIX, filesOnCp); + LOG.info("{} Searching for yang files in following dependencies: {}", YangToSourcesProcessor.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, META_INF_YANG_STRING); + File yangDir = new File(file, YangToSourcesProcessor.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()); @@ -274,9 +296,10 @@ final class Util { ZipEntry entry = entries.nextElement(); String entryName = entry.getName(); - if (entryName.startsWith(META_INF_YANG_STRING_JAR) + if (entryName.startsWith(YangToSourcesProcessor.META_INF_YANG_STRING_JAR) && !entry.isDirectory() && entryName.endsWith(RFC6020_YANG_FILE_EXTENSION)) { - LOG.debug("{} Found a YANG file in {}: {}", LOG_PREFIX, file, entryName); + LOG.debug("{} Found a YANG file in {}: {}", YangToSourcesProcessor.LOG_PREFIX, file, + entryName); yangsFilesFromDependencies.add(file); break; } @@ -291,14 +314,16 @@ final class Util { } static final class ContextHolder { + private static final Splitter SEP_SPLITTER = Splitter.on(File.separator); + private final SchemaContext context; private final Set yangModules; - private final Map yangFiles; + private final Set yangFiles; - ContextHolder(final SchemaContext context, final Set yangModules, final Map yangFiles) { - this.context = Preconditions.checkNotNull(context); - this.yangModules = ImmutableSet.copyOf(yangModules); - this.yangFiles = ImmutableMap.copyOf(yangFiles); + ContextHolder(final SchemaContext context, final Set yangModules, final Set yangFiles) { + this.context = context; + this.yangModules = yangModules; + this.yangFiles = yangFiles; } SchemaContext getContext() { @@ -309,13 +334,17 @@ final class Util { return yangModules; } + Set getYangFiles() { + return yangFiles; + } + Optional moduleToResourcePath(final Module mod) { - final String fileName = yangFiles.get(mod); - if (fileName == null) { + if (!yangFiles.contains(mod)) { return Optional.empty(); } - return Optional.of("/" + YangToSourcesProcessor.META_INF_YANG_STRING_JAR + "/" + fileName); + return Optional.of("/" + YangToSourcesProcessor.META_INF_YANG_STRING_JAR + "/" + + Iterables.getLast(SEP_SPLITTER.split(mod.getModuleSourcePath()))); } } } 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 new file mode 100644 index 0000000000..523ae55d61 --- /dev/null +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFile.java @@ -0,0 +1,40 @@ +/* + * 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 new file mode 100644 index 0000000000..72ba67d4c8 --- /dev/null +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFile.java @@ -0,0 +1,40 @@ +/* + * 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(); + } +} diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java index 97c810d751..bb820517da 100644 --- a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java @@ -8,21 +8,19 @@ 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; @@ -32,17 +30,14 @@ 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.repo.YangTextSchemaSourceRegistration; +import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream; +import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; 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; @@ -55,12 +50,9 @@ class YangToSourcesProcessor { private static final Logger LOG = LoggerFactory.getLogger(YangToSourcesProcessor.class); static final String LOG_PREFIX = "yang-to-sources:"; - 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"; + 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 final File yangFilesRootDir; private final Set excludedFiles; @@ -69,6 +61,7 @@ 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 excludedFiles, @@ -88,6 +81,7 @@ 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, @@ -126,6 +120,8 @@ class YangToSourcesProcessor { @SuppressWarnings("checkstyle:illegalCatch") private ContextHolder processYang() throws MojoExecutionException { + SchemaContext resolveSchemaContext; + List closeables = new ArrayList<>(); LOG.info("{} Inspecting {}", LOG_PREFIX, yangFilesRootDir); try { /* @@ -163,15 +159,15 @@ class YangToSourcesProcessor { return null; } - final Builder b = ImmutableMap.builder(); - final YangTextSchemaContextResolver resolver = YangTextSchemaContextResolver.create("maven-plugin"); + final List yangsInProject = new ArrayList<>(); for (final File f : yangFilesInProject) { - final YangTextSchemaSourceRegistration reg = resolver.registerSource(YangTextSchemaSource.forFile(f)); - // Registration has an accurate identifier - b.put(reg.getInstance().getIdentifier(), f.getName()); + // FIXME: This is hack - normal path should be reported. + yangsInProject.add(new NamedFileInputStream(f, META_INF_YANG_STRING + File.separator + f.getName())); } - final Map sourcesInProject = b.build(); + List all = new ArrayList<>(); + all.addAll(yangsInProject); + closeables.addAll(yangsInProject); /** * Set contains all modules generated from input sources. Number of @@ -179,44 +175,50 @@ class YangToSourcesProcessor { * (parsed submodule's data are added to its parent module). Set * cannot contains null values. */ - if (inspectDependencies) { - final List sourcesInDependencies = Util.findYangFilesInDependenciesAsStream( - project); - for (YangTextSchemaSource s : toUniqueSources(sourcesInDependencies)) { - resolver.registerSource(s); + final Set projectYangModules = new HashSet<>(); + final Set projectYangFiles = new HashSet<>(); + try { + if (inspectDependencies) { + YangsInZipsResult dependentYangResult = Util.findYangFilesInDependenciesAsStream(project); + Closeable dependentYangResult1 = dependentYangResult; + closeables.add(dependentYangResult1); + List yangStreams = toStreamsWithoutDuplicates(dependentYangResult.getYangStreams()); + all.addAll(yangStreams); + closeables.addAll(yangStreams); } - } - final SchemaContext schemaContext = resolver.trySchemaContext(); - final Set projectYangModules = new HashSet<>(); - final Map 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); + resolveSchemaContext = YangParserTestUtils.parseYangStreams(all); + + Set 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); + } } } } + } finally { + for (AutoCloseable closeable : closeables) { + closeable.close(); + } } - 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) { + 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 + } catch (Exception e) { 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 " @@ -224,29 +226,39 @@ class YangToSourcesProcessor { } } - private static SourceIdentifier moduleToIdentifier(final Module module) { - final QNameModule mod = module.getQNameModule(); - final Date rev = mod.getRevision(); - final Optional optRev; - if (!SimpleDateFormatUtil.DEFAULT_DATE_REV.equals(rev)) { - optRev = Optional.of(mod.getFormattedRevision()); - } else { - optRev = Optional.absent(); + private static boolean containedInFiles(final List 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; + } + } } - return RevisionSourceIdentifier.create(module.getName(), optRev); + return false; } - private static Collection toUniqueSources(final Collection sources) + private static List toStreamsWithoutDuplicates(final List list) throws IOException { - final Map byContent = new HashMap<>(); - for (YangTextSchemaSource s : sources) { - try (Reader reader = s.asCharSource(StandardCharsets.UTF_8).openStream()) { + final Map byContent = new HashMap<>(); + + for (YangSourceFromDependency yangFromDependency : list) { + try (Reader reader = yangFromDependency.asCharSource(StandardCharsets.UTF_8).openStream()) { final String contents = CharStreams.toString(reader); - byContent.putIfAbsent(contents, s); + byContent.putIfAbsent(contents, yangFromDependency); + } catch (IOException e) { + throw new IOException("Exception when reading from: " + yangFromDependency.getDescription(), e); } + + } + List inputs = new ArrayList<>(byContent.size()); + for (YangSourceFromDependency entry : byContent.values()) { + inputs.add(entry.openStream()); } - return byContent.values(); + return inputs; } /** diff --git a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/UtilTest.java b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/UtilTest.java index 5380b8b488..e5fd2e6bf1 100644 --- a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/UtilTest.java +++ b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/UtilTest.java @@ -7,14 +7,6 @@ */ 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; @@ -26,10 +18,8 @@ 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; @@ -43,51 +33,53 @@ 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 = 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 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 Set artifacts = new HashSet<>(); artifacts.add(artifact); artifacts.add(artifact2); - 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); + 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); final List files = Util.getClassPath(project); - assertEquals(2, files.size()); - assertTrue(files.contains(file) && files.contains(file2)); + Assert.assertEquals(2, files.size()); + Assert.assertTrue(files.contains(file) && files.contains(file2)); } @Test public void checkClasspathTest() throws Exception { - 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 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 List remoteRepos = new ArrayList<>(); remoteRepos.add(localRepo); @@ -98,40 +90,41 @@ public class UtilTest { final List listDepcy = new ArrayList<>(); listDepcy.add(dep); - 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); + 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); Util.checkClasspath(project, repoSystem, localRepo, remoteRepos); - assertEquals(1, artifacts.size()); - assertEquals(1, remoteRepos.size()); - assertEquals(1, listDepcy.size()); + Assert.assertEquals(1, artifacts.size()); + Assert.assertEquals(1, remoteRepos.size()); + Assert.assertEquals(1, listDepcy.size()); } @Test public void findYangFilesInDependenciesAsStream() throws Exception { - final MavenProject project = mock(MavenProject.class); + final MavenProject project = Mockito.mock(MavenProject.class); prepareProject(project); - final List yangzip = Util.findYangFilesInDependenciesAsStream(project); - assertNotNull(yangzip); - assertEquals(2, yangzip.size()); + final YangsInZipsResult yangzip = Util.findYangFilesInDependenciesAsStream(project); + Assert.assertNotNull(yangzip); + Assert.assertEquals(2, yangzip.getYangStreams().size()); + yangzip.close(); } @Test public void findYangFilesInDependencies() throws Exception { - final MavenProject project = mock(MavenProject.class); + final MavenProject project = Mockito.mock(MavenProject.class); prepareProject(project); final Collection files = Util.findYangFilesInDependencies(project); - assertNotNull(files); - assertEquals(2, files.size()); + Assert.assertNotNull(files); + Assert.assertEquals(2, files.size()); } @Test @@ -139,18 +132,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 Map yangModules = new HashMap<>(); - final Util.ContextHolder cxH = new ContextHolder(context, yangModules.keySet(), yangModules); - assertEquals(context, cxH.getContext()); - assertEquals(yangModules.keySet(), cxH.getYangModules()); + final Set yangModules = new HashSet<>(); + final Util.ContextHolder cxH = new ContextHolder(context, yangModules, yangModules); + Assert.assertEquals(context, cxH.getContext()); + Assert.assertEquals(yangModules, 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)); - assertNotNull(createDirectories); - assertEquals(metaInfPath, createDirectories.toString()); + Assert.assertNotNull(createDirectories); + Assert.assertEquals(metaInfPath, createDirectories.toString()); Runtime.getRuntime().exec("cp " + path + "/test.yang " + metaInfPath + "/"); Runtime.getRuntime().exec("cp " + path + "/test2.yang " + metaInfPath + "/"); return getClass().getResource("/tests"); @@ -161,7 +154,7 @@ public class UtilTest { if (url == null) { url = makeMetaInf(); } - assertNotNull(url); + Assert.assertNotNull(url); final File testFile = new File(getClass().getResource("/tests").toURI()); File testFile2 = new File(getClass().getResource("/").getPath(), "test.jar"); testFile2.createNewFile(); @@ -173,16 +166,16 @@ public class UtilTest { addSourceFileToTargetJar(new File(getClass().getResource("/tests/META-INF").getPath()), target); target.close(); - final Artifact artifact = mock(Artifact.class); - final Artifact artifact2 = mock(Artifact.class); + final Artifact artifact = Mockito.mock(Artifact.class); + final Artifact artifact2 = Mockito.mock(Artifact.class); final Set artifacts = new HashSet<>(); artifacts.add(artifact); artifacts.add(artifact2); - when(project.getArtifacts()).thenReturn(artifacts); - when(artifact.getFile()).thenReturn(testFile); - when(artifact2.getFile()).thenReturn(testFile2); + Mockito.when(project.getArtifacts()).thenReturn(artifacts); + Mockito.when(artifact.getFile()).thenReturn(testFile); + Mockito.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 new file mode 100644 index 0000000000..5286855d40 --- /dev/null +++ b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceFromFileTest.java @@ -0,0 +1,26 @@ +/* + * 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 new file mode 100644 index 0000000000..d0e65d5125 --- /dev/null +++ b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/YangSourceInZipFileTest.java @@ -0,0 +1,34 @@ +/* + * 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()); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java index cf5e75f8c0..2dd566bf17 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java @@ -9,7 +9,6 @@ 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; @@ -253,18 +252,6 @@ 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 getSource( final SourceIdentifier sourceIdentifier) { -- 2.36.6