Encapsulate project directory access 92/104792/3
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 7 Mar 2023 20:47:37 +0000 (21:47 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 7 Mar 2023 20:57:56 +0000 (21:57 +0100)
The access fact that a GeneratorTask has accessed a particular project
directory needs to be mediated. Add ProjectFileAccess to act as an
intermediary, so that the fact we generate files and Project
modifications can be disconnected.

JIRA: YANGTOOLS-745
Change-Id: Ib550a9c30936444a0077b6f08a3f1e85184173a3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/GeneratorTask.java
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/GeneratorTaskFactory.java
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/ProjectFileAccess.java [new file with mode: 0644]

index be391cdbc677fda45202d9a5806d07f260186965..61a1f968e62a98a41d15015b51f45973f1f2797a 100644 (file)
@@ -7,7 +7,6 @@
  */
 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;
@@ -18,12 +17,8 @@ import com.google.common.collect.Table.Cell;
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
-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;
@@ -37,22 +32,15 @@ import org.slf4j.LoggerFactory;
 final class GeneratorTask extends ParserConfigAware {
     private static final Logger LOG = LoggerFactory.getLogger(GeneratorTask.class);
 
-    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;
+    private final @NonNull GeneratorTaskFactory factory;
+    private final @NonNull ContextHolder contextHolder;
+    private final @NonNull ProjectFileAccess access;
 
     GeneratorTask(final @NonNull GeneratorTaskFactory factory, final @NonNull ContextHolder contextHolder,
-            final MavenProject project) {
+            final ProjectFileAccess access) {
         this.factory = requireNonNull(factory);
         this.contextHolder = requireNonNull(contextHolder);
-        this.project = requireNonNull(project);
-
-        buildDir = new File(project.getBuild().getDirectory());
-        suffix = factory.getIdentifier();
+        this.access = requireNonNull(access);
     }
 
     @Override
@@ -66,7 +54,7 @@ final class GeneratorTask extends ParserConfigAware {
         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);
+        LOG.info("{}: Defined {} files in {}", factory.getIdentifier(), generatedFiles.size(), sw);
 
         // Step two: create generation tasks for each target file and group them by parent directory
         sw.reset().start();
@@ -77,14 +65,14 @@ final class GeneratorTask extends ParserConfigAware {
             final File target;
             switch (file.getLifecycle()) {
                 case PERSISTENT:
-                    target = new File(persistentPath(cell.getRowKey()), relativePath);
+                    target = new File(access.persistentPath(cell.getRowKey()), relativePath);
                     if (target.exists()) {
                         LOG.debug("Skipping existing persistent {}", target);
                         continue;
                     }
                     break;
                 case TRANSIENT:
-                    target = new File(transientPath(cell.getRowKey()), relativePath);
+                    target = new File(access.transientPath(cell.getRowKey()), relativePath);
                     break;
                 default:
                     throw new IllegalStateException("Unsupported file type in " + file);
@@ -112,70 +100,10 @@ final class GeneratorTask extends ParserConfigAware {
                 .collect(Collectors.toList());
         LOG.debug("Generated {} files in {}", result.size(), sw);
 
+        access.updateMavenProject();
         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 GeneratedFile file;
         private final File target;
index a14af78a9cdaa64d02edff072abf27073927b4c0..c769fe618f062eb89236ff1635af0677032d9aa0 100644 (file)
@@ -67,7 +67,7 @@ final class GeneratorTaskFactory extends ParserConfigAware implements Identifiab
      * @param context model generation context
      */
     GeneratorTask createTask(final MavenProject project, final ContextHolder context) {
-        return new GeneratorTask(this, context, project);
+        return new GeneratorTask(this, context, new ProjectFileAccess(project, getIdentifier()));
     }
 
     @Override
diff --git a/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/ProjectFileAccess.java b/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/ProjectFileAccess.java
new file mode 100644 (file)
index 0000000..9a41e62
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2023 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 java.util.Objects.requireNonNull;
+
+import java.io.File;
+import org.apache.maven.model.Resource;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorException;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
+
+/**
+ * An object mediating access to the project directory.
+ */
+final class ProjectFileAccess {
+    private final MavenProject project;
+    private final String buildDirSuffix;
+
+    private @Nullable File sourceDir;
+    private @Nullable File resourceDir;
+    private @Nullable File buildSourceDir;
+    private @Nullable File buildResourceDir;
+
+    ProjectFileAccess(final MavenProject project, final String buildDirSuffix) {
+        this.project = requireNonNull(project);
+        this.buildDirSuffix = requireNonNull(buildDirSuffix);
+    }
+
+    @NonNull File persistentPath(final GeneratedFileType fileType) throws FileGeneratorException {
+        if (GeneratedFileType.SOURCE.equals(fileType)) {
+            var local = sourceDir;
+            if (local == null) {
+                sourceDir = local = new File(project.getBuild().getSourceDirectory());
+            }
+            return local;
+        } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
+            var local = resourceDir;
+            if (local == null) {
+                resourceDir = local = new File(new File(project.getBuild().getSourceDirectory()).getParentFile(),
+                    "resources");
+            }
+            return local;
+        } else {
+            throw new FileGeneratorException("Unknown generated file type " + fileType);
+        }
+    }
+
+    @NonNull File transientPath(final GeneratedFileType fileType) throws FileGeneratorException {
+        if (GeneratedFileType.SOURCE.equals(fileType)) {
+            var local = buildSourceDir;
+            if (local == null) {
+                buildSourceDir = local = buildDirectoryFor("generated-sources");
+            }
+            return local;
+        } else if (GeneratedFileType.RESOURCE.equals(fileType)) {
+            var local = buildResourceDir;
+            if (local == null) {
+                buildResourceDir = local = buildDirectoryFor("generated-resources");
+            }
+            return local;
+        } else {
+            throw new FileGeneratorException("Unknown generated file type " + fileType);
+        }
+    }
+
+    void updateMavenProject() {
+        var local = buildSourceDir;
+        if (local != null) {
+            project.addCompileSourceRoot(local.getPath());
+        }
+        local = buildResourceDir;
+        if (local != null) {
+            final var resource = new Resource();
+            resource.setDirectory(local.toString());
+            project.addResource(resource);
+        }
+    }
+
+    private @NonNull File buildDirectoryFor(final String name) {
+        return new File(project.getBuild().getDirectory()
+            + File.separatorChar + name
+            + File.separatorChar + buildDirSuffix);
+    }
+}