Add StateStorage 24/104624/3
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 28 Feb 2023 15:16:15 +0000 (16:16 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 28 Feb 2023 15:59:42 +0000 (16:59 +0100)
The task of storing and restoring YangToSourceState can be filled
by multiple means. Add StateStorage interface and a simple
implementation based on BuildContext.

JIRA: YANGTOOLS-745
Change-Id: I2bc53ade834b140a429be9d7dcc9e6aba078d66f
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/BuildContextStateStorage.java [new file with mode: 0644]
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/StateStorage.java [new file with mode: 0644]
plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java

diff --git a/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/BuildContextStateStorage.java b/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/BuildContextStateStorage.java
new file mode 100644 (file)
index 0000000..2422d57
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.IOException;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+/**
+ * A {@link StateStorage} based on {@link BuildContext}.
+ */
+@NonNullByDefault
+final class BuildContextStateStorage extends StateStorage {
+    private static final String STATE_KEY = YangToSourcesState.class.getName();
+
+    private final BuildContext buildContext;
+
+    BuildContextStateStorage(final BuildContext buildContext) {
+        this.buildContext = requireNonNull(buildContext);
+    }
+
+    @Override
+    @Nullable YangToSourcesState loadState() throws IOException {
+        final var value = buildContext.getValue(STATE_KEY);
+        if (value instanceof YangToSourcesState state) {
+            return state;
+        } else if (value == null) {
+            return null;
+        } else {
+            throw new IOException("Unexpected loaded state " + value);
+        }
+    }
+
+    @Override
+    void storeState(final YangToSourcesState state) {
+        buildContext.setValue(STATE_KEY, requireNonNull(state));
+    }
+}
\ No newline at end of file
diff --git a/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/StateStorage.java b/plugin/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/StateStorage.java
new file mode 100644 (file)
index 0000000..2f50858
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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 java.io.IOException;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+/**
+ * A storage engine able to store and load {@link YangToSourcesState}.
+ */
+@NonNullByDefault
+abstract class StateStorage {
+    private static final Logger LOG = LoggerFactory.getLogger(StateStorage.class);
+
+    static StateStorage of(final BuildContext buildContext) {
+        // FIXME: detect no-op BuildContext and fall back to a file
+        LOG.debug("{} Using BuildContext to store state", YangToSourcesProcessor.LOG_PREFIX);
+        return new BuildContextStateStorage(buildContext);
+    }
+
+    abstract @Nullable YangToSourcesState loadState() throws IOException;
+
+    abstract void storeState(YangToSourcesState state) throws IOException;
+}
index acc34e79f5159206d2f6258de93d9ed9f5089c09..351bab7c90064236c2bb9d5aabc46ed30d8421bf 100644 (file)
@@ -65,7 +65,6 @@ class YangToSourcesProcessor {
     static final String LOG_PREFIX = "yang-to-sources:";
     private static final String META_INF_STR = "META-INF";
     private static final String YANG_STR = "yang";
-    private static final String BUILD_CONTEXT_STATE_NAME = YangToSourcesProcessor.class.getName();
 
     static final String META_INF_YANG_STRING = META_INF_STR + File.separator + YANG_STR;
     static final String META_INF_YANG_STRING_JAR = META_INF_STR + "/" + YANG_STR;
@@ -79,6 +78,7 @@ class YangToSourcesProcessor {
     private final boolean inspectDependencies;
     private final BuildContext buildContext;
     private final YangProvider yangProvider;
+    private final StateStorage stateStorage;
 
     private YangToSourcesProcessor(final BuildContext buildContext, final File yangFilesRootDir,
             final Collection<File> excludedFiles, final List<FileGeneratorArg> fileGeneratorsArgs,
@@ -91,6 +91,7 @@ class YangToSourcesProcessor {
         this.project = requireNonNull(project);
         this.inspectDependencies = inspectDependencies;
         this.yangProvider = requireNonNull(yangProvider);
+        stateStorage = StateStorage.of(buildContext);
         parserFactory = DEFAULT_PARSER_FACTORY;
     }
 
@@ -110,10 +111,14 @@ class YangToSourcesProcessor {
     }
 
     void execute() throws MojoExecutionException, MojoFailureException {
-        var prevState = buildContext.getValue(BUILD_CONTEXT_STATE_NAME);
+        YangToSourcesState prevState;
+        try {
+            prevState = stateStorage.loadState();
+        } catch (IOException e) {
+            throw new MojoFailureException("Failed to restore execution state", e);
+        }
         if (prevState == null) {
-            LOG.debug("{} BuildContext did not provide state", LOG_PREFIX);
-            // FIXME: look for persisted state and restore it
+            LOG.debug("{} no previous execution state present", LOG_PREFIX);
         }
 
         // Collect all files in the current project.
@@ -246,10 +251,11 @@ class YangToSourcesProcessor {
             codeGenerators.stream()
                 .collect(ImmutableMap.toImmutableMap(GeneratorTaskFactory::getIdentifier, GeneratorTaskFactory::arg)),
             new FileStateSet(ImmutableMap.copyOf(uniqueOutputFiles)));
-        buildContext.setValue(BUILD_CONTEXT_STATE_NAME, outputState);
-        if (buildContext.getValue(BUILD_CONTEXT_STATE_NAME) == null) {
-            LOG.debug("{} BuildContext did not retain state, persisting", LOG_PREFIX);
-            // FIXME: persist in target/ directory (there is a maven best practice where)
+
+        try {
+            stateStorage.storeState(outputState);
+        } catch (IOException e) {
+            throw new MojoFailureException("Failed to store execution state", e);
         }
     }