import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+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.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.commons.io.IOUtils;
-import org.apache.maven.model.Resource;
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.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
static final String META_INF_YANG_SERVICES_STRING_JAR = "META-INF" + "/" + "services";
private final File yangFilesRootDir;
- private final File[] excludedFiles;
+ private final Set<File> excludedFiles;
private final List<CodeGeneratorArg> codeGenerators;
private final MavenProject project;
private final boolean inspectDependencies;
private final YangTextSchemaContextResolver resolver;
@VisibleForTesting
- YangToSourcesProcessor(final File yangFilesRootDir, final File[] excludedFiles, final List<CodeGeneratorArg> codeGenerators,
- final MavenProject project, final boolean inspectDependencies, final YangProvider yangProvider) {
+ YangToSourcesProcessor(final File yangFilesRootDir, final Collection<File> excludedFiles,
+ final List<CodeGeneratorArg> codeGenerators, final MavenProject project, final boolean inspectDependencies,
+ final YangProvider yangProvider) {
this(new DefaultBuildContext(), yangFilesRootDir, excludedFiles, codeGenerators, project,
inspectDependencies, yangProvider);
}
- private YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir, final File[] excludedFiles,
- final List<CodeGeneratorArg> codeGenerators, final MavenProject project, final boolean inspectDependencies, final YangProvider
- yangProvider) {
- this.buildContext = Util.checkNotNull(buildContext, "buildContext");
- this.yangFilesRootDir = Util.checkNotNull(yangFilesRootDir, "yangFilesRootDir");
- this.excludedFiles = new File[excludedFiles.length];
- int i = 0;
- for (File file : excludedFiles) {
- this.excludedFiles[i++] = new File(file.getPath());
- }
- this.codeGenerators = Collections.unmodifiableList(Util.checkNotNull(codeGenerators, "codeGenerators"));
- this.project = Util.checkNotNull(project, "project");
+ private YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir,
+ final Collection<File> excludedFiles, final List<CodeGeneratorArg> codeGenerators,
+ final MavenProject project, final boolean inspectDependencies, final YangProvider yangProvider) {
+ this.buildContext = Preconditions.checkNotNull(buildContext, "buildContext");
+ this.yangFilesRootDir = Preconditions.checkNotNull(yangFilesRootDir, "yangFilesRootDir");
+ this.excludedFiles = ImmutableSet.copyOf(excludedFiles);
+ this.codeGenerators = ImmutableList.copyOf(codeGenerators);
+ this.project = Preconditions.checkNotNull(project);
this.inspectDependencies = inspectDependencies;
this.yangProvider = yangProvider;
this.resolver = YangTextSchemaContextResolver.create("maven-plugin");
}
- YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir, final File[] excludedFiles,
- final List<CodeGeneratorArg> codeGenerators, final MavenProject project, final boolean inspectDependencies) {
+ YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir,
+ final Collection<File> excludedFiles, final List<CodeGeneratorArg> codeGenerators,
+ final MavenProject project, final boolean inspectDependencies) {
this(yangFilesRootDir, excludedFiles, codeGenerators, project, inspectDependencies, new YangProvider());
}
yangProvider.addYangsToMetaInf(project, yangFilesRootDir, excludedFiles);
// add META_INF/services
- File generatedServicesDir = new File(project.getBasedir(), CodeGeneratorArg.YANG_SERVICES_GENERATED_DIR);
+ File generatedServicesDir = new GeneratedDirectories(project).getYangServicesDir();
YangProvider.setResource(generatedServicesDir, project);
LOG.debug("{} Yang services files from: {} marked as resources: {}", LOG_PREFIX, generatedServicesDir,
META_INF_YANG_SERVICES_STRING_JAR);
*/
final Collection<File> yangFilesInProject = Util.listFiles(yangFilesRootDir, excludedFiles);
-
final Collection<File> allFiles = new ArrayList<>(yangFilesInProject);
if (inspectDependencies) {
allFiles.addAll(Util.findYangFilesInDependencies(project));
* (parsed submodule's data are added to its parent module). Set
* cannot contains null values.
*/
- Set<Module> projectYangModules;
+ final Set<Module> projectYangModules = new HashSet<>();
+ final Set<Module> projectYangFiles = new HashSet<>();
try {
if (inspectDependencies) {
YangsInZipsResult dependentYangResult = Util.findYangFilesInDependenciesAsStream(project);
resolveSchemaContext = YangParserTestUtils.parseYangStreams(all);
Set<Module> parsedAllYangModules = resolveSchemaContext.getModules();
- projectYangModules = new HashSet<>();
for (Module module : parsedAllYangModules) {
- final String path = module.getModuleSourcePath();
- if (path != null) {
- LOG.debug("Looking for source {}", path);
- for (NamedFileInputStream is : yangsInProject) {
- LOG.debug("In project destination {}", is.getFileDestination());
- if (path.equals(is.getFileDestination())) {
- LOG.debug("Module {} belongs to current project", module);
- projectYangModules.add(module);
- break;
+ 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);
}
}
}
}
LOG.info("{} {} files parsed from {}", LOG_PREFIX, Util.YANG_SUFFIX.toUpperCase(), yangsInProject);
- return new ContextHolder(resolveSchemaContext, projectYangModules);
+ LOG.debug("Project YANG files: {}", projectYangFiles);
+
+ return new ContextHolder(resolveSchemaContext, projectYangModules, projectYangFiles);
// MojoExecutionException is thrown since execution cannot continue
} catch (Exception e) {
}
}
- private static List<InputStream> toStreamsWithoutDuplicates(final List<YangSourceFromDependency> list) throws IOException {
+ 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;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static List<InputStream> toStreamsWithoutDuplicates(final List<YangSourceFromDependency> list)
+ throws IOException {
final Map<String, YangSourceFromDependency> byContent = new HashMap<>();
for (YangSourceFromDependency yangFromDependency : list) {
- try (InputStream dataStream = yangFromDependency.openStream()) {
- String contents = IOUtils.toString(dataStream);
+ try (Reader reader = yangFromDependency.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);
return inputs;
}
- static class YangProvider {
- private static final Logger LOG = LoggerFactory.getLogger(YangProvider.class);
-
- void addYangsToMetaInf(final MavenProject project, final File yangFilesRootDir, final File[] excludedFiles)
- throws MojoFailureException {
-
- // copy project's src/main/yang/*.yang to target/generated-sources/yang/META-INF/yang/*.yang
-
- File generatedYangDir = new File(project.getBasedir(), CodeGeneratorArg.YANG_GENERATED_DIR);
- addYangsToMetaInf(project, yangFilesRootDir, excludedFiles, generatedYangDir);
-
- // Also copy to the actual build output dir if different than "target". When running in
- // Eclipse this can differ (eg "target-ide").
-
- File actualGeneratedYangDir = new File(project.getBuild().getDirectory(),
- CodeGeneratorArg.YANG_GENERATED_DIR.replace("target" + File.separator, ""));
- if (!actualGeneratedYangDir.equals(generatedYangDir)) {
- addYangsToMetaInf(project, yangFilesRootDir, excludedFiles, actualGeneratedYangDir);
- }
- }
-
- private static void addYangsToMetaInf(final MavenProject project, final File yangFilesRootDir,
- final File[] excludedFiles, final File generatedYangDir) throws MojoFailureException {
-
- File withMetaInf = new File(generatedYangDir, META_INF_YANG_STRING);
- withMetaInf.mkdirs();
-
- try {
- Collection<File> files = Util.listFiles(yangFilesRootDir, excludedFiles);
- for (File file : files) {
- org.apache.commons.io.FileUtils.copyFile(file, new File(withMetaInf, file.getName()));
- }
- } catch (IOException e) {
- LOG.warn("Failed to generate files into root {}", yangFilesRootDir, e);
- throw new MojoFailureException("Unable to list yang files into resource folder", e);
- }
-
- setResource(generatedYangDir, project);
-
- LOG.debug("{} Yang files from: {} marked as resources: {}", LOG_PREFIX, yangFilesRootDir,
- META_INF_YANG_STRING_JAR);
- }
-
- private static void setResource(final File targetYangDir, final MavenProject project) {
- Resource res = new Resource();
- res.setDirectory(targetYangDir.getPath());
- project.addResource(res);
- }
- }
-
/**
* Call generate on every generator from plugin configuration
*/
LOG.debug("{} Folder: {} marked as resources for generator: {}", LOG_PREFIX, resourceBaseDir,
codeGeneratorCfg.getCodeGeneratorClass());
- Collection<File> generated = g.generateSources(context.getContext(), outputDir, context.getYangModules());
+ FileUtils.deleteDirectory(outputDir);
+ LOG.info("{} Succesfully deleted output directory {}", LOG_PREFIX, outputDir);
+
+ Collection<File> generated = g.generateSources(context.getContext(), outputDir, context.getYangModules(),
+ context::moduleToResourcePath);
LOG.info("{} Sources generated by {}: {}", LOG_PREFIX, codeGeneratorCfg.getCodeGeneratorClass(), generated);
}