Use FileGenerator for java-api-generator 80/77680/17
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 11 Nov 2018 20:19:16 +0000 (21:19 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 22 Jun 2021 12:37:35 +0000 (14:37 +0200)
Do not use deprecated BasicCodeGenerator interface to interact with
yang-maven-plugin. Using FileGenerator allows us to decouple lifecycle
and eliminate a bit of duplication.

JIRA: MDSAL-232
Change-Id: I04931ff6f70f548de5a49042201283c7e503f92e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
34 files changed:
binding/binding-parent/pom.xml
binding/maven-sal-api-gen-plugin/pom.xml
binding/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/mdsal/binding/maven/api/gen/plugin/CodeGeneratorImpl.java [deleted file]
binding/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/mdsal/binding/yang/unified/doc/generator/GeneratorImpl.xtend
binding/mdsal-binding-java-api-generator/pom.xml
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/CodeGeneratorGeneratedFile.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/GeneratorJavaFile.java [deleted file]
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGenerator.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGeneratorFactory.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/SupplierGeneratedFile.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/AugmentToUsesInAugmentCompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java with 98% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/BaseCompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/BaseCompilationTest.java with 78% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/Bug1276Test.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/Bug1276Test.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/Bug5151Test.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/Bug5151Test.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/Bug532Test.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/Bug532Test.java with 96% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/CascadeUsesCompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/CascadeUsesCompilationTest.java with 93% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/ClassCodeGeneratorTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/ClassCodeGeneratorTest.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/CompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/CompilationTest.java with 99% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/CompilationTestUtils.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/CompilationTestUtils.java with 99% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/EncodingInJavaDocTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/EncodingInJavaDocTest.java with 89% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/FileSearchUtil.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/FileSearchUtil.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/GeneratorJavaFileTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/GeneratorJavaFileTest.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/NestedGroupingCompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/NestedGroupingCompilationTest.java with 89% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/SpecializingLeafrefTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/SpecializingLeafrefTest.java with 98% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/TypedefCompilationTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/TypedefCompilationTest.java with 99% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionTypedefUnusedImportTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/UnionTypedefUnusedImportTest.java with 92% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionWithIdentityrefTest.java [moved from binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/UnionWithIdentityrefTest.java with 97% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/YangModuleInfoCompilationTest.java [moved from binding/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/mdsal/binding/yang/unified/doc/generator/maven/YangModuleInfoCompilationTest.java with 84% similarity]
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/package-info.java [deleted file]
binding/mdsal-binding-java-api-generator/src/test/resources/yang-module-info/import-module.yang [moved from binding/maven-sal-api-gen-plugin/src/test/resources/yang-module-info/import-module.yang with 100% similarity]
binding/mdsal-binding-java-api-generator/src/test/resources/yang-module-info/main-module.yang [moved from binding/maven-sal-api-gen-plugin/src/test/resources/yang-module-info/main-module.yang with 100% similarity]
binding/mdsal-binding-java-api-generator/src/test/resources/yang-module-info/submodule1.yang [moved from binding/maven-sal-api-gen-plugin/src/test/resources/yang-module-info/submodule1.yang with 100% similarity]
binding/mdsal-binding-java-api-generator/src/test/resources/yang-module-info/submodule2.yang [moved from binding/maven-sal-api-gen-plugin/src/test/resources/yang-module-info/submodule2.yang with 100% similarity]
binding/mdsal-binding-java-api-generator/src/test/resources/yang-module-info/submodule3.yang [moved from binding/maven-sal-api-gen-plugin/src/test/resources/yang-module-info/submodule3.yang with 100% similarity]

index 72bc6319c4c473653fcabb58f0f9ed37f52ad647..3591fff7aa235d2a5fdd22ce0e620f5213e301c4 100644 (file)
                             <artifactId>yang-maven-plugin</artifactId>
                             <version>7.0.3</version>
                             <dependencies>
+                                <dependency>
+                                    <groupId>org.opendaylight.mdsal</groupId>
+                                    <artifactId>mdsal-binding-generator-impl</artifactId>
+                                    <version>8.0.0-SNAPSHOT</version>
+                                </dependency>
+                                <dependency>
+                                    <groupId>org.opendaylight.mdsal</groupId>
+                                    <artifactId>mdsal-binding-java-api-generator</artifactId>
+                                    <version>8.0.0-SNAPSHOT</version>
+                                </dependency>
                                 <dependency>
                                     <groupId>org.opendaylight.mdsal</groupId>
                                     <artifactId>maven-sal-api-gen-plugin</artifactId>
                                     <version>8.0.0-SNAPSHOT</version>
-                                    <type>jar</type>
                                 </dependency>
                             </dependencies>
                             <executions>
                                         <goal>generate-sources</goal>
                                     </goals>
                                     <configuration>
-                                        <codeGenerators>
-                                            <generator>
-                                                <codeGeneratorClass>org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                                                <resourceBaseDir>${project.build.directory}/generated-sources/spi</resourceBaseDir>
-                                            </generator>
-                                        </codeGenerators>
                                         <inspectDependencies>true</inspectDependencies>
                                     </configuration>
                                 </execution>
index bd2ce79b0dd36bd155cc978267d325070ef2f875..dc8a890c6a270919eb482eac296cc9fe7c1af605 100644 (file)
             <artifactId>yang-maven-plugin-spi</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-binding-generator-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-binding-generator-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-binding-java-api-generator</artifactId>
+            <groupId>org.eclipse.xtext</groupId>
+            <artifactId>org.eclipse.xtext.xbase.lib</artifactId>
         </dependency>
 
         <dependency>
             <artifactId>plexus-build-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.kohsuke.metainf-services</groupId>
+            <artifactId>metainf-services</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-test-util</artifactId>
diff --git a/binding/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/mdsal/binding/maven/api/gen/plugin/CodeGeneratorImpl.java b/binding/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/mdsal/binding/maven/api/gen/plugin/CodeGeneratorImpl.java
deleted file mode 100644 (file)
index d3459d1..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2013 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.mdsal.binding.maven.api.gen.plugin;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-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.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-import org.apache.maven.project.MavenProject;
-import org.opendaylight.mdsal.binding.generator.api.BindingGenerator;
-import org.opendaylight.mdsal.binding.java.api.generator.GeneratorJavaFile;
-import org.opendaylight.mdsal.binding.java.api.generator.GeneratorJavaFile.FileKind;
-import org.opendaylight.mdsal.binding.java.api.generator.YangModuleInfoTemplate;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
-import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
-import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
-import org.opendaylight.yangtools.yang2sources.spi.ModuleResourceResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonatype.plexus.build.incremental.BuildContext;
-
-public final class CodeGeneratorImpl implements BasicCodeGenerator, BuildContextAware, MavenProjectAware {
-    public static final String CONFIG_PERSISTENT_SOURCES_DIR = "persistentSourcesDir";
-    public static final String CONFIG_IGNORE_DUPLICATE_FILES = "ignoreDuplicateFiles";
-
-    private static final Logger LOG = LoggerFactory.getLogger(CodeGeneratorImpl.class);
-    private static final String FS = File.separator;
-
-    private BuildContext buildContext;
-    private File projectBaseDir;
-    private Map<String, String> additionalConfig;
-    private MavenProject mavenProject;
-    private File resourceBaseDir;
-
-    @Override
-    public Collection<File> generateSources(final EffectiveModelContext context, final File outputDir,
-            final Set<Module> yangModules, final ModuleResourceResolver moduleResourcePathResolver) throws IOException {
-        final File outputBaseDir;
-
-        outputBaseDir = outputDir == null ? getDefaultOutputBaseDir() : outputDir;
-
-        // Step one: determine binding types which we are generating
-        final Stopwatch sw = Stopwatch.createStarted();
-        final List<GeneratedType> types = ServiceLoader.load(BindingGenerator.class)
-                .findFirst().orElseThrow(() -> new IllegalStateException("No BindingGenerator implementation found"))
-                .generateTypes(context, yangModules);
-        LOG.info("Found {} Binding types in {}", types.size(), sw);
-
-        final GeneratorJavaFile generator = new GeneratorJavaFile(types);
-
-        File persistentSourcesDir = null;
-        boolean ignoreDuplicateFiles = true;
-        if (additionalConfig != null) {
-            String persistenSourcesPath = additionalConfig.get(CONFIG_PERSISTENT_SOURCES_DIR);
-            if (persistenSourcesPath != null) {
-                persistentSourcesDir = new File(persistenSourcesPath);
-            }
-            String ignoreDuplicateFilesString = additionalConfig.get(CONFIG_IGNORE_DUPLICATE_FILES);
-            if (ignoreDuplicateFilesString != null) {
-                ignoreDuplicateFiles = Boolean.parseBoolean(ignoreDuplicateFilesString);
-            }
-        }
-        if (persistentSourcesDir == null) {
-            persistentSourcesDir = new File(projectBaseDir, "src" + FS + "main" + FS + "java");
-        }
-
-        final Table<FileKind, String, Supplier<String>> generatedFiles = generator.generateFileContent(
-            ignoreDuplicateFiles);
-
-        // Step two: create generation tasks for each target file and group them by parent directory
-        final ListMultimap<Path, GenerationTask> dirs = MultimapBuilder.hashKeys().arrayListValues().build();
-        for (Cell<FileKind, String, Supplier<String>> cell : generatedFiles.cellSet()) {
-            final File target;
-            switch (cell.getRowKey()) {
-                case PERSISTENT:
-                    target = new File(persistentSourcesDir, cell.getColumnKey());
-                    if (target.exists()) {
-                        LOG.debug("Skipping existing persistent {}", target);
-                        continue;
-                    }
-                    break;
-                case TRANSIENT:
-                    target = new File(outputBaseDir, cell.getColumnKey());
-                    break;
-                default:
-                    throw new IllegalStateException("Unsupported file type in " + cell);
-            }
-
-            dirs.put(target.getParentFile().toPath(), new GenerationTask(buildContext, target, cell.getValue()));
-        }
-        LOG.info("Generating {} Binding source files into {} directories", dirs.size(), dirs.keySet().size());
-
-        // 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);
-            } 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(GenerationTask::generateFile)
-                .collect(Collectors.toList());
-        LOG.debug("{} Binding source type files generated in {}", result.size(), sw);
-
-        // Step five: generate auxiliary files
-        result.addAll(generateModuleInfos(outputBaseDir, yangModules, context, moduleResourcePathResolver));
-        return result;
-    }
-
-    private Collection<? extends File> generateModuleInfos(final File outputBaseDir, final Set<Module> yangModules,
-            final EffectiveModelContext context, final ModuleResourceResolver moduleResourcePathResolver)
-                throws IOException {
-        Builder<File> result = ImmutableSet.builder();
-        Builder<String> bindingProviders = ImmutableSet.builder();
-        for (Module module : yangModules) {
-            Builder<String> currentProvidersBuilder = ImmutableSet.builder();
-            // TODO: do not mutate parameters, output of a method is defined by its return value
-            Set<File> moduleInfoProviders = generateYangModuleInfo(outputBaseDir, module, context,
-                moduleResourcePathResolver, currentProvidersBuilder);
-            ImmutableSet<String> currentProviders = currentProvidersBuilder.build();
-            LOG.debug("Adding ModuleInfo providers {}", currentProviders);
-            bindingProviders.addAll(currentProviders);
-            result.addAll(moduleInfoProviders);
-        }
-
-        result.add(writeMetaInfServices(resourceBaseDir, YangModelBindingProvider.class, bindingProviders.build()));
-        return result.build();
-    }
-
-    private File writeMetaInfServices(final File outputBaseDir, final Class<YangModelBindingProvider> serviceClass,
-            final ImmutableSet<String> services) throws IOException {
-        File metainfServicesFolder = new File(outputBaseDir, "META-INF" + File.separator + "services");
-        Files.createDirectories(metainfServicesFolder.toPath());
-        File serviceFile = new File(metainfServicesFolder, serviceClass.getName());
-
-        String src = Joiner.on('\n').join(services);
-
-        return writeFile(serviceFile, src);
-    }
-
-    public static final String DEFAULT_OUTPUT_BASE_DIR_PATH = "target" + File.separator + "generated-sources"
-            + File.separator + "maven-sal-api-gen";
-
-    private File getDefaultOutputBaseDir() {
-        File outputBaseDir;
-        outputBaseDir = new File(DEFAULT_OUTPUT_BASE_DIR_PATH);
-        setOutputBaseDirAsSourceFolder(outputBaseDir, mavenProject);
-        LOG.debug("Adding {} as compile source root", outputBaseDir.getPath());
-        return outputBaseDir;
-    }
-
-    private static void setOutputBaseDirAsSourceFolder(final File outputBaseDir, final MavenProject mavenProject) {
-        requireNonNull(mavenProject, "Maven project needs to be set in this phase");
-        mavenProject.addCompileSourceRoot(outputBaseDir.getPath());
-    }
-
-    @Override
-    public void setAdditionalConfig(final Map<String, String> additionalConfiguration) {
-        this.additionalConfig = additionalConfiguration;
-    }
-
-    @Override
-    public void setResourceBaseDir(final File resourceBaseDir) {
-        this.resourceBaseDir = resourceBaseDir;
-    }
-
-    @Override
-    public void setMavenProject(final MavenProject project) {
-        this.mavenProject = project;
-        this.projectBaseDir = project.getBasedir();
-    }
-
-    @Override
-    public void setBuildContext(final BuildContext buildContext) {
-        this.buildContext = requireNonNull(buildContext);
-    }
-
-    private Set<File> generateYangModuleInfo(final File outputBaseDir, final Module module,
-            final EffectiveModelContext ctx, final ModuleResourceResolver moduleResourcePathResolver,
-            final Builder<String> providerSourceSet) throws IOException {
-        Builder<File> generatedFiles = ImmutableSet.builder();
-
-        final YangModuleInfoTemplate template = new YangModuleInfoTemplate(module, ctx,
-            mod -> moduleResourcePathResolver.findModuleResourcePath(mod, YangTextSchemaSource.class));
-        String moduleInfoSource = template.generate();
-        if (moduleInfoSource.isEmpty()) {
-            throw new IllegalStateException("Generated code should not be empty!");
-        }
-        String providerSource = template.generateModelProvider();
-
-        final File packageDir = GeneratorJavaFile.packageToDirectory(outputBaseDir,
-            BindingMapping.getRootPackageName(module.getQNameModule()));
-
-        generatedFiles.add(writeJavaSource(packageDir, BindingMapping.MODULE_INFO_CLASS_NAME, moduleInfoSource));
-        generatedFiles.add(writeJavaSource(packageDir, BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME,
-            providerSource));
-        providerSourceSet.add(template.getModelBindingProviderName());
-
-        return generatedFiles.build();
-
-    }
-
-    private File writeJavaSource(final File packageDir, final String className, final String source)
-            throws IOException {
-        Files.createDirectories(packageDir.toPath());
-        final File file = new File(packageDir, className + ".java");
-        writeFile(file, source);
-        return file;
-    }
-
-    @SuppressWarnings("checkstyle:illegalCatch")
-    private File writeFile(final File file, final String source) {
-        try (OutputStream stream = buildContext.newFileOutputStream(file)) {
-            try (Writer fw = new OutputStreamWriter(stream, StandardCharsets.UTF_8)) {
-                try (BufferedWriter bw = new BufferedWriter(fw)) {
-                    bw.write(source);
-                }
-            } catch (RuntimeException e) {
-                LOG.error("Could not write file: {}", file, e);
-            }
-        } catch (IOException e) {
-            LOG.error("Could not create file: {}", file, e);
-        }
-        return file;
-    }
-
-    private static final class GenerationTask {
-        private final BuildContext buildContext;
-        private final Supplier<String> contentSupplier;
-        private final File target;
-
-        GenerationTask(final BuildContext buildContext, final File target, final Supplier<String> contentSupplier) {
-            this.buildContext = requireNonNull(buildContext);
-            this.target = requireNonNull(target);
-            this.contentSupplier = requireNonNull(contentSupplier);
-        }
-
-        File generateFile() {
-            try {
-                try (OutputStream stream = buildContext.newFileOutputStream(target)) {
-                    try (Writer fw = new OutputStreamWriter(stream, StandardCharsets.UTF_8)) {
-                        try (BufferedWriter bw = new BufferedWriter(fw)) {
-                            bw.write(contentSupplier.get());
-                        }
-                    }
-                }
-            } catch (IOException e) {
-                throw new IllegalStateException("Failed to generate file " + target, e);
-            }
-            return target;
-        }
-    }
-}
index 139421732563294846a1e6e5aabd3a3ecd10ced9..df0652ac7520f31f77e0eaa07b18bc9e2a61d8ee 100644 (file)
@@ -65,7 +65,7 @@ class GeneratorImpl {
 
     static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl)
 
-    val Map<String, String> imports = new HashMap()
+    val Map<String, String> imports = new HashMap
     val Map<TypeDefinition<?>, SchemaPath> types = new IdentityHashMap
     var Module currentModule
     var EffectiveModelContext ctx
index bfb2719c7fe43aa9b3b2c789b6e8232e9a2e6e4a..cb14ff975aa93733f63ecb678c84f4afb72544ff 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-model-export</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>plugin-generator-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-text</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.kohsuke.metainf-services</groupId>
+            <artifactId>metainf-services</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/CodeGeneratorGeneratedFile.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/CodeGeneratorGeneratedFile.java
new file mode 100644 (file)
index 0000000..f362d3f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.mdsal.binding.java.api.generator;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import java.io.IOException;
+import java.io.Writer;
+import org.opendaylight.mdsal.binding.model.api.CodeGenerator;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.yangtools.plugin.generator.api.AbstractGeneratedTextFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileLifecycle;
+
+final class CodeGeneratorGeneratedFile extends AbstractGeneratedTextFile {
+    private final CodeGenerator generator;
+    private final Type type;
+
+    CodeGeneratorGeneratedFile(final GeneratedFileLifecycle lifecycle, final CodeGenerator generator, final Type type) {
+        super(lifecycle);
+        this.generator = requireNonNull(generator);
+        this.type = requireNonNull(type);
+    }
+
+    @Override
+    protected void writeBody(final Writer output) throws IOException {
+        output.write(generator.generate(type));
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+        return super.addToStringAttributes(helper).add("generator", generator).add("type", type);
+    }
+}
diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/GeneratorJavaFile.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/GeneratorJavaFile.java
deleted file mode 100644 (file)
index c7b1c37..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2013 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.mdsal.binding.java.api.generator;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.Table;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Supplier;
-import org.opendaylight.mdsal.binding.model.api.CodeGenerator;
-import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
-import org.opendaylight.mdsal.binding.model.api.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Generates files with JAVA source codes for every specified type.
- */
-public final class GeneratorJavaFile {
-    public enum FileKind {
-        /**
-         * Transient file. It should be generated in target/generated-sources/ directory or similar.
-         */
-        TRANSIENT,
-        /**
-         * Persistent file. It should be generated in src/main/java/ directory or similar.
-         */
-        PERSISTENT,
-    }
-
-    private static final class GeneratorStringSupplier implements Supplier<String> {
-        private final CodeGenerator generator;
-        private final Type type;
-
-        GeneratorStringSupplier(final CodeGenerator generator, final Type type) {
-            this.generator = requireNonNull(generator);
-            this.type = requireNonNull(type);
-        }
-
-        @Override
-        public String get() {
-            return generator.generate(type);
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(this).add("generator", generator).add("type", type).toString();
-        }
-    }
-
-    private static final Logger LOG = LoggerFactory.getLogger(GeneratorJavaFile.class);
-
-    /**
-     * List of <code>CodeGenerator</code> instances.
-     */
-    private final List<CodeGenerator> generators = new ArrayList<>();
-
-    /**
-     * Set of <code>Type</code> instances for which the JAVA code is generated.
-     */
-    private final Collection<? extends Type> types;
-
-    /**
-     * Creates instance of this class with the set of <code>types</code> for which the JAVA code is generated. Generator
-     * instantiated this way uses the default build context, e.g. it will re-generate any and all files. The instances
-     * of concrete JAVA code generator are created.
-     *
-     * @param types set of types for which JAVA code should be generated
-     */
-    public GeneratorJavaFile(final Collection<? extends Type> types) {
-        this.types = requireNonNull(types);
-        generators.add(new InterfaceGenerator());
-        generators.add(new TOGenerator());
-        generators.add(new EnumGenerator());
-        generators.add(new BuilderGenerator());
-    }
-
-    public Table<FileKind, String, Supplier<String>> generateFileContent(final boolean ignoreDuplicates) {
-        final Table<FileKind, String, Supplier<String>> result = HashBasedTable.create();
-        for (Type type : types) {
-            for (CodeGenerator generator : generators) {
-                if (!generator.isAcceptable(type)) {
-                    continue;
-                }
-
-                final FileKind kind = type instanceof GeneratedTransferObject
-                        && ((GeneratedTransferObject) type).isUnionTypeBuilder()
-                        ? FileKind.PERSISTENT : FileKind.TRANSIENT;
-                final String file = type.getPackageName().replace('.', File.separatorChar)
-                        +  File.separator + generator.getUnitName(type) + ".java";
-
-                if (result.contains(kind, file)) {
-                    if (ignoreDuplicates) {
-                        LOG.warn("Naming conflict for type '{}': file with same name already exists and will not be "
-                                + "generated.", type.getFullyQualifiedName());
-                        continue;
-                    }
-                    throw new IllegalStateException("Duplicate " + kind + " file '" + file + "' for "
-                            + type.getFullyQualifiedName());
-                }
-
-                result.put(kind, file, new GeneratorStringSupplier(generator, type));
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Creates the package directory path as concatenation of <code>parentDirectory</code> and parsed
-     * <code>packageName</code>. The parsing of <code>packageName</code> is realized as replacement of the package name
-     * dots with the file system separator.
-     *
-     * @param parentDirectory <code>File</code> object with reference to parent directory
-     * @param packageName string with the name of the package
-     * @return <code>File</code> object which refers to the new directory for package <code>packageName</code>
-     */
-    public static File packageToDirectory(final File parentDirectory, final String packageName) {
-        if (packageName == null) {
-            throw new IllegalArgumentException("Package Name cannot be NULL!");
-        }
-
-        return new File(parentDirectory, packageName.replace('.', File.separatorChar));
-    }
-}
diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGenerator.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGenerator.java
new file mode 100644 (file)
index 0000000..963d875
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2020 PATHEON.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.mdsal.binding.java.api.generator;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.CharMatcher;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import org.opendaylight.mdsal.binding.generator.api.BindingGenerator;
+import org.opendaylight.mdsal.binding.model.api.CodeGenerator;
+import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
+import org.opendaylight.mdsal.binding.model.api.GeneratedType;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
+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.GeneratedFileLifecycle;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
+import org.opendaylight.yangtools.plugin.generator.api.ModuleResourceResolver;
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class JavaFileGenerator implements FileGenerator {
+    public static final String CONFIG_IGNORE_DUPLICATE_FILES = "ignoreDuplicateFiles";
+
+    private static final Logger LOG = LoggerFactory.getLogger(JavaFileGenerator.class);
+    private static final CharMatcher DOT_MATCHER = CharMatcher.is('.');
+    private static final String MODULE_INFO = BindingMapping.MODULE_INFO_CLASS_NAME + ".java";
+    private static final String MODEL_BINDING_PROVIDER = BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME + ".java";
+    private static final GeneratedFilePath MODEL_BINDING_PROVIDER_SERVICE =
+        GeneratedFilePath.ofPath("META-INF/services/" + YangModelBindingProvider.class.getName());
+    private static final List<CodeGenerator> GENERATORS = List.of(
+        new InterfaceGenerator(), new TOGenerator(), new EnumGenerator(), new BuilderGenerator());
+
+    private final BindingGenerator bindingGenerator;
+    private final boolean ignoreDuplicateFiles;
+
+    JavaFileGenerator(final Map<String, String> additionalConfig) {
+        final String ignoreDuplicateFilesString = additionalConfig.get(CONFIG_IGNORE_DUPLICATE_FILES);
+        if (ignoreDuplicateFilesString != null) {
+            ignoreDuplicateFiles = Boolean.parseBoolean(ignoreDuplicateFilesString);
+        } else {
+            ignoreDuplicateFiles = true;
+        }
+        bindingGenerator = ServiceLoader.load(BindingGenerator.class).findFirst()
+            .orElseThrow(() -> new IllegalStateException("No BindingGenerator implementation found"));
+    }
+
+    @Override
+    public Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generateFiles(final EffectiveModelContext context,
+            final Set<Module> localModules, final ModuleResourceResolver moduleResourcePathResolver)
+                throws FileGeneratorException {
+        final Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> result =
+            generateFiles(bindingGenerator.generateTypes(context, localModules), ignoreDuplicateFiles);
+
+        // YangModuleInfo files
+        final Builder<String> bindingProviders = ImmutableSet.builder();
+        for (Module module : localModules) {
+            final YangModuleInfoTemplate template = new YangModuleInfoTemplate(module, context,
+                mod -> moduleResourcePathResolver.findModuleResourcePath(mod, YangTextSchemaSource.class));
+            final String path = DOT_MATCHER.replaceFrom(template.getPackageName(), '/') + "/";
+
+            result.put(GeneratedFileType.SOURCE, GeneratedFilePath.ofPath(path + MODULE_INFO),
+                new SupplierGeneratedFile(GeneratedFileLifecycle.TRANSIENT, template::generate));
+            result.put(GeneratedFileType.SOURCE, GeneratedFilePath.ofPath(path + MODEL_BINDING_PROVIDER),
+                new SupplierGeneratedFile(GeneratedFileLifecycle.TRANSIENT, template::generateModelProvider));
+
+            bindingProviders.add(template.getModelBindingProviderName());
+        }
+
+        // META-INF/services entries, sorted to make the build predictable
+        final List<String> sorted = new ArrayList<>(bindingProviders.build());
+        sorted.sort(String::compareTo);
+
+        result.put(GeneratedFileType.RESOURCE, MODEL_BINDING_PROVIDER_SERVICE,
+            GeneratedFile.of(GeneratedFileLifecycle.TRANSIENT, String.join("\n", sorted)));
+
+        return ImmutableTable.copyOf(result);
+    }
+
+    @VisibleForTesting
+    static Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generateFiles(final List<GeneratedType> types,
+            final boolean ignoreDuplicateFiles) {
+        final Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> result = HashBasedTable.create();
+
+        for (Type type : types) {
+            for (CodeGenerator generator : GENERATORS) {
+                if (!generator.isAcceptable(type)) {
+                    continue;
+                }
+
+                final GeneratedFileLifecycle kind = type instanceof GeneratedTransferObject
+                        && ((GeneratedTransferObject) type).isUnionTypeBuilder()
+                        ? GeneratedFileLifecycle.PERSISTENT : GeneratedFileLifecycle.TRANSIENT;
+                final GeneratedFilePath file =  GeneratedFilePath.ofFilePath(
+                    type.getPackageName().replace('.', File.separatorChar)
+                    + File.separator + generator.getUnitName(type) + ".java");
+
+                if (result.contains(GeneratedFileType.SOURCE, file)) {
+                    if (ignoreDuplicateFiles) {
+                        LOG.warn("Naming conflict for type '{}': file with same name already exists and will not be "
+                                + "generated.", type.getFullyQualifiedName());
+                        continue;
+                    }
+                    throw new IllegalStateException("Duplicate " + kind + " file '" + file.getPath() + "' for "
+                            + type.getFullyQualifiedName());
+                }
+
+                result.put(GeneratedFileType.SOURCE, file, new CodeGeneratorGeneratedFile(kind, generator, type));
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGeneratorFactory.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileGeneratorFactory.java
new file mode 100644 (file)
index 0000000..90f1c5a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.mdsal.binding.java.api.generator;
+
+import java.util.Map;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yangtools.plugin.generator.api.AbstractFileGeneratorFactory;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
+
+@MetaInfServices(value = FileGeneratorFactory.class)
+public final class JavaFileGeneratorFactory extends AbstractFileGeneratorFactory {
+    public JavaFileGeneratorFactory() {
+        super(JavaFileGenerator.class.getName());
+    }
+
+    @Override
+    public JavaFileGenerator newFileGenerator(final Map<String, String> additionalConfiguration) {
+        return new JavaFileGenerator(additionalConfiguration);
+    }
+}
diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/SupplierGeneratedFile.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/SupplierGeneratedFile.java
new file mode 100644 (file)
index 0000000..5a87127
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021 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.mdsal.binding.java.api.generator;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.function.Supplier;
+import org.opendaylight.yangtools.plugin.generator.api.AbstractGeneratedTextFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileLifecycle;
+
+final class SupplierGeneratedFile extends AbstractGeneratedTextFile {
+    private final Supplier<String> supplier;
+
+    SupplierGeneratedFile(final GeneratedFileLifecycle lifecycle, final Supplier<String> supplier) {
+        super(lifecycle);
+        this.supplier = requireNonNull(supplier);
+    }
+
+    @Override
+    protected void writeBody(final Writer output) throws IOException {
+        output.write(supplier.get());
+    }
+}
@@ -5,27 +5,27 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
+import static java.nio.file.Files.newOutputStream;
 import static org.junit.Assert.assertTrue;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Table;
 import com.google.common.collect.Table.Cell;
 import com.google.common.io.Files;
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Optional;
-import java.util.function.Supplier;
 import org.junit.BeforeClass;
 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingGenerator;
-import org.opendaylight.mdsal.binding.java.api.generator.GeneratorJavaFile;
-import org.opendaylight.mdsal.binding.java.api.generator.YangModuleInfoTemplate;
 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
@@ -45,12 +45,14 @@ public abstract class BaseCompilationTest {
             throws IOException {
         types.sort((o1, o2) -> o2.getName().compareTo(o1.getName()));
 
-        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
-        final Table<?, String, Supplier<String>> generatedFiles = generator.generateFileContent(true);
-        for (Cell<?, String, Supplier<String>> cell : generatedFiles.cellSet()) {
-            final File target = new File(sourcesOutputDir, cell.getColumnKey());
+        final Table<?, GeneratedFilePath, GeneratedFile> generatedFiles = JavaFileGenerator.generateFiles(types, true);
+        for (Cell<?, GeneratedFilePath, GeneratedFile> cell : generatedFiles.cellSet()) {
+            final File target = new File(sourcesOutputDir, cell.getColumnKey().getPath());
             Files.createParentDirs(target);
-            Files.asCharSink(target, StandardCharsets.UTF_8).write(cell.getValue().get());
+
+            try (OutputStream os = newOutputStream(target.toPath())) {
+                cell.getValue().writeBody(os);
+            }
         }
     }
 
@@ -66,8 +68,8 @@ public abstract class BaseCompilationTest {
             final YangModuleInfoTemplate template = new YangModuleInfoTemplate(module, context,
                 mod -> Optional.of("fake/" + mod.getName()));
 
-            final File file = new File(GeneratorJavaFile.packageToDirectory(sourcesOutputDir,
-                BindingMapping.getRootPackageName(module.getQNameModule())),
+            final File file = new File(new File(sourcesOutputDir,
+                BindingMapping.getRootPackageName(module.getQNameModule()).replace('.', File.separatorChar)),
                 BindingMapping.MODULE_INFO_CLASS_NAME + ".java");
             Files.createParentDirs(file);
             Files.asCharSink(file, StandardCharsets.UTF_8).write(template.generate());
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import java.io.File;
 import java.lang.reflect.Constructor;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -5,13 +5,13 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.BASE_PKG;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.cleanUp;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.testCompilation;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.BASE_PKG;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.cleanUp;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.testCompilation;
 
 import com.google.common.collect.Lists;
 import java.io.File;
@@ -5,20 +5,20 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.BASE_PKG;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.NS_BAR;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.NS_BAZ;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.NS_FOO;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.assertFilesCount;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.assertImplementsIfc;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.cleanUp;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.testCompilation;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.BASE_PKG;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.NS_BAR;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.NS_BAZ;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.NS_FOO;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.assertFilesCount;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.assertImplementsIfc;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.cleanUp;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.testCompilation;
 
 import java.io.File;
 import java.lang.reflect.Constructor;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -16,7 +16,6 @@ import static org.junit.Assert.assertNotNull;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingGenerator;
-import org.opendaylight.mdsal.binding.java.api.generator.TOGenerator;
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty;
 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static com.google.common.base.Preconditions.checkState;
 import static org.junit.Assert.assertEquals;
@@ -5,10 +5,10 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.cleanUp;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.testCompilation;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.cleanUp;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.testCompilation;
 
 import java.io.File;
 import org.junit.Test;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -5,15 +5,15 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertTrue;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.BASE_PKG;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.NS_TEST;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.assertFilesCount;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.assertImplementsIfc;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.cleanUp;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.testCompilation;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.BASE_PKG;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.NS_TEST;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.assertFilesCount;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.assertImplementsIfc;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.cleanUp;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.testCompilation;
 
 import java.io.File;
 import java.net.URL;
@@ -5,20 +5,20 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.DOUBLE_TAB;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.TAB;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.TRIPLE_TAB;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.doubleTab;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.getFiles;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.tab;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.FileSearchUtil.tripleTab;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.DOUBLE_TAB;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.TAB;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.TRIPLE_TAB;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.doubleTab;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.getFiles;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.tab;
+import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.tripleTab;
 
 import java.io.File;
 import java.io.IOException;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -5,13 +5,13 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertFalse;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.FS;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.GENERATOR_OUTPUT_PATH;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.cleanUp;
-import static org.opendaylight.mdsal.binding.java.api.generator.test.CompilationTestUtils.testCompilation;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.FS;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.GENERATOR_OUTPUT_PATH;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.cleanUp;
+import static org.opendaylight.mdsal.binding.java.api.generator.CompilationTestUtils.testCompilation;
 
 import java.io.File;
 import java.io.IOException;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.java.api.generator.test;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -5,7 +5,7 @@
  * 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.mdsal.binding.yang.unified.doc.generator.maven;
+package org.opendaylight.mdsal.binding.java.api.generator;
 
 import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -15,18 +15,22 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Table;
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.OutputStream;
 import java.lang.reflect.Method;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
 import javax.tools.Diagnostic;
@@ -34,15 +38,15 @@ import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
-import org.apache.maven.project.MavenProject;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl;
+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.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.sonatype.plexus.build.incremental.DefaultBuildContext;
 
 /**
  * Test correct generation of YangModuleInfo class.
@@ -152,29 +156,36 @@ public class YangModuleInfoCompilationTest {
             throws Exception {
         final List<File> sourceFiles = getSourceFiles(resourceDirPath);
         final EffectiveModelContext context = YangParserTestUtils.parseYangFiles(sourceFiles);
-        CodeGeneratorImpl codegen = new CodeGeneratorImpl();
-        codegen.setBuildContext(new DefaultBuildContext());
-        codegen.generateSources(context, sourcesOutputDir, Set.copyOf(context.getModules()),
-            (module, representation) -> Optional.of(resourceDirPath + File.separator + module.getName()
-            + YangConstants.RFC6020_YANG_FILE_EXTENSION));
+        final Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> codegen = new JavaFileGenerator(Map.of())
+            .generateFiles(context, Set.copyOf(context.getModules()),
+                (module, representation) -> Optional.of(resourceDirPath + File.separator + module.getName()
+                    + YangConstants.RFC6020_YANG_FILE_EXTENSION));
+
+        assertEquals(15, codegen.size());
+        assertEquals(14, codegen.row(GeneratedFileType.SOURCE).size());
+        assertEquals(1, codegen.row(GeneratedFileType.RESOURCE).size());
+
+        for (Entry<GeneratedFilePath, GeneratedFile> entry : codegen.row(GeneratedFileType.SOURCE).entrySet()) {
+            final Path path = new File(sourcesOutputDir,
+                entry.getKey().getPath().replace(GeneratedFilePath.SEPARATOR, File.separatorChar)).toPath();
+
+            Files.createDirectories(path.getParent());
+            try (OutputStream out = Files.newOutputStream(path)) {
+                entry.getValue().writeBody(out);
+            }
+        }
     }
 
     @Test
     public void generateTestSourcesWithAdditionalConfig() throws Exception {
         final List<File> sourceFiles = getSourceFiles("/yang-module-info");
         final EffectiveModelContext context = YangParserTestUtils.parseYangFiles(sourceFiles);
-        CodeGeneratorImpl codegen = new CodeGeneratorImpl();
-        codegen.setBuildContext(new DefaultBuildContext());
-        codegen.setResourceBaseDir(null);
-        codegen.setMavenProject(new MavenProject());
-        codegen.setAdditionalConfig(ImmutableMap.of("test", "test"));
-        Collection<File> files = codegen.generateSources(context, null, Set.copyOf(context.getModules()),
-            (module, representation) -> Optional.of(module.getName()));
-        assertFalse(files.isEmpty());
-        files.forEach(file -> {
-            deleteTestDir(file);
-            assertFalse(file.exists());
-        });
+        JavaFileGenerator codegen = new JavaFileGenerator(Map.of("test", "test"));
+        Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> files = codegen.generateFiles(context,
+            Set.copyOf(context.getModules()), (module, representation) -> Optional.of(module.getName()));
+        assertEquals(15, files.size());
+        assertEquals(14, files.row(GeneratedFileType.SOURCE).size());
+        assertEquals(1, files.row(GeneratedFileType.RESOURCE).size());
     }
 
     private static void testCompilation(final File sourcesOutputDir, final File compiledOutputDir) {
diff --git a/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/package-info.java b/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/test/package-info.java
deleted file mode 100644 (file)
index 08ae043..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * Copyright (c) 2013 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.mdsal.binding.java.api.generator.test;