diff --git a/docs/readthedocs/io/csvfiles.rst b/docs/readthedocs/io/csvfiles.rst index bd4efe103..a3b9f251d 100644 --- a/docs/readthedocs/io/csvfiles.rst +++ b/docs/readthedocs/io/csvfiles.rst @@ -4,25 +4,25 @@ csv files Naming of files =============== -A naming strategy provides a mapping between model classes and the file names, in which the serialized representation of -several objects of this class can be found. -Currently we offer two different, pre-defined file naming strategies, which you might extend to fit your needs: +A naming strategy provides a mapping between model classes and the human readable names of those entities to be used +within e.g. the data sinks, in which the serialized representation of several objects of this class can be found. +Currently we offer two different, pre-defined naming strategies, which you might extend to fit your needs: -1. **FileNamingStrategy**: - A basic file naming strategy that is able to add prefix and suffix to the file names. A flat folder structure is - considered. For more details see `Default naming strategy`_. +1. **EntityPersistenceNamingStrategy**: + A basic naming strategy that is able to add prefix and suffix to the names of the entities. A flat folder structure + is considered. For more details see `Default naming strategy`_. 2. **HierarchicFileNamingStrategy**: - An extended version of the FileNamingStrategy. Additionally, the `Default directory hierarchy`_ is taken into - account. Please note, that this directory hierarchy is only meant to be used in conjunction with input models. + An extended version of the EntityPersistenceNamingStrategy. Additionally, the `Default directory hierarchy`_ is taken + into account. Please note, that this directory hierarchy is only meant to be used in conjunction with input models. However, you can control the behaviour of serialization and de-serialization of models by injecting the desired naming strategy you like into :code:`CsvDataSource` and :code:`CsvFileSink`. Default naming strategy ======================= -There is a default mapping from model class to file naming in the case you would like to use csv files for +There is a default mapping from model class to naming of entities in the case you would like to use csv files for (de-)serialization of models. -You may extend / alter the naming with pre- or suffix by calling :code:`new FileNamingStrategy("prefix", "suffix")`. +You may extend / alter the naming with pre- or suffix by calling :code:`new EntityPersistenceNamingStrategy("prefix","suffix")`. Input ----- @@ -224,7 +224,7 @@ An application example to load an *exampleGrid* from csv files located in :code: String gridName = "exampleGrid"; String csvSep = ","; String folderPath = "./exampleGrid"; - FileNamingStrategy namingStrategy = new FileNamingStrategy(); // Default naming strategy + EntityPersistenceNamingStrategy namingStrategy = new EntityPersistenceNamingStrategy(); // Default naming strategy /* Instantiating sources */ TypeSource typeSource = new CsvTypeSource(csvSep, folderPath, namingStrategy); @@ -273,7 +273,7 @@ Serializing models is a bit easier: /* Parameterization */ String csvSep = ","; String folderPath = "./exampleGrid"; - FileNamingStrategy namingStrategy = new FileNamingStrategy(); + EntityPersistenceNamingStrategy namingStrategy = new EntityPersistenceNamingStrategy(); boolean initEmptyFiles = false; /* Instantiating the sink */ diff --git a/docs/uml/main/DataSinkClassDiagram.puml b/docs/uml/main/DataSinkClassDiagram.puml index 795861c33..e7e3531f2 100644 --- a/docs/uml/main/DataSinkClassDiagram.puml +++ b/docs/uml/main/DataSinkClassDiagram.puml @@ -20,10 +20,10 @@ OutputDataSink --|> DataSink ' Implementations class CsvFileSink { -+ CsvFileSink(String, ProcessorProvider, FileNamingStrategy, boolean, String) -+ CsvFileSink(String, FileNamingStrategy, boolean, String) ++ CsvFileSink(String, ProcessorProvider, EntityPersistenceNamingStrategy, boolean, String) ++ CsvFileSink(String, EntityPersistenceNamingStrategy, boolean, String) + CsvFileSink(String) -- void initFiles(ProcessorProvider, FileNamingStrategy) +- void initFiles(ProcessorProvider, EntityPersistenceNamingStrategy) - void write(UniqueEntity) } CsvFileSink ..|> InputDataSink @@ -31,7 +31,7 @@ CsvFileSink ..|> OutputDataSink class InfluxDBFileSink { -+ InfluxDbSink(InfluxDbConnector, FileNamingStrategy) ++ InfluxDbSink(InfluxDbConnector, EntityPersistenceNamingStrategy) + InfluxDbSink(InfluxDbConnector) - Set extractPoints(UniqueEntity) - String transformToMeasurementName(String) diff --git a/docs/uml/main/DataSourceClassDiagram.puml b/docs/uml/main/DataSourceClassDiagram.puml index 21bdb36b8..77a8e2976 100644 --- a/docs/uml/main/DataSourceClassDiagram.puml +++ b/docs/uml/main/DataSourceClassDiagram.puml @@ -111,7 +111,7 @@ DataSource <|-- TimeSeriesSource class CsvTimeSeriesSource { - IndividualTimeSeries timeSeries - + {static} CsvTimeSeriesSource getSource(\n\tString,\n\tString,\n\tFileNamingStrategy,\n\tsvFileConnector.CsvIndividualTimeSeriesMetaInformation) + + {static} CsvTimeSeriesSource getSource(\n\tString,\n\tString,\n\tEntityPersistenceNamingStrategy,\n\tCsvFileConnector.CsvIndividualTimeSeriesMetaInformation) - IndividualTimeSeries buildIndividualTimeSeries(\n\tUUID,\n\tfilePath,\n\tFunction,\n\tOptional>>) - Optional> buildTimeBasedValue(\n\tMap,\n\tClass,\n\tTimeBasedSimpleValueFactory) } @@ -127,7 +127,7 @@ interface DataConnector { Abstract Class CsvDataSource { - String csvSep # CsvFileConnector connector - + CsvDataSource(String, String, FileNamingStrategy) + + CsvDataSource(String, String, EntityPersistenceNamingStrategy) } DataSource <|.. CsvDataSource @@ -137,7 +137,7 @@ Class CsvTypeSource { - LineTypeInputFactory lineTypeInputFactory - Transformer3WTypeInputFactory transformer3WTypeInputFactory - SystemParticipantTypeInputFactory systemParticipantTypeInputFactory - + CsvTypeSource(String, String, FileNamingStrategy) + + CsvTypeSource(String, String, EntityPersistenceNamingStrategy) } TypeSource <|.. CsvTypeSource CsvDataSource <|-- CsvTypeSource @@ -147,7 +147,7 @@ Class CsvThermalSource { - ThermalBusInputFactory thermalBusInputFactory - CylindricalStorageInputFactory cylindricalStorageInputFactory - ThermalHouseInputFactory thermalHouseInputFactory - + CsvThermalSource(String, String, FileNamingStrategy, TypeSource) + + CsvThermalSource(String, String, EntityPersistenceNamingStrategy, TypeSource) } ThermalSource <|.. CsvThermalSource CsvDataSource <|-- CsvThermalSource @@ -160,7 +160,7 @@ Class CsvRawGridSource { - Transformer3WInputFactory transformer3WInputFactory - SwitchInputFactory switchInputFactory - MeasurementUnitInputFactory measurementUnitInputFactory - + CsvRawGridSource(String, String, FileNamingStrategy, TypeSource) + + CsvRawGridSource(String, String, EntityPersistenceNamingStrategy, TypeSource) } RawGridSource <|.. CsvRawGridSource CsvDataSource <|-- CsvRawGridSource @@ -179,7 +179,7 @@ Class CsvSystemParticipantSource { - StorageInputFactory storageInputFactory - WecInputFactory wecInputFactory - EvcsInputFactory evcsInputFactory - + CsvSystemParticipantSource(String, String, FileNamingStrategy, TypeSource, ThermalSource, RawGridSource) + + CsvSystemParticipantSource(String, String, EntityPersistenceNamingStrategy, TypeSource, ThermalSource, RawGridSource) } SystemParticipantSource <|.. CsvSystemParticipantSource CsvDataSource <|-- CsvSystemParticipantSource @@ -189,7 +189,7 @@ Class CsvGraphicSource { - RawGridSource rawGridSource - LineGraphicInputFactory lineGraphicInputFactory - NodeGraphicInputFactory nodeGraphicInputFactory - + CsvGraphicSource(String, String, FileNamingStrategy, TypeSource, RawGridSource) + + CsvGraphicSource(String, String, EntityPersistenceNamingStrategy, TypeSource, RawGridSource) } GraphicSource <|.. CsvGraphicSource CsvDataSource <|-- CsvGraphicSource @@ -197,10 +197,10 @@ CsvDataSource <|-- CsvGraphicSource Class CsvFileConnector { - Map, BufferedCsvWriter> entityWriters - Map timeSeriesWriters - - FileNamingStrategy fileNamingStrategy + - EntityPersistenceNamingStrategy entityPersistenceNamingStrategy - String baseDirectoryName - {static} String FILE_ENDING - + CsvFileConnector(String, FileNamingStrategy) + + CsvFileConnector(String, EntityPersistenceNamingStrategy) + BufferedCsvWriter getOrInitWriter(Class, String[], String) + BufferedCsvWriter getOrInitWriter(T, String[], String) + BufferedCsvWriter initWriter(String, CsvFileDefinition) diff --git a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java index b84583b45..a63fceb05 100644 --- a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java +++ b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java @@ -9,6 +9,7 @@ import edu.ie3.datamodel.io.csv.*; import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.timeseries.TimeSeries; import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry; @@ -40,7 +41,7 @@ public class CsvFileConnector implements DataConnector { private final Map timeSeriesWriters = new HashMap<>(); // ATTENTION: Do not finalize. It's meant for lazy evaluation. private Map individualTimeSeriesMetaInformation; - private final FileNamingStrategy fileNamingStrategy; + private final EntityPersistenceNamingStrategy entityPersistenceNamingStrategy; private final String baseDirectoryName; private static final String FILE_ENDING = ".csv"; @@ -48,9 +49,10 @@ public class CsvFileConnector implements DataConnector { private static final String FILE_SEPARATOR_REPLACEMENT = File.separator.equals("\\") ? "\\\\" : "/"; - public CsvFileConnector(String baseDirectoryName, FileNamingStrategy fileNamingStrategy) { + public CsvFileConnector( + String baseDirectoryName, EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { this.baseDirectoryName = baseDirectoryName; - this.fileNamingStrategy = fileNamingStrategy; + this.entityPersistenceNamingStrategy = entityPersistenceNamingStrategy; } public synchronized BufferedCsvWriter getOrInitWriter( @@ -136,7 +138,8 @@ private BufferedCsvWriter initWriter(String baseDirectory, CsvFileDefinition fil /** * Initializes a file reader for the given class that should be read in. The expected file name is - * determined based on {@link FileNamingStrategy} of the this {@link CsvFileConnector} instance + * determined based on {@link EntityPersistenceNamingStrategy} of the this {@link + * CsvFileConnector} instance * * @param clz the class of the entity that should be read * @return the reader that contains information about the file to be read in @@ -146,7 +149,7 @@ public BufferedReader initReader(Class clz) throws FileN String filePath = null; try { filePath = - fileNamingStrategy + entityPersistenceNamingStrategy .getFilePath(clz) .orElseThrow( () -> @@ -209,7 +212,8 @@ public Optional getIndividualTimeSeriesMeta String filePathWithoutEnding = removeFileEnding(filePath); IndividualTimeSeriesMetaInformation metaInformation = (IndividualTimeSeriesMetaInformation) - fileNamingStrategy.extractTimeSeriesMetaInformation(filePathWithoutEnding); + entityPersistenceNamingStrategy.extractTimeSeriesMetaInformation( + filePathWithoutEnding); return new CsvIndividualTimeSeriesMetaInformation( metaInformation, filePathWithoutEnding); }) @@ -249,7 +253,7 @@ public Map> initTimeSeriesReader( * @throws FileNotFoundException If the file is not present */ public BufferedReader initIdCoordinateReader() throws FileNotFoundException { - String filePath = fileNamingStrategy.getIdCoordinateFileName(); + String filePath = entityPersistenceNamingStrategy.getIdCoordinateEntityName(); return initReader(filePath); } @@ -267,7 +271,7 @@ private Set getIndividualTimeSeriesFilePaths() { .filter( path -> { String withoutEnding = removeFileEnding(path.toString()); - return fileNamingStrategy + return entityPersistenceNamingStrategy .getIndividualTimeSeriesPattern() .matcher(withoutEnding) .matches(); @@ -297,7 +301,7 @@ private Optional buildReadingData( String filePathString, ColumnScheme... columnSchemes) { try { FileNameMetaInformation metaInformation = - fileNamingStrategy.extractTimeSeriesMetaInformation(filePathString); + entityPersistenceNamingStrategy.extractTimeSeriesMetaInformation(filePathString); if (!IndividualTimeSeriesMetaInformation.class.isAssignableFrom(metaInformation.getClass())) { log.error( "The time series file '{}' does not represent an individual time series.", @@ -359,10 +363,10 @@ private String removeFileEnding(String input) { private , E extends TimeSeriesEntry, V extends Value> CsvFileDefinition buildFileDefinition(T timeSeries, String[] headLineElements, String csvSep) throws ConnectorException { - String directoryPath = fileNamingStrategy.getDirectoryPath(timeSeries).orElse(""); + String directoryPath = entityPersistenceNamingStrategy.getDirectoryPath(timeSeries).orElse(""); String fileName = - fileNamingStrategy - .getFileName(timeSeries) + entityPersistenceNamingStrategy + .getEntityName(timeSeries) .orElseThrow( () -> new ConnectorException( @@ -382,10 +386,10 @@ CsvFileDefinition buildFileDefinition(T timeSeries, String[] headLineElements, S private CsvFileDefinition buildFileDefinition( Class clz, String[] headLineElements, String csvSep) throws ConnectorException { - String directoryPath = fileNamingStrategy.getDirectoryPath(clz).orElse(""); + String directoryPath = entityPersistenceNamingStrategy.getDirectoryPath(clz).orElse(""); String fileName = - fileNamingStrategy - .getFileName(clz) + entityPersistenceNamingStrategy + .getEntityName(clz) .orElseThrow( () -> new ConnectorException( diff --git a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java index 585f53061..ec58a13da 100644 --- a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java @@ -8,6 +8,8 @@ import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation; import edu.ie3.datamodel.io.csv.timeseries.LoadProfileTimeSeriesMetaInformation; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; +import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy; import edu.ie3.datamodel.io.source.TimeSeriesMappingSource; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; @@ -39,7 +41,9 @@ * * @version 0.1 * @since 03.02.20 + * @deprecated replaced by {@link EntityPersistenceNamingStrategy} */ +@Deprecated public class FileNamingStrategy { protected static final Logger logger = LogManager.getLogger(FileNamingStrategy.class); @@ -118,6 +122,15 @@ public FileNamingStrategy(String prefix) { this(prefix, ""); } + /** + * Create a {@link EntityPersistenceNamingStrategy} from a {@link FileNamingStrategy} + * + * @return an instance of {@link EntityPersistenceNamingStrategy} + */ + public EntityPersistenceNamingStrategy asEntityPersistenceNamingStrategy() { + return new EntityPersistenceNamingStrategy(this.prefix, this.suffix); + } + /** * Prepares the prefix by appending an underscore and bringing it to lower case * diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java new file mode 100644 index 000000000..e1211de2a --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -0,0 +1,519 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.io.naming; + +import edu.ie3.datamodel.io.csv.FileNameMetaInformation; +import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; +import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation; +import edu.ie3.datamodel.io.csv.timeseries.LoadProfileTimeSeriesMetaInformation; +import edu.ie3.datamodel.io.source.TimeSeriesMappingSource; +import edu.ie3.datamodel.models.UniqueEntity; +import edu.ie3.datamodel.models.input.*; +import edu.ie3.datamodel.models.input.graphics.GraphicInput; +import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicInput; +import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.timeseries.TimeSeries; +import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry; +import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; +import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput; +import edu.ie3.datamodel.models.value.*; +import edu.ie3.util.StringUtils; +import java.nio.file.Path; +import java.util.Optional; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.io.FilenameUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Provides an easy to use standard way to name files, tables or any other persistent representation + * of models. Normal use cases are e.g., I/O operations with .csv files or databases. If a folder + * structure is required for file based I/O operations, one might consider using {@link + * HierarchicFileNamingStrategy} + * + * @version 0.1 + * @since 03.02.20 + */ +public class EntityPersistenceNamingStrategy { + + protected static final Logger logger = + LogManager.getLogger(EntityPersistenceNamingStrategy.class); + + private static final String UUID_STRING = + "[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}"; + /** + * Regex to match the naming convention of a file for an individual time series. The column scheme + * is accessible via the named capturing group "columnScheme". The time series' UUID is accessible + * by the named capturing group "uuid" + */ + private static final Pattern INDIVIDUAL_TIME_SERIES_PATTERN = + Pattern.compile("its_(?[a-zA-Z]{1,11})_(?" + UUID_STRING + ")"); + + /** + * Pattern to identify individual time series in this instance of the naming strategy (takes care + * of prefix and suffix) + */ + protected final Pattern individualTimeSeriesPattern; + + /** + * Regex to match the naming convention of a file for a repetitive load profile time series. The + * profile is accessible via the named capturing group "profile", the uuid by the group "uuid" + */ + private static final Pattern LOAD_PROFILE_TIME_SERIES = + Pattern.compile("lpts_(?[a-zA-Z][0-9])_(?" + UUID_STRING + ")"); + + /** + * Pattern to identify load profile time series in this instance of the naming strategy (takes + * care of prefix and suffix) + */ + protected final Pattern loadProfileTimeSeriesPattern; + + private static final String RES_ENTITY_SUFFIX = "_res"; + + private final String prefix; + private final String suffix; + + /** + * Constructor for building the names of the data sinks without provided entities with prefix and + * suffix + */ + public EntityPersistenceNamingStrategy() { + this("", ""); + } + + /** + * Constructor for building the names of the data sinks + * + * @param prefix Prefix of the data sinks + */ + public EntityPersistenceNamingStrategy(String prefix) { + this(prefix, ""); + } + + /** + * Constructor for building the names of the data sinks + * + * @param prefix Prefix of the data sinks + * @param suffix Suffixes of the data sinks + */ + public EntityPersistenceNamingStrategy(String prefix, String suffix) { + this.prefix = preparePrefix(prefix); + this.suffix = prepareSuffix(suffix); + + this.individualTimeSeriesPattern = + Pattern.compile( + prefix + + (prefix.isEmpty() ? "" : "_") + + INDIVIDUAL_TIME_SERIES_PATTERN.pattern() + + (suffix.isEmpty() ? "" : "_") + + suffix); + this.loadProfileTimeSeriesPattern = + Pattern.compile( + prefix + + (prefix.isEmpty() ? "" : "_") + + LOAD_PROFILE_TIME_SERIES.pattern() + + (suffix.isEmpty() ? "" : "_") + + suffix); + } + + public Pattern getLoadProfileTimeSeriesPattern() { + return loadProfileTimeSeriesPattern; + } + + public Pattern getIndividualTimeSeriesPattern() { + return individualTimeSeriesPattern; + } + + /** + * Prepares the prefix by appending an underscore and bringing it to lower case + * + * @param prefix Intended prefix + * @return Prefix with trailing underscore + */ + private static String preparePrefix(String prefix) { + return StringUtils.cleanString(prefix).replaceAll("([^_])$", "$1_").toLowerCase(); + } + + /** + * Prepares the suffix by prepending an underscore and bringing it to lower case + * + * @param suffix Intended suffix + * @return Suffix with trailing leading + */ + private static String prepareSuffix(String suffix) { + return StringUtils.cleanString(suffix).replaceAll("^([^_])", "_$1").toLowerCase(); + } + + /** + * Get the full path to the file with regard to some (not explicitly specified) base directory. + * The path does NOT start or end with any of the known file separators or file extension. + * + * @param cls Targeted class of the given file + * @return An optional sub path to the actual file + * @deprecated This class should foremost provide namings for the entities and nothing around file + * naming or pathing in specific. This method will be moved from this class, when this issue is + * addressed + */ + @Deprecated + public Optional getFilePath(Class cls) { + // do not adapt orElseGet, see https://www.baeldung.com/java-optional-or-else-vs-or-else-get for + // details + return getFilePath( + getEntityName(cls).orElseGet(() -> ""), getDirectoryPath(cls).orElseGet(() -> "")); + } + + /** + * Compose a full file path from directory name and file name. Additionally perform some checks, + * like if the file name itself actually is available + * + * @param fileName File name + * @param subDirectories Sub directory path + * @return Concatenation of sub directory structure and file name + * @deprecated This class should foremost provide namings for the entities and nothing around file + * naming or pathing in specific. This method will be moved from this class, when this issue is + * addressed + */ + @Deprecated + private Optional getFilePath(String fileName, String subDirectories) { + if (fileName.isEmpty()) return Optional.empty(); + if (!subDirectories.isEmpty()) + return Optional.of(FilenameUtils.concat(subDirectories, fileName)); + else return Optional.of(fileName); + } + + /** + * Returns the name of the entity, that should be used for persistence. + * + * @param cls Targeted class of the given file + * @return The name of the entity + */ + public Optional getEntityName(Class cls) { + if (InputEntity.class.isAssignableFrom(cls)) + return getInputEntityName(cls.asSubclass(InputEntity.class)); + if (ResultEntity.class.isAssignableFrom(cls)) + return getResultEntityName(cls.asSubclass(ResultEntity.class)); + logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); + return Optional.empty(); + } + + /** + * Get the name for all {@link InputEntity}s + * + * @param cls Targeted class of the given entity + * @return The entity name + */ + public Optional getInputEntityName(Class cls) { + if (AssetTypeInput.class.isAssignableFrom(cls)) + return getTypeEntityName(cls.asSubclass(AssetTypeInput.class)); + if (AssetInput.class.isAssignableFrom(cls)) + return getAssetInputEntityName(cls.asSubclass(AssetInput.class)); + if (RandomLoadParameters.class.isAssignableFrom(cls)) { + String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); + return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); + } + if (GraphicInput.class.isAssignableFrom(cls)) + return getGraphicsInputEntityName(cls.asSubclass(GraphicInput.class)); + if (OperatorInput.class.isAssignableFrom(cls)) + return getOperatorInputEntityName(cls.asSubclass(OperatorInput.class)); + if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) + return getTimeSeriesMappingEntityName(); + logger.error("The class '{}' is not covered for input entity naming.", cls); + return Optional.empty(); + } + + /** + * Get the entity name for all {@link ResultEntity}s + * + * @param resultEntityClass the result entity class an entity name string should be generated from + * @return the entity name string + */ + public Optional getResultEntityName(Class resultEntityClass) { + String resultEntityString = + camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); + return Optional.of(addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX))); + } + + /** + * Get the entity name for all {@link AssetTypeInput}s + * + * @param typeClass the asset type class an entity name string should be generated from + * @return the entity name string + */ + public Optional getTypeEntityName(Class typeClass) { + String assetTypeString = camelCaseToSnakeCase(typeClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetTypeString)); + } + + /** + * Get the entity name for all {@link AssetInput}s + * + * @param assetInputClass the asset input class an entity name string should be generated from + * @return the entity name string + */ + public Optional getAssetInputEntityName(Class assetInputClass) { + String assetInputString = camelCaseToSnakeCase(assetInputClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the entity name for all {@link CharacteristicInput}s + * + * @param assetCharClass the asset characteristics class an entity name string should be generated + * from + * @return the entity name string + */ + public Optional getAssetCharacteristicsEntityName( + Class assetCharClass) { + String assetCharString = camelCaseToSnakeCase(assetCharClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetCharString)); + } + + /** + * Converts a given camel case string to its snake case representation + * + * @param camelCaseString the camel case string + * @return the resulting snake case representation + */ + private String camelCaseToSnakeCase(String camelCaseString) { + String snakeCaseReplacement = "$1_$2"; + /* Separate all lower case letters, that are followed by a capital or a digit by underscore */ + String regularCamelCaseRegex = "([a-z])([A-Z0-9]+)"; + /* Separate all digits, that are followed by a letter by underscore */ + String numberLetterCamelCaseRegex = "([0-9])([a-zA-Z]+)"; + /* Separate two or more capitals, that are not at the beginning of the string by underscore */ + String specialCamelCaseRegex = "((? getGraphicsInputEntityName(Class graphicClass) { + String assetInputString = camelCaseToSnakeCase(graphicClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the entity name for all {@link OperatorInput}s + * + * @param operatorClass the asset input class an entity name string should be generated from + * @return the entity name string + */ + public Optional getOperatorInputEntityName(Class operatorClass) { + String assetInputString = camelCaseToSnakeCase(operatorClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the entity name for time series mapping + * + * @return The entity name string + */ + public Optional getTimeSeriesMappingEntityName() { + return Optional.of(addPrefixAndSuffix("time_series_mapping")); + } + + /** + * Returns the sub directory structure with regard to some (not explicitly specified) base + * directory. The path does NOT start or end with any of the known file separators. + * + * @param cls Targeted class of the given file + * @return An optional sub directory path + */ + public Optional getDirectoryPath(Class cls) { + return Optional.empty(); + } + + /** + * Get the full path to the file with regard to some (not explicitly specified) base directory. + * The path does NOT start or end with any of the known file separators or file extension. + * + * @param Type of the time series + * @param Type of the entry in the time series + * @param Type of the value, that is carried by the time series entry + * @param timeSeries Time series to derive naming information from + * @return An optional sub path to the actual file + */ + public , E extends TimeSeriesEntry, V extends Value> + Optional getFilePath(T timeSeries) { + // do not adapt orElseGet, see https://www.baeldung.com/java-optional-or-else-vs-or-else-get for + // details + return getFilePath( + getEntityName(timeSeries).orElseGet(() -> ""), + getDirectoryPath(timeSeries).orElseGet(() -> "")); + } + + /** + * Builds a file name (and only the file name without any directories and extension) of the given + * information. + * + * @param Type of the time series + * @param Type of the entry in the time series + * @param Type of the value, that is carried by the time series entry + * @param timeSeries Time series to derive naming information from + * @return A file name for this particular time series + */ + public , E extends TimeSeriesEntry, V extends Value> + Optional getEntityName(T timeSeries) { + if (timeSeries instanceof IndividualTimeSeries) { + Optional maybeFirstElement = timeSeries.getEntries().stream().findFirst(); + if (maybeFirstElement.isPresent()) { + Class valueClass = maybeFirstElement.get().getValue().getClass(); + Optional mayBeColumnScheme = ColumnScheme.parse(valueClass); + if (mayBeColumnScheme.isPresent()) { + return Optional.of( + prefix + .concat("its") + .concat("_") + .concat(mayBeColumnScheme.get().getScheme()) + .concat("_") + .concat(timeSeries.getUuid().toString()) + .concat(suffix)); + } else { + logger.error("Unsupported content of time series {}", timeSeries); + return Optional.empty(); + } + } else { + logger.error("Unable to determine content of time series {}", timeSeries); + return Optional.empty(); + } + } else if (timeSeries instanceof LoadProfileInput) { + LoadProfileInput loadProfileInput = (LoadProfileInput) timeSeries; + return Optional.of( + prefix + .concat("lpts") + .concat("_") + .concat(loadProfileInput.getType().getKey()) + .concat("_") + .concat(loadProfileInput.getUuid().toString()) + .concat(suffix)); + } else { + logger.error("There is no naming strategy defined for {}", timeSeries); + return Optional.empty(); + } + } + + /** + * Returns the sub directory structure with regard to some (not explicitly specified) base + * directory. The path does NOT start or end with any of the known file separators. + * + * @param Type of the time series + * @param Type of the entry in the time series + * @param Type of the value, that is carried by the time series entry + * @param timeSeries Time series to derive naming information from + * @return An optional sub directory path + */ + public , E extends TimeSeriesEntry, V extends Value> + Optional getDirectoryPath(T timeSeries) { + return Optional.empty(); + } + + /** + * Extracts meta information from a file name, of a time series. + * + * @param path Path to the file + * @return The meeting meta information + */ + public FileNameMetaInformation extractTimeSeriesMetaInformation(Path path) { + /* Extract file name from possibly fully qualified path */ + Path fileName = path.getFileName(); + if (fileName == null) + throw new IllegalArgumentException("Unable to extract file name from path '" + path + "'."); + return extractTimeSeriesMetaInformation(fileName.toString()); + } + + /** + * Extracts meta information from a file name, of a time series. Here, a file name without + * leading path has to be provided + * + * @param fileName File name + * @return The meeting meta information + */ + public FileNameMetaInformation extractTimeSeriesMetaInformation(String fileName) { + /* Remove the file ending (ending limited to 255 chars, which is the max file name allowed in NTFS and ext4) */ + String withoutEnding = fileName.replaceAll("(?:\\.[^\\\\/\\s]{1,255}){1,2}$", ""); + + if (individualTimeSeriesPattern.matcher(withoutEnding).matches()) + return extractIndividualTimesSeriesMetaInformation(withoutEnding); + else if (loadProfileTimeSeriesPattern.matcher(withoutEnding).matches()) + return extractLoadProfileTimesSeriesMetaInformation(withoutEnding); + else + throw new IllegalArgumentException( + "Unknown format of '" + fileName + "'. Cannot extract meta information."); + } + + /** + * Extracts meta information from a valid file name for a individual time series + * + * @param fileName File name to extract information from + * @return Meta information form individual time series file name + */ + private IndividualTimeSeriesMetaInformation extractIndividualTimesSeriesMetaInformation( + String fileName) { + Matcher matcher = individualTimeSeriesPattern.matcher(fileName); + if (!matcher.matches()) + throw new IllegalArgumentException( + "Cannot extract meta information on individual time series from '" + fileName + "'."); + + String columnSchemeKey = matcher.group("columnScheme"); + ColumnScheme columnScheme = + ColumnScheme.parse(columnSchemeKey) + .orElseThrow( + () -> + new IllegalArgumentException( + "Cannot parse '" + columnSchemeKey + "' to valid column scheme.")); + + return new IndividualTimeSeriesMetaInformation( + UUID.fromString(matcher.group("uuid")), columnScheme); + } + + /** + * Extracts meta information from a valid file name for a load profile time series + * + * @param fileName File name to extract information from + * @return Meta information form load profile time series file name + */ + private LoadProfileTimeSeriesMetaInformation extractLoadProfileTimesSeriesMetaInformation( + String fileName) { + Matcher matcher = loadProfileTimeSeriesPattern.matcher(fileName); + if (!matcher.matches()) + throw new IllegalArgumentException( + "Cannot extract meta information on load profile time series from '" + fileName + "'."); + + return new LoadProfileTimeSeriesMetaInformation( + UUID.fromString(matcher.group("uuid")), matcher.group("profile")); + } + + /** + * Get the entity name for coordinates + * + * @return the entity name string + */ + public String getIdCoordinateEntityName() { + return addPrefixAndSuffix("coordinates"); + } +} diff --git a/src/main/java/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java similarity index 92% rename from src/main/java/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategy.java rename to src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java index 15ab0fbdd..5df0b2927 100644 --- a/src/main/java/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java @@ -3,8 +3,10 @@ * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ -package edu.ie3.datamodel.io.csv; +package edu.ie3.datamodel.io.naming; +import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy; +import edu.ie3.datamodel.io.csv.FileHierarchy; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.timeseries.TimeSeries; import edu.ie3.datamodel.models.timeseries.TimeSeriesEntry; @@ -17,10 +19,10 @@ import org.apache.commons.io.FilenameUtils; /** - * A file naming strategy, that takes hierarchic order of sub folders into account. For the standard + * A naming strategy, that takes hierarchic order of sub folders into account. For the standard * structure that can be found in the documentation {@link DefaultDirectoryHierarchy} can be used */ -public class HierarchicFileNamingStrategy extends FileNamingStrategy { +public class HierarchicFileNamingStrategy extends EntityPersistenceNamingStrategy { private static final String FILE_SEPARATOR_REGEX = "[\\\\/]"; private static final String FILE_SEPARATOR_REPLACEMENT = File.separator.equals("\\") ? "\\\\" : "/"; diff --git a/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java b/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java index bf91060fd..c7b8c1eb9 100644 --- a/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java +++ b/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java @@ -11,9 +11,9 @@ import edu.ie3.datamodel.exceptions.SinkException; import edu.ie3.datamodel.io.connectors.CsvFileConnector; import edu.ie3.datamodel.io.csv.BufferedCsvWriter; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.extractor.Extractor; import edu.ie3.datamodel.io.extractor.NestedEntity; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.processor.ProcessorProvider; import edu.ie3.datamodel.io.processor.timeseries.TimeSeriesProcessorKey; import edu.ie3.datamodel.models.UniqueEntity; @@ -59,7 +59,7 @@ public class CsvFileSink implements InputDataSink, OutputDataSink { private final String csvSep; public CsvFileSink(String baseFolderPath) { - this(baseFolderPath, new FileNamingStrategy(), false, ","); + this(baseFolderPath, new EntityPersistenceNamingStrategy(), false, ","); } /** @@ -68,7 +68,7 @@ public CsvFileSink(String baseFolderPath) { * starting several sinks and use them for specific entities. * * @param baseFolderPath the base folder path where the files should be put into - * @param fileNamingStrategy the file naming strategy that should be used + * @param entityPersistenceNamingStrategy the data sink naming strategy that should be used * @param initFiles true if the files should be created during initialization (might create files, * that only consist of a headline, because no data will be written into them), false * otherwise @@ -76,10 +76,15 @@ public CsvFileSink(String baseFolderPath) { */ public CsvFileSink( String baseFolderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, boolean initFiles, String csvSep) { - this(baseFolderPath, new ProcessorProvider(), fileNamingStrategy, initFiles, csvSep); + this( + baseFolderPath, + new ProcessorProvider(), + entityPersistenceNamingStrategy, + initFiles, + csvSep); } /** @@ -93,7 +98,7 @@ public CsvFileSink( * * @param baseFolderPath the base folder path where the files should be put into * @param processorProvider the processor provided that should be used for entity de-serialization - * @param fileNamingStrategy the file naming strategy that should be used + * @param entityPersistenceNamingStrategy the data sink naming strategy that should be used * @param initFiles true if the files should be created during initialization (might create files, * that only consist of a headline, because no data will be written into them), false * otherwise @@ -102,12 +107,12 @@ public CsvFileSink( public CsvFileSink( String baseFolderPath, ProcessorProvider processorProvider, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, boolean initFiles, String csvSep) { this.csvSep = csvSep; this.processorProvider = processorProvider; - this.connector = new CsvFileConnector(baseFolderPath, fileNamingStrategy); + this.connector = new CsvFileConnector(baseFolderPath, entityPersistenceNamingStrategy); if (initFiles) initFiles(processorProvider, connector); } diff --git a/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java b/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java index da6d49077..6164a1cb3 100644 --- a/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java +++ b/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java @@ -7,7 +7,7 @@ import edu.ie3.datamodel.exceptions.SinkException; import edu.ie3.datamodel.io.connectors.InfluxDbConnector; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.processor.ProcessorProvider; import edu.ie3.datamodel.io.processor.timeseries.TimeSeriesProcessorKey; import edu.ie3.datamodel.models.UniqueEntity; @@ -33,18 +33,20 @@ public class InfluxDbSink implements OutputDataSink { private static final String FIELD_NAME_INPUT = "inputModel"; private final InfluxDbConnector connector; - private final FileNamingStrategy fileNamingStrategy; + private final EntityPersistenceNamingStrategy entityPersistenceNamingStrategy; private final ProcessorProvider processorProvider; /** * Initializes a new InfluxDbWeatherSource * * @param connector needed for database connection - * @param fileNamingStrategy needed to create measurement names for entities + * @param entityPersistenceNamingStrategy needed to create measurement names for entities */ - public InfluxDbSink(InfluxDbConnector connector, FileNamingStrategy fileNamingStrategy) { + public InfluxDbSink( + InfluxDbConnector connector, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { this.connector = connector; - this.fileNamingStrategy = fileNamingStrategy; + this.entityPersistenceNamingStrategy = entityPersistenceNamingStrategy; this.processorProvider = new ProcessorProvider( ProcessorProvider.allResultEntityProcessors(), @@ -52,12 +54,12 @@ public InfluxDbSink(InfluxDbConnector connector, FileNamingStrategy fileNamingSt } /** - * Initializes a new InfluxDbWeatherSource with a default FileNamingStrategy + * Initializes a new InfluxDbWeatherSource with a default EntityPersistenceNamingStrategy * * @param connector needed for database connection */ public InfluxDbSink(InfluxDbConnector connector) { - this(connector, new FileNamingStrategy()); + this(connector, new EntityPersistenceNamingStrategy()); } @Override @@ -100,14 +102,14 @@ public void flush() { /** * Transforms a ResultEntity to an influxDB data point.
* As the equivalent to a relational table, the influxDB measurement point will be named using the - * given FileNamingStrategy if possible, or the class name otherwise. All special characters in - * the measurement name will be replaced by underscores. + * given EntityPersistenceNamingStrategy if possible, or the class name otherwise. All special + * characters in the measurement name will be replaced by underscores. * * @param entity the entity to transform */ private Optional transformToPoint(ResultEntity entity) { Optional measurementName = - fileNamingStrategy.getResultEntityFileName(entity.getClass()); + entityPersistenceNamingStrategy.getResultEntityName(entity.getClass()); if (!measurementName.isPresent()) log.warn( "I could not get a measurement name for class {}. I am using its simple name instead.", @@ -158,15 +160,15 @@ private Optional transformToPoint(ResultEntity entity, String measurement /** * Transforms a timeSeries to influxDB data points, one point for each value.
* As the equivalent to a relational table, the influxDB measurement point will be named using the - * given FileNamingStrategy if possible, or the class name otherwise. All special characters in - * the measurement name will be replaced by underscores. + * given EntityPersistenceNamingStrategy if possible, or the class name otherwise. All special + * characters in the measurement name will be replaced by underscores. * * @param timeSeries the time series to transform */ private , V extends Value> Set transformToPoints( TimeSeries timeSeries) { if (timeSeries.getEntries().isEmpty()) return Collections.emptySet(); - Optional measurementName = fileNamingStrategy.getFileName(timeSeries); + Optional measurementName = entityPersistenceNamingStrategy.getEntityName(timeSeries); if (!measurementName.isPresent()) { String valueClassName = timeSeries.getEntries().iterator().next().getValue().getClass().getSimpleName(); @@ -223,8 +225,9 @@ private , V extends Value> Set transformToPo /** * Transforms an entity to an influxDB data point.
- * The measurement point will be named by the given FileNamingStrategy if possible, or the class - * name otherwise. All special characters in the measurement name will be replaced by underscores. + * The measurement point will be named by the given EntityPersistenceNamingStrategy if possible, + * or the class name otherwise. All special characters in the measurement name will be replaced by + * underscores. * * @param entity the entity of which influxDB points will be extracted * @param bounded to be all unique entities, but logs an error and returns an empty Set if it diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java index 89e337fcb..6319d0a9b 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java @@ -7,10 +7,10 @@ import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.connectors.CsvFileConnector; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.input.AssetInputEntityData; import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; import edu.ie3.datamodel.models.input.AssetTypeInput; @@ -64,9 +64,12 @@ public abstract class CsvDataSource { */ @Deprecated private boolean notYetLoggedWarning = true; - public CsvDataSource(String csvSep, String folderPath, FileNamingStrategy fileNamingStrategy) { + public CsvDataSource( + String csvSep, + String folderPath, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { this.csvSep = csvSep; - this.connector = new CsvFileConnector(folderPath, fileNamingStrategy); + this.connector = new CsvFileConnector(folderPath, entityPersistenceNamingStrategy); } /** diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvGraphicSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvGraphicSource.java index 1436b7684..3052c8114 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvGraphicSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvGraphicSource.java @@ -5,11 +5,11 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputEntityData; import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputFactory; import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputEntityData; import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputFactory; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.GraphicSource; import edu.ie3.datamodel.io.source.RawGridSource; import edu.ie3.datamodel.io.source.TypeSource; @@ -49,10 +49,10 @@ public class CsvGraphicSource extends CsvDataSource implements GraphicSource { public CsvGraphicSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, TypeSource typeSource, RawGridSource rawGridSource) { - super(csvSep, folderPath, fileNamingStrategy); + super(csvSep, folderPath, entityPersistenceNamingStrategy); this.typeSource = typeSource; this.rawGridSource = rawGridSource; diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java index 4c5ac0009..a6b6dff9b 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java @@ -5,9 +5,9 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.SimpleFactoryData; import edu.ie3.datamodel.io.factory.timeseries.IdCoordinateFactory; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.IdCoordinateSource; import java.io.BufferedReader; import java.io.IOException; @@ -32,9 +32,9 @@ public class CsvIdCoordinateSource extends CsvDataSource implements IdCoordinate public CsvIdCoordinateSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, IdCoordinateFactory factory) { - super(csvSep, folderPath, fileNamingStrategy); + super(csvSep, folderPath, entityPersistenceNamingStrategy); this.factory = factory; diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvRawGridSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvRawGridSource.java index 202e45400..e802cabeb 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvRawGridSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvRawGridSource.java @@ -5,9 +5,9 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.input.*; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.RawGridSource; import edu.ie3.datamodel.io.source.TypeSource; import edu.ie3.datamodel.models.UniqueEntity; @@ -54,9 +54,9 @@ public class CsvRawGridSource extends CsvDataSource implements RawGridSource { public CsvRawGridSource( String csvSep, String gridFolderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, TypeSource typeSource) { - super(csvSep, gridFolderPath, fileNamingStrategy); + super(csvSep, gridFolderPath, entityPersistenceNamingStrategy); this.typeSource = typeSource; // init factories diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSource.java index a0921536d..4d944885a 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSource.java @@ -5,10 +5,10 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData; import edu.ie3.datamodel.io.factory.input.participant.*; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.RawGridSource; import edu.ie3.datamodel.io.source.SystemParticipantSource; import edu.ie3.datamodel.io.source.ThermalSource; @@ -67,11 +67,11 @@ public class CsvSystemParticipantSource extends CsvDataSource implements SystemP public CsvSystemParticipantSource( String csvSep, String participantsFolderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, TypeSource typeSource, ThermalSource thermalSource, RawGridSource rawGridSource) { - super(csvSep, participantsFolderPath, fileNamingStrategy); + super(csvSep, participantsFolderPath, entityPersistenceNamingStrategy); this.typeSource = typeSource; this.rawGridSource = rawGridSource; this.thermalSource = thermalSource; diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvThermalSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvThermalSource.java index 4c3ca0b48..c541dd09d 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvThermalSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvThermalSource.java @@ -5,8 +5,8 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.input.*; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.ThermalSource; import edu.ie3.datamodel.io.source.TypeSource; import edu.ie3.datamodel.models.input.OperatorInput; @@ -46,9 +46,9 @@ public class CsvThermalSource extends CsvDataSource implements ThermalSource { public CsvThermalSource( String csvSep, String thermalUnitsFolderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, TypeSource typeSource) { - super(csvSep, thermalUnitsFolderPath, fileNamingStrategy); + super(csvSep, thermalUnitsFolderPath, entityPersistenceNamingStrategy); this.typeSource = typeSource; // init factories diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSource.java index 73dd3461f..63ecdb2fd 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSource.java @@ -5,10 +5,10 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation; import edu.ie3.datamodel.io.factory.SimpleEntityData; import edu.ie3.datamodel.io.factory.timeseries.TimeSeriesMappingFactory; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.TimeSeriesMappingSource; import java.util.Map; import java.util.Optional; @@ -22,8 +22,10 @@ public class CsvTimeSeriesMappingSource extends CsvDataSource implements TimeSer private final Map mapping; public CsvTimeSeriesMappingSource( - String csvSep, String folderPath, FileNamingStrategy fileNamingStrategy) { - super(csvSep, folderPath, fileNamingStrategy); + String csvSep, + String folderPath, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { + super(csvSep, folderPath, entityPersistenceNamingStrategy); /* Build the map */ mapping = diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java index 56f2499bb..d09ffcafd 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java @@ -7,8 +7,8 @@ import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.connectors.CsvFileConnector; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.timeseries.*; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.TimeSeriesSource; import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; @@ -33,7 +33,8 @@ public class CsvTimeSeriesSource extends CsvDataSource * * @param csvSep the separator string for csv columns * @param folderPath path to the folder holding the time series files - * @param fileNamingStrategy strategy for the naming of time series files + * @param entityPersistenceNamingStrategy strategy for the naming of time series files / data + * sinks * @param metaInformation The given meta information * @throws SourceException If the given meta information are not supported * @return The source @@ -41,7 +42,7 @@ public class CsvTimeSeriesSource extends CsvDataSource public static CsvTimeSeriesSource getSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, CsvFileConnector.CsvIndividualTimeSeriesMetaInformation metaInformation) throws SourceException { switch (metaInformation.getColumnScheme()) { @@ -51,7 +52,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), PValue.class, @@ -62,7 +63,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), SValue.class, @@ -73,7 +74,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), EnergyPriceValue.class, @@ -84,7 +85,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatAndSValue.class, @@ -95,7 +96,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatAndPValue.class, @@ -106,7 +107,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatDemandValue.class, @@ -122,7 +123,8 @@ public static CsvTimeSeriesSource getSource( * * @param csvSep the separator string for csv columns * @param folderPath path to the folder holding the time series files - * @param fileNamingStrategy strategy for the naming of time series files + * @param entityPersistenceNamingStrategy strategy for the naming of time series files / data + * sinks * @param timeSeriesUuid Unique identifier of the time series * @param filePath Path of the file, excluding extension and being relative to {@code folderPath} * @param valueClass Class of the value @@ -131,12 +133,12 @@ public static CsvTimeSeriesSource getSource( public CsvTimeSeriesSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, UUID timeSeriesUuid, String filePath, Class valueClass, TimeBasedSimpleValueFactory factory) { - super(csvSep, folderPath, fileNamingStrategy); + super(csvSep, folderPath, entityPersistenceNamingStrategy); /* Read in the full time series */ try { diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTypeSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTypeSource.java index 96e4a6862..4b83856f6 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTypeSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTypeSource.java @@ -5,7 +5,6 @@ */ package edu.ie3.datamodel.io.source.csv; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.SimpleEntityData; import edu.ie3.datamodel.io.factory.input.OperatorInputFactory; @@ -13,6 +12,7 @@ import edu.ie3.datamodel.io.factory.typeinput.SystemParticipantTypeInputFactory; import edu.ie3.datamodel.io.factory.typeinput.Transformer2WTypeInputFactory; import edu.ie3.datamodel.io.factory.typeinput.Transformer3WTypeInputFactory; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.TypeSource; import edu.ie3.datamodel.models.input.InputEntity; import edu.ie3.datamodel.models.input.OperatorInput; @@ -41,8 +41,10 @@ public class CsvTypeSource extends CsvDataSource implements TypeSource { private final SystemParticipantTypeInputFactory systemParticipantTypeInputFactory; public CsvTypeSource( - String csvSep, String typeFolderPath, FileNamingStrategy fileNamingStrategy) { - super(csvSep, typeFolderPath, fileNamingStrategy); + String csvSep, + String typeFolderPath, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { + super(csvSep, typeFolderPath, entityPersistenceNamingStrategy); // init factories operatorInputFactory = new OperatorInputFactory(); diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java index 3be0790a2..123aab015 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java @@ -6,11 +6,11 @@ package edu.ie3.datamodel.io.source.csv; import edu.ie3.datamodel.io.connectors.CsvFileConnector; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; import edu.ie3.datamodel.io.factory.timeseries.IdCoordinateFactory; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.io.source.IdCoordinateSource; import edu.ie3.datamodel.io.source.WeatherSource; import edu.ie3.datamodel.models.UniqueEntity; @@ -43,7 +43,8 @@ public class CsvWeatherSource extends CsvDataSource implements WeatherSource { * * @param csvSep the separator string for csv columns * @param folderPath path to the folder holding the time series files - * @param fileNamingStrategy strategy for the naming of time series files + * @param entityPersistenceNamingStrategy strategy for the naming of time series files / data + * sinks * @param weatherFactory factory to transfer field to value mapping into actual java object * instances * @param coordinateFactory factory to build coordinate id to coordinate mapping @@ -51,14 +52,15 @@ public class CsvWeatherSource extends CsvDataSource implements WeatherSource { public CsvWeatherSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, TimeBasedWeatherValueFactory weatherFactory, IdCoordinateFactory coordinateFactory) { this( csvSep, folderPath, - fileNamingStrategy, - new CsvIdCoordinateSource(csvSep, folderPath, fileNamingStrategy, coordinateFactory), + entityPersistenceNamingStrategy, + new CsvIdCoordinateSource( + csvSep, folderPath, entityPersistenceNamingStrategy, coordinateFactory), weatherFactory); } @@ -68,7 +70,8 @@ public CsvWeatherSource( * * @param csvSep the separator string for csv columns * @param folderPath path to the folder holding the time series files - * @param fileNamingStrategy strategy for the naming of time series files + * @param entityPersistenceNamingStrategy strategy for the naming of time series files / data + * sinks * @param coordinateSource a coordinate source to map ids to points * @param weatherFactory factory to transfer field to value mapping into actual java object * instances @@ -76,10 +79,10 @@ public CsvWeatherSource( public CsvWeatherSource( String csvSep, String folderPath, - FileNamingStrategy fileNamingStrategy, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy, IdCoordinateSource coordinateSource, TimeBasedWeatherValueFactory weatherFactory) { - super(csvSep, folderPath, fileNamingStrategy); + super(csvSep, folderPath, entityPersistenceNamingStrategy); this.coordinateSource = coordinateSource; this.weatherFactory = weatherFactory; diff --git a/src/main/java/edu/ie3/datamodel/models/input/container/GridContainer.java b/src/main/java/edu/ie3/datamodel/models/input/container/GridContainer.java index 8c95f009f..e4cc16e3c 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/container/GridContainer.java +++ b/src/main/java/edu/ie3/datamodel/models/input/container/GridContainer.java @@ -43,7 +43,7 @@ public List allEntitiesAsList() { } @Override - public void validate() { + public final void validate() { // sanity check to ensure distinct UUIDs Optional exceptionString = ValidationUtils.checkForDuplicateUuids(new HashSet<>(this.allEntitiesAsList())); diff --git a/src/main/java/edu/ie3/datamodel/models/input/system/SystemParticipantInput.java b/src/main/java/edu/ie3/datamodel/models/input/system/SystemParticipantInput.java index ba8a144e6..073506cc6 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/system/SystemParticipantInput.java +++ b/src/main/java/edu/ie3/datamodel/models/input/system/SystemParticipantInput.java @@ -32,7 +32,7 @@ public abstract class SystemParticipantInput extends AssetInput implements HasNo * @param node that the asset is connected to * @param qCharacteristics Description of a reactive power characteristic */ - public SystemParticipantInput( + protected SystemParticipantInput( UUID uuid, String id, OperatorInput operator, @@ -52,7 +52,7 @@ public SystemParticipantInput( * @param node that the asset is connected to * @param qCharacteristics Description of a reactive power characteristic */ - public SystemParticipantInput( + protected SystemParticipantInput( UUID uuid, String id, NodeInput node, ReactivePowerCharacteristic qCharacteristics) { super(uuid, id); this.node = node; diff --git a/src/main/java/edu/ie3/datamodel/models/voltagelevels/GermanVoltageLevelUtils.java b/src/main/java/edu/ie3/datamodel/models/voltagelevels/GermanVoltageLevelUtils.java index e0413e690..2c1378f9f 100644 --- a/src/main/java/edu/ie3/datamodel/models/voltagelevels/GermanVoltageLevelUtils.java +++ b/src/main/java/edu/ie3/datamodel/models/voltagelevels/GermanVoltageLevelUtils.java @@ -22,6 +22,8 @@ public class GermanVoltageLevelUtils { protected static final Logger logger = LoggerFactory.getLogger(GermanVoltageLevelUtils.class); + private static final String MS = "Mittelspannung"; + public static final CommonVoltageLevel LV = new CommonVoltageLevel( "Niederspannung", @@ -31,21 +33,21 @@ public class GermanVoltageLevelUtils { Quantities.getQuantity(0d, KILOVOLT), Quantities.getQuantity(10d, KILOVOLT))); public static final CommonVoltageLevel MV_10KV = new CommonVoltageLevel( - "Mittelspannung", + MS, Quantities.getQuantity(10d, KILOVOLT), new HashSet<>(Arrays.asList("ms", "mv", "ms_10kv", "mv_10kV")), new RightOpenInterval<>( Quantities.getQuantity(10d, KILOVOLT), Quantities.getQuantity(20d, KILOVOLT))); public static final CommonVoltageLevel MV_20KV = new CommonVoltageLevel( - "Mittelspannung", + MS, Quantities.getQuantity(20d, KILOVOLT), new HashSet<>(Arrays.asList("ms", "mv", "ms_20kv", "mv_20kV")), new RightOpenInterval<>( Quantities.getQuantity(20d, KILOVOLT), Quantities.getQuantity(30d, KILOVOLT))); public static final CommonVoltageLevel MV_30KV = new CommonVoltageLevel( - "Mittelspannung", + MS, Quantities.getQuantity(30d, KILOVOLT), new HashSet<>(Arrays.asList("ms", "mv", "ms_30kv", "mv_30kV")), new RightOpenInterval<>( diff --git a/src/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy index 5d89ddaa0..8b73dabcf 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy @@ -8,9 +8,9 @@ package edu.ie3.datamodel.io.connectors import edu.ie3.datamodel.exceptions.ConnectorException import edu.ie3.datamodel.io.csv.CsvFileDefinition import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy -import edu.ie3.datamodel.io.csv.FileNamingStrategy -import edu.ie3.datamodel.io.csv.HierarchicFileNamingStrategy +import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries @@ -45,7 +45,7 @@ class CsvFileConnectorTest extends Specification { def setupSpec() { tmpDirectory = Files.createTempDirectory("psdm_csv_file_connector_") - cfc = new CsvFileConnector(tmpDirectory.toString(), new FileNamingStrategy()) + cfc = new CsvFileConnector(tmpDirectory.toString(), new EntityPersistenceNamingStrategy()) def gridPaths = ["node_input.csv"] timeSeriesPaths = [ "its_pq_53990eea-1b5d-47e8-9134-6d8de36604bf.csv", @@ -211,8 +211,8 @@ class CsvFileConnectorTest extends Specification { def "The csv file connector is able to init writers utilizing no directory hierarchy"() { given: "a suitable connector" def baseDirectory = FilenameUtils.concat(tmpDirectory.toString(), "directoryHierarchy") - def fileNamingStrategy = new FileNamingStrategy() - def connector = new CsvFileConnector(baseDirectory, fileNamingStrategy) + def entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + def connector = new CsvFileConnector(baseDirectory, entityPersistenceNamingStrategy) and: "expected results" def nodeFile = new File(FilenameUtils.concat(baseDirectory, "node_input.csv")) @@ -230,8 +230,8 @@ class CsvFileConnectorTest extends Specification { def "The csv file connector throws ConnectorException if no csv file definition can be built from class information"() { given: def baseDirectory = tmpDirectory.toString() - def fileNamingStrategy = new FileNamingStrategy() - def connector = new CsvFileConnector(baseDirectory, fileNamingStrategy) + def entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + def connector = new CsvFileConnector(baseDirectory, entityPersistenceNamingStrategy) when: connector.buildFileDefinition(String, ["a", "b", "c"] as String[], ",") @@ -244,8 +244,8 @@ class CsvFileConnectorTest extends Specification { def "The csv file connector is able to build correct csv file definition from class upon request"() { given: def baseDirectory = tmpDirectory.toString() - def fileNamingStrategy = new FileNamingStrategy() - def connector = new CsvFileConnector(baseDirectory, fileNamingStrategy) + def entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + def connector = new CsvFileConnector(baseDirectory, entityPersistenceNamingStrategy) def expected = new CsvFileDefinition("node_input.csv", "", ["a", "b", "c"] as String[], ",") when: @@ -272,8 +272,8 @@ class CsvFileConnectorTest extends Specification { def "The csv file connector throws ConnectorException if no csv file definition can be built from time series"() { given: "a suitable connector" def baseDirectory = tmpDirectory.toString() - def fileNamingStrategy = new FileNamingStrategy() - def connector = new CsvFileConnector(baseDirectory, fileNamingStrategy) + def entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + def connector = new CsvFileConnector(baseDirectory, entityPersistenceNamingStrategy) and: "credible input" def timeSeries = Mock(RepetitiveTimeSeries) @@ -289,8 +289,8 @@ class CsvFileConnectorTest extends Specification { def "The csv file connector is able to build correct csv file definition from time series upon request"() { given: "a suitable connector" def baseDirectory = tmpDirectory.toString() - def fileNamingStrategy = new FileNamingStrategy() - def connector = new CsvFileConnector(baseDirectory, fileNamingStrategy) + def entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + def connector = new CsvFileConnector(baseDirectory, entityPersistenceNamingStrategy) def expected = new CsvFileDefinition("its_c_0c03ce9f-ab0e-4715-bc13-f9d903f26dbf.csv", "", ["a", "b", "c"] as String[], ",") and: "credible input" diff --git a/src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy index 92441daed..15a1dcadc 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy @@ -51,6 +51,7 @@ import java.nio.file.Paths import java.time.ZonedDateTime import java.util.regex.Pattern +@Deprecated class FileNamingStrategyTest extends Specification { def "The uuid pattern actually matches a valid uuid"() { diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy new file mode 100644 index 000000000..f8c3d9672 --- /dev/null +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -0,0 +1,974 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ +package edu.ie3.datamodel.io.naming + +import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme +import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation +import edu.ie3.datamodel.io.csv.timeseries.LoadProfileTimeSeriesMetaInformation +import edu.ie3.datamodel.io.source.TimeSeriesMappingSource +import edu.ie3.datamodel.models.BdewLoadProfile +import edu.ie3.datamodel.models.UniqueEntity +import edu.ie3.datamodel.models.input.MeasurementUnitInput +import edu.ie3.datamodel.models.input.NodeInput +import edu.ie3.datamodel.models.input.RandomLoadParameters +import edu.ie3.datamodel.models.input.connector.LineInput +import edu.ie3.datamodel.models.input.connector.SwitchInput +import edu.ie3.datamodel.models.input.connector.Transformer2WInput +import edu.ie3.datamodel.models.input.connector.Transformer3WInput +import edu.ie3.datamodel.models.input.connector.type.LineTypeInput +import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput +import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput +import edu.ie3.datamodel.models.input.graphics.LineGraphicInput +import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput +import edu.ie3.datamodel.models.input.system.BmInput +import edu.ie3.datamodel.models.input.system.ChpInput +import edu.ie3.datamodel.models.input.system.EvInput +import edu.ie3.datamodel.models.input.system.EvcsInput +import edu.ie3.datamodel.models.input.system.FixedFeedInInput +import edu.ie3.datamodel.models.input.system.HpInput +import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.datamodel.models.input.system.PvInput +import edu.ie3.datamodel.models.input.system.StorageInput +import edu.ie3.datamodel.models.input.system.WecInput +import edu.ie3.datamodel.models.input.system.type.BmTypeInput +import edu.ie3.datamodel.models.input.system.type.ChpTypeInput +import edu.ie3.datamodel.models.input.system.type.EvTypeInput +import edu.ie3.datamodel.models.input.system.type.HpTypeInput +import edu.ie3.datamodel.models.input.system.type.StorageTypeInput +import edu.ie3.datamodel.models.input.system.type.WecTypeInput +import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput +import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput +import edu.ie3.datamodel.models.result.NodeResult +import edu.ie3.datamodel.models.result.connector.LineResult +import edu.ie3.datamodel.models.result.connector.SwitchResult +import edu.ie3.datamodel.models.result.connector.Transformer2WResult +import edu.ie3.datamodel.models.result.connector.Transformer3WResult +import edu.ie3.datamodel.models.result.system.BmResult +import edu.ie3.datamodel.models.result.system.ChpResult +import edu.ie3.datamodel.models.result.system.EvResult +import edu.ie3.datamodel.models.result.system.EvcsResult +import edu.ie3.datamodel.models.result.system.FixedFeedInResult +import edu.ie3.datamodel.models.result.system.LoadResult +import edu.ie3.datamodel.models.result.system.PvResult +import edu.ie3.datamodel.models.result.system.StorageResult +import edu.ie3.datamodel.models.result.system.WecResult +import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult +import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult +import edu.ie3.datamodel.models.timeseries.IntValue +import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries +import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue +import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput +import edu.ie3.datamodel.models.timeseries.repetitive.RepetitiveTimeSeries +import edu.ie3.datamodel.models.value.EnergyPriceValue +import edu.ie3.util.quantities.PowerSystemUnits +import spock.lang.Specification +import tech.units.indriya.quantity.Quantities + +import java.nio.file.Paths +import java.time.ZonedDateTime +import java.util.regex.Pattern + +class EntityPersistenceNamingStrategyTest extends Specification { + + def "The uuid pattern actually matches a valid uuid"() { + given: + def pattern = Pattern.compile(EntityPersistenceNamingStrategy.UUID_STRING) + def uuidString = UUID.randomUUID().toString() + + when: + def matcher = pattern.matcher(uuidString) + + then: + matcher.matches() + } + + def "The pattern for an individual time series file name actually matches a valid file name and extracts the correct groups"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def validFileName = "its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276" + + when: + def matcher = fns.individualTimeSeriesPattern.matcher(validFileName) + + then: "the pattern matches" + matcher.matches() + + then: "it also has correct capturing groups" + matcher.groupCount() == 2 + matcher.group(1) == "c" + matcher.group("columnScheme") == "c" + matcher.group(2) == "4881fda2-bcee-4f4f-a5bb-6a09bf785276" + matcher.group("uuid") == "4881fda2-bcee-4f4f-a5bb-6a09bf785276" + } + + def "The pattern for a repetitive load profile time series file name actually matches a valid file name and extracts the correct groups"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def validFileName = "lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304" + + when: + def matcher = fns.loadProfileTimeSeriesPattern.matcher(validFileName) + + then: "the pattern matches" + matcher.matches() + + then: "it also has correct capturing groups" + matcher.groupCount() == 2 + matcher.group(1) == "g3" + matcher.group(2) == "bee0a8b6-4788-4f18-bf72-be52035f7304" + matcher.group("profile") == "g3" + matcher.group("uuid") == "bee0a8b6-4788-4f18-bf72-be52035f7304" + } + + def "Trying to extract time series meta information throws an Exception, if it is provided a malformed string"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def path = Paths.get("/bla/foo") + + when: + fns.extractTimeSeriesMetaInformation(path) + + then: + def ex = thrown(IllegalArgumentException) + ex.message == "Unknown format of 'foo'. Cannot extract meta information." + } + + def "Trying to extract individual time series meta information throws an Exception, if it is provided a malformed string"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def fileName = "foo" + + when: + fns.extractIndividualTimesSeriesMetaInformation(fileName) + + then: + def ex = thrown(IllegalArgumentException) + ex.message == "Cannot extract meta information on individual time series from 'foo'." + } + + def "Trying to extract load profile time series meta information throws an Exception, if it is provided a malformed string"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def fileName = "foo" + + when: + fns.extractLoadProfileTimesSeriesMetaInformation(fileName) + + then: + def ex = thrown(IllegalArgumentException) + ex.message == "Cannot extract meta information on load profile time series from 'foo'." + } + + def "The EntityPersistenceNamingStrategy extracts correct meta information from a valid individual time series file name"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def path = Paths.get(pathString) + + when: + def metaInformation = fns.extractTimeSeriesMetaInformation(path) + + then: + IndividualTimeSeriesMetaInformation.isAssignableFrom(metaInformation.getClass()) + (metaInformation as IndividualTimeSeriesMetaInformation).with { + assert it.uuid == UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") + assert it.columnScheme == expectedColumnScheme + } + + where: + pathString || expectedColumnScheme + "/bla/foo/its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.ENERGY_PRICE + "/bla/foo/its_p_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.ACTIVE_POWER + "/bla/foo/its_pq_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.APPARENT_POWER + "/bla/foo/its_h_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.HEAT_DEMAND + "/bla/foo/its_ph_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.ACTIVE_POWER_AND_HEAT_DEMAND + "/bla/foo/its_pqh_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND + "/bla/foo/its_weather_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv" || ColumnScheme.WEATHER + } + + def "The EntityPersistenceNamingStrategy extracts correct meta information from a valid individual time series file name with pre- and suffix"() { + given: + def fns = new EntityPersistenceNamingStrategy("prefix", "suffix") + def path = Paths.get(pathString) + + when: + def metaInformation = fns.extractTimeSeriesMetaInformation(path) + + then: + IndividualTimeSeriesMetaInformation.isAssignableFrom(metaInformation.getClass()) + (metaInformation as IndividualTimeSeriesMetaInformation).with { + assert it.uuid == UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") + assert it.columnScheme == expectedColumnScheme + } + + where: + pathString || expectedColumnScheme + "/bla/foo/prefix_its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.ENERGY_PRICE + "/bla/foo/prefix_its_p_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.ACTIVE_POWER + "/bla/foo/prefix_its_pq_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.APPARENT_POWER + "/bla/foo/prefix_its_h_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.HEAT_DEMAND + "/bla/foo/prefix_its_ph_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.ACTIVE_POWER_AND_HEAT_DEMAND + "/bla/foo/prefix_its_pqh_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND + "/bla/foo/prefix_its_weather_4881fda2-bcee-4f4f-a5bb-6a09bf785276_suffix.csv" || ColumnScheme.WEATHER + } + + def "The EntityPersistenceNamingStrategy throw an IllegalArgumentException, if the column scheme is malformed."() { + given: + def fns = new EntityPersistenceNamingStrategy() + def path = Paths.get("/bla/foo/its_whoops_4881fda2-bcee-4f4f-a5bb-6a09bf785276.csv") + + when: + fns.extractTimeSeriesMetaInformation(path) + + then: + def ex = thrown(IllegalArgumentException) + ex.message == "Cannot parse 'whoops' to valid column scheme." + } + + def "The EntityPersistenceNamingStrategy extracts correct meta information from a valid load profile time series file name"() { + given: + def fns = new EntityPersistenceNamingStrategy() + def path = Paths.get("/bla/foo/lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304.csv") + + when: + def metaInformation = fns.extractTimeSeriesMetaInformation(path) + + then: + LoadProfileTimeSeriesMetaInformation.isAssignableFrom(metaInformation.getClass()) + (metaInformation as LoadProfileTimeSeriesMetaInformation).with { + assert uuid == UUID.fromString("bee0a8b6-4788-4f18-bf72-be52035f7304") + assert profile == "g3" + } + } + + def "The EntityPersistenceNamingStrategy extracts correct meta information from a valid load profile time series file name with pre- and suffix"() { + given: + def fns = new EntityPersistenceNamingStrategy("prefix", "suffix") + def path = Paths.get("/bla/foo/prefix_lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304_suffix.csv") + + when: + def metaInformation = fns.extractTimeSeriesMetaInformation(path) + + then: + LoadProfileTimeSeriesMetaInformation.isAssignableFrom(metaInformation.getClass()) + (metaInformation as LoadProfileTimeSeriesMetaInformation).with { + assert uuid == UUID.fromString("bee0a8b6-4788-4f18-bf72-be52035f7304") + assert profile == "g3" + } + } + + def "The EntityPersistenceNamingStrategy is able to prepare the prefix properly"() { + when: + String actual = EntityPersistenceNamingStrategy.preparePrefix(prefix) + + then: + actual == expected + + where: + prefix || expected + "abc123" || "abc123_" + "aBc123" || "abc123_" + "ABC123" || "abc123_" + "abc123_" || "abc123_" + "aBc123_" || "abc123_" + "ABC123_" || "abc123_" + } + + def "The EntityPersistenceNamingStrategy is able to prepare the suffix properly"() { + when: + String actual = EntityPersistenceNamingStrategy.prepareSuffix(prefix) + + then: + actual == suffix + + where: + prefix || suffix + "abc123" || "_abc123" + "aBc123" || "_abc123" + "ABC123" || "_abc123" + "_abc123" || "_abc123" + "_aBc123" || "_abc123" + "_ABC123" || "_abc123" + } + + def "A EntityPersistenceNamingStrategy should recognize if empty strings are passed in the prefix/suffix constructor and don't add underlines then"() { + given: "a naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("", "") + + expect: + strategy.prefix == "" + strategy.suffix == "" + } + + def "A EntityPersistenceNamingStrategy should correctly append and prepend underscores"() { + given: "a naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("bla", "foo") + + expect: + strategy.prefix == "bla_" + strategy.suffix == "_foo" + } + + def "A EntityPersistenceNamingStrategy should correctly append underscore, when only prefix is set"() { + given: "a naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("bla") + + expect: + strategy.prefix == "bla_" + strategy.suffix == "" + } + + def "A EntityPersistenceNamingStrategy should return an empty optional on a invalid class"() { + given: "a naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(String) + + then: + !res.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all result models"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + LoadResult || "load_res" + FixedFeedInResult || "fixed_feed_in_res" + BmResult || "bm_res" + PvResult || "pv_res" + ChpResult || "chp_res" + WecResult || "wec_res" + StorageResult || "storage_res" + EvcsResult || "evcs_res" + EvResult || "ev_res" + Transformer2WResult || "transformer_2_w_res" + Transformer3WResult || "transformer_3_w_res" + LineResult || "line_res" + SwitchResult || "switch_res" + NodeResult || "node_res" + CylindricalStorageResult || "cylindrical_storage_res" + ThermalHouseResult || "thermal_house_res" + } + + def "A EntityPersistenceNamingStrategy with pre- and suffixes should return valid strings for all result models"() { + given: "a naming strategy with pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + LoadResult || "prefix_load_res_suffix" + FixedFeedInResult || "prefix_fixed_feed_in_res_suffix" + BmResult || "prefix_bm_res_suffix" + PvResult || "prefix_pv_res_suffix" + ChpResult || "prefix_chp_res_suffix" + WecResult || "prefix_wec_res_suffix" + StorageResult || "prefix_storage_res_suffix" + EvcsResult || "prefix_evcs_res_suffix" + EvResult || "prefix_ev_res_suffix" + Transformer2WResult || "prefix_transformer_2_w_res_suffix" + Transformer3WResult || "prefix_transformer_3_w_res_suffix" + LineResult || "prefix_line_res_suffix" + SwitchResult || "prefix_switch_res_suffix" + NodeResult || "prefix_node_res_suffix" + CylindricalStorageResult || "prefix_cylindrical_storage_res_suffix" + ThermalHouseResult || "prefix_thermal_house_res_suffix" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all input assets models"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + FixedFeedInInput || "fixed_feed_in_input" + PvInput || "pv_input" + WecInput || "wec_input" + ChpInput || "chp_input" + BmInput || "bm_input" + EvInput || "ev_input" + LoadInput || "load_input" + StorageInput || "storage_input" + HpInput || "hp_input" + LineInput || "line_input" + SwitchInput || "switch_input" + NodeInput || "node_input" + MeasurementUnitInput || "measurement_unit_input" + EvcsInput || "evcs_input" + Transformer2WInput || "transformer_2_w_input" + Transformer3WInput || "transformer_3_w_input" + CylindricalStorageInput || "cylindrical_storage_input" + ThermalHouseInput || "thermal_house_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all input types models"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + BmTypeInput || "bm_type_input" + ChpTypeInput || "chp_type_input" + EvTypeInput || "ev_type_input" + HpTypeInput || "hp_type_input" + LineTypeInput || "line_type_input" + StorageTypeInput || "storage_type_input" + Transformer2WTypeInput || "transformer_2_w_type_input" + Transformer3WTypeInput || "transformer_3_w_type_input" + WecTypeInput || "wec_type_input" + WecTypeInput || "wec_type_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for a Load Parameter Model"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + RandomLoadParameters || "random_load_parameters_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for a graphic input Model"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + NodeGraphicInput || "node_graphic_input" + LineGraphicInput || "line_graphic_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffix should return empty Optional, if the content of the time series is not covered"() { + given: + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + def entries = [ + new TimeBasedValue(ZonedDateTime.now(), new IntValue(5)) + ] as SortedSet + IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> UUID.randomUUID() + timeSeries.entries >> entries + + when: + Optional actual = strategy.getEntityName(timeSeries) + + then: + !actual.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffix should return empty Optional, if the time series is empty"() { + given: + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + def entries = [] as SortedSet + IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> UUID.randomUUID() + timeSeries.entries >> entries + + when: + Optional actual = strategy.getEntityName(timeSeries) + + then: + !actual.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffix should return valid file name for individual time series" () { + given: + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + def entries = [ + new TimeBasedValue(ZonedDateTime.now(), new EnergyPriceValue(Quantities.getQuantity(500d, PowerSystemUnits.EURO_PER_MEGAWATTHOUR)))] as SortedSet + IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> uuid + timeSeries.entries >> entries + + when: + Optional actual = strategy.getEntityName(timeSeries) + + then: + actual.present + actual.get() == expectedFileName + + where: + clazz | uuid || expectedFileName + IndividualTimeSeries | UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") || "its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276" + } + + def "A EntityPersistenceNamingStrategy with pre- or suffix should return valid file name for individual time series" () { + given: + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("aa", "zz") + def entries = [] as SortedSet + entries.add(new TimeBasedValue(ZonedDateTime.now(), new EnergyPriceValue(Quantities.getQuantity(500d, PowerSystemUnits.EURO_PER_MEGAWATTHOUR)))) + IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> uuid + timeSeries.entries >> entries + + when: + Optional actual = strategy.getEntityName(timeSeries) + + then: + actual.present + actual.get() == expectedFileName + + where: + clazz | uuid || expectedFileName + IndividualTimeSeries | UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") || "aa_its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276_zz" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffix should return valid file name for load profile input" () { + given: + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + LoadProfileInput timeSeries = Mock(LoadProfileInput) + timeSeries.uuid >> uuid + timeSeries.type >> type + + when: + Optional actual = strategy.getEntityName(timeSeries) + + then: + actual.present + actual.get() == expectedFileName + + where: + clazz | uuid | type || expectedFileName + LoadProfileInput | UUID.fromString("bee0a8b6-4788-4f18-bf72-be52035f7304") | BdewLoadProfile.G3 || "lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304" + } + + def "A EntityPersistenceNamingStrategy returns empty Optional, when there is no naming defined for a given time series class"() { + given: + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() + RepetitiveTimeSeries timeSeries = Mock(RepetitiveTimeSeries) + + when: + Optional fileName = entityPersistenceNamingStrategy.getEntityName(timeSeries) + + then: + !fileName.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for time series mapping"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getEntityName(TimeSeriesMappingSource.MappingEntry) + + then: + res.present + res.get() == "time_series_mapping" + } + + def "A EntityPersistenceNamingStrategy with pre- and suffix should return valid strings for time series mapping"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getEntityName(TimeSeriesMappingSource.MappingEntry) + + then: + res.present + res.get() == "prefix_time_series_mapping_suffix" + } + + def "A simple file naming strategy does return empty sub directory path for system type and characteristic model input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + BmTypeInput || Optional.empty() + ChpTypeInput || Optional.empty() + EvTypeInput || Optional.empty() + HpTypeInput || Optional.empty() + StorageTypeInput || Optional.empty() + WecTypeInput || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for other system model input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + FixedFeedInInput || Optional.empty() + PvInput || Optional.empty() + WecInput || Optional.empty() + ChpInput || Optional.empty() + BmInput || Optional.empty() + EvInput || Optional.empty() + LoadInput || Optional.empty() + StorageInput || Optional.empty() + HpInput || Optional.empty() + EvcsInput || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for connector model input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + LineInput || Optional.empty() + SwitchInput || Optional.empty() + Transformer2WInput || Optional.empty() + Transformer3WInput || Optional.empty() + LineTypeInput || Optional.empty() + Transformer2WTypeInput || Optional.empty() + Transformer3WTypeInput || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for graphics model input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + NodeGraphicInput || Optional.empty() + LineGraphicInput || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for thermal model input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + CylindricalStorageInput || Optional.empty() + ThermalHouseInput || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for any other model classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + NodeInput || Optional.empty() + MeasurementUnitInput || Optional.empty() + RandomLoadParameters || Optional.empty() + TimeSeriesMappingSource.MappingEntry || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for any result class"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def actual = strategy.getDirectoryPath(modelClass as Class) + + then: + actual == expected + + where: + modelClass || expected + LoadResult || Optional.empty() + FixedFeedInResult || Optional.empty() + BmResult || Optional.empty() + PvResult || Optional.empty() + ChpResult || Optional.empty() + WecResult || Optional.empty() + StorageResult || Optional.empty() + EvcsResult || Optional.empty() + EvResult || Optional.empty() + Transformer2WResult || Optional.empty() + Transformer3WResult || Optional.empty() + LineResult || Optional.empty() + SwitchResult || Optional.empty() + NodeResult || Optional.empty() + CylindricalStorageResult || Optional.empty() + ThermalHouseResult || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for load profile time series"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + def timeSeries = Mock(LoadProfileInput) + + when: + def actual = strategy.getDirectoryPath(timeSeries) + + then: + actual == Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for individual time series"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + def timeSeries = Mock(IndividualTimeSeries) + + when: + def actual = strategy.getDirectoryPath(timeSeries) + + then: + actual == Optional.empty() + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all connector input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + LineInput || "line_input" + SwitchInput || "switch_input" + Transformer2WInput || "transformer_2_w_input" + Transformer3WInput || "transformer_3_w_input" + LineTypeInput || "line_type_input" + Transformer2WTypeInput || "transformer_2_w_type_input" + Transformer3WTypeInput || "transformer_3_w_type_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all graphics input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + NodeGraphicInput || "node_graphic_input" + LineGraphicInput || "line_graphic_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all thermal input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + CylindricalStorageInput || "cylindrical_storage_input" + ThermalHouseInput || "thermal_house_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all system characteristic and type input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + BmTypeInput || "bm_type_input" + ChpTypeInput || "chp_type_input" + EvTypeInput || "ev_type_input" + HpTypeInput || "hp_type_input" + StorageTypeInput || "storage_type_input" + WecTypeInput || "wec_type_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all other system input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + FixedFeedInInput || "fixed_feed_in_input" + PvInput || "pv_input" + WecInput || "wec_input" + ChpInput || "chp_input" + BmInput || "bm_input" + EvInput || "ev_input" + LoadInput || "load_input" + StorageInput || "storage_input" + HpInput || "hp_input" + EvcsInput || "evcs_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all other input classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + NodeInput || "node_input" + MeasurementUnitInput || "measurement_unit_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all result classes"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + LoadResult || "load_res" + FixedFeedInResult || "fixed_feed_in_res" + BmResult || "bm_res" + PvResult || "pv_res" + ChpResult || "chp_res" + WecResult || "wec_res" + StorageResult || "storage_res" + EvcsResult || "evcs_res" + EvResult || "ev_res" + Transformer2WResult || "transformer_2_w_res" + Transformer3WResult || "transformer_3_w_res" + LineResult || "line_res" + SwitchResult || "switch_res" + NodeResult || "node_res" + CylindricalStorageResult || "cylindrical_storage_res" + ThermalHouseResult || "thermal_house_res" + } + + def "A simple file naming strategy does return valid file path for load profile time series"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + def timeSeries = Mock(LoadProfileInput) + timeSeries.uuid >> uuid + timeSeries.type >> type + + when: + def actual = strategy.getFilePath(timeSeries) + + then: + actual.present + actual.get() == expectedFilePath + + where: + clazz | uuid | type || expectedFilePath + LoadProfileInput | UUID.fromString("bee0a8b6-4788-4f18-bf72-be52035f7304") | BdewLoadProfile.G3 || "lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304" + } + + def "A simple file naming strategy does return valid file path for individual time series"() { + given: "a naming strategy without pre- or suffixes" + def strategy = new EntityPersistenceNamingStrategy() + def entries = [ + new TimeBasedValue(ZonedDateTime.now(), new EnergyPriceValue(Quantities.getQuantity(500d, PowerSystemUnits.EURO_PER_MEGAWATTHOUR)))] as SortedSet + def timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> uuid + timeSeries.entries >> entries + + when: + def actual = strategy.getFilePath(timeSeries) + + then: + actual.present + actual.get() == expectedFilePath + + where: + clazz | uuid || expectedFilePath + IndividualTimeSeries | UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") || "its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276" + } +} diff --git a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy similarity index 80% rename from src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy rename to src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy index 07a733553..c2de9934c 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy @@ -3,8 +3,9 @@ * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ -package edu.ie3.datamodel.io.csv +package edu.ie3.datamodel.io.naming +import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.BdewLoadProfile import edu.ie3.datamodel.models.UniqueEntity @@ -21,8 +22,6 @@ import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput import edu.ie3.datamodel.models.input.graphics.LineGraphicInput import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput import edu.ie3.datamodel.models.input.system.* -import edu.ie3.datamodel.models.input.system.characteristic.EvCharacteristicInput -import edu.ie3.datamodel.models.input.system.characteristic.WecCharacteristicInput import edu.ie3.datamodel.models.input.system.type.* import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput @@ -56,19 +55,19 @@ class HierarchicFileNamingStrategyTest extends Specification { defaultHierarchy = new DefaultDirectoryHierarchy(tmpPath.toString(), "test_grid") } - def "A FileNamingStrategy should return an empty optional on a invalid class"() { - given: "a file naming strategy" + def "A HierarchicFileNamingStrategy should return an empty optional on a invalid class"() { + given: "a naming strategy" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: - def res = strategy.getFileName(String) + def res = strategy.getEntityName(String) then: !res.present } - def "A FileNamingStrategy without pre- or suffixes should return valid directory paths for all result models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory paths for all result models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -98,8 +97,8 @@ class HierarchicFileNamingStrategyTest extends Specification { ThermalHouseResult || "test_grid" + File.separator + "results" + File.separator + "thermal" } - def "A FileNamingStrategy without pre- or suffixes should return valid directory paths for all input assets models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory paths for all input assets models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -131,8 +130,8 @@ class HierarchicFileNamingStrategyTest extends Specification { ThermalHouseInput || "test_grid" + File.separator + "input" + File.separator + "thermal" } - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all input assets models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all system input assets models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -153,53 +152,34 @@ class HierarchicFileNamingStrategyTest extends Specification { LoadInput || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "load_input" StorageInput || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "storage_input" HpInput || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "hp_input" - LineInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "line_input" - SwitchInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "switch_input" - NodeInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "node_input" - MeasurementUnitInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "measurement_unit_input" EvcsInput || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "evcs_input" - Transformer2WInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "transformer_2_w_input" - Transformer3WInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "transformer_3_w_input" - CylindricalStorageInput || "test_grid" + File.separator + "input" + File.separator + "thermal" + File.separator + "cylindrical_storage_input" - ThermalHouseInput || "test_grid" + File.separator + "input" + File.separator + "thermal" + File.separator + "thermal_house_input" } - def "A FileNamingStrategy without pre- or suffixes should return valid directory paths for all asset characteristics models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all other input assets models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: - def res = strategy.getDirectoryPath(modelClass as Class) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - WecCharacteristicInput || "test_grid" + File.separator + "input" + File.separator + "global" - EvCharacteristicInput || "test_grid" + File.separator + "input" + File.separator + "global" - } - - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all asset characteristics models"() { - given: "a file naming strategy without pre- or suffixes" - def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) - - when: - def res = strategy.getFilePath(modelClass as Class) + def res = strategy.getFilePath(modelClass) then: res.present res.get() == expectedString where: - modelClass || expectedString - WecCharacteristicInput || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "wec_characteristic_input" - EvCharacteristicInput || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "ev_characteristic_input" + modelClass || expectedString + LineInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "line_input" + SwitchInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "switch_input" + NodeInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "node_input" + MeasurementUnitInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "measurement_unit_input" + Transformer2WInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "transformer_2_w_input" + Transformer3WInput || "test_grid" + File.separator + "input" + File.separator + "grid" + File.separator + "transformer_3_w_input" + CylindricalStorageInput || "test_grid" + File.separator + "input" + File.separator + "thermal" + File.separator + "cylindrical_storage_input" + ThermalHouseInput || "test_grid" + File.separator + "input" + File.separator + "thermal" + File.separator + "thermal_house_input" } - def "A FileNamingStrategy without pre- or suffixes should return valid directory paths for all input types models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory paths for all input types models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -223,8 +203,8 @@ class HierarchicFileNamingStrategyTest extends Specification { WecTypeInput || "test_grid" + File.separator + "input" + File.separator + "global" } - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all input types models"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all input types models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -247,8 +227,8 @@ class HierarchicFileNamingStrategyTest extends Specification { WecTypeInput || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "wec_type_input" } - def "A FileNamingStrategy without pre- or suffixes should return valid directory path for a Load Parameter Model"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory path for a Load Parameter Model"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -263,8 +243,8 @@ class HierarchicFileNamingStrategyTest extends Specification { RandomLoadParameters || "test_grid" + File.separator + "input" + File.separator + "global" } - def "A FileNamingStrategy without pre- or suffixes should return valid file path for a Load Parameter Model"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file path for a Load Parameter Model"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -279,8 +259,8 @@ class HierarchicFileNamingStrategyTest extends Specification { RandomLoadParameters || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "random_load_parameters_input" } - def "A FileNamingStrategy without pre- or suffixes should return valid directory paths for a graphic input Model"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory paths for a graphic input Model"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -296,8 +276,8 @@ class HierarchicFileNamingStrategyTest extends Specification { LineGraphicInput || "test_grid" + File.separator + "input" + File.separator + "graphics" } - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for a graphic input Model"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for a graphic input Model"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -313,7 +293,7 @@ class HierarchicFileNamingStrategyTest extends Specification { LineGraphicInput || "test_grid" + File.separator + "input" + File.separator + "graphics" + File.separator + "line_graphic_input" } - def "A FileNamingStrategy should return valid directory path for individual time series"() { + def "A HierarchicFileNamingStrategy should return valid directory path for individual time series"() { given: def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) @@ -330,7 +310,7 @@ class HierarchicFileNamingStrategyTest extends Specification { IndividualTimeSeries || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "time_series" } - def "A FileNamingStrategy without pre- or suffix should return valid file path for individual time series"() { + def "A HierarchicFileNamingStrategy without pre- or suffix should return valid file path for individual time series"() { given: def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) def entries = [ @@ -351,7 +331,7 @@ class HierarchicFileNamingStrategyTest extends Specification { IndividualTimeSeries | UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "time_series" + File.separator + "its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276" } - def "A FileNamingStrategy with pre- or suffix should return valid file path for individual time series"() { + def "A HierarchicFileNamingStrategy with pre- or suffix should return valid file path for individual time series"() { given: def strategy = new HierarchicFileNamingStrategy("aa", "zz", defaultHierarchy) def entries = [ @@ -372,7 +352,7 @@ class HierarchicFileNamingStrategyTest extends Specification { IndividualTimeSeries | UUID.fromString("4881fda2-bcee-4f4f-a5bb-6a09bf785276") || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "time_series" + File.separator + "aa_its_c_4881fda2-bcee-4f4f-a5bb-6a09bf785276_zz" } - def "A FileNamingStrategy without pre- or suffix should return valid directory path for load profile input"() { + def "A HierarchicFileNamingStrategy without pre- or suffix should return valid directory path for load profile input"() { given: def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) def timeSeries = Mock(LoadProfileInput) @@ -389,7 +369,7 @@ class HierarchicFileNamingStrategyTest extends Specification { LoadProfileInput || "test_grid" + File.separator + "input" + File.separator + "global" } - def "A FileNamingStrategy without pre- or suffix should return valid file path for load profile input"() { + def "A HierarchicFileNamingStrategy without pre- or suffix should return valid file path for load profile input"() { given: def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) def timeSeries = Mock(LoadProfileInput) @@ -408,20 +388,20 @@ class HierarchicFileNamingStrategyTest extends Specification { LoadProfileInput | UUID.fromString("bee0a8b6-4788-4f18-bf72-be52035f7304") | BdewLoadProfile.G3 || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "lpts_g3_bee0a8b6-4788-4f18-bf72-be52035f7304" } - def "A FileNamingStrategy returns empty Optional, when there is no naming defined for a given time series class"() { + def "A HierarchicFileNamingStrategy returns empty Optional, when there is no naming defined for a given time series class"() { given: def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) def timeSeries = Mock(RepetitiveTimeSeries) when: - def fileName = strategy.getFileName(timeSeries) + def fileName = strategy.getEntityName(timeSeries) then: !fileName.present } - def "A FileNamingStrategy without pre- or suffixes should return valid directory path for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory path for time series mapping"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -432,8 +412,8 @@ class HierarchicFileNamingStrategyTest extends Specification { res.get() == "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "time_series" } - def "A FileNamingStrategy without pre- or suffixes should return valid file path for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file path for time series mapping"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -444,8 +424,8 @@ class HierarchicFileNamingStrategyTest extends Specification { res.get() == "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "time_series" + File.separator + "time_series_mapping" } - def "A FileNamingStrategy with pre- and suffix should return valid file path for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" + def "A HierarchicFileNamingStrategy with pre- and suffix should return valid file path for time series mapping"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy("prefix", "suffix", defaultHierarchy) when: @@ -457,7 +437,7 @@ class HierarchicFileNamingStrategyTest extends Specification { } def "A hierarchic file naming strategy returns correct individual time series file name pattern"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -468,7 +448,7 @@ class HierarchicFileNamingStrategyTest extends Specification { } def "A hierarchic file naming strategy returns correct load profile time series file name pattern"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -477,4 +457,4 @@ class HierarchicFileNamingStrategyTest extends Specification { then: actual == "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "lpts_(?[a-zA-Z][0-9])_(?[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12})" } -} +} \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/io/sink/CsvFileSinkTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/sink/CsvFileSinkTest.groovy index b18e8e302..1c79ad6c9 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/sink/CsvFileSinkTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/sink/CsvFileSinkTest.groovy @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.io.sink -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.io.processor.ProcessorProvider import edu.ie3.datamodel.io.processor.input.InputEntityProcessor import edu.ie3.datamodel.io.processor.result.ResultEntityProcessor @@ -85,7 +85,7 @@ class CsvFileSinkTest extends Specification implements TimeSeriesTestData { new ResultEntityProcessor(PvResult), new ResultEntityProcessor(EvResult) ], [] as Map), - new FileNamingStrategy(), + new EntityPersistenceNamingStrategy(), true, ",") csvFileSink.shutdown() @@ -157,7 +157,7 @@ class CsvFileSinkTest extends Specification implements TimeSeriesTestData { new InputEntityProcessor(ThermalBusInput), new InputEntityProcessor(LineTypeInput) ], [] as Map), - new FileNamingStrategy(), + new EntityPersistenceNamingStrategy(), false, ",") @@ -214,7 +214,7 @@ class CsvFileSinkTest extends Specification implements TimeSeriesTestData { CsvFileSink csvFileSink = new CsvFileSink(testBaseFolderPath, new ProcessorProvider([], timeSeriesProcessorMap), - new FileNamingStrategy(), + new EntityPersistenceNamingStrategy(), false, ",") @@ -288,7 +288,7 @@ class CsvFileSinkTest extends Specification implements TimeSeriesTestData { new ProcessorProvider( ProcessorProvider.allEntityProcessors(), new HashMap, Value>, TimeSeriesEntry, Value>>()), - new FileNamingStrategy(), + new EntityPersistenceNamingStrategy(), false, ",") @@ -308,7 +308,7 @@ class CsvFileSinkTest extends Specification implements TimeSeriesTestData { def csvFileSink = new CsvFileSink( testBaseFolderPath, new ProcessorProvider(), - new FileNamingStrategy(), + new EntityPersistenceNamingStrategy(), false, ",") diff --git a/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy index ee2b2a745..e7252af42 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy @@ -6,7 +6,7 @@ package edu.ie3.datamodel.io.sink import edu.ie3.datamodel.io.connectors.InfluxDbConnector -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.result.ResultEntity @@ -43,7 +43,7 @@ class InfluxDbSinkIT extends Specification { InfluxDbConnector connector @Shared - FileNamingStrategy fileNamingStrategy + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy @Shared InfluxDbSink sink @@ -51,7 +51,7 @@ class InfluxDbSinkIT extends Specification { def setupSpec() { connector = new InfluxDbConnector(influxDbContainer.url,"test_out", "test_scenario") sink = new InfluxDbSink(connector) - fileNamingStrategy = new FileNamingStrategy() + entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() } @@ -73,7 +73,7 @@ class InfluxDbSinkIT extends Specification { when: sink.persist(lineResult1) sink.flush() - def key = fileNamingStrategy.getFileName(LineResult).get().trim().replaceAll("\\W", "_") + def key = entityPersistenceNamingStrategy.getEntityName(LineResult).get().trim().replaceAll("\\W", "_") def queryResult = connector.getSession().query(new Query("SELECT * FROM " + key)) def parsedResults = InfluxDbConnector.parseQueryResult(queryResult) def fieldMap = parsedResults.get(key).first() @@ -125,8 +125,8 @@ class InfluxDbSinkIT extends Specification { ] when: sink.persistAll(entities) - def key_line = fileNamingStrategy.getFileName(LineResult).get().trim().replaceAll("\\W", "_") - def key_chp = fileNamingStrategy.getFileName(ChpResult).get().trim().replaceAll("\\W", "_") + def key_line = entityPersistenceNamingStrategy.getEntityName(LineResult).get().trim().replaceAll("\\W", "_") + def key_chp = entityPersistenceNamingStrategy.getEntityName(ChpResult).get().trim().replaceAll("\\W", "_") def queryResult = connector.getSession().query(new Query("SELECT * FROM " + key_line + ", " + key_chp)) def parsedResults = InfluxDbConnector.parseQueryResult(queryResult) def lineResults = parsedResults.get(key_line) @@ -154,7 +154,7 @@ class InfluxDbSinkIT extends Specification { IndividualTimeSeries timeSeries = new IndividualTimeSeries(UUID.randomUUID(), [p1, p2, p3] as Set) when: sink.persistTimeSeries(timeSeries) - def key = fileNamingStrategy.getFileName(timeSeries).get().trim().replaceAll("\\W", "_") + def key = entityPersistenceNamingStrategy.getEntityName(timeSeries).get().trim().replaceAll("\\W", "_") def queryResult = connector.getSession().query(new Query("SELECT * FROM " + key)) def parsedResults = InfluxDbConnector.parseQueryResult(queryResult) def pValuesMap = parsedResults.get(key) @@ -270,14 +270,14 @@ class InfluxDbSinkIT extends Specification { } //Always return an empty Optional for results - class EmptyFileNamingStrategy extends FileNamingStrategy { + class EmptyFileNamingStrategy extends EntityPersistenceNamingStrategy { @Override - Optional getResultEntityFileName(Class resultEntityClass) { + Optional getResultEntityName(Class resultEntityClass) { return Optional.empty() } @Override - , E extends TimeSeriesEntry, V extends Value> Optional getFileName(T timeSeries) { + , E extends TimeSeriesEntry, V extends Value> Optional getEntityName(T timeSeries) { return Optional.empty() } } diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CosmoCsvIdCoordinateSourceIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CosmoCsvIdCoordinateSourceIT.groovy index 1685c017d..cb61d71ee 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CosmoCsvIdCoordinateSourceIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CosmoCsvIdCoordinateSourceIT.groovy @@ -20,7 +20,7 @@ class CosmoCsvIdCoordinateSourceIT extends Specification implements CsvTestDataM CsvIdCoordinateSource source def setupSpec() { - source = new CsvIdCoordinateSource(csvSep, coordinatesFolderPath + "_cosmo", fileNamingStrategy, new CosmoIdCoordinateFactory()) + source = new CsvIdCoordinateSource(csvSep, coordinatesFolderPath + "_cosmo", entityPersistenceNamingStrategy, new CosmoIdCoordinateFactory()) } def "The CsvCoordinateSource is able to create a valid stream from a coordinate file"() { diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvDataSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvDataSourceTest.groovy index 9659a6b00..7758d26e3 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvDataSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvDataSourceTest.groovy @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.io.source.csv -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.UniqueEntity import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput @@ -29,8 +29,8 @@ class CsvDataSourceTest extends Specification { // methods in a public or protected method makes them available for testing private final class DummyCsvSource extends CsvDataSource { - DummyCsvSource(String csvSep, String folderPath, FileNamingStrategy fileNamingStrategy) { - super(csvSep, folderPath, fileNamingStrategy) + DummyCsvSource(String csvSep, String folderPath, EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { + super(csvSep, folderPath, entityPersistenceNamingStrategy) } Map buildFieldsToAttributes( @@ -62,9 +62,9 @@ class CsvDataSourceTest extends Specification { @Shared String csvSep = "," String testBaseFolderPath = new File(getClass().getResource('/testGridFiles').toURI()).getAbsolutePath() - FileNamingStrategy fileNamingStrategy = new FileNamingStrategy() + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() - DummyCsvSource dummyCsvSource = new DummyCsvSource(csvSep, testBaseFolderPath, fileNamingStrategy) + DummyCsvSource dummyCsvSource = new DummyCsvSource(csvSep, testBaseFolderPath, entityPersistenceNamingStrategy) def "A csv data source returns empty optional, when looking for a specific uuid"() { given: @@ -100,7 +100,7 @@ class CsvDataSourceTest extends Specification { expect: dummyCsvSource.connector != null dummyCsvSource.connector.baseDirectoryName == testBaseFolderPath - dummyCsvSource.connector.fileNamingStrategy == fileNamingStrategy + dummyCsvSource.connector.entityPersistenceNamingStrategy == entityPersistenceNamingStrategy dummyCsvSource.connector.entityWriters.isEmpty() } diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy index 6668bd2ef..43a81f910 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy @@ -20,9 +20,9 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should provide an instance of GraphicElements based on valid input data correctly"() { given: - def typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - def rawGridSource = new CsvRawGridSource(csvSep, gridFolderPath, fileNamingStrategy, typeSource) - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, typeSource, rawGridSource) + def typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + def rawGridSource = new CsvRawGridSource(csvSep, gridFolderPath, entityPersistenceNamingStrategy, typeSource) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, typeSource, rawGridSource) when: def graphicElementsOpt = csvGraphicSource.getGraphicElements() @@ -38,9 +38,9 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should process invalid input data as expected when requested to provide an instance of GraphicElements"() { given: - def typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) + def typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) def rawGridSource = - new CsvRawGridSource(csvSep, gridFolderPath, fileNamingStrategy, typeSource) { + new CsvRawGridSource(csvSep, gridFolderPath, entityPersistenceNamingStrategy, typeSource) { @Override Set getNodes() { return Collections.emptySet() @@ -52,7 +52,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { } } - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, typeSource, rawGridSource) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, typeSource, rawGridSource) when: def graphicElementsOpt = csvGraphicSource.getGraphicElements() @@ -64,7 +64,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should read and handle a valid node graphics file as expected"() { given: - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) def expectedNodeGraphicD = new NodeGraphicInput( gtd.nodeGraphicD.uuid, gtd.nodeGraphicD.graphicLayer, @@ -92,7 +92,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should read and handle a valid line graphics file as expected"() { given: - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) when: def lineGraphics = csvGraphicSource.getLineGraphicInput([gtd.lineCtoD] as Set) @@ -104,7 +104,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should build node graphic entity data from valid and invalid input data correctly"() { given: - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) def fieldsToAttributesMap = [ "uuid" : "09aec636-791b-45aa-b981-b14edf171c4c", "graphic_layer": "main", @@ -138,7 +138,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should build line graphic entity data from valid and invalid input data correctly"() { given: - def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) + def csvGraphicSource = new CsvGraphicSource(csvSep, graphicsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvRawGridSource)) def fieldsToAttributesMap = [ "uuid" : "ece86139-3238-4a35-9361-457ecb4258b0", "graphic_layer": "main", diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy index f1a1ffcbe..07b235d10 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy @@ -27,8 +27,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { CsvRawGridSource source def setupSpec() { - CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - source = new CsvRawGridSource(csvSep, gridFolderPath, fileNamingStrategy, typeSource) + CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + source = new CsvRawGridSource(csvSep, gridFolderPath, entityPersistenceNamingStrategy, typeSource) } def "The CsvRawGridSource is able to convert single valid AssetInputEntityData to ConnectorInputEntityData"() { @@ -742,8 +742,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def "The CsvRawGridSource returns an empty Optional, if one mandatory element for the RawGridElements is missing"() { given: "a source pointing to malformed grid data" - CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - source = new CsvRawGridSource(csvSep, gridFolderPath+"_malformed", fileNamingStrategy, typeSource) + CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + source = new CsvRawGridSource(csvSep, gridFolderPath + "_malformed", entityPersistenceNamingStrategy, typeSource) when: "loading a total grid structure from file" def actual = source.getGridData() @@ -754,8 +754,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def "The CsvRawGridSource returns an empty Optional, if the RawGridElements contain no single element"() { given: "a source pointing to malformed grid data" - CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - source = new CsvRawGridSource(csvSep, gridFolderPath+"_empty", fileNamingStrategy, typeSource) + CsvTypeSource typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + source = new CsvRawGridSource(csvSep, gridFolderPath + "_empty", entityPersistenceNamingStrategy, typeSource) when: "loading a total grid structure from file" def actual = source.getGridData() diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy index a16acf375..dac895b8d 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy @@ -32,11 +32,11 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should provide an instance of SystemParticipants based on valid input data correctly"() { given: - def typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - def thermalSource = new CsvThermalSource(csvSep, participantsFolderPath, fileNamingStrategy, typeSource) - def rawGridSource = new CsvRawGridSource(csvSep, gridFolderPath, fileNamingStrategy, typeSource) + def typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + def thermalSource = new CsvThermalSource(csvSep, participantsFolderPath, entityPersistenceNamingStrategy, typeSource) + def rawGridSource = new CsvRawGridSource(csvSep, gridFolderPath, entityPersistenceNamingStrategy, typeSource) def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, - participantsFolderPath, fileNamingStrategy, typeSource, + participantsFolderPath, entityPersistenceNamingStrategy, typeSource, thermalSource, rawGridSource) when: @@ -61,12 +61,12 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should process invalid input data as expected when requested to provide an instance of SystemParticipants"() { given: - def typeSource = new CsvTypeSource(csvSep, typeFolderPath, fileNamingStrategy) - def thermalSource = new CsvThermalSource(csvSep, participantsFolderPath, fileNamingStrategy, typeSource) + def typeSource = new CsvTypeSource(csvSep, typeFolderPath, entityPersistenceNamingStrategy) + def thermalSource = new CsvThermalSource(csvSep, participantsFolderPath, entityPersistenceNamingStrategy, typeSource) def rawGridSource = Spy(CsvRawGridSource, constructorArgs: [ csvSep, gridFolderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, typeSource ]) { // partly fake the return method of the csv raw grid source to always return empty node sets @@ -75,7 +75,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat getNodes(_) >> new HashSet() } as RawGridSource def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, - participantsFolderPath, fileNamingStrategy, typeSource, + participantsFolderPath, entityPersistenceNamingStrategy, typeSource, thermalSource, rawGridSource) when: @@ -88,7 +88,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should build typed entity from valid and invalid input data as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, - participantsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), + participantsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) def nodeAssetInputEntityData = new NodeAssetInputEntityData(fieldsToAttributes, clazz, operator, node) @@ -114,7 +114,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should build hp input entity from valid and invalid input data as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, - participantsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), + participantsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) def sysPartTypedEntityData = new SystemParticipantTypedEntityData<>(fieldsToAttributes, HpInput, sptd.hpInput.operator, sptd.hpInput.node, sptd.hpTypeInput) @@ -140,7 +140,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should build chp input entity from valid and invalid input data as expected"(List thermalStorages, List thermalBuses, Map fieldsToAttributes, boolean resultIsPresent, ChpInputEntityData resultData) { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, - participantsFolderPath, fileNamingStrategy, Mock(CsvTypeSource), + participantsFolderPath, entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) def sysPartTypedEntityData = new SystemParticipantTypedEntityData<>(fieldsToAttributes, ChpInput, sptd.chpInput.operator, sptd.chpInput.node, sptd.chpTypeInput) @@ -168,7 +168,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from a valid heat pump input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def heatPumps = csvSystemParticipantSource.getHeatPumps(nodes as Set, operators as Set, types as Set, thermalBuses as Set) @@ -190,7 +190,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from a valid chp input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def chpUnits = csvSystemParticipantSource.getChpPlants(nodes as Set, operators as Set, types as Set, thermalBuses as Set, thermalStorages as Set) @@ -214,7 +214,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid ev input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getEvs(nodes as Set, operators as Set, types as Set) @@ -235,7 +235,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid wec input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getWecPlants(nodes as Set, operators as Set, types as Set) @@ -256,7 +256,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid storage input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getStorages(nodes as Set, operators as Set, types as Set) @@ -277,7 +277,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid bm input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getBmPlants(nodes as Set, operators as Set, types as Set) @@ -298,7 +298,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid ev charging station input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getEvCS(nodes as Set, operators as Set) @@ -318,7 +318,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid load input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getLoads(nodes as Set, operators as Set) @@ -338,7 +338,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid pv input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getPvPlants(nodes as Set, operators as Set) @@ -358,7 +358,7 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid fixedFeedIn input file as expected"() { given: def csvSystemParticipantSource = new CsvSystemParticipantSource(csvSep, participantsFolderPath, - fileNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) + entityPersistenceNamingStrategy, Mock(CsvTypeSource), Mock(CsvThermalSource), Mock(CsvRawGridSource)) expect: def sysParts = csvSystemParticipantSource.getFixedFeedIns(nodes as Set, operators as Set) diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy index ac0d23fcb..67999fad6 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.io.source.csv -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy /** * Holds meta data for csv tests e.g. file and folder paths @@ -23,5 +23,5 @@ trait CsvTestDataMeta { static String coordinatesFolderPath = testParticipantsBaseFolderPath.concat(File.separator).concat("coordinates") static String csvSep = "," - static FileNamingStrategy fileNamingStrategy = new FileNamingStrategy() + static EntityPersistenceNamingStrategy entityPersistenceNamingStrategy = new EntityPersistenceNamingStrategy() } \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy index 9daa00085..ef9b9090d 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy @@ -5,9 +5,9 @@ */ package edu.ie3.datamodel.io.source.csv -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.factory.input.AssetInputEntityData import edu.ie3.datamodel.io.factory.input.ThermalUnitInputEntityData +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.models.input.thermal.ThermalUnitInput @@ -21,8 +21,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { def "A CsvThermalSource should return ThermalBuses from valid and invalid input data as expected"() { given: - def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) - def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, fileNamingStrategy, csvTypeSource) + def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) + def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, entityPersistenceNamingStrategy, csvTypeSource) def operators = csvTypeSource.operators //test method when no operators are provided as constructor parameters @@ -50,8 +50,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { def "A CsvThermalSource should return a CylindricalStorageInput from valid and invalid input data as expected"() { given: - def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) - def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, fileNamingStrategy, csvTypeSource) + def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) + def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, entityPersistenceNamingStrategy, csvTypeSource) def operators = csvTypeSource.operators def thermalBuses = csvThermalSource.thermalBuses @@ -93,8 +93,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { def "A CsvThermalSource should build thermal unit input entity from valid and invalid input data as expected"() { given: - def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) - def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, fileNamingStrategy, csvTypeSource) + def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) + def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, entityPersistenceNamingStrategy, csvTypeSource) def operator = new OperatorInput(UUID.fromString("8f9682df-0744-4b58-a122-f0dc730f6510"), "testOperator") def validFieldsToAttributes = [ "uuid" : "717af017-cc69-406f-b452-e022d7fb516a", @@ -135,8 +135,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { def "A CsvThermalSource should return a ThermalHouseInput from valid and invalid input data as expected"() { given: - def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) - def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, fileNamingStrategy, csvTypeSource) + def csvTypeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) + def csvThermalSource = new CsvThermalSource(csvSep, thermalFolderPath, entityPersistenceNamingStrategy, csvTypeSource) def operators = csvTypeSource.operators def thermalBuses = csvThermalSource.thermalBuses diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSourceIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSourceIT.groovy index ac1ad471f..8382af87d 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSourceIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesMappingSourceIT.groovy @@ -6,8 +6,8 @@ package edu.ie3.datamodel.io.source.csv import edu.ie3.datamodel.io.connectors.CsvFileConnector -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import spock.lang.Shared import spock.lang.Specification @@ -17,7 +17,7 @@ class CsvTimeSeriesMappingSourceIT extends Specification implements CsvTestDataM TimeSeriesMappingSource source def setupSpec() { - source = new CsvTimeSeriesMappingSource(";", timeSeriesFolderPath, new FileNamingStrategy()) + source = new CsvTimeSeriesMappingSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy()) } def "The csv time series mapping source is able to provide a valid time series mapping from files"() { diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceIT.groovy index 1d74241e9..f18b3f425 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceIT.groovy @@ -6,8 +6,8 @@ package edu.ie3.datamodel.io.source.csv import edu.ie3.datamodel.exceptions.SourceException -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.factory.timeseries.TimeBasedSimpleValueFactory +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.value.HeatAndPValue import edu.ie3.util.TimeUtil @@ -26,7 +26,7 @@ class CsvTimeSeriesSourceIT extends Specification implements CsvTestDataMeta { def setup() { factory = new TimeBasedSimpleValueFactory<>(HeatAndPValue) - source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy(), UUID.fromString("76c9d846-797c-4f07-b7ec-2245f679f5c7"), "its_ph_76c9d846-797c-4f07-b7ec-2245f679f5c7", HeatAndPValue, factory) + source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), UUID.fromString("76c9d846-797c-4f07-b7ec-2245f679f5c7"), "its_ph_76c9d846-797c-4f07-b7ec-2245f679f5c7", HeatAndPValue, factory) } def "A csv time series source throw an Exception, if the file cannot be found"() { @@ -57,7 +57,7 @@ class CsvTimeSeriesSourceIT extends Specification implements CsvTestDataMeta { def "Construction a csv time series source with malicious parameters, leads to IllegalArgumentException"() { when: - new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy(), UUID.fromString("fbc59b5b-9307-4fb4-a406-c1f08f26fee5"), "file/not/found", HeatAndPValue, factory) + new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), UUID.fromString("fbc59b5b-9307-4fb4-a406-c1f08f26fee5"), "file/not/found", HeatAndPValue, factory) then: def e = thrown(IllegalArgumentException) @@ -87,4 +87,4 @@ class CsvTimeSeriesSourceIT extends Specification implements CsvTestDataMeta { actual.present actual.get() == new HeatAndPValue(Quantities.getQuantity(1250.0, StandardUnits.ACTIVE_POWER_IN), Quantities.getQuantity(12.0, StandardUnits.HEAT_DEMAND)) } -} +} \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy index 698c3132a..616e8cb3e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy @@ -5,11 +5,12 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy + import static edu.ie3.datamodel.models.StandardUnits.ENERGY_PRICE import edu.ie3.datamodel.exceptions.SourceException import edu.ie3.datamodel.io.connectors.CsvFileConnector -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme import edu.ie3.datamodel.io.factory.timeseries.TimeBasedSimpleValueFactory import edu.ie3.datamodel.io.source.IdCoordinateSource @@ -31,7 +32,7 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(5) >> defaultCoordinate def factory = new TimeBasedSimpleValueFactory(EnergyPriceValue) - def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy(), UUID.fromString("2fcb3e53-b94a-4b96-bea4-c469e499f1a1"), "its_c_2fcb3e53-b94a-4b96-bea4-c469e499f1a1", EnergyPriceValue, factory) + def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), UUID.fromString("2fcb3e53-b94a-4b96-bea4-c469e499f1a1"), "its_c_2fcb3e53-b94a-4b96-bea4-c469e499f1a1", EnergyPriceValue, factory) def time = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") def timeUtil = new TimeUtil(ZoneId.of("UTC"), Locale.GERMANY, "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'") def fieldToValue = [ @@ -58,7 +59,7 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def metaInformation = new CsvFileConnector.CsvIndividualTimeSeriesMetaInformation(UUID.fromString("8bc9120d-fb9b-4484-b4e3-0cdadf0feea9"), ColumnScheme.WEATHER, "its_weather_8bc9120d-fb9b-4484-b4e3-0cdadf0feea9") when: - CsvTimeSeriesSource.getSource(";", timeSeriesFolderPath, fileNamingStrategy, metaInformation) + CsvTimeSeriesSource.getSource(";", timeSeriesFolderPath, entityPersistenceNamingStrategy, metaInformation) then: def e = thrown(SourceException) @@ -70,7 +71,7 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def metaInformation = new CsvFileConnector.CsvIndividualTimeSeriesMetaInformation(uuid, columnScheme, path) when: - def actual = CsvTimeSeriesSource.getSource(";", timeSeriesFolderPath, fileNamingStrategy, metaInformation) + def actual = CsvTimeSeriesSource.getSource(";", timeSeriesFolderPath, entityPersistenceNamingStrategy, metaInformation) then: actual.timeSeries.entries.size() == amountOfEntries @@ -85,4 +86,4 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { UUID.fromString("3fbfaa97-cff4-46d4-95ba-a95665e87c26") | ColumnScheme.APPARENT_POWER | "its_pq_3fbfaa97-cff4-46d4-95ba-a95665e87c26" || 2 | SValue UUID.fromString("46be1e57-e4ed-4ef7-95f1-b2b321cb2047") | ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND | "its_pqh_46be1e57-e4ed-4ef7-95f1-b2b321cb2047" || 2 | HeatAndSValue } -} +} \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTypeSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTypeSourceTest.groovy index 289ff0e75..63072d46b 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTypeSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTypeSourceTest.groovy @@ -5,7 +5,7 @@ */ package edu.ie3.datamodel.io.source.csv -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.models.input.OperatorInput import spock.lang.Specification import edu.ie3.test.common.GridTestData as gtd @@ -16,7 +16,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid 2W Transformer type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def transformer2WTypes = typeSource.transformer2WTypes @@ -45,7 +45,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { UUID.fromString("f15105c4-a2de-4ab8-a621-4bc98e372d92"), "Univ.-Prof. Dr. rer. hort. Klaus-Dieter Brokkoli") def secondOperator = new OperatorInput( UUID.fromString("8f9682df-0744-4b58-a122-f0dc730f6510"), "TestOperator") - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def operators = typeSource.operators @@ -57,7 +57,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid line type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def lineTypes = typeSource.lineTypes @@ -73,7 +73,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid 3W Transformer type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def transformer3WTypes = typeSource.transformer3WTypes @@ -102,7 +102,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid bm type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def bmTypes = typeSource.bmTypes @@ -117,7 +117,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid chp type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def chpTypes = typeSource.chpTypes @@ -134,7 +134,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid hp type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def hpTypes = typeSource.hpTypes @@ -149,7 +149,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid storage type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def storageTypes = typeSource.storageTypes @@ -170,7 +170,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid wec type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def wecTypes = typeSource.wecTypes @@ -192,7 +192,7 @@ class CsvTypeSourceTest extends Specification implements CsvTestDataMeta { def "A CsvTypeSource should read and handle valid ev type file as expected"() { given: - def typeSource = new CsvTypeSource(",", typeFolderPath, new FileNamingStrategy()) + def typeSource = new CsvTypeSource(",", typeFolderPath, new EntityPersistenceNamingStrategy()) expect: def evTypes = typeSource.evTypes diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourceIconTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourceIconTest.groovy index f0289f990..d72904c39 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourceIconTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourceIconTest.groovy @@ -5,8 +5,8 @@ */ package edu.ie3.datamodel.io.source.csv -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.factory.timeseries.IconTimeBasedWeatherValueFactory +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.io.source.IdCoordinateSource import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue @@ -36,7 +36,7 @@ class CsvWeatherSourceIconTest extends Specification implements CsvTestDataMeta, coordinateSource = WeatherTestData.coordinateSource def weatherFactory = new IconTimeBasedWeatherValueFactory() folderPath = new File(getClass().getResource('/weather/icon').toURI()).absolutePath - source = new CsvWeatherSource(",", folderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + source = new CsvWeatherSource(",", folderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) } def "A CsvWeatherSource can read and correctly parse a single value for a specific date and coordinate"() { @@ -106,7 +106,7 @@ class CsvWeatherSourceIconTest extends Specification implements CsvTestDataMeta, def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(_) >> { args -> args[0] == 67775 ? Optional.of(expectedCoordinate) : Optional.empty() } def weatherFactory = new IconTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(",", folderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(",", folderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = new TreeMap<>(String.CASE_INSENSITIVE_ORDER) fieldToValues.putAll( [ @@ -153,7 +153,7 @@ class CsvWeatherSourceIconTest extends Specification implements CsvTestDataMeta, given: def coordinateSource = new WeatherTestData.DummyIdCoordinateSource() def weatherFactory = new IconTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(",", folderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(",", folderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "datum" : "2019-08-01 01:00:00", "albRad" : "13.015240669", @@ -197,7 +197,7 @@ class CsvWeatherSourceIconTest extends Specification implements CsvTestDataMeta, given: def coordinateSource = new WeatherTestData.DummyIdCoordinateSource() def weatherFactory = new IconTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(",", folderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(",", folderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "datum" : "2019-08-01 01:00:00", "albRad" : "13.015240669", @@ -240,7 +240,7 @@ class CsvWeatherSourceIconTest extends Specification implements CsvTestDataMeta, given: def coordinateSource = new WeatherTestData.DummyIdCoordinateSource() def weatherFactory = new IconTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(",", folderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(",", folderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "datum" : "2019-08-01 01:00:00", "albrad" : "13.015240669", diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourcePsdmTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourcePsdmTest.groovy index 5b2567cd5..07ceff508 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourcePsdmTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvWeatherSourcePsdmTest.groovy @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy + import static edu.ie3.datamodel.models.StandardUnits.SOLAR_IRRADIANCE import static edu.ie3.datamodel.models.StandardUnits.TEMPERATURE import static edu.ie3.datamodel.models.StandardUnits.WIND_DIRECTION @@ -12,7 +14,6 @@ import static edu.ie3.datamodel.models.StandardUnits.WIND_VELOCITY import edu.ie3.datamodel.io.factory.timeseries.PsdmTimeBasedWeatherValueFactory import edu.ie3.datamodel.models.value.SolarIrradianceValue -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.source.IdCoordinateSource import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue @@ -41,7 +42,7 @@ class CsvWeatherSourcePsdmTest extends Specification implements CsvTestDataMeta, def setupSpec() { coordinateSource = PsdmWeatherTestData.coordinateSource def weatherFactory = new PsdmTimeBasedWeatherValueFactory() - source = new CsvWeatherSource(";", timeSeriesFolderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + source = new CsvWeatherSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) } def "A CsvWeatherSource can read and correctly parse a single value for a specific date and coordinate"() { @@ -108,7 +109,7 @@ class CsvWeatherSourcePsdmTest extends Specification implements CsvTestDataMeta, def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(_) >> { args -> args[0] == 5 ? Optional.of(defaultCoordinate) : Optional.empty() } def weatherFactory = new PsdmTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(";", timeSeriesFolderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "uuid" : "71a79f59-eebf-40c1-8358-ba7414077d57", "time" : "2020-10-16T12:40:42Z", @@ -152,7 +153,7 @@ class CsvWeatherSourcePsdmTest extends Specification implements CsvTestDataMeta, def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(_) >> { args -> args[0] == 5 ? Optional.of(defaultCoordinate) : Optional.empty() } def weatherFactory = new PsdmTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(";", timeSeriesFolderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "uuid" : "71a79f59-eebf-40c1-8358-ba7414077d57", "time" : "2020-10-16T12:40:42Z", @@ -177,7 +178,7 @@ class CsvWeatherSourcePsdmTest extends Specification implements CsvTestDataMeta, def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(_) >> { args -> args[0] == 5 ? Optional.of(defaultCoordinate) : Optional.empty() } def weatherFactory = new PsdmTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(";", timeSeriesFolderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "uuid" : "71a79f59-eebf-40c1-8358-ba7414077d57", "time" : "2020-10-16T12:40:42Z", @@ -200,7 +201,7 @@ class CsvWeatherSourcePsdmTest extends Specification implements CsvTestDataMeta, def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(_) >> Optional.empty() def weatherFactory = new PsdmTimeBasedWeatherValueFactory() - def source = new CsvWeatherSource(";", timeSeriesFolderPath, new FileNamingStrategy(), coordinateSource, weatherFactory) + def source = new CsvWeatherSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy(), coordinateSource, weatherFactory) def fieldToValues = [ "uuid" : "71a79f59-eebf-40c1-8358-ba7414077d57", "time" : "2020-10-16T12:40:42Z", diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/IconCsvIdCoordinateSourceIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/IconCsvIdCoordinateSourceIT.groovy index 3b96d43f7..c2c59b880 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/IconCsvIdCoordinateSourceIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/IconCsvIdCoordinateSourceIT.groovy @@ -20,7 +20,7 @@ class IconCsvIdCoordinateSourceIT extends Specification implements CsvTestDataMe CsvIdCoordinateSource source def setupSpec() { - source = new CsvIdCoordinateSource(csvSep, coordinatesFolderPath + "_icon", fileNamingStrategy, new IconIdCoordinateFactory()) + source = new CsvIdCoordinateSource(csvSep, coordinatesFolderPath + "_icon", entityPersistenceNamingStrategy, new IconIdCoordinateFactory()) } def "The CsvCoordinateSource is able to create a valid stream from a coordinate file"() {