+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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 static com.google.common.base.Verify.verify;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.MultimapBuilder;
-import com.google.common.collect.Table;
-import com.google.common.collect.Table.Cell;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.maven.model.Build;
-import org.apache.maven.model.Resource;
-import org.apache.maven.project.MavenProject;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
-import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
-import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
-import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
-import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonatype.plexus.build.incremental.BuildContext;
-
-final class FileGeneratorTask extends GeneratorTask<FileGeneratorTaskFactory> {
- private static final Logger LOG = LoggerFactory.getLogger(FileGeneratorTask.class);
-
- private final Map<GeneratedFileType, File> persistentDirs = new HashMap<>(4);
- private final Map<GeneratedFileType, File> transientDirs = new HashMap<>(4);
- private final MavenProject project;
- private final File buildDir;
- private final String suffix;
-
- FileGeneratorTask(final @NonNull FileGeneratorTaskFactory factory, final @NonNull ContextHolder context,
- final MavenProject project) {
- super(factory, context);
-
- final Build build = project.getBuild();
- final String buildDirectory = build.getDirectory();
- this.buildDir = new File(buildDirectory);
- this.suffix = factory.getIdentifier();
- this.project = project;
- }
-
- @Override
- Collection<File> execute(final FileGeneratorTaskFactory factory, final ContextHolder modelContext,
- final BuildContext buildContext) throws FileGeneratorException, IOException {
- // Step one: determine what files are going to be generated
- final Stopwatch sw = Stopwatch.createStarted();
- final FileGenerator gen = factory.generator();
- final Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generatedFiles = gen.generateFiles(
- modelContext.getContext(), modelContext.getYangModules(), modelContext);
- LOG.info("{}: Defined {} files in {}", suffix, generatedFiles.size(), sw);
-
- // Step two: create generation tasks for each target file and group them by parent directory
- sw.reset().start();
- final ListMultimap<File, WriteTask> dirs = MultimapBuilder.hashKeys().arrayListValues().build();
- for (Cell<GeneratedFileType, GeneratedFilePath, GeneratedFile> cell : generatedFiles.cellSet()) {
- final GeneratedFile file = cell.getValue();
- final String relativePath = cell.getColumnKey().getPath();
- final File target;
- switch (file.getLifecycle()) {
- case PERSISTENT:
- target = new File(persistentPath(cell.getRowKey()), relativePath);
- if (target.exists()) {
- LOG.debug("Skipping existing persistent {}", target);
- continue;
- }
- break;
- case TRANSIENT:
- target = new File(transientPath(cell.getRowKey()), relativePath);
- break;
- default:
- throw new IllegalStateException("Unsupported file type in " + file);
- }
-
- dirs.put(target.getParentFile(), new WriteTask(buildContext, target, cell.getValue()));
- }
- LOG.info("Sorted {} files into {} directories in {}", dirs.size(), dirs.keySet().size(), sw);
-
- // Step three: submit parent directory creation tasks (via parallelStream()) and wait for them to complete
- sw.reset().start();
- dirs.keySet().parallelStream().forEach(path -> {
- try {
- Files.createDirectories(path.toPath());
- } catch (IOException e) {
- throw new IllegalStateException("Failed to create " + path, e);
- }
- });
- LOG.debug("Parent directories created in {}", sw);
-
- // Step four: submit all code generation tasks (via parallelStream()) and wait for them to complete
- sw.reset().start();
- final List<File> result = dirs.values().parallelStream()
- .map(WriteTask::generateFile)
- .collect(Collectors.toList());
- LOG.debug("Generated {} files in {}", result.size(), sw);
-
- return result;
- }
-
- private File persistentPath(final GeneratedFileType fileType) throws FileGeneratorException {
- final File existing = persistentDirs.get(fileType);
- if (existing != null) {
- return existing;
- }
- final File newDir = persistentDirectory(fileType);
- verify(persistentDirs.put(fileType, newDir) == null);
- return newDir;
- }
-
- private File transientPath(final GeneratedFileType fileType) throws FileGeneratorException {
- final File existing = transientDirs.get(fileType);
- if (existing != null) {
- return existing;
- }
-
- final File newDir = transientDirectory(fileType);
- verify(transientDirs.put(fileType, newDir) == null);
- return newDir;
- }
-
- private File persistentDirectory(final GeneratedFileType fileType) throws FileGeneratorException {
- final File ret;
- if (GeneratedFileType.SOURCE.equals(fileType)) {
- ret = new File(project.getBuild().getSourceDirectory());
- } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
- ret = new File(new File(project.getBuild().getSourceDirectory()).getParentFile(), "resources");
- } else {
- throw new FileGeneratorException("Unknown generated file type " + fileType);
- }
- return ret;
- }
-
- private File transientDirectory(final GeneratedFileType fileType) throws FileGeneratorException {
- final File ret;
- if (GeneratedFileType.SOURCE.equals(fileType)) {
- ret = transientDirectory("generated-sources");
- project.addCompileSourceRoot(ret.toString());
- } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
- ret = transientDirectory("generated-resources");
- project.addResource(createResouce(ret));
- } else {
- throw new FileGeneratorException("Unknown generated file type " + fileType);
- }
- return ret;
- }
-
- private File transientDirectory(final String component) {
- return new File(buildDir, subdirFileName(component));
- }
-
- private String subdirFileName(final String component) {
- return component + File.separatorChar + suffix;
- }
-
- private static Resource createResouce(final File directory) {
- final Resource ret = new Resource();
- ret.setDirectory(directory.toString());
- return ret;
- }
-
- private static final class WriteTask {
- private final BuildContext buildContext;
- private final GeneratedFile file;
- private final File target;
-
- WriteTask(final BuildContext buildContext, final File target, final GeneratedFile file) {
- this.buildContext = requireNonNull(buildContext);
- this.target = requireNonNull(target);
- this.file = requireNonNull(file);
- }
-
- File generateFile() {
- try (OutputStream stream = buildContext.newFileOutputStream(target)) {
- file.writeBody(stream);
- } catch (IOException e) {
- throw new IllegalStateException("Failed to generate file " + target, e);
- }
- return target;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.MoreObjects.ToStringHelper;
-import org.apache.maven.project.MavenProject;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
-import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
-import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
-
-/**
- * Bridge to a {@link FileGenerator} instance.
- *
- * @author Robert Varga
- */
-final class FileGeneratorTaskFactory extends GeneratorTaskFactory implements Identifiable<String> {
- private final FileGeneratorArg arg;
- private final FileGenerator gen;
-
- private FileGeneratorTaskFactory(final FileGenerator gen, final FileGeneratorArg arg) {
- super(gen.importResolutionMode());
- this.arg = arg;
- this.gen = gen;
- }
-
- static FileGeneratorTaskFactory of(final FileGeneratorFactory factory, final FileGeneratorArg arg)
- throws FileGeneratorException {
- return new FileGeneratorTaskFactory(factory.newFileGenerator(arg.getConfiguration()), arg);
- }
-
- @Override
- public String getIdentifier() {
- return arg.getIdentifier();
- }
-
- @Override
- FileGeneratorTask createTask(final MavenProject project, final ContextHolder context) {
- return new FileGeneratorTask(this, context, project);
- }
-
- @Override
- FileGenerator generator() {
- return gen;
- }
-
- @Override
- ToStringHelper addToStringProperties(final ToStringHelper helper) {
- return super.addToStringProperties(helper).add("argument", arg);
- }
-}
*/
package org.opendaylight.yangtools.yang2sources.plugin;
+import static com.google.common.base.Verify.verify;
import static java.util.Objects.requireNonNull;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.MultimapBuilder;
+import com.google.common.collect.Table;
+import com.google.common.collect.Table.Cell;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNullByDefault;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.maven.model.Resource;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonatype.plexus.build.incremental.BuildContext;
-@NonNullByDefault
-abstract class GeneratorTask<T extends GeneratorTaskFactory> extends ParserConfigAware {
- private final ContextHolder context;
- private final T factory;
+final class GeneratorTask extends ParserConfigAware {
+ private static final Logger LOG = LoggerFactory.getLogger(GeneratorTask.class);
- GeneratorTask(final T factory, final ContextHolder context) {
+ private final Map<GeneratedFileType, File> persistentDirs = new HashMap<>(4);
+ private final Map<GeneratedFileType, File> transientDirs = new HashMap<>(4);
+ private final GeneratorTaskFactory factory;
+ private final ContextHolder contextHolder;
+ private final MavenProject project;
+ private final File buildDir;
+ private final String suffix;
+
+ GeneratorTask(final @NonNull GeneratorTaskFactory factory, final @NonNull ContextHolder contextHolder,
+ final MavenProject project) {
this.factory = requireNonNull(factory);
- this.context = requireNonNull(context);
+ this.contextHolder = requireNonNull(contextHolder);
+ this.project = requireNonNull(project);
+
+ buildDir = new File(project.getBuild().getDirectory());
+ suffix = factory.getIdentifier();
}
@Override
- final YangParserConfiguration parserConfig() {
+ YangParserConfiguration parserConfig() {
return factory.parserConfig();
}
- final Collection<File> execute(final BuildContext buildContext) throws FileGeneratorException, IOException {
- return execute(factory, context, buildContext);
+ Collection<File> execute(final BuildContext buildContext) throws FileGeneratorException, IOException {
+ // Step one: determine what files are going to be generated
+ final Stopwatch sw = Stopwatch.createStarted();
+ final FileGenerator gen = factory.generator();
+ final Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generatedFiles = gen.generateFiles(
+ contextHolder.getContext(), contextHolder.getYangModules(), contextHolder);
+ LOG.info("{}: Defined {} files in {}", suffix, generatedFiles.size(), sw);
+
+ // Step two: create generation tasks for each target file and group them by parent directory
+ sw.reset().start();
+ final ListMultimap<File, WriteTask> dirs = MultimapBuilder.hashKeys().arrayListValues().build();
+ for (Cell<GeneratedFileType, GeneratedFilePath, GeneratedFile> cell : generatedFiles.cellSet()) {
+ final GeneratedFile file = cell.getValue();
+ final String relativePath = cell.getColumnKey().getPath();
+ final File target;
+ switch (file.getLifecycle()) {
+ case PERSISTENT:
+ target = new File(persistentPath(cell.getRowKey()), relativePath);
+ if (target.exists()) {
+ LOG.debug("Skipping existing persistent {}", target);
+ continue;
+ }
+ break;
+ case TRANSIENT:
+ target = new File(transientPath(cell.getRowKey()), relativePath);
+ break;
+ default:
+ throw new IllegalStateException("Unsupported file type in " + file);
+ }
+
+ dirs.put(target.getParentFile(), new WriteTask(buildContext, target, cell.getValue()));
+ }
+ LOG.info("Sorted {} files into {} directories in {}", dirs.size(), dirs.keySet().size(), sw);
+
+ // Step three: submit parent directory creation tasks (via parallelStream()) and wait for them to complete
+ sw.reset().start();
+ dirs.keySet().parallelStream().forEach(path -> {
+ try {
+ Files.createDirectories(path.toPath());
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to create " + path, e);
+ }
+ });
+ LOG.debug("Parent directories created in {}", sw);
+
+ // Step four: submit all code generation tasks (via parallelStream()) and wait for them to complete
+ sw.reset().start();
+ final List<File> result = dirs.values().parallelStream()
+ .map(WriteTask::generateFile)
+ .collect(Collectors.toList());
+ LOG.debug("Generated {} files in {}", result.size(), sw);
+
+ return result;
}
- abstract Collection<File> execute(T factory, ContextHolder modelContext, BuildContext buildContext)
- throws FileGeneratorException, IOException;
+ private File persistentPath(final GeneratedFileType fileType) throws FileGeneratorException {
+ final File existing = persistentDirs.get(fileType);
+ if (existing != null) {
+ return existing;
+ }
+ final File newDir = persistentDirectory(fileType);
+ verify(persistentDirs.put(fileType, newDir) == null);
+ return newDir;
+ }
+
+ private File transientPath(final GeneratedFileType fileType) throws FileGeneratorException {
+ final File existing = transientDirs.get(fileType);
+ if (existing != null) {
+ return existing;
+ }
+
+ final File newDir = transientDirectory(fileType);
+ verify(transientDirs.put(fileType, newDir) == null);
+ return newDir;
+ }
+
+ private File persistentDirectory(final GeneratedFileType fileType) throws FileGeneratorException {
+ final File ret;
+ if (GeneratedFileType.SOURCE.equals(fileType)) {
+ ret = new File(project.getBuild().getSourceDirectory());
+ } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
+ ret = new File(new File(project.getBuild().getSourceDirectory()).getParentFile(), "resources");
+ } else {
+ throw new FileGeneratorException("Unknown generated file type " + fileType);
+ }
+ return ret;
+ }
+
+ private File transientDirectory(final GeneratedFileType fileType) throws FileGeneratorException {
+ final File ret;
+ if (GeneratedFileType.SOURCE.equals(fileType)) {
+ ret = transientDirectory("generated-sources");
+ project.addCompileSourceRoot(ret.toString());
+ } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
+ ret = transientDirectory("generated-resources");
+ project.addResource(createResouce(ret));
+ } else {
+ throw new FileGeneratorException("Unknown generated file type " + fileType);
+ }
+ return ret;
+ }
+
+ private File transientDirectory(final String component) {
+ return new File(buildDir, subdirFileName(component));
+ }
+
+ private String subdirFileName(final String component) {
+ return component + File.separatorChar + suffix;
+ }
+
+ private static Resource createResouce(final File directory) {
+ final Resource ret = new Resource();
+ ret.setDirectory(directory.toString());
+ return ret;
+ }
+
+ private static final class WriteTask {
+ private final BuildContext buildContext;
+ private final GeneratedFile file;
+ private final File target;
+
+ WriteTask(final BuildContext buildContext, final File target, final GeneratedFile file) {
+ this.buildContext = requireNonNull(buildContext);
+ this.target = requireNonNull(target);
+ this.file = requireNonNull(file);
+ }
+
+ File generateFile() {
+ try (OutputStream stream = buildContext.newFileOutputStream(target)) {
+ file.writeBody(stream);
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to generate file " + target, e);
+ }
+ return target;
+ }
+ }
}
*/
package org.opendaylight.yangtools.yang2sources.plugin;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
import org.apache.maven.project.MavenProject;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.yangtools.plugin.generator.api.FileGenerator.ImportResolutionMode;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
@NonNullByDefault
-abstract class GeneratorTaskFactory extends ParserConfigAware {
+final class GeneratorTaskFactory extends ParserConfigAware implements Identifiable<String> {
private final YangParserConfiguration parserConfig;
+ private final FileGeneratorArg arg;
+ private final FileGenerator gen;
- GeneratorTaskFactory(final ImportResolutionMode importMode) {
- parserConfig = switch (importMode) {
+ private GeneratorTaskFactory(final FileGenerator gen, final FileGeneratorArg arg) {
+ this.gen = requireNonNull(gen);
+ this.arg = requireNonNull(arg);
+ parserConfig = switch (gen.importResolutionMode()) {
case REVISION_EXACT_OR_LATEST -> YangParserConfiguration.DEFAULT;
};
}
+ static GeneratorTaskFactory of(final FileGeneratorFactory factory, final FileGeneratorArg arg)
+ throws FileGeneratorException {
+ return new GeneratorTaskFactory(factory.newFileGenerator(arg.getConfiguration()), arg);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return arg.getIdentifier();
+ }
+
@Override
- final YangParserConfiguration parserConfig() {
+ YangParserConfiguration parserConfig() {
return parserConfig;
}
- final String generatorName() {
- return generator().getClass().getName();
+ FileGenerator generator() {
+ return gen;
+ }
+
+ String generatorName() {
+ return gen.getClass().getName();
}
/**
* @param project current Maven Project
* @param context model generation context
*/
- abstract GeneratorTask<?> createTask(MavenProject project, ContextHolder context);
-
- abstract Object generator();
-
- ToStringHelper addToStringProperties(final ToStringHelper helper) {
- return helper.add("generator", generatorName());
+ GeneratorTask createTask(final MavenProject project, final ContextHolder context) {
+ return new GeneratorTask(this, context, project);
}
@Override
- public final String toString() {
- return addToStringProperties(MoreObjects.toStringHelper(this).omitNullValues()).toString();
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("generator", generatorName()).add("argument", arg).toString();
}
}
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
import org.opendaylight.yangtools.yang.common.YangConstants;
private final File yangFilesRootDir;
private final Set<File> excludedFiles;
private final Map<String, FileGeneratorArg> fileGeneratorArgs;
- private final MavenProject project;
+ private final @NonNull MavenProject project;
private final boolean inspectDependencies;
private final BuildContext buildContext;
private final YangProvider yangProvider;
}
try {
- generators.add(FileGeneratorTaskFactory.of(entry.getValue(), arg));
+ generators.add(GeneratorTaskFactory.of(entry.getValue(), arg));
} catch (FileGeneratorException e) {
throw new MojoExecutionException("File generator " + id + " failed", e);
}
}
final Stopwatch sw = Stopwatch.createStarted();
- final GeneratorTask<?> task = factory.createTask(project, context);
+ final GeneratorTask task = factory.createTask(project, context);
LOG.debug("{} Task {} initialized in {}", LOG_PREFIX, task, sw);
final Collection<File> files;