--- /dev/null
+/*
+ * 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.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * A {@link StateStorage} based on a single project file.
+ */
+final class FileStateStorage extends StateStorage {
+ private final Path stateFile;
+
+ FileStateStorage(final Path stateFile) {
+ this.stateFile = requireNonNull(stateFile);
+ }
+
+ @Override
+ @Nullable YangToSourcesState loadState() throws IOException {
+ if (Files.exists(stateFile)) {
+ try (var in = new DataInputStream(Files.newInputStream(stateFile))) {
+ return YangToSourcesState.readFrom(in);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ void storeState(final YangToSourcesState state) throws IOException {
+ Files.createDirectories(stateFile.getParent());
+ try (var out = new DataOutputStream(Files.newOutputStream(stateFile))) {
+ state.writeTo(out);
+ }
+ }
+}
\ No newline at end of file
package org.opendaylight.yangtools.yang2sources.plugin;
import java.io.IOException;
+import java.nio.file.Path;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.slf4j.Logger;
@NonNullByDefault
abstract class StateStorage {
private static final Logger LOG = LoggerFactory.getLogger(StateStorage.class);
+ private static final String DUMMY_KEY = StateStorage.class.getName();
+ private static final Object DUMMY_VALUE = new Object();
- 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);
+ static StateStorage of(final BuildContext buildContext, final Path fallbackFile) {
+ // Check if BuildContext works. If it does, we use it, otherwise we use fallback to the specified directory
+ buildContext.setValue(DUMMY_KEY, DUMMY_VALUE);
+ if (DUMMY_VALUE.equals(buildContext.getValue(DUMMY_KEY))) {
+ buildContext.setValue(DUMMY_KEY, null);
+ LOG.debug("{} Using BuildContext to store state", YangToSourcesProcessor.LOG_PREFIX);
+ return new BuildContextStateStorage(buildContext);
+ }
+
+ LOG.debug("{} Using {} to store state", YangToSourcesProcessor.LOG_PREFIX, fallbackFile);
+ return new FileStateStorage(fallbackFile);
}
abstract @Nullable YangToSourcesState loadState() throws IOException;
this.project = requireNonNull(project);
this.inspectDependencies = inspectDependencies;
this.yangProvider = requireNonNull(yangProvider);
- stateStorage = StateStorage.of(buildContext);
+ stateStorage = StateStorage.of(buildContext, stateFilePath(project.getBuild().getDirectory()));
parserFactory = DEFAULT_PARSER_FACTORY;
}
return generatorToFiles.build();
}
+
+ @VisibleForTesting
+ static @NonNull Path stateFilePath(final String projectBuildDirectory) {
+ // ${project.build.directory}/maven-status/yang-maven-plugin/execution.state
+ return Path.of(projectBuildDirectory, "maven-status", "yang-maven-plugin", "execution.state");
+ }
}
record YangToSourcesState(
@NonNull ImmutableMap<String, FileGeneratorArg> fileGeneratorArgs,
@NonNull FileStateSet outputFiles) implements WritableObject {
+ // 'ymp' followed by a byte value '1'
+ private static final int MAGIC = 0x796D7001;
+
YangToSourcesState {
requireNonNull(fileGeneratorArgs);
requireNonNull(outputFiles);
}
static @NonNull YangToSourcesState readFrom(final DataInput in) throws IOException {
+ final int magic = in.readInt();
+ if (magic != MAGIC) {
+ throw new IOException("Unrecognized magic " + Integer.toHexString(magic));
+ }
return new YangToSourcesState(readConfigurations(in), FileStateSet.readFrom(in));
}
@Override
public void writeTo(final DataOutput out) throws IOException {
+ out.writeInt(MAGIC);
writeConfigurations(out, fileGeneratorArgs.values());
outputFiles.writeTo(out);
}
import com.google.common.collect.Iterators;
import java.io.IOException;
+import java.nio.file.Files;
import java.util.List;
import java.util.ServiceLoader;
import org.apache.maven.model.Build;
private Plugin plugin;
@Before
- public void before() {
+ public void before() throws IOException {
+ Files.deleteIfExists(YangToSourcesProcessor.stateFilePath("target/"));
doReturn("target/").when(build).getDirectory();
doReturn(build).when(project).getBuild();