diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/CgmesImport.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/CgmesImport.java
index 4f9fd5a7222..2d8c2c06e36 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/CgmesImport.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/CgmesImport.java
@@ -189,6 +189,11 @@ public boolean exists(String suffix, String ext) throws IOException {
return ds.exists(suffix, ext) && filter.test(DataSourceUtil.getFileName(getBaseName(), suffix, ext));
}
+ @Override
+ public boolean isDataExtension(String ext) {
+ return ds.isDataExtension(ext);
+ }
+
@Override
public boolean exists(String fileName) throws IOException {
return ds.exists(fileName) && filter.test(fileName);
diff --git a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesOnDataSource.java b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesOnDataSource.java
index 15ac210058a..4654c1a7490 100644
--- a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesOnDataSource.java
+++ b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesOnDataSource.java
@@ -24,6 +24,8 @@
* @author Luma ZamarreƱo {@literal }
*/
public class CgmesOnDataSource {
+ private static final String EXTENSIONS = "xml";
+
public CgmesOnDataSource(ReadOnlyDataSource ds) {
this.dataSource = ds;
}
@@ -32,29 +34,55 @@ public ReadOnlyDataSource dataSource() {
return dataSource;
}
+ private boolean checkIfMainFileNotWithCgmesData(boolean isCim14) {
+ if (dataSource.getDataExtension() == null || dataSource.getDataExtension().isEmpty()) {
+ return false;
+ } else if (EXTENSIONS.equals(dataSource.getDataExtension())) {
+ try (InputStream is = dataSource.newInputStream(null, EXTENSIONS)) {
+ return isCim14 ? !existsNamespacesCim14(NamespaceReader.namespaces(is)) : !existsNamespaces(NamespaceReader.namespaces(is));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ return true;
+ }
+
public boolean exists() {
+ // Check that the main file is a CGMES file
+ if (checkIfMainFileNotWithCgmesData(false)) {
+ return false;
+ }
// check that RDF and CIM16 are defined as namespaces in the data source
- Set foundNamespaces = namespaces();
- if (!foundNamespaces.contains(RDF_NAMESPACE)) {
+ return existsNamespaces(namespaces());
+ }
+
+ private boolean existsNamespaces(Set namespaces) {
+ if (!namespaces.contains(RDF_NAMESPACE)) {
return false;
}
// FIXME(Luma) This is legacy behaviour, we do not consider CIM14 valid in this check
// But I think we do not need to support 14 separately?
- return foundNamespaces.contains(CIM_16_NAMESPACE) || foundNamespaces.contains(CIM_100_NAMESPACE);
+ return namespaces.contains(CIM_16_NAMESPACE) || namespaces.contains(CIM_100_NAMESPACE);
}
public boolean existsCim14() {
+ // Check that the main file is a CGMES file
+ if (checkIfMainFileNotWithCgmesData(true)) {
+ return false;
+ }
// check that RDF and CIM16 are defined as namespaces in the data source
- Set foundNamespaces = namespaces();
- if (!foundNamespaces.contains(RDF_NAMESPACE)) {
+ return existsNamespacesCim14(namespaces());
+ }
+
+ private boolean existsNamespacesCim14(Set namespaces) {
+ if (!namespaces.contains(RDF_NAMESPACE)) {
return false;
}
// FIXME(Luma) This is legacy behaviour, we do not consider CIM14 valid in this check
// But I think we do not need to support 14 separately?
- if (!foundNamespaces.contains(CIM_14_NAMESPACE)) {
+ if (!namespaces.contains(CIM_14_NAMESPACE)) {
return false;
}
-
return names().stream().anyMatch(CgmesSubset.EQUIPMENT::isValidName);
}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/AbstractArchiveDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/AbstractArchiveDataSource.java
index a1439a91845..6871f2b1149 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/AbstractArchiveDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/AbstractArchiveDataSource.java
@@ -17,8 +17,8 @@ public abstract class AbstractArchiveDataSource extends AbstractFileSystemDataSo
private final String archiveFileName;
final ArchiveFormat archiveFormat;
- AbstractArchiveDataSource(Path directory, String archiveFileName, String baseName, CompressionFormat compressionFormat, ArchiveFormat archiveFormat, DataSourceObserver observer) {
- super(directory, baseName, compressionFormat, observer);
+ AbstractArchiveDataSource(Path directory, String archiveFileName, String baseName, String dataExtension, CompressionFormat compressionFormat, ArchiveFormat archiveFormat, DataSourceObserver observer) {
+ super(directory, baseName, dataExtension, compressionFormat, observer);
this.archiveFileName = archiveFileName;
this.archiveFormat = archiveFormat;
}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/AbstractFileSystemDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/AbstractFileSystemDataSource.java
index 3b208ae0b09..335b0295b53 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/AbstractFileSystemDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/AbstractFileSystemDataSource.java
@@ -17,6 +17,7 @@
abstract class AbstractFileSystemDataSource implements DataSource {
final Path directory;
final String baseName;
+ final String dataExtension;
final CompressionFormat compressionFormat;
final DataSourceObserver observer;
@@ -27,14 +28,21 @@ abstract class AbstractFileSystemDataSource implements DataSource {
* @param observer Data source observer
*/
AbstractFileSystemDataSource(Path directory, String baseName,
+ String dataExtension,
CompressionFormat compressionFormat,
DataSourceObserver observer) {
this.directory = Objects.requireNonNull(directory);
this.baseName = Objects.requireNonNull(baseName);
+ this.dataExtension = dataExtension;
this.compressionFormat = compressionFormat;
this.observer = observer;
}
+ @Override
+ public boolean isDataExtension(String ext) {
+ return dataExtension == null || dataExtension.isEmpty() || dataExtension.equals(ext);
+ }
+
public Path getDirectory() {
return this.directory;
}
@@ -44,10 +52,19 @@ public String getBaseName() {
return baseName;
}
+ @Override
+ public String getDataExtension() {
+ return dataExtension;
+ }
+
public CompressionFormat getCompressionFormat() {
return compressionFormat;
}
+ String getCompressionExtension() {
+ return compressionFormat == null ? "" : "." + compressionFormat.getExtension();
+ }
+
public DataSourceObserver getObserver() {
return observer;
}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSource.java
index f2a4ae78ad4..145b69d82ce 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSource.java
@@ -18,12 +18,8 @@
*/
public class Bzip2DirectoryDataSource extends DirectoryDataSource {
- public Bzip2DirectoryDataSource(Path directory, String baseName, DataSourceObserver observer) {
- super(directory, baseName, CompressionFormat.BZIP2, observer);
- }
-
- public Bzip2DirectoryDataSource(Path directory, String baseName) {
- super(directory, baseName, CompressionFormat.BZIP2, null);
+ public Bzip2DirectoryDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
+ super(directory, baseName, dataExtension, CompressionFormat.BZIP2, observer);
}
@Override
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/DataSourceBuilder.java b/commons/src/main/java/com/powsybl/commons/datasource/DataSourceBuilder.java
new file mode 100644
index 00000000000..9736c8d3cbe
--- /dev/null
+++ b/commons/src/main/java/com/powsybl/commons/datasource/DataSourceBuilder.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.commons.datasource;
+
+import com.powsybl.commons.PowsyblException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+class DataSourceBuilder {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceBuilder.class);
+ private Path directory;
+ private String baseName;
+ private String archiveFileName;
+ private CompressionFormat compressionFormat;
+ private ArchiveFormat archiveFormat;
+ private String dataExtension = "";
+ private DataSourceObserver observer;
+
+ DataSourceBuilder withDirectory(Path directory) {
+ this.directory = directory;
+ return this;
+ }
+
+ DataSourceBuilder withBaseName(String baseName) {
+ this.baseName = baseName;
+ return this;
+ }
+
+ DataSourceBuilder withArchiveFileName(String archiveFileName) {
+ this.archiveFileName = archiveFileName;
+ return this;
+ }
+
+ DataSourceBuilder withCompressionFormat(CompressionFormat compressionFormat) {
+ this.compressionFormat = compressionFormat;
+ return this;
+ }
+
+ DataSourceBuilder withArchiveFormat(ArchiveFormat archiveFormat) {
+ this.archiveFormat = archiveFormat;
+ return this;
+ }
+
+ DataSourceBuilder withDataExtension(String dataExtension) {
+ this.dataExtension = dataExtension;
+ return this;
+ }
+
+ DataSourceBuilder withObserver(DataSourceObserver observer) {
+ this.observer = observer;
+ return this;
+ }
+
+ DataSource build() {
+ // Check the mandatory parameters
+ buildChecks();
+
+ // Create the datasource
+ if (compressionFormat == CompressionFormat.ZIP || archiveFormat == ArchiveFormat.ZIP) {
+ return buildZip();
+ } else if (compressionFormat == null) {
+ return new DirectoryDataSource(directory, baseName, dataExtension, observer);
+ } else {
+ return switch (compressionFormat) {
+ case BZIP2 -> new Bzip2DirectoryDataSource(directory, baseName, dataExtension, observer);
+ case GZIP -> new GzDirectoryDataSource(directory, baseName, dataExtension, observer);
+ case XZ -> new XZDirectoryDataSource(directory, baseName, dataExtension, observer);
+ case ZSTD -> new ZstdDirectoryDataSource(directory, baseName, dataExtension, observer);
+ default -> {
+ LOGGER.warn("Unsupported compression format {}", compressionFormat);
+ yield new DirectoryDataSource(directory, baseName, dataExtension, observer);
+ }
+ };
+ }
+ }
+
+ private void buildChecks() {
+ if (directory == null) {
+ throw new PowsyblException("Datasource directory cannot be null");
+ }
+ if (!Files.isDirectory(directory)) {
+ throw new PowsyblException("Datasource directory has to be a directory");
+ }
+ if (baseName == null) {
+ throw new PowsyblException("Datasource baseName cannot be null");
+ }
+ }
+
+ private DataSource buildZip() {
+ if (compressionFormat != null && archiveFormat != null && !(compressionFormat == CompressionFormat.ZIP && archiveFormat == ArchiveFormat.ZIP)) {
+ throw new PowsyblException(String.format("Incoherence between compression format %s and archive format %s", compressionFormat, archiveFormat));
+ }
+ return archiveFileName == null ?
+ new ZipArchiveDataSource(directory, baseName, dataExtension, observer) :
+ new ZipArchiveDataSource(directory, archiveFileName, baseName, dataExtension, observer);
+ }
+}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/DataSourceUtil.java b/commons/src/main/java/com/powsybl/commons/datasource/DataSourceUtil.java
index 23a5cc25011..2a4f7aa7939 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/DataSourceUtil.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/DataSourceUtil.java
@@ -40,45 +40,44 @@ static String getBaseName(String fileName) {
}
static DataSource createDataSource(Path directory, String basename, CompressionFormat compressionExtension, DataSourceObserver observer) {
+ return createDataSource(directory, basename, null, compressionExtension, observer);
+ }
+
+ static DataSource createDataSource(Path directory, String basename, String dataExtension, CompressionFormat compressionFormat, DataSourceObserver observer) {
Objects.requireNonNull(directory);
Objects.requireNonNull(basename);
- if (compressionExtension == null) {
- return new DirectoryDataSource(directory, basename, observer);
- } else {
- switch (compressionExtension) {
- case BZIP2:
- return new Bzip2DirectoryDataSource(directory, basename, observer);
- case GZIP:
- return new GzDirectoryDataSource(directory, basename, observer);
- case XZ:
- return new XZDirectoryDataSource(directory, basename, observer);
- case ZIP:
- return new ZipArchiveDataSource(directory, basename, observer);
- case ZSTD:
- return new ZstdDirectoryDataSource(directory, basename, observer);
- default:
- throw new IllegalStateException("Unexpected CompressionFormat value: " + compressionExtension);
- }
+ DataSourceBuilder dataSourceBuilder = new DataSourceBuilder()
+ .withDirectory(directory)
+ .withBaseName(basename)
+ .withDataExtension(dataExtension)
+ .withCompressionFormat(compressionFormat)
+ .withObserver(observer);
+
+ // If a zip compression is asked
+ if (compressionFormat == CompressionFormat.ZIP) {
+ dataSourceBuilder.withArchiveFormat(ArchiveFormat.ZIP);
}
+
+ return dataSourceBuilder.build();
}
static DataSource createDataSource(Path directory, String fileNameOrBaseName, DataSourceObserver observer) {
Objects.requireNonNull(directory);
Objects.requireNonNull(fileNameOrBaseName);
- if (fileNameOrBaseName.endsWith(".zst")) {
- return new ZstdDirectoryDataSource(directory, getBaseName(fileNameOrBaseName.substring(0, fileNameOrBaseName.length() - 4)), observer);
- } else if (fileNameOrBaseName.endsWith(".zip")) {
- return new ZipArchiveDataSource(directory, fileNameOrBaseName, getBaseName(fileNameOrBaseName.substring(0, fileNameOrBaseName.length() - 4)), observer);
- } else if (fileNameOrBaseName.endsWith(".xz")) {
- return new XZDirectoryDataSource(directory, getBaseName(fileNameOrBaseName.substring(0, fileNameOrBaseName.length() - 3)), observer);
- } else if (fileNameOrBaseName.endsWith(".gz")) {
- return new GzDirectoryDataSource(directory, getBaseName(fileNameOrBaseName.substring(0, fileNameOrBaseName.length() - 3)), observer);
- } else if (fileNameOrBaseName.endsWith(".bz2")) {
- return new Bzip2DirectoryDataSource(directory, getBaseName(fileNameOrBaseName.substring(0, fileNameOrBaseName.length() - 4)), observer);
- } else {
- return new DirectoryDataSource(directory, getBaseName(fileNameOrBaseName), observer);
- }
+ // Get the file information
+ FileInformation fileInformation = new FileInformation(fileNameOrBaseName);
+
+ DataSourceBuilder dataSourceBuilder = new DataSourceBuilder()
+ .withDirectory(directory)
+ .withArchiveFileName(fileNameOrBaseName)
+ .withBaseName(fileInformation.getBaseName())
+ .withDataExtension(fileInformation.getDataExtension())
+ .withCompressionFormat(fileInformation.getCompressionFormat())
+ .withArchiveFormat(fileInformation.getArchiveFormat())
+ .withObserver(observer);
+
+ return dataSourceBuilder.build();
}
}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/DirectoryDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/DirectoryDataSource.java
index 24fca2af1d4..3a92a4b84ff 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/DirectoryDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/DirectoryDataSource.java
@@ -25,22 +25,25 @@
public class DirectoryDataSource extends AbstractFileSystemDataSource {
public DirectoryDataSource(Path directory, String baseName) {
- this(directory, baseName, null, null);
+ this(directory, baseName, null, null, null);
}
public DirectoryDataSource(Path directory, String baseName,
DataSourceObserver observer) {
- this(directory, baseName, null, observer);
+ this(directory, baseName, null, null, observer);
+ }
+
+ public DirectoryDataSource(Path directory, String baseName,
+ String dataExtension,
+ DataSourceObserver observer) {
+ this(directory, baseName, dataExtension, null, observer);
}
DirectoryDataSource(Path directory, String baseName,
+ String dataExtension,
CompressionFormat compressionFormat,
DataSourceObserver observer) {
- super(directory, baseName, compressionFormat, observer);
- }
-
- protected String getCompressionExt() {
- return compressionFormat == null ? "" : "." + compressionFormat.getExtension();
+ super(directory, baseName, dataExtension, compressionFormat, observer);
}
/**
@@ -59,7 +62,8 @@ protected OutputStream getCompressedOutputStream(OutputStream os) throws IOExcep
private Path getPath(String fileName) {
Objects.requireNonNull(fileName);
- return directory.resolve(fileName + getCompressionExt());
+ FileInformation fileInformation = new FileInformation(fileName, false);
+ return directory.resolve(fileInformation.getCompressionFormat() == null ? fileName + getCompressionExtension() : fileName);
}
@Override
@@ -74,6 +78,11 @@ public OutputStream newOutputStream(String fileName, boolean append) throws IOEx
return observer != null ? new ObservableOutputStream(os, path.toString(), observer) : os;
}
+ /**
+ * Check if a file exists in the datasource.
+ * @param fileName Name of the file (excluding the compression extension)
+ * @return true if the file exists, else false
+ */
@Override
public boolean exists(String fileName) throws IOException {
Path path = getPath(fileName);
@@ -104,7 +113,7 @@ public Set listNames(String regex) throws IOException {
.map(Path::toString)
.filter(name -> name.startsWith(baseName))
// Return names after removing the compression extension
- .map(name -> name.replace(getCompressionExt(), ""))
+ .map(name -> name.replace(getCompressionExtension(), ""))
.filter(s -> p.matcher(s).matches())
.collect(Collectors.toSet());
}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/FileInformation.java b/commons/src/main/java/com/powsybl/commons/datasource/FileInformation.java
new file mode 100644
index 00000000000..2cb17ece723
--- /dev/null
+++ b/commons/src/main/java/com/powsybl/commons/datasource/FileInformation.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.commons.datasource;
+
+import com.powsybl.commons.PowsyblException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+public class FileInformation {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FileInformation.class);
+ private String baseName;
+ private CompressionFormat compressionFormat;
+ private ArchiveFormat archiveFormat;
+ private String dataExtension;
+
+ FileInformation(String fileName) {
+ Objects.requireNonNull(fileName);
+ computeInformation(fileName, true);
+ }
+
+ FileInformation(String fileName, boolean dataSourceInitialization) {
+ Objects.requireNonNull(fileName);
+ computeInformation(fileName, dataSourceInitialization);
+ }
+
+ private void computeInformation(String fileName, boolean dataSourceInitialization) {
+ // Check if filename is empty or only a dot
+ if (fileName.isEmpty() || fileName.equals(".")) {
+ throw new PowsyblException("File name cannot be empty nor just a dot");
+ }
+
+ // Last dot index
+ int currentDotIndex = fileName.lastIndexOf('.');
+
+ // Compression extension
+ compressionFormat = switch (fileName.substring(currentDotIndex + 1)) {
+ case "bz2" -> CompressionFormat.BZIP2;
+ case "gz" -> CompressionFormat.GZIP;
+ case "xz" -> CompressionFormat.XZ;
+ case "zip" -> CompressionFormat.ZIP;
+ case "zst" -> CompressionFormat.ZSTD;
+ default -> null;
+ };
+
+ // File name without the compression extension
+ String fileNameWithoutCompressionExtension = compressionFormat == null ? fileName : fileName.substring(0, currentDotIndex);
+
+ // Archive extension
+ String fileNameWithoutCompressionNorArchive;
+ archiveFormat = compressionFormat == CompressionFormat.ZIP ? ArchiveFormat.ZIP : null;
+ fileNameWithoutCompressionNorArchive = fileNameWithoutCompressionExtension;
+
+ // Last dot index
+ currentDotIndex = fileNameWithoutCompressionNorArchive.lastIndexOf('.');
+
+ /* Data datasource extension
+ * Four cases are possible:
+ * - case 1 ("dummy"): currentDotIndex < 0 -> no source format is given
+ * - case 2 (".dummy"): currentDotIndex == 0 -> considered as a hidden file so no source format is given
+ * - case 3 ("dummy.foo"): ".foo" is the source format
+ */
+ dataExtension = currentDotIndex < 1 ? "" : fileNameWithoutCompressionNorArchive.substring(currentDotIndex + 1);
+ logDataExtension(fileName, dataExtension, dataSourceInitialization);
+
+ // Base name
+ baseName = dataExtension.isEmpty() ?
+ fileNameWithoutCompressionNorArchive :
+ fileNameWithoutCompressionNorArchive.substring(0, currentDotIndex);
+ if (baseName.isEmpty()) {
+ LOGGER.warn("Base name is empty in file {}", fileName);
+ }
+ }
+
+ private void logDataExtension(String fileName, String dataExtension, boolean dataSourceInitialization) {
+ if (dataSourceInitialization && dataExtension.isEmpty()) {
+ LOGGER.warn("Data extension is empty in file {}", fileName);
+ }
+ }
+
+ public String getBaseName() {
+ return baseName;
+ }
+
+ public CompressionFormat getCompressionFormat() {
+ return compressionFormat;
+ }
+
+ public ArchiveFormat getArchiveFormat() {
+ return archiveFormat;
+ }
+
+ public String getDataExtension() {
+ return dataExtension;
+ }
+
+ public String toString() {
+ return "FileInformation["
+ + "baseName=" + baseName + ", "
+ + "dataExtension=" + dataExtension + ", "
+ + "archiveFormat=" + archiveFormat + ", "
+ + "compressionFormat=" + compressionFormat
+ + "]";
+ }
+}
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/GenericReadOnlyDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/GenericReadOnlyDataSource.java
index c5643233a2b..51a576a21a7 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/GenericReadOnlyDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/GenericReadOnlyDataSource.java
@@ -21,15 +21,15 @@ public class GenericReadOnlyDataSource implements ReadOnlyDataSource {
private final ReadOnlyDataSource[] dataSources;
- public GenericReadOnlyDataSource(Path directory, String baseName, DataSourceObserver observer) {
+ public GenericReadOnlyDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
dataSources = new DataSource[] {
- new DirectoryDataSource(directory, baseName, observer),
- new ZstdDirectoryDataSource(directory, baseName, observer),
+ new DirectoryDataSource(directory, baseName, dataExtension, observer),
+ new ZstdDirectoryDataSource(directory, baseName, dataExtension, observer),
new ZipArchiveDataSource(directory),
- new ZipArchiveDataSource(directory, baseName + ".zip", baseName, observer),
- new XZDirectoryDataSource(directory, baseName, observer),
- new GzDirectoryDataSource(directory, baseName, observer),
- new Bzip2DirectoryDataSource(directory, baseName, observer)
+ new ZipArchiveDataSource(directory, baseName, dataExtension, observer),
+ new XZDirectoryDataSource(directory, baseName, dataExtension, observer),
+ new GzDirectoryDataSource(directory, baseName, dataExtension, observer),
+ new Bzip2DirectoryDataSource(directory, baseName, dataExtension, observer)
};
}
@@ -37,18 +37,27 @@ public GenericReadOnlyDataSource(Path directory, String baseName, DataSourceObse
* The data source contains all files inside the given directory.
*/
public GenericReadOnlyDataSource(Path directory) {
- this(directory, "");
+ this(directory, "", null);
}
public GenericReadOnlyDataSource(Path directory, String baseName) {
this(directory, baseName, null);
}
+ public GenericReadOnlyDataSource(Path directory, String baseName, String dataExtension) {
+ this(directory, baseName, dataExtension, null);
+ }
+
@Override
public String getBaseName() {
return dataSources[0].getBaseName();
}
+ @Override
+ public String getDataExtension() {
+ return dataSources[0].getDataExtension();
+ }
+
@Override
public boolean exists(String suffix, String ext) throws IOException {
for (ReadOnlyDataSource dataSource : dataSources) {
@@ -59,6 +68,16 @@ public boolean exists(String suffix, String ext) throws IOException {
return false;
}
+ @Override
+ public boolean isDataExtension(String ext) {
+ for (ReadOnlyDataSource dataSource : dataSources) {
+ if (dataSource.isDataExtension(ext)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public boolean exists(String fileName) throws IOException {
for (ReadOnlyDataSource dataSource : dataSources) {
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/GzDirectoryDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/GzDirectoryDataSource.java
index 6381c570d3b..5b6609be310 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/GzDirectoryDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/GzDirectoryDataSource.java
@@ -19,12 +19,8 @@
*/
public class GzDirectoryDataSource extends DirectoryDataSource {
- public GzDirectoryDataSource(Path directory, String baseName, DataSourceObserver observer) {
- super(directory, baseName, CompressionFormat.GZIP, observer);
- }
-
- public GzDirectoryDataSource(Path directory, String baseName) {
- super(directory, baseName, CompressionFormat.GZIP, null);
+ public GzDirectoryDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
+ super(directory, baseName, dataExtension, CompressionFormat.GZIP, observer);
}
@Override
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSource.java
index e09592615c4..8db6959c269 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSource.java
@@ -51,6 +51,11 @@ public boolean exists(String suffix, String ext) throws IOException {
});
}
+ @Override
+ public boolean isDataExtension(String ext) {
+ return dataSources.stream().anyMatch(dataSource -> dataSource.isDataExtension(ext));
+ }
+
@Override
public boolean exists(String fileName) throws IOException {
return dataSources.stream().anyMatch(dataSource -> {
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyDataSource.java
index c4ee48e42ac..91f29c53f2a 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyDataSource.java
@@ -18,6 +18,10 @@ public interface ReadOnlyDataSource {
String getBaseName();
+ default String getDataExtension() {
+ return null;
+ }
+
/**
* Check if a file exists in the datasource. The file name will be constructed as:
* {@code .}
@@ -29,11 +33,18 @@ public interface ReadOnlyDataSource {
/**
* Check if a file exists in the datasource.
- * @param fileName Name of the file (excluding the compression extension)
+ * @param fileName Name of the file
* @return true if the file exists, else false
*/
boolean exists(String fileName) throws IOException;
+ /**
+ * Check if the provided extension is a data extension for the datasource
+ * @param ext Extension to compare to the data extension of the datasource
+ * @return true if the datasource data extension is null, empty or equal to {@code ext}, else false
+ */
+ boolean isDataExtension(String ext);
+
InputStream newInputStream(String suffix, String ext) throws IOException;
InputStream newInputStream(String fileName) throws IOException;
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyMemDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyMemDataSource.java
index 0d2c8a2b115..b776622de69 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyMemDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/ReadOnlyMemDataSource.java
@@ -67,6 +67,16 @@ public boolean exists(String suffix, String ext) throws IOException {
return exists(DataSourceUtil.getFileName(baseName, suffix, ext));
}
+ /**
+ * {@inheritDoc}
+ * As a ReadOnlyMemDataSource does not have a main extension, this method always returns true
+ * @return true
+ */
+ @Override
+ public boolean isDataExtension(String ext) {
+ return true;
+ }
+
@Override
public boolean exists(String fileName) throws IOException {
Objects.requireNonNull(fileName);
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/ResourceDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/ResourceDataSource.java
index b3ec498b802..ac69880802e 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/ResourceDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/ResourceDataSource.java
@@ -22,14 +22,21 @@ public class ResourceDataSource implements ReadOnlyDataSource {
private final String baseName;
+ private final String dataExtension;
+
private final List resourceSets;
public ResourceDataSource(String baseName, ResourceSet... resourceSets) {
- this(baseName, Arrays.asList(resourceSets));
+ this(baseName, null, Arrays.asList(resourceSets));
}
public ResourceDataSource(String baseName, List resourceSets) {
+ this(baseName, null, resourceSets);
+ }
+
+ public ResourceDataSource(String baseName, String dataExtension, List resourceSets) {
this.baseName = Objects.requireNonNull(baseName);
+ this.dataExtension = dataExtension;
this.resourceSets = Objects.requireNonNull(resourceSets);
}
@@ -38,11 +45,21 @@ public String getBaseName() {
return baseName;
}
+ @Override
+ public String getDataExtension() {
+ return dataExtension;
+ }
+
@Override
public boolean exists(String suffix, String ext) {
return exists(DataSourceUtil.getFileName(baseName, suffix, ext));
}
+ @Override
+ public boolean isDataExtension(String ext) {
+ return dataExtension == null || dataExtension.isEmpty() || dataExtension.equals(ext);
+ }
+
@Override
public boolean exists(String fileName) {
Objects.requireNonNull(fileName);
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/XZDirectoryDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/XZDirectoryDataSource.java
index a5eb4014e79..74a8b68e62e 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/XZDirectoryDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/XZDirectoryDataSource.java
@@ -18,12 +18,8 @@
*/
public class XZDirectoryDataSource extends DirectoryDataSource {
- public XZDirectoryDataSource(Path directory, String baseName, DataSourceObserver observer) {
- super(directory, baseName, CompressionFormat.XZ, observer);
- }
-
- public XZDirectoryDataSource(Path directory, String baseName) {
- super(directory, baseName, CompressionFormat.XZ, null);
+ public XZDirectoryDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
+ super(directory, baseName, dataExtension, CompressionFormat.XZ, observer);
}
@Override
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/ZipArchiveDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/ZipArchiveDataSource.java
index 7cdff8ab992..b6c90f26c19 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/ZipArchiveDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/ZipArchiveDataSource.java
@@ -33,20 +33,28 @@
*/
public class ZipArchiveDataSource extends AbstractArchiveDataSource {
- public ZipArchiveDataSource(Path directory, String zipFileName, String baseName, DataSourceObserver observer) {
- super(directory, zipFileName, baseName, CompressionFormat.ZIP, ArchiveFormat.ZIP, observer);
+ public ZipArchiveDataSource(Path directory, String zipFileName, String baseName, String dataExtension, DataSourceObserver observer) {
+ super(directory, zipFileName, baseName, dataExtension, CompressionFormat.ZIP, ArchiveFormat.ZIP, observer);
}
- public ZipArchiveDataSource(Path directory, String zipFileName, String baseName) {
- this(directory, zipFileName, baseName, null);
+ public ZipArchiveDataSource(Path directory, String zipFileName, String baseName, String dataExtension) {
+ this(directory, zipFileName, baseName, dataExtension, null);
}
- public ZipArchiveDataSource(Path directory, String baseName) {
- this(directory, baseName + ".zip", baseName, null);
+ public ZipArchiveDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
+ this(directory, baseName + ((dataExtension == null || dataExtension.isEmpty()) ? "" : "." + dataExtension) + ".zip", baseName, dataExtension, observer);
+ }
+
+ public ZipArchiveDataSource(Path directory, String baseName, String dataExtension) {
+ this(directory, baseName + ((dataExtension == null || dataExtension.isEmpty()) ? "" : "." + dataExtension) + ".zip", baseName, dataExtension, null);
}
public ZipArchiveDataSource(Path directory, String baseName, DataSourceObserver observer) {
- this(directory, baseName + ".zip", baseName, observer);
+ this(directory, baseName + ".zip", baseName, null, observer);
+ }
+
+ public ZipArchiveDataSource(Path directory, String baseName) {
+ this(directory, baseName + ".zip", baseName, null, null);
}
public ZipArchiveDataSource(Path zipFile) {
diff --git a/commons/src/main/java/com/powsybl/commons/datasource/ZstdDirectoryDataSource.java b/commons/src/main/java/com/powsybl/commons/datasource/ZstdDirectoryDataSource.java
index f91fe3d36bd..b5b06a5f18c 100644
--- a/commons/src/main/java/com/powsybl/commons/datasource/ZstdDirectoryDataSource.java
+++ b/commons/src/main/java/com/powsybl/commons/datasource/ZstdDirectoryDataSource.java
@@ -18,12 +18,8 @@
*/
public class ZstdDirectoryDataSource extends DirectoryDataSource {
- public ZstdDirectoryDataSource(Path directory, String baseName, DataSourceObserver observer) {
- super(directory, baseName, CompressionFormat.ZSTD, observer);
- }
-
- public ZstdDirectoryDataSource(Path directory, String baseName) {
- super(directory, baseName, CompressionFormat.ZSTD, null);
+ public ZstdDirectoryDataSource(Path directory, String baseName, String dataExtension, DataSourceObserver observer) {
+ super(directory, baseName, dataExtension, CompressionFormat.ZSTD, observer);
}
@Override
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/AbstractFileSystemDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/AbstractFileSystemDataSourceTest.java
index 8a285694a99..c615887e620 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/AbstractFileSystemDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/AbstractFileSystemDataSourceTest.java
@@ -44,8 +44,8 @@ protected boolean appendTest() {
protected abstract DataSource createDataSource(DataSourceObserver observer);
- protected String getFileName(String baseName, CompressionFormat compressionFormat) {
- return testDir + "/" + baseName
+ protected String getFileName(String baseName, String dataExtension, CompressionFormat compressionFormat) {
+ return testDir + "/" + baseName + (dataExtension == null || dataExtension.isEmpty() ? "" : "." + dataExtension)
+ (compressionFormat == null ? "" : "." + compressionFormat.getExtension());
}
@@ -53,9 +53,9 @@ protected String getFileName(String baseName, CompressionFormat compressionForma
@ParameterizedTest
@MethodSource("provideArgumentsForWriteThenReadTest")
- void writeThenReadTest(String baseName, CompressionFormat compressionFormat) throws IOException {
+ void writeThenReadTest(String baseName, String dataExtension, CompressionFormat compressionFormat) throws IOException {
// Compute the full filename
- String fileName = getFileName(baseName, compressionFormat);
+ String fileName = getFileName(baseName, dataExtension, compressionFormat);
// Create the files
createFiles(fileName);
@@ -112,11 +112,11 @@ private void writeThenReadTest(DataSource dataSource, String suffix, String ext)
@ParameterizedTest
@MethodSource("provideArgumentsForClassAndListingTest")
- void testClassAndListing(String baseName,
+ void testClassAndListing(String baseName, String dataExtension,
CompressionFormat compressionFormat, Class extends AbstractFileSystemDataSource> dataSourceClass,
Set listedFiles, Set listedBarFiles) throws IOException {
// Compute the full filename
- String fileName = getFileName(baseName, compressionFormat);
+ String fileName = getFileName(baseName, dataExtension, compressionFormat);
// Update the list of unlisted files
unlistedFiles = existingFiles.stream().filter(name -> !listedFiles.contains(name)).collect(Collectors.toSet());
@@ -145,8 +145,9 @@ void testGetters() {
// Checks
assertInstanceOf(AbstractFileSystemDataSource.class, dataSourceWithObserver);
- assertEquals("foo", dataSourceWithObserver.getBaseName());
assertEquals(testDir, ((AbstractFileSystemDataSource) dataSourceWithObserver).getDirectory());
+ assertEquals("foo", dataSourceWithObserver.getBaseName());
+ assertEquals("iidm", dataSourceWithObserver.getDataExtension());
assertEquals(compressionFormat, ((AbstractFileSystemDataSource) dataSourceWithObserver).getCompressionFormat());
assertEquals(observer, ((AbstractFileSystemDataSource) dataSourceWithObserver).getObserver());
@@ -157,7 +158,28 @@ void testGetters() {
assertInstanceOf(AbstractFileSystemDataSource.class, dataSourceWithoutObserver);
assertEquals("foo", dataSourceWithoutObserver.getBaseName());
assertEquals(testDir, ((AbstractFileSystemDataSource) dataSourceWithoutObserver).getDirectory());
+ assertEquals("foo", dataSourceWithoutObserver.getBaseName());
+ assertNull(dataSourceWithoutObserver.getDataExtension());
assertEquals(compressionFormat, ((AbstractFileSystemDataSource) dataSourceWithoutObserver).getCompressionFormat());
assertNull(((AbstractFileSystemDataSource) dataSourceWithoutObserver).getObserver());
}
+
+ @Test
+ void testExists() throws IOException {
+ // Observer
+ DataSourceObserver observer = new DefaultDataSourceObserver();
+
+ // Create the files
+ createFiles(getFileName("foo", "iidm", compressionFormat));
+
+ // Create the datasource
+ DataSource dataSourceWithObserver = createDataSource(observer);
+
+ // Checks
+ assertTrue(dataSourceWithObserver.exists(null, "iidm"));
+ assertTrue(dataSourceWithObserver.exists(null, "txt"));
+ assertTrue(dataSourceWithObserver.isDataExtension("iidm"));
+ assertFalse(dataSourceWithObserver.isDataExtension("txt"));
+
+ }
}
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSourceTest.java
index 9e19f4874d1..3d6ccae925f 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/Bzip2DirectoryDataSourceTest.java
@@ -36,12 +36,12 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new Bzip2DirectoryDataSource(testDir, "foo_bar", observer), observer);
- checkDataSource(new Bzip2DirectoryDataSource(testDir, "foo_bar"), null);
+ checkDataSource(new Bzip2DirectoryDataSource(testDir, "foo_bar", "iidm", observer), observer);
}
private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals("iidm", dataSource.getDataExtension());
assertEquals(compressionFormat, dataSource.getCompressionFormat());
assertEquals("foo_bar", dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -55,19 +55,19 @@ protected boolean appendTest() {
@Override
protected DataSource createDataSource() {
- return new Bzip2DirectoryDataSource(testDir, "foo");
+ return new Bzip2DirectoryDataSource(testDir, "foo", null, null);
}
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new Bzip2DirectoryDataSource(testDir, "foo", observer);
+ return new Bzip2DirectoryDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.BZIP2),
- Arguments.of("foo", CompressionFormat.BZIP2),
- Arguments.of("foo.v3", CompressionFormat.BZIP2)
+ Arguments.of("foo", "iidm", CompressionFormat.BZIP2),
+ Arguments.of("foo", "", CompressionFormat.BZIP2),
+ Arguments.of("foo", "v3", CompressionFormat.BZIP2)
);
}
@@ -78,13 +78,13 @@ static Stream provideArgumentsForClassAndListingTest() {
"foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz");
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.xz", "foo_bar.xz", "foo_bar.iidm.zst", "foo_bar.zst", "foo_bar.iidm.gz", "foo_bar.gz");
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
+ Arguments.of("foo", "iidm", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
+ Arguments.of("foo", "", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
+ Arguments.of("foo", "v3", CompressionFormat.BZIP2, Bzip2DirectoryDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/DataSourceBuilderTest.java b/commons/src/test/java/com/powsybl/commons/datasource/DataSourceBuilderTest.java
new file mode 100644
index 00000000000..1ad9ecfd6c3
--- /dev/null
+++ b/commons/src/test/java/com/powsybl/commons/datasource/DataSourceBuilderTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.commons.datasource;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import com.powsybl.commons.PowsyblException;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+class DataSourceBuilderTest {
+ protected FileSystem fileSystem;
+ protected Path testDir;
+
+ @BeforeEach
+ void setUp() throws IOException {
+ fileSystem = Jimfs.newFileSystem(Configuration.unix());
+ testDir = fileSystem.getPath("/tmp");
+ Files.createDirectories(testDir);
+ }
+
+ @Test
+ void testBuilder() {
+ // Observer
+ DataSourceObserver observer = new DefaultDataSourceObserver();
+
+ // Constant parameters
+ DataSourceBuilder builder = new DataSourceBuilder()
+ .withDirectory(testDir)
+ .withBaseName("foo")
+ .withDataExtension(".baz")
+ .withObserver(observer);
+
+ // Directory datasource
+ assertInstanceOf(DirectoryDataSource.class, builder.build());
+ assertInstanceOf(GzDirectoryDataSource.class, builder.withCompressionFormat(CompressionFormat.GZIP).build());
+ assertInstanceOf(ZstdDirectoryDataSource.class, builder.withCompressionFormat(CompressionFormat.ZSTD).build());
+ assertInstanceOf(XZDirectoryDataSource.class, builder.withCompressionFormat(CompressionFormat.XZ).build());
+ assertInstanceOf(Bzip2DirectoryDataSource.class, builder.withCompressionFormat(CompressionFormat.BZIP2).build());
+
+ // Archive datasources
+ assertInstanceOf(ZipArchiveDataSource.class, builder.withArchiveFormat(ArchiveFormat.ZIP).withCompressionFormat(null).build());
+ assertInstanceOf(ZipArchiveDataSource.class, builder.withCompressionFormat(CompressionFormat.ZIP).build());
+ assertInstanceOf(ZipArchiveDataSource.class, builder.withArchiveFormat(null).build());
+ }
+
+ @Test
+ void testBuilderErrors() {
+ // Observer
+ DataSourceObserver observer = new DefaultDataSourceObserver();
+
+ // Builder
+ DataSourceBuilder builder = new DataSourceBuilder()
+ .withCompressionFormat(CompressionFormat.ZIP)
+ .withArchiveFileName("bar.zip")
+ .withDataExtension(".baz")
+ .withArchiveFormat(ArchiveFormat.ZIP)
+ .withObserver(observer);
+
+ // Directory missing
+ PowsyblException exception = assertThrows(PowsyblException.class, builder::build);
+ assertEquals("Datasource directory cannot be null", exception.getMessage());
+
+ // Directory parameter is not a directory but a file
+ Path file = testDir.resolve("fake.zip");
+ builder.withDirectory(file);
+ exception = assertThrows(PowsyblException.class, builder::build);
+ assertEquals("Datasource directory has to be a directory", exception.getMessage());
+
+ // Base name missing
+ builder.withDirectory(testDir);
+ exception = assertThrows(PowsyblException.class, builder::build);
+ assertEquals("Datasource baseName cannot be null", exception.getMessage());
+ }
+
+ @Test
+ void testBuilderErrorsZip() {
+ DataSourceBuilder builder = new DataSourceBuilder()
+ .withDirectory(testDir)
+ .withBaseName("foo")
+ .withArchiveFileName("bar.zip")
+ .withDataExtension(".baz");
+
+ // Wrong compression format
+ builder.withCompressionFormat(CompressionFormat.GZIP).withArchiveFormat(ArchiveFormat.ZIP);
+ PowsyblException exception = assertThrows(PowsyblException.class, builder::build);
+ assertEquals("Incoherence between compression format GZIP and archive format ZIP", exception.getMessage());
+ }
+}
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/DirectoryDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/DirectoryDataSourceTest.java
index 2641571df76..5eb13218e6c 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/DirectoryDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/DirectoryDataSourceTest.java
@@ -71,13 +71,15 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new DirectoryDataSource(testDir, "foo_bar", CompressionFormat.GZIP, observer), CompressionFormat.GZIP, observer);
- checkDataSource(new DirectoryDataSource(testDir, "foo_bar", observer), null, observer);
- checkDataSource(new DirectoryDataSource(testDir, "foo_bar"), null, null);
+ checkDataSource(new DirectoryDataSource(testDir, "foo_bar"), null, null, null);
+ checkDataSource(new DirectoryDataSource(testDir, "foo_bar", observer), null, null, observer);
+ checkDataSource(new DirectoryDataSource(testDir, "foo_bar", "iidm", observer), "iidm", null, observer);
+ checkDataSource(new DirectoryDataSource(testDir, "foo_bar", "iidm", CompressionFormat.GZIP, observer), "iidm", CompressionFormat.GZIP, observer);
}
- private void checkDataSource(DirectoryDataSource dataSource, CompressionFormat compressionFormat, DataSourceObserver observer) {
+ private void checkDataSource(DirectoryDataSource dataSource, String dataExtension, CompressionFormat compressionFormat, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals(dataExtension, dataSource.getDataExtension());
assertEquals(compressionFormat, dataSource.getCompressionFormat());
assertEquals("foo_bar", dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -90,14 +92,14 @@ protected DataSource createDataSource() {
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new DirectoryDataSource(testDir, "foo", observer);
+ return new DirectoryDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", null),
- Arguments.of("foo", null),
- Arguments.of("foo.v3", null)
+ Arguments.of("foo", "iidm", null),
+ Arguments.of("foo", "", null),
+ Arguments.of("foo", "v3", null)
);
}
@@ -110,13 +112,13 @@ static Stream provideArgumentsForClassAndListingTest() {
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.bz2", "foo_bar.bz2", "foo_bar.iidm.xz", "foo_bar.xz",
"foo_bar.iidm.zst", "foo_bar.zst", "foo_bar.iidm.gz", "foo_bar.gz");
return Stream.of(
- Arguments.of("foo.iidm", null, DirectoryDataSource.class,
+ Arguments.of("foo", "iidm", null, DirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", null, DirectoryDataSource.class,
+ Arguments.of("foo", "", null, DirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", null, DirectoryDataSource.class,
+ Arguments.of("foo", "v3", null, DirectoryDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/FileInformationTest.java b/commons/src/test/java/com/powsybl/commons/datasource/FileInformationTest.java
new file mode 100644
index 00000000000..4396afc5586
--- /dev/null
+++ b/commons/src/test/java/com/powsybl/commons/datasource/FileInformationTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.commons.datasource;
+
+import com.powsybl.commons.PowsyblException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+class FileInformationTest {
+
+ @Test
+ void tests() {
+ unitTest("dummy", "dummy", null, null, "");
+ unitTest("dummy.iidm", "dummy", null, null, "iidm");
+ unitTest("dummy.xml.xz", "dummy", CompressionFormat.XZ, null, "xml");
+
+ // A zip file is a compressed archive
+ unitTest("dummy.zip", "dummy", CompressionFormat.ZIP, ArchiveFormat.ZIP, "");
+
+ // It can still specify the source format
+ unitTest("dummy.jiidm.zip", "dummy", CompressionFormat.ZIP, ArchiveFormat.ZIP, "jiidm");
+
+ // If there is a usual format and additional extensions, those extensions go in the baseName
+ unitTest("dummy.v3.xml.zst", "dummy.v3", CompressionFormat.ZSTD, null, "xml");
+
+ // If there are additional extensions but no usual format, the last extension becomes the source format
+ unitTest("dummy.v3.bz2", "dummy", CompressionFormat.BZIP2, null, "v3");
+
+ // Hidden files
+ unitTest(".dummy", ".dummy", null, null, "");
+ unitTest(".iidm", ".iidm", null, null, "");
+ unitTest(".zip", "", CompressionFormat.ZIP, ArchiveFormat.ZIP, "");
+ unitTest(".dummy.jiidm.zip", ".dummy", CompressionFormat.ZIP, ArchiveFormat.ZIP, "jiidm");
+
+ PowsyblException exception = assertThrows(PowsyblException.class, () -> new FileInformation(""));
+ assertEquals("File name cannot be empty nor just a dot", exception.getMessage());
+
+ exception = assertThrows(PowsyblException.class, () -> new FileInformation("."));
+ assertEquals("File name cannot be empty nor just a dot", exception.getMessage());
+ }
+
+ private void unitTest(String filename, String baseName,
+ CompressionFormat compressionFormat, ArchiveFormat archiveFormat, String dataExtension) {
+ // Create the file information object
+ FileInformation fileInformation = new FileInformation(filename);
+
+ // Check the information
+ assertEquals(baseName, fileInformation.getBaseName());
+ assertEquals(compressionFormat, fileInformation.getCompressionFormat());
+ assertEquals(archiveFormat, fileInformation.getArchiveFormat());
+ assertEquals(dataExtension, fileInformation.getDataExtension());
+ }
+
+ @Test
+ void testToString() {
+ // Create the file information object
+ FileInformation fileInformation = new FileInformation("foo.bar.zip");
+
+ assertEquals("FileInformation[baseName=foo, dataExtension=bar, archiveFormat=ZIP, compressionFormat=ZIP]", fileInformation.toString());
+ }
+}
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/GenericReadOnlyDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/GenericReadOnlyDataSourceTest.java
new file mode 100644
index 00000000000..0f3a28f82a8
--- /dev/null
+++ b/commons/src/test/java/com/powsybl/commons/datasource/GenericReadOnlyDataSourceTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.commons.datasource;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+class GenericReadOnlyDataSourceTest {
+
+ protected FileSystem fileSystem;
+ protected Path testDir;
+ protected Set unlistedFiles;
+ protected Set existingFiles;
+ protected Set filesInArchive;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem(Configuration.unix());
+ testDir = fileSystem.getPath("/tmp");
+ Files.createDirectories(testDir);
+
+ // Files
+ existingFiles = Set.of(
+ "foo", "foo.txt", "foo.iidm", "foo.xiidm", "foo.v3.iidm", "foo.v3", "foo_bar.iidm", "foo_bar", "bar.iidm", "bar",
+ "foo.bz2", "foo.txt.bz2", "foo.iidm.bz2", "foo.xiidm.bz2", "foo.v3.iidm.bz2", "foo.v3.bz2", "foo_bar.iidm.bz2", "foo_bar.bz2", "bar.iidm.bz2", "bar.bz2",
+ "foo.xz", "foo.txt.xz", "foo.iidm.xz", "foo.xiidm.xz", "foo.v3.iidm.xz", "foo.v3.xz", "foo_bar.iidm.xz", "foo_bar.xz", "bar.iidm.xz", "bar.xz",
+ "foo.zst", "foo.txt.zst", "foo.iidm.zst", "foo.xiidm.zst", "foo.v3.iidm.zst", "foo.v3.zst", "foo_bar.iidm.zst", "foo_bar.zst", "bar.iidm.zst", "bar.zst",
+ "foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz", "bar.iidm.gz", "bar.gz"
+ );
+ filesInArchive = Set.of(
+ "foo_in_archive", "foo_in_archive.txt", "foo_in_archive.iidm", "foo_in_archive.xiidm",
+ "foo_in_archive.v3.iidm", "foo_in_archive.v3", "foo_bar_in_archive.iidm", "foo_bar_in_archive",
+ "bar_in_archive.iidm", "bar_in_archive");
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ fileSystem.close();
+ }
+
+ @Test
+ void testConstructors() {
+ // Observer
+ DataSourceObserver observer = new DefaultDataSourceObserver();
+
+ // Check constructors
+ checkDataSource(new GenericReadOnlyDataSource(testDir), "", null);
+ checkDataSource(new GenericReadOnlyDataSource(testDir, "foo_bar"), "foo_bar", null);
+ checkDataSource(new GenericReadOnlyDataSource(testDir, "foo_bar", "iidm"), "foo_bar", "iidm");
+ checkDataSource(new GenericReadOnlyDataSource(testDir, "foo_bar", "iidm", observer), "foo_bar", "iidm");
+ }
+
+ private void checkDataSource(GenericReadOnlyDataSource dataSource, String baseName, String dataExtension) {
+ assertEquals(baseName, dataSource.getBaseName());
+ assertEquals(dataExtension, dataSource.getDataExtension());
+ }
+
+ private String getFileName(String baseName, String dataExtension) {
+ return testDir + "/" + baseName + (dataExtension == null || dataExtension.isEmpty() ? "" : "." + dataExtension);
+ }
+
+ private void createFiles(String archiveName) throws IOException {
+ // Create the test files in the directory
+ existingFiles.forEach(fileName -> {
+ try {
+ Files.createFile(fileSystem.getPath(testDir + "/" + fileName));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ // Create the Zip archive and add the files
+ try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(fileSystem.getPath(archiveName + ".zip")))) {
+ filesInArchive.forEach(fileInArchive -> {
+ try {
+ ZipEntry e = new ZipEntry(fileInArchive);
+ out.putNextEntry(e);
+ byte[] data = "Test String".getBytes();
+ out.write(data, 0, data.length);
+ out.closeEntry();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ });
+ }
+ }
+
+ // Currently, the files are not filtered in the zip archive
+ static Stream provideArgumentsForClassAndListingTest() {
+ Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.bz2", "foo_bar.bz2", "foo_bar.iidm.xz", "foo_bar.xz",
+ "foo_bar.iidm.zst", "foo_bar.zst", "foo_bar.iidm.gz", "foo_bar.gz", "foo_bar_in_archive.iidm", "foo_bar_in_archive",
+ "bar_in_archive.iidm", "bar_in_archive");
+ return Stream.of(
+ Arguments.of("foo", "iidm", GenericReadOnlyDataSource.class,
+ Set.of("foo", "foo.txt", "foo.iidm", "foo.xiidm", "foo.v3.iidm", "foo.v3", "foo_bar.iidm", "foo_bar",
+ "foo.bz2", "foo.txt.bz2", "foo.iidm.bz2", "foo.xiidm.bz2", "foo.v3.iidm.bz2", "foo.v3.bz2", "foo_bar.iidm.bz2", "foo_bar.bz2",
+ "foo.xz", "foo.txt.xz", "foo.iidm.xz", "foo.xiidm.xz", "foo.v3.iidm.xz", "foo.v3.xz", "foo_bar.iidm.xz", "foo_bar.xz",
+ "foo.zst", "foo.txt.zst", "foo.iidm.zst", "foo.xiidm.zst", "foo.v3.iidm.zst", "foo.v3.zst", "foo_bar.iidm.zst", "foo_bar.zst",
+ "foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz",
+ "foo_in_archive", "foo_in_archive.txt", "foo_in_archive.iidm", "foo_in_archive.xiidm",
+ "foo_in_archive.v3.iidm", "foo_in_archive.v3", "foo_bar_in_archive.iidm", "foo_bar_in_archive",
+ "bar_in_archive.iidm", "bar_in_archive", "foo.iidm.zip"),
+ listedBarFiles),
+ Arguments.of("foo", "", GenericReadOnlyDataSource.class,
+ Set.of("foo", "foo.txt", "foo.iidm", "foo.xiidm", "foo.v3.iidm", "foo.v3", "foo_bar.iidm", "foo_bar",
+ "foo.bz2", "foo.txt.bz2", "foo.iidm.bz2", "foo.xiidm.bz2", "foo.v3.iidm.bz2", "foo.v3.bz2", "foo_bar.iidm.bz2", "foo_bar.bz2",
+ "foo.xz", "foo.txt.xz", "foo.iidm.xz", "foo.xiidm.xz", "foo.v3.iidm.xz", "foo.v3.xz", "foo_bar.iidm.xz", "foo_bar.xz",
+ "foo.zst", "foo.txt.zst", "foo.iidm.zst", "foo.xiidm.zst", "foo.v3.iidm.zst", "foo.v3.zst", "foo_bar.iidm.zst", "foo_bar.zst",
+ "foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz",
+ "foo_in_archive", "foo_in_archive.txt", "foo_in_archive.iidm", "foo_in_archive.xiidm",
+ "foo_in_archive.v3.iidm", "foo_in_archive.v3", "foo_bar_in_archive.iidm", "foo_bar_in_archive",
+ "bar_in_archive.iidm", "bar_in_archive", "foo.zip"),
+ listedBarFiles),
+ Arguments.of("foo", "v3", GenericReadOnlyDataSource.class,
+ Set.of("foo", "foo.txt", "foo.iidm", "foo.xiidm", "foo.v3.iidm", "foo.v3", "foo_bar.iidm", "foo_bar",
+ "foo.bz2", "foo.txt.bz2", "foo.iidm.bz2", "foo.xiidm.bz2", "foo.v3.iidm.bz2", "foo.v3.bz2", "foo_bar.iidm.bz2", "foo_bar.bz2",
+ "foo.xz", "foo.txt.xz", "foo.iidm.xz", "foo.xiidm.xz", "foo.v3.iidm.xz", "foo.v3.xz", "foo_bar.iidm.xz", "foo_bar.xz",
+ "foo.zst", "foo.txt.zst", "foo.iidm.zst", "foo.xiidm.zst", "foo.v3.iidm.zst", "foo.v3.zst", "foo_bar.iidm.zst", "foo_bar.zst",
+ "foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz",
+ "foo_in_archive", "foo_in_archive.txt", "foo_in_archive.iidm", "foo_in_archive.xiidm",
+ "foo_in_archive.v3.iidm", "foo_in_archive.v3", "foo_bar_in_archive.iidm", "foo_bar_in_archive",
+ "bar_in_archive.iidm", "bar_in_archive", "foo.v3.zip"),
+ listedBarFiles)
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideArgumentsForClassAndListingTest")
+ void testClassAndListing(String baseName, String dataExtension,
+ Class extends AbstractFileSystemDataSource> dataSourceClass,
+ Set listedFiles, Set listedBarFiles) throws IOException {
+ // Compute the full filename
+ String fileName = getFileName(baseName, dataExtension);
+
+ // Update the list of unlisted files
+ unlistedFiles = existingFiles.stream().filter(name -> !listedFiles.contains(name)).collect(Collectors.toSet());
+
+ // Create the files
+ createFiles(fileName);
+
+ // Create the datasource
+ GenericReadOnlyDataSource dataSource = new GenericReadOnlyDataSource(testDir, baseName, dataExtension);
+
+ // Check the class
+ assertInstanceOf(dataSourceClass, dataSource);
+
+ // List all the files in the datasource
+ assertEquals(listedFiles, dataSource.listNames(".*"));
+ assertEquals(listedBarFiles, dataSource.listNames(".*bar.*"));
+ }
+
+ @Test
+ void testIsDataExtension() {
+ GenericReadOnlyDataSource dataSource = new GenericReadOnlyDataSource(testDir, "foo_bar");
+ assertTrue(dataSource.isDataExtension("test"));
+ assertTrue(dataSource.isDataExtension("iidm"));
+
+ dataSource = new GenericReadOnlyDataSource(testDir, "foo_bar", "iidm");
+ assertTrue(dataSource.isDataExtension("test"));
+ assertTrue(dataSource.isDataExtension("iidm"));
+
+ }
+}
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/GzDirectoryDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/GzDirectoryDataSourceTest.java
index b49391e9189..793082c13ef 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/GzDirectoryDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/GzDirectoryDataSourceTest.java
@@ -36,12 +36,12 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new GzDirectoryDataSource(testDir, "foo_bar", observer), observer);
- checkDataSource(new GzDirectoryDataSource(testDir, "foo_bar"), null);
+ checkDataSource(new GzDirectoryDataSource(testDir, "foo_bar", "iidm", observer), observer);
}
private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals("iidm", dataSource.getDataExtension());
assertEquals(compressionFormat, dataSource.getCompressionFormat());
assertEquals("foo_bar", dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -49,19 +49,19 @@ private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver
@Override
protected DataSource createDataSource() {
- return new GzDirectoryDataSource(testDir, "foo");
+ return new GzDirectoryDataSource(testDir, "foo", null, null);
}
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new GzDirectoryDataSource(testDir, "foo", observer);
+ return new GzDirectoryDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.GZIP),
- Arguments.of("foo", CompressionFormat.GZIP),
- Arguments.of("foo.v3", CompressionFormat.GZIP)
+ Arguments.of("foo", "iidm", CompressionFormat.GZIP),
+ Arguments.of("foo", "", CompressionFormat.GZIP),
+ Arguments.of("foo", "v3", CompressionFormat.GZIP)
);
}
@@ -72,13 +72,13 @@ static Stream provideArgumentsForClassAndListingTest() {
"foo.zst", "foo.txt.zst", "foo.iidm.zst", "foo.xiidm.zst", "foo.v3.iidm.zst", "foo.v3.zst", "foo_bar.iidm.zst", "foo_bar.zst");
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.bz2", "foo_bar.bz2", "foo_bar.iidm.xz", "foo_bar.xz", "foo_bar.iidm.zst", "foo_bar.zst");
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.GZIP, GzDirectoryDataSource.class,
+ Arguments.of("foo", "iidm", CompressionFormat.GZIP, GzDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", CompressionFormat.GZIP, GzDirectoryDataSource.class,
+ Arguments.of("foo", "", CompressionFormat.GZIP, GzDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", CompressionFormat.GZIP, GzDirectoryDataSource.class,
+ Arguments.of("foo", "v3", CompressionFormat.GZIP, GzDirectoryDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/MemDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/MemDataSourceTest.java
index 419cd822b02..282f5947b1c 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/MemDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/MemDataSourceTest.java
@@ -63,6 +63,11 @@ void baseNameTest() {
assertEquals(dataSource.getBaseName(), getBaseName());
}
+ @Test
+ void dataExtensionTest() {
+ assertNull(dataSource.getDataExtension());
+ }
+
private void writeThenReadTest(String suffix, String ext) throws IOException {
// check file does not exist
assertFalse(dataSource.exists(suffix, ext));
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSourceTest.java
index 3d79eabc81d..8ac50671499 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/MultipleReadOnlyDataSourceTest.java
@@ -38,6 +38,7 @@ void setUp() throws Exception {
Files.createDirectories(testDir);
Files.createFile(testDir.resolve("a.txt"));
Files.createFile(testDir.resolve("b.txt"));
+ Files.createFile(testDir.resolve("b.foo"));
}
@AfterEach
@@ -48,14 +49,16 @@ void tearDown() throws Exception {
@Test
void test() throws IOException {
ReadOnlyDataSource dataSource = new MultipleReadOnlyDataSource(new DirectoryDataSource(testDir, "a"),
- new DirectoryDataSource(testDir, "b"));
+ new DirectoryDataSource(testDir, "b", "txt", null));
assertEquals("a", dataSource.getBaseName());
assertTrue(dataSource.exists(null, "txt"));
assertFalse(dataSource.exists(null, "json"));
+ assertTrue(dataSource.exists(null, "foo"));
+ assertTrue(dataSource.isDataExtension("foo"));
assertTrue(dataSource.exists("a.txt"));
assertTrue(dataSource.exists("b.txt"));
assertFalse(dataSource.exists("c.txt"));
- assertEquals(Set.of("a.txt", "b.txt"), dataSource.listNames(".*"));
+ assertEquals(Set.of("a.txt", "b.txt", "b.foo"), dataSource.listNames(".*"));
try (var is = dataSource.newInputStream("a.txt")) {
assertNotNull(is);
}
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/ResourcesDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/ResourcesDataSourceTest.java
index 079159a3905..c41dbce5f82 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/ResourcesDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/ResourcesDataSourceTest.java
@@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;
import java.util.Collections;
+import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@@ -18,10 +19,35 @@
*/
class ResourcesDataSourceTest {
+ @Test
+ void testExists() {
+ ResourceDataSource dataSourceWithNoDataExtension = new ResourceDataSource("foo", List.of(new ResourceSet("/test/", "foo.txt", "foo.bar")));
+ assertTrue(dataSourceWithNoDataExtension.exists("foo.txt"));
+ assertTrue(dataSourceWithNoDataExtension.exists(null, "bar"));
+ assertTrue(dataSourceWithNoDataExtension.exists(null, "txt"));
+ assertTrue(dataSourceWithNoDataExtension.isDataExtension("bar"));
+ assertTrue(dataSourceWithNoDataExtension.isDataExtension("txt"));
+
+ ResourceDataSource dataSourceWithEmptyDataExtension = new ResourceDataSource("foo", "", List.of(new ResourceSet("/test/", "foo.txt", "foo.bar")));
+ assertTrue(dataSourceWithEmptyDataExtension.exists("foo.txt"));
+ assertTrue(dataSourceWithEmptyDataExtension.exists(null, "bar"));
+ assertTrue(dataSourceWithEmptyDataExtension.exists(null, "txt"));
+ assertTrue(dataSourceWithEmptyDataExtension.isDataExtension("bar"));
+ assertTrue(dataSourceWithEmptyDataExtension.isDataExtension("txt"));
+
+ ResourceDataSource dataSourceWithDataExtension = new ResourceDataSource("foo", "txt", List.of(new ResourceSet("/test/", "foo.txt", "foo.bar")));
+ assertTrue(dataSourceWithDataExtension.exists("foo.txt"));
+ assertTrue(dataSourceWithDataExtension.exists(null, "bar"));
+ assertTrue(dataSourceWithDataExtension.exists(null, "txt"));
+ assertFalse(dataSourceWithDataExtension.isDataExtension("bar"));
+ assertTrue(dataSourceWithDataExtension.isDataExtension("txt"));
+ }
+
@Test
void test() {
ResourceDataSource dataSource = new ResourceDataSource("foo", new ResourceSet("/test/", "foo.txt"));
assertEquals("foo", dataSource.getBaseName());
+ assertNull(dataSource.getDataExtension());
assertTrue(dataSource.exists("foo.txt"));
assertTrue(dataSource.exists(null, "txt"));
assertFalse(dataSource.exists("foo.doc"));
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/XZDirectoryDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/XZDirectoryDataSourceTest.java
index a670c4c19bd..197c3b5f0e8 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/XZDirectoryDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/XZDirectoryDataSourceTest.java
@@ -36,12 +36,12 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new XZDirectoryDataSource(testDir, "foo_bar", observer), observer);
- checkDataSource(new XZDirectoryDataSource(testDir, "foo_bar"), null);
+ checkDataSource(new XZDirectoryDataSource(testDir, "foo_bar", "iidm", observer), observer);
}
private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals("iidm", dataSource.getDataExtension());
assertEquals(compressionFormat, dataSource.getCompressionFormat());
assertEquals("foo_bar", dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -55,19 +55,19 @@ protected boolean appendTest() {
@Override
protected DataSource createDataSource() {
- return new XZDirectoryDataSource(testDir, "foo");
+ return new XZDirectoryDataSource(testDir, "foo", null, null);
}
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new XZDirectoryDataSource(testDir, "foo", observer);
+ return new XZDirectoryDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.XZ),
- Arguments.of("foo", CompressionFormat.XZ),
- Arguments.of("foo.v3", CompressionFormat.XZ)
+ Arguments.of("foo", "iidm", CompressionFormat.XZ),
+ Arguments.of("foo", "", CompressionFormat.XZ),
+ Arguments.of("foo", "v3", CompressionFormat.XZ)
);
}
@@ -78,13 +78,13 @@ static Stream provideArgumentsForClassAndListingTest() {
"foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz");
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.bz2", "foo_bar.bz2", "foo_bar.iidm.zst", "foo_bar.zst", "foo_bar.iidm.gz", "foo_bar.gz");
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.XZ, XZDirectoryDataSource.class,
+ Arguments.of("foo", "iidm", CompressionFormat.XZ, XZDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", CompressionFormat.XZ, XZDirectoryDataSource.class,
+ Arguments.of("foo", "", CompressionFormat.XZ, XZDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", CompressionFormat.XZ, XZDirectoryDataSource.class,
+ Arguments.of("foo", "v3", CompressionFormat.XZ, XZDirectoryDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/ZipArchiveDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/ZipArchiveDataSourceTest.java
index 5e72fafdb9b..f715be6551b 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/ZipArchiveDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/ZipArchiveDataSourceTest.java
@@ -55,15 +55,21 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new ZipArchiveDataSource(testDir, "foo_bar.zip", "foo", observer), "foo_bar.zip", "foo", observer);
- checkDataSource(new ZipArchiveDataSource(testDir, "foo_bar.zip", "foo"), "foo_bar.zip", "foo", null);
- checkDataSource(new ZipArchiveDataSource(testDir, "foo", observer), "foo.zip", "foo", observer);
- checkDataSource(new ZipArchiveDataSource(testDir, "foo"), "foo.zip", "foo", null);
- checkDataSource(new ZipArchiveDataSource(testDir.resolve("foo_bar.zip")), "foo_bar.zip", "foo_bar", null);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo_bar.zip", "foo", "iidm", observer), "foo_bar.zip", "foo", "iidm", observer);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo_bar.zip", "foo", "iidm"), "foo_bar.zip", "foo", "iidm", null);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", "iidm", observer), "foo.iidm.zip", "foo", "iidm", observer);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", "", observer), "foo.zip", "foo", "", observer);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", "iidm"), "foo.iidm.zip", "foo", "iidm", null);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", (String) null), "foo.zip", "foo", null, null);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", ""), "foo.zip", "foo", "", null);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo", observer), "foo.zip", "foo", null, observer);
+ checkDataSource(new ZipArchiveDataSource(testDir, "foo"), "foo.zip", "foo", null, null);
+ checkDataSource(new ZipArchiveDataSource(testDir.resolve("foo_bar.zip")), "foo_bar.zip", "foo_bar", null, null);
}
- private void checkDataSource(ZipArchiveDataSource dataSource, String zipFileName, String baseName, DataSourceObserver observer) {
+ private void checkDataSource(ZipArchiveDataSource dataSource, String zipFileName, String baseName, String dataExtension, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals(dataExtension, dataSource.getDataExtension());
assertEquals(zipFileName, dataSource.getArchiveFilePath().getFileName().toString());
assertEquals(baseName, dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -76,19 +82,19 @@ protected boolean appendTest() {
@Override
protected DataSource createDataSource() {
- return new ZipArchiveDataSource(testDir, "foo.zip", "foo");
+ return new ZipArchiveDataSource(testDir, "foo.zip", "foo", null, null);
}
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new ZipArchiveDataSource(testDir, "foo", observer);
+ return new ZipArchiveDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.ZIP),
- Arguments.of("foo", CompressionFormat.ZIP),
- Arguments.of("foo.v3", CompressionFormat.ZIP)
+ Arguments.of("foo", "iidm", CompressionFormat.ZIP),
+ Arguments.of("foo", "", CompressionFormat.ZIP),
+ Arguments.of("foo", "v3", CompressionFormat.ZIP)
);
}
@@ -97,13 +103,13 @@ static Stream provideArgumentsForClassAndListingTest() {
Set listedFiles = Set.of("foo", "foo.txt", "foo.iidm", "foo.xiidm", "foo.v3.iidm", "foo.v3", "foo_bar.iidm", "foo_bar", "bar.iidm", "bar");
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "bar.iidm", "bar");
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.ZIP, ZipArchiveDataSource.class,
+ Arguments.of("foo", "iidm", CompressionFormat.ZIP, ZipArchiveDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", CompressionFormat.ZIP, ZipArchiveDataSource.class,
+ Arguments.of("foo", "", CompressionFormat.ZIP, ZipArchiveDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", CompressionFormat.ZIP, ZipArchiveDataSource.class,
+ Arguments.of("foo", "v3", CompressionFormat.ZIP, ZipArchiveDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/java/com/powsybl/commons/datasource/ZstdDirectoryDataSourceTest.java b/commons/src/test/java/com/powsybl/commons/datasource/ZstdDirectoryDataSourceTest.java
index 5d8cfbc67b5..c94f790e76f 100644
--- a/commons/src/test/java/com/powsybl/commons/datasource/ZstdDirectoryDataSourceTest.java
+++ b/commons/src/test/java/com/powsybl/commons/datasource/ZstdDirectoryDataSourceTest.java
@@ -36,12 +36,12 @@ void testConstructors() {
DataSourceObserver observer = new DefaultDataSourceObserver();
// Check constructors
- checkDataSource(new ZstdDirectoryDataSource(testDir, "foo_bar", observer), observer);
- checkDataSource(new ZstdDirectoryDataSource(testDir, "foo_bar"), null);
+ checkDataSource(new ZstdDirectoryDataSource(testDir, "foo_bar", "iidm", observer), observer);
}
private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver observer) {
assertEquals(testDir, dataSource.getDirectory());
+ assertEquals("iidm", dataSource.getDataExtension());
assertEquals(compressionFormat, dataSource.getCompressionFormat());
assertEquals("foo_bar", dataSource.getBaseName());
assertEquals(observer, dataSource.getObserver());
@@ -49,19 +49,19 @@ private void checkDataSource(DirectoryDataSource dataSource, DataSourceObserver
@Override
protected DataSource createDataSource() {
- return new ZstdDirectoryDataSource(testDir, "foo");
+ return new ZstdDirectoryDataSource(testDir, "foo", null, null);
}
@Override
protected DataSource createDataSource(DataSourceObserver observer) {
- return new ZstdDirectoryDataSource(testDir, "foo", observer);
+ return new ZstdDirectoryDataSource(testDir, "foo", "iidm", observer);
}
static Stream provideArgumentsForWriteThenReadTest() {
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.ZSTD),
- Arguments.of("foo", CompressionFormat.ZSTD),
- Arguments.of("foo.v3", CompressionFormat.ZSTD)
+ Arguments.of("foo", "iidm", CompressionFormat.ZSTD),
+ Arguments.of("foo", "", CompressionFormat.ZSTD),
+ Arguments.of("foo", "v3", CompressionFormat.ZSTD)
);
}
@@ -72,13 +72,13 @@ static Stream provideArgumentsForClassAndListingTest() {
"foo.gz", "foo.txt.gz", "foo.iidm.gz", "foo.xiidm.gz", "foo.v3.iidm.gz", "foo.v3.gz", "foo_bar.iidm.gz", "foo_bar.gz");
Set listedBarFiles = Set.of("foo_bar.iidm", "foo_bar", "foo_bar.iidm.bz2", "foo_bar.bz2", "foo_bar.iidm.xz", "foo_bar.xz", "foo_bar.iidm.gz", "foo_bar.gz");
return Stream.of(
- Arguments.of("foo.iidm", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
+ Arguments.of("foo", "iidm", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
+ Arguments.of("foo", "", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
listedFiles,
listedBarFiles),
- Arguments.of("foo.v3", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
+ Arguments.of("foo", "v3", CompressionFormat.ZSTD, ZstdDirectoryDataSource.class,
listedFiles,
listedBarFiles)
);
diff --git a/commons/src/test/resources/test/foo.bar b/commons/src/test/resources/test/foo.bar
new file mode 100644
index 00000000000..19102815663
--- /dev/null
+++ b/commons/src/test/resources/test/foo.bar
@@ -0,0 +1 @@
+foo
\ No newline at end of file
diff --git a/ieee-cdf/ieee-cdf-converter/src/main/java/com/powsybl/ieeecdf/converter/IeeeCdfImporter.java b/ieee-cdf/ieee-cdf-converter/src/main/java/com/powsybl/ieeecdf/converter/IeeeCdfImporter.java
index 0d410b6082e..9b24cd54af6 100644
--- a/ieee-cdf/ieee-cdf-converter/src/main/java/com/powsybl/ieeecdf/converter/IeeeCdfImporter.java
+++ b/ieee-cdf/ieee-cdf-converter/src/main/java/com/powsybl/ieeecdf/converter/IeeeCdfImporter.java
@@ -80,7 +80,7 @@ public String getComment() {
@Override
public boolean exists(ReadOnlyDataSource dataSource) {
try {
- if (dataSource.exists(null, EXT)) {
+ if (dataSource.isDataExtension(EXT) && dataSource.exists(null, EXT)) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(dataSource.newInputStream(null, EXT)))) {
String titleLine = reader.readLine();
if (titleLine != null) {
diff --git a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/MultipleImporterIssueTest.java b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/MultipleImporterIssueTest.java
new file mode 100644
index 00000000000..5b546d9bf1f
--- /dev/null
+++ b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/MultipleImporterIssueTest.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2022, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package com.powsybl.iidm.network;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import com.powsybl.commons.datasource.DataSourceUtil;
+import com.powsybl.commons.datasource.ReadOnlyDataSource;
+import com.powsybl.commons.report.ReportNode;
+import com.powsybl.computation.ComputationManager;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * @author Geoffroy Jamgotchian
+ */
+class MultipleImporterIssueTest {
+
+ static class FooImporter implements Importer {
+
+ @Override
+ public String getFormat() {
+ return "foo";
+ }
+
+ @Override
+ public String getComment() {
+ return "";
+ }
+
+ @Override
+ public boolean exists(ReadOnlyDataSource dataSource) {
+ try {
+ return dataSource.isDataExtension("foo") && dataSource.exists(null, "foo");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public Network importData(ReadOnlyDataSource dataSource, NetworkFactory networkFactory, Properties parameters, ReportNode reportNode) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static class BarImporter implements Importer {
+
+ @Override
+ public String getFormat() {
+ return "bar";
+ }
+
+ @Override
+ public String getComment() {
+ return "";
+ }
+
+ @Override
+ public boolean exists(ReadOnlyDataSource dataSource) {
+ try {
+ return dataSource.isDataExtension("bar") && dataSource.exists(null, "bar");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public Network importData(ReadOnlyDataSource dataSource, NetworkFactory networkFactory, Properties parameters, ReportNode reportNode) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Test
+ void test() throws IOException {
+ try (FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix())) {
+ Path workingDir = fileSystem.getPath("/work");
+ Path fooFile = workingDir.resolve("test.foo");
+ Path barFile = workingDir.resolve("test.bar");
+ Files.createFile(fooFile);
+ Files.createFile(barFile);
+
+ var dataSource = DataSourceUtil.createDataSource(workingDir, "test.bar", null);
+ ComputationManager computationManager = Mockito.mock(ComputationManager.class);
+ var importer = Importer.find(dataSource, new ImportersLoaderList(new FooImporter(), new BarImporter()), computationManager, new ImportConfig());
+ assertNotNull(importer);
+ assertInstanceOf(BarImporter.class, importer);
+ }
+ }
+}
diff --git a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java
index 1e36b7cc62c..21de23731e5 100644
--- a/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java
+++ b/iidm/iidm-api/src/test/java/com/powsybl/iidm/network/TestImporter.java
@@ -34,7 +34,7 @@ public String getComment() {
@Override
public boolean exists(ReadOnlyDataSource dataSource) {
try {
- return dataSource == null || dataSource.exists(null, "tst");
+ return dataSource == null || dataSource.isDataExtension("tst") && dataSource.exists(null, "tst");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
diff --git a/iidm/iidm-serde/pom.xml b/iidm/iidm-serde/pom.xml
index 0206f45cad9..0c29d3e1ec8 100644
--- a/iidm/iidm-serde/pom.xml
+++ b/iidm/iidm-serde/pom.xml
@@ -118,6 +118,12 @@
${project.version}
test
+
+ ${project.groupId}
+ powsybl-tools-test
+ ${project.version}
+ test
+
diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/AbstractTreeDataImporter.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/AbstractTreeDataImporter.java
index 621c93a5a43..9a41534cf25 100644
--- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/AbstractTreeDataImporter.java
+++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/AbstractTreeDataImporter.java
@@ -97,7 +97,7 @@ public List getParameters() {
private String findExtension(ReadOnlyDataSource dataSource) throws IOException {
for (String ext : getExtensions()) {
- if (dataSource.exists(null, ext)) {
+ if (dataSource.isDataExtension(ext) && dataSource.exists(null, ext)) {
return ext;
}
}
diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/BinaryImporter.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/BinaryImporter.java
index 27460f369d1..deb44113a06 100644
--- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/BinaryImporter.java
+++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/BinaryImporter.java
@@ -27,7 +27,7 @@
@AutoService(Importer.class)
public class BinaryImporter extends AbstractTreeDataImporter {
- private static final String[] EXTENSIONS = {"biidm", "bin", "iidm.bin"};
+ private static final String[] EXTENSIONS = {"biidm", "bin"};
@Override
protected String[] getExtensions() {
diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/JsonImporter.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/JsonImporter.java
index 92eda22af8a..25100ed9ca4 100644
--- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/JsonImporter.java
+++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/JsonImporter.java
@@ -28,7 +28,7 @@
@AutoService(Importer.class)
public class JsonImporter extends AbstractTreeDataImporter {
- private static final String[] EXTENSIONS = {"jiidm", "json", "iidm.json"};
+ private static final String[] EXTENSIONS = {"jiidm", "json"};
@Override
protected String[] getExtensions() {
diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/XMLImporter.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/XMLImporter.java
index 0d50956f6f0..f1910f38716 100644
--- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/XMLImporter.java
+++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/XMLImporter.java
@@ -34,7 +34,7 @@
public class XMLImporter extends AbstractTreeDataImporter {
private static final Logger LOGGER = LoggerFactory.getLogger(XMLImporter.class);
- private static final String[] EXTENSIONS = {"xiidm", "iidm", "xml", "iidm.xml"};
+ private static final String[] EXTENSIONS = {"xiidm", "iidm", "xml"};
private static final Supplier XML_INPUT_FACTORY_SUPPLIER = Suppliers.memoize(XMLInputFactory::newInstance);
diff --git a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/ConversionTest.java b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/ConversionTest.java
new file mode 100644
index 00000000000..d381a90e247
--- /dev/null
+++ b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/ConversionTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package com.powsybl.iidm.serde;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import com.powsybl.commons.config.InMemoryPlatformConfig;
+import com.powsybl.iidm.network.ImportConfig;
+import com.powsybl.iidm.network.tools.ConversionTool;
+import com.powsybl.tools.CommandLineTools;
+import com.powsybl.tools.test.AbstractToolTest;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Nicolas Rol {@literal }
+ */
+class ConversionTest {
+
+ protected FileSystem fileSystem;
+
+ protected InMemoryPlatformConfig platformConfig;
+
+ private CommandLineTools tools;
+
+ @BeforeEach
+ public void setUp() {
+ fileSystem = Jimfs.newFileSystem(Configuration.unix());
+ platformConfig = new InMemoryPlatformConfig(fileSystem);
+ tools = new CommandLineTools(Collections.singletonList(createConversionTool()));
+ }
+
+ private ConversionTool createConversionTool() {
+ return new ConversionTool() {
+
+ @Override
+ protected ImportConfig createImportConfig() {
+ return ImportConfig.load(platformConfig);
+ }
+ };
+ }
+
+ @Test
+ void testConversionZip() throws IOException {
+ // Prepare the firectory and file
+ Files.createDirectory(fileSystem.getPath("/tmp"));
+ Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/slackTerminal.xml")), fileSystem.getPath("/tmp/foo.xiidm"));
+
+ // Prepare the command
+ String[] commandLine = new String[] {
+ "convert-network",
+ "--input-file", "/tmp/foo.xiidm",
+ "--output-format", "XIIDM",
+ "--output-file", "/tmp/bar.zip"
+ };
+
+ // Assert the command is successful
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ByteArrayOutputStream berr = new ByteArrayOutputStream();
+ int status = AbstractToolTest.runCommand(commandLine, bout, berr, tools, fileSystem);
+
+ // Assert the command worked
+ assertEquals(0, status);
+ assertEquals("Generating file /tmp/bar.zip:bar.xiidm..." + System.lineSeparator(),
+ bout.toString(StandardCharsets.UTF_8));
+ assertEquals("", berr.toString(StandardCharsets.UTF_8));
+
+ // Assert the right files are created
+ Path zipFilePath = fileSystem.getPath("/tmp/bar.zip");
+ assertTrue(Files.isRegularFile(zipFilePath));
+ try (ZipFile zipFile = ZipFile.builder()
+ .setSeekableByteChannel(Files.newByteChannel(zipFilePath))
+ .get()) {
+ assertNotNull(zipFile.getEntry("bar.xiidm"));
+ } catch (IOException e) {
+ fail();
+ }
+ }
+}
diff --git a/matpower/matpower-converter/src/main/java/com/powsybl/matpower/converter/MatpowerImporter.java b/matpower/matpower-converter/src/main/java/com/powsybl/matpower/converter/MatpowerImporter.java
index 40ca6a38e3a..6f6c97274c7 100644
--- a/matpower/matpower-converter/src/main/java/com/powsybl/matpower/converter/MatpowerImporter.java
+++ b/matpower/matpower-converter/src/main/java/com/powsybl/matpower/converter/MatpowerImporter.java
@@ -516,7 +516,7 @@ private static boolean reactiveLimitsAreOk(double minQ, double maxQ) {
@Override
public boolean exists(ReadOnlyDataSource dataSource) {
try {
- return dataSource.exists(null, MatpowerConstants.EXT);
+ return dataSource.isDataExtension(MatpowerConstants.EXT) && dataSource.exists(null, MatpowerConstants.EXT);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
diff --git a/powerfactory/powerfactory-converter/src/main/java/com/powsybl/powerfactory/converter/PowerFactoryImporter.java b/powerfactory/powerfactory-converter/src/main/java/com/powsybl/powerfactory/converter/PowerFactoryImporter.java
index c3aaf1b2bf7..5b20a9d0269 100644
--- a/powerfactory/powerfactory-converter/src/main/java/com/powsybl/powerfactory/converter/PowerFactoryImporter.java
+++ b/powerfactory/powerfactory-converter/src/main/java/com/powsybl/powerfactory/converter/PowerFactoryImporter.java
@@ -64,7 +64,7 @@ public String getComment() {
private Optional> findProjectLoader(ReadOnlyDataSource dataSource) {
for (PowerFactoryDataLoader studyCaseLoader : PowerFactoryDataLoader.find(StudyCase.class)) {
try {
- if (dataSource.exists(null, studyCaseLoader.getExtension())) {
+ if (dataSource.isDataExtension(studyCaseLoader.getExtension()) && dataSource.exists(null, studyCaseLoader.getExtension())) {
return Optional.of(studyCaseLoader);
}
} catch (IOException e) {
diff --git a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java
index ef1fecaeec0..b256104154d 100644
--- a/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java
+++ b/psse/psse-converter/src/main/java/com/powsybl/psse/converter/PsseImporter.java
@@ -83,7 +83,7 @@ public boolean exists(ReadOnlyDataSource dataSource) {
private String findExtension(ReadOnlyDataSource dataSource) throws IOException {
for (String ext : EXTENSIONS) {
- if (dataSource.exists(null, ext)) {
+ if (dataSource.isDataExtension(ext) && dataSource.exists(null, ext)) {
return ext;
}
}
diff --git a/tools-test/src/main/java/com/powsybl/tools/test/AbstractToolTest.java b/tools-test/src/main/java/com/powsybl/tools/test/AbstractToolTest.java
index 6ff033accef..5b3a37d8cf6 100644
--- a/tools-test/src/main/java/com/powsybl/tools/test/AbstractToolTest.java
+++ b/tools-test/src/main/java/com/powsybl/tools/test/AbstractToolTest.java
@@ -137,6 +137,17 @@ protected void assertCommandMatchTextOrRegex(String[] args, int expectedStatus,
private void assertCommand(String[] args, int expectedStatus, String expectedOut, String expectedErr, BiConsumer comparisonFunction) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ByteArrayOutputStream berr = new ByteArrayOutputStream();
+ int status = runCommand(args, bout, berr, tools, fileSystem);
+ assertEquals(expectedStatus, status);
+ if (expectedOut != null) {
+ assertMatches(expectedOut, bout, comparisonFunction);
+ }
+ if (expectedErr != null) {
+ assertMatches(expectedErr, berr, comparisonFunction);
+ }
+ }
+
+ public static int runCommand(String[] args, ByteArrayOutputStream bout, ByteArrayOutputStream berr, CommandLineTools tools, FileSystem fileSystem) {
int status;
try (PrintStream out = new PrintStream(bout);
PrintStream err = new PrintStream(berr);
@@ -173,13 +184,7 @@ public ComputationManager createLongTimeExecutionComputationManager(CommandLine
}
});
}
- assertEquals(expectedStatus, status);
- if (expectedOut != null) {
- assertMatches(expectedOut, bout, comparisonFunction);
- }
- if (expectedErr != null) {
- assertMatches(expectedErr, berr, comparisonFunction);
- }
+ return status;
}
@Test
diff --git a/ucte/ucte-converter/src/main/java/com/powsybl/ucte/converter/UcteImporter.java b/ucte/ucte-converter/src/main/java/com/powsybl/ucte/converter/UcteImporter.java
index 2f9db7339ca..edb2e9b4445 100644
--- a/ucte/ucte-converter/src/main/java/com/powsybl/ucte/converter/UcteImporter.java
+++ b/ucte/ucte-converter/src/main/java/com/powsybl/ucte/converter/UcteImporter.java
@@ -951,7 +951,7 @@ public List getParameters() {
private String findExtension(ReadOnlyDataSource dataSource, boolean throwException) throws IOException {
for (String ext : EXTENSIONS) {
- if (dataSource.exists(null, ext)) {
+ if (dataSource.isDataExtension(ext) && dataSource.exists(null, ext)) {
return ext;
}
}