From 9c38ee148a4cb472949a4d7b16e0f73d31ee97a9 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Feb 2021 12:53:51 +0100 Subject: [PATCH 01/24] #246 Deprecated FileNamingStrategy, created EntityPersistenceNamingStrategy for replacing it and refactored the code --- .../datamodel/io/csv/FileNamingStrategy.java | 2 + .../file/EntityPersistenceNamingStrategy.java | 493 ++++++++++++++++++ 2 files changed, 495 insertions(+) create mode 100644 src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java 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 563ff6737..bd6cff121 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,7 @@ 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.file.EntityPersistenceNamingStrategy; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; import edu.ie3.datamodel.models.input.AssetTypeInput; @@ -39,6 +40,7 @@ * * @version 0.1 * @since 03.02.20 + * @deprecated replaced by {@link EntityPersistenceNamingStrategy} */ public class FileNamingStrategy { diff --git a/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java new file mode 100644 index 000000000..b665c52b6 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java @@ -0,0 +1,493 @@ +/* + * © 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.file; + +import edu.ie3.datamodel.io.csv.FileNameMetaInformation; +import edu.ie3.datamodel.io.csv.HierarchicFileNamingStrategy; +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.models.UniqueEntity; +import edu.ie3.datamodel.models.input.AssetInput; +import edu.ie3.datamodel.models.input.AssetTypeInput; +import edu.ie3.datamodel.models.input.OperatorInput; +import edu.ie3.datamodel.models.input.RandomLoadParameters; +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.mapping.TimeSeriesMapping; +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 based on the class that should be processed + * e.g. when writing .csv files. Represents a flat dir with all files inside. To use a hierarchic + * directory structure 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 file names without provided files with prefix and suffix */ + public EntityPersistenceNamingStrategy() { + this("", ""); + } + + /** + * Constructor for building the file names + * + * @param prefix Prefix of the files + */ + public EntityPersistenceNamingStrategy(String prefix) { + this(prefix, ""); + } + + /** + * Constructor for building the file names + * + * @param prefix Prefix of the files + * @param suffix Suffixes of the files + */ + 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); + } + + /** + * 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 + */ + 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( + getFileName(cls).orElseGet(() -> ""), getDirectoryPath(cls).orElseGet(() -> "")); + } + + 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 file name (and only the file name without any directories and extension). + * + * @param cls Targeted class of the given file + * @return The file name + */ + public Optional getFileName(Class cls) { + if (AssetTypeInput.class.isAssignableFrom(cls)) + return getTypeFileName(cls.asSubclass(AssetTypeInput.class)); + if (AssetInput.class.isAssignableFrom(cls)) + return getAssetInputFileName(cls.asSubclass(AssetInput.class)); + if (ResultEntity.class.isAssignableFrom(cls)) + return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); + if (CharacteristicInput.class.isAssignableFrom(cls)) + return getAssetCharacteristicsFileName(cls.asSubclass(CharacteristicInput.class)); + if (cls.equals(RandomLoadParameters.class)) { + String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); + return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); + } + if (GraphicInput.class.isAssignableFrom(cls)) + return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class)); + if (OperatorInput.class.isAssignableFrom(cls)) + return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); + if (TimeSeriesMapping.Entry.class.isAssignableFrom(cls)) return getTimeSeriesMappingFileName(); + logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); + return Optional.empty(); + } + + /** + * Get the the file name for all {@link AssetTypeInput}s + * + * @param typeClass the asset type class a filename string should be generated from + * @return the filename string + */ + public Optional getTypeFileName(Class typeClass) { + String assetTypeString = camelCaseToSnakeCase(typeClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetTypeString)); + } + + /** + * Get the the file name for all {@link AssetInput}s + * + * @param assetInputClass the asset input class a filename string should be generated from + * @return the filename string + */ + public Optional getAssetInputFileName(Class assetInputClass) { + String assetInputString = camelCaseToSnakeCase(assetInputClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the the file name for all {@link ResultEntity}s + * + * @param resultEntityClass the result entity class a filename string should be generated from + * @return the filename string + */ + public Optional getResultEntityFileName(Class resultEntityClass) { + return Optional.of(buildResultEntityString(resultEntityClass)); + } + + private String buildResultEntityString(Class resultEntityClass) { + String resultEntityString = + camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); + return addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX)); + } + + /** + * Get the the file name for all {@link CharacteristicInput}s + * + * @param assetCharClass the asset characteristics class a filename string should be generated + * from + * @return the filename string + */ + public Optional getAssetCharacteristicsFileName( + 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 = "((? getGraphicsInputFileName(Class graphicClass) { + String assetInputString = camelCaseToSnakeCase(graphicClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the the file name for all {@link OperatorInput}s + * + * @param operatorClass the asset input class a filename string should be generated from + * @return the filename string + */ + public Optional getOperatorInputFileName(Class operatorClass) { + String assetInputString = camelCaseToSnakeCase(operatorClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the file name for time series mapping + * + * @return The file name string + */ + public Optional getTimeSeriesMappingFileName() { + 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( + getFileName(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 getFileName(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 (getIndividualTimeSeriesPattern().matcher(withoutEnding).matches()) + return extractIndividualTimesSeriesMetaInformation(withoutEnding); + else if (getLoadProfileTimeSeriesPattern().matcher(withoutEnding).matches()) + return extractLoadProfileTimesSeriesMetaInformation(withoutEnding); + else + throw new IllegalArgumentException( + "Unknown format of '" + fileName + "'. Cannot extract meta information."); + } + + public Pattern getIndividualTimeSeriesPattern() { + return individualTimeSeriesPattern; + } + + /** + * 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 = getIndividualTimeSeriesPattern().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); + } + + public Pattern getLoadProfileTimeSeriesPattern() { + return loadProfileTimeSeriesPattern; + } + + /** + * 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 = getLoadProfileTimeSeriesPattern().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 the file name for coordinates + * + * @return the filename string + */ + public String getIdCoordinateFileName() { + return addPrefixAndSuffix("coordinates"); + } +} From 9d668abe9fec47cbb233f25c64c6d336d5d97656 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Feb 2021 18:27:28 +0100 Subject: [PATCH 02/24] #279 Duplicated test cases of FileNamingStrategy to test EntityPersistenceNamingStrategy --- ...EntityPersistenceNamingStrategyTest.groovy | 832 ++++++++++++++++++ 1 file changed, 832 insertions(+) create mode 100644 src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy diff --git a/src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy new file mode 100644 index 000000000..08a119836 --- /dev/null +++ b/src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy @@ -0,0 +1,832 @@ +/* + * © 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.file + +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.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.* +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 +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.* +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.mapping.TimeSeriesMapping +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 file naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("", "") + + expect: + strategy.prefix == "" + strategy.suffix == "" + } + + def "A EntityPersistenceNamingStrategy should correctly append and prepend underscores"() { + given: "a file 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 file 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 file naming strategy" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(String) + + then: + !res.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all result models"() { + given: "a file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(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 file naming strategy with pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getFileName(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 file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(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 asset characteristics models"() { + given: "a file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + WecCharacteristicInput || "wec_characteristic_input" + EvCharacteristicInput || "ev_characteristic_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all input types models"() { + given: "a file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(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 file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(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 file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getType() >> type + + when: + Optional actual = strategy.getFileName(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.getFileName(timeSeries) + + then: + !fileName.present + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for time series mapping"() { + given: "a file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(TimeSeriesMapping.Entry) + + 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 file naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getFileName(TimeSeriesMapping.Entry) + + then: + res.present + res.get() == "prefix_time_series_mapping_suffix" + } + + def "A simple file naming strategy does return empty sub directory path for any model input class"() { + given: "a file 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() + LineInput || Optional.empty() + SwitchInput || Optional.empty() + NodeInput || Optional.empty() + MeasurementUnitInput || Optional.empty() + EvcsInput || Optional.empty() + Transformer2WInput || Optional.empty() + Transformer3WInput || Optional.empty() + CylindricalStorageInput || Optional.empty() + ThermalHouseInput || Optional.empty() + BmTypeInput || Optional.empty() + ChpTypeInput || Optional.empty() + EvTypeInput || Optional.empty() + HpTypeInput || Optional.empty() + LineTypeInput || Optional.empty() + StorageTypeInput || Optional.empty() + Transformer2WTypeInput || Optional.empty() + Transformer3WTypeInput || Optional.empty() + WecTypeInput || Optional.empty() + WecTypeInput || Optional.empty() + RandomLoadParameters || Optional.empty() + NodeGraphicInput || Optional.empty() + LineGraphicInput || Optional.empty() + WecCharacteristicInput || Optional.empty() + EvCharacteristicInput || Optional.empty() + TimeSeriesMapping.Entry || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for any result class"() { + given: "a file 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 file 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 file 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 input classes"() { + given: "a file 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 + WecCharacteristicInput || "wec_characteristic_input" + 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" + EvCharacteristicInput || "ev_characteristic_input" + 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" + NodeGraphicInput || "node_graphic_input" + LineGraphicInput || "line_graphic_input" + } + + def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all result classes"() { + given: "a file 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 file 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 file 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" + } +} From 5c81759d4a1bd6a7be4abe0e3330b10aa506a28c Mon Sep 17 00:00:00 2001 From: Johannes Hiry Date: Fri, 5 Mar 2021 16:00:06 +0100 Subject: [PATCH 03/24] minor, task-unrelated changes and code improvements --- .../datamodel/models/input/container/GridContainer.java | 2 +- .../models/input/system/SystemParticipantInput.java | 4 ++-- .../models/voltagelevels/GermanVoltageLevelUtils.java | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) 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<>( From 731345c8654a0deec32185e9665f3eff65b3835b Mon Sep 17 00:00:00 2001 From: Johannes Hiry Date: Fri, 5 Mar 2021 16:26:56 +0100 Subject: [PATCH 04/24] minor change + transform sample --- .../edu/ie3/datamodel/io/csv/FileNamingStrategy.java | 10 ++++++++++ .../io/file/EntityPersistenceNamingStrategy.java | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) 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 bd6cff121..d1ca99797 100644 --- a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java @@ -42,6 +42,7 @@ * @since 03.02.20 * @deprecated replaced by {@link EntityPersistenceNamingStrategy} */ +@Deprecated public class FileNamingStrategy { protected static final Logger logger = LogManager.getLogger(FileNamingStrategy.class); @@ -120,6 +121,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/file/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java index b665c52b6..3b216998a 100644 --- a/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java @@ -35,9 +35,10 @@ import org.apache.logging.log4j.Logger; /** - * Provides an easy to use standard way to name files based on the class that should be processed - * e.g. when writing .csv files. Represents a flat dir with all files inside. To use a hierarchic - * directory structure one might consider using {@link HierarchicFileNamingStrategy} + * Provides an easy to use standard way to name files, tables or anything other data sink that is + * used in order to persist entities. 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 From a30327350148f6bbf98671a6d53c314bbc3bc3fc Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 8 Mar 2021 20:51:24 +0100 Subject: [PATCH 05/24] #279 Replaced occurences of FileNamingStrategy with EntityPersistenceNamingStrategy and moved EntityPersistenceNamingStrategy and HierarchicFileNamingStrategy --- docs/readthedocs/io/csvfiles.rst | 2 +- docs/uml/main/DataSourceClassDiagram.puml | 4 +- .../io/connectors/CsvFileConnector.java | 27 ++++++------ .../datamodel/io/csv/FileNamingStrategy.java | 3 +- .../EntityPersistenceNamingStrategy.java | 3 +- .../HierarchicFileNamingStrategy.java | 6 ++- .../ie3/datamodel/io/sink/CsvFileSink.java | 21 ++++++---- .../ie3/datamodel/io/sink/InfluxDbSink.java | 33 ++++++++------- .../io/source/csv/CsvDataSource.java | 9 ++-- .../io/source/csv/CsvGraphicSource.java | 6 +-- .../io/source/csv/CsvIdCoordinateSource.java | 6 +-- .../io/source/csv/CsvRawGridSource.java | 6 +-- .../csv/CsvSystemParticipantSource.java | 6 +-- .../io/source/csv/CsvThermalSource.java | 6 +-- .../io/source/csv/CsvTimeSeriesSource.java | 10 +++-- .../io/source/csv/CsvTypeSource.java | 8 ++-- .../io/source/csv/CsvWeatherSource.java | 17 ++++---- .../io/connectors/CsvFileConnectorTest.groovy | 26 ++++++------ .../io/csv/FileNamingStrategyTest.groovy | 1 + .../HierarchicFileNamingStrategyTest.groovy | 1 + ...EntityPersistenceNamingStrategyTest.groovy | 2 +- .../datamodel/io/sink/CsvFileSinkTest.groovy | 12 +++--- .../datamodel/io/sink/InfluxDbSinkIT.groovy | 16 +++---- .../csv/CosmoCsvIdCoordinateSourceIT.groovy | 2 +- .../io/source/csv/CsvDataSourceTest.groovy | 12 +++--- .../io/source/csv/CsvGraphicSourceTest.groovy | 20 ++++----- .../io/source/csv/CsvRawGridSourceTest.groovy | 12 +++--- .../csv/CsvSystemParticipantSourceTest.groovy | 42 +++++++++---------- .../io/source/csv/CsvTestDataMeta.groovy | 4 +- .../io/source/csv/CsvThermalSourceTest.groovy | 18 ++++---- .../source/csv/CsvTimeSeriesSourceIT.groovy | 4 +- .../source/csv/CsvTimeSeriesSourceTest.groovy | 7 ++-- .../io/source/csv/CsvTypeSourceTest.groovy | 22 +++++----- .../csv/CsvWeatherSourceIconTest.groovy | 12 +++--- .../csv/CsvWeatherSourcePsdmTest.groovy | 13 +++--- .../csv/IconCsvIdCoordinateSourceIT.groovy | 2 +- 36 files changed, 213 insertions(+), 188 deletions(-) rename src/main/java/edu/ie3/datamodel/io/{file => naming}/EntityPersistenceNamingStrategy.java (99%) rename src/main/java/edu/ie3/datamodel/io/{csv => naming}/HierarchicFileNamingStrategy.java (94%) rename src/test/groovy/edu/ie3/datamodel/io/{file => naming}/EntityPersistenceNamingStrategyTest.groovy (99%) diff --git a/docs/readthedocs/io/csvfiles.rst b/docs/readthedocs/io/csvfiles.rst index d69854607..e971fc275 100644 --- a/docs/readthedocs/io/csvfiles.rst +++ b/docs/readthedocs/io/csvfiles.rst @@ -8,7 +8,7 @@ A naming strategy provides a mapping between model classes and the file names, i 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: -1. **FileNamingStrategy**: +1. **EntityPersistenceNamingStrategy**: 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`_. 2. **HierarchicFileNamingStrategy**: diff --git a/docs/uml/main/DataSourceClassDiagram.puml b/docs/uml/main/DataSourceClassDiagram.puml index 8bcea506c..266cd8d38 100644 --- a/docs/uml/main/DataSourceClassDiagram.puml +++ b/docs/uml/main/DataSourceClassDiagram.puml @@ -103,7 +103,7 @@ interface DataConnector { Abstract Class CsvDataSource { - String csvSep # CsvFileConnector connector - + CsvDataSource(String, String, FileNamingStrategy) + + CsvDataSource(String, String, EntityPersistenceNamingStrategy) } DataSource <|.. CsvDataSource @@ -113,7 +113,7 @@ Class CsvTypeSource { - LineTypeInputFactory lineTypeInputFactory - Transformer3WTypeInputFactory transformer3WTypeInputFactory - SystemParticipantTypeInputFactory systemParticipantTypeInputFactory - + CsvTypeSource(String, String, FileNamingStrategy) + + CsvTypeSource(String, String, EntityPersistenceNamingStrategy) } TypeSource <|.. CsvTypeSource CsvDataSource <|-- CsvTypeSource 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 b5789866f..674856313 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; @@ -38,7 +39,7 @@ public class CsvFileConnector implements DataConnector { private final Map, BufferedCsvWriter> entityWriters = new HashMap<>(); private final Map timeSeriesWriters = new HashMap<>(); - private final FileNamingStrategy fileNamingStrategy; + private final EntityPersistenceNamingStrategy entityPersistenceNamingStrategy; private final String baseDirectoryName; private static final String FILE_ENDING = ".csv"; @@ -46,9 +47,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( @@ -134,7 +136,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 @@ -144,7 +147,7 @@ public BufferedReader initReader(Class clz) throws FileN String filePath = null; try { filePath = - fileNamingStrategy + entityPersistenceNamingStrategy .getFilePath(clz) .orElseThrow( () -> @@ -205,7 +208,7 @@ public Map> initTimeSeriesReader( * @throws FileNotFoundException If the file is not present */ public BufferedReader initIdCoordinateReader() throws FileNotFoundException { - String filePath = fileNamingStrategy.getIdCoordinateFileName(); + String filePath = entityPersistenceNamingStrategy.getIdCoordinateFileName(); return initReader(filePath); } @@ -223,7 +226,7 @@ private Set getIndividualTimeSeriesFilePaths() { .filter( path -> { String withoutEnding = removeFileEnding(path.toString()); - return fileNamingStrategy + return entityPersistenceNamingStrategy .getIndividualTimeSeriesPattern() .matcher(withoutEnding) .matches(); @@ -250,7 +253,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.", @@ -312,9 +315,9 @@ 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 + entityPersistenceNamingStrategy .getFileName(timeSeries) .orElseThrow( () -> @@ -335,9 +338,9 @@ 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 + entityPersistenceNamingStrategy .getFileName(clz) .orElseThrow( () -> 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 d1ca99797..0b722c272 100644 --- a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java @@ -8,7 +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.file.EntityPersistenceNamingStrategy; +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy; +import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy; import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; import edu.ie3.datamodel.models.input.AssetTypeInput; diff --git a/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java similarity index 99% rename from src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java rename to src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index 3b216998a..f7c8a937a 100644 --- a/src/main/java/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -3,10 +3,9 @@ * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ -package edu.ie3.datamodel.io.file; +package edu.ie3.datamodel.io.naming; import edu.ie3.datamodel.io.csv.FileNameMetaInformation; -import edu.ie3.datamodel.io.csv.HierarchicFileNamingStrategy; import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation; import edu.ie3.datamodel.io.csv.timeseries.LoadProfileTimeSeriesMetaInformation; 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 94% 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..0b5ee4c67 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; @@ -20,7 +22,7 @@ * A file 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..daab9b542 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 file 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 file 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..f4ddd7102 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.getResultEntityFileName(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.getFileName(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 89c127b04..243679576 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/CsvTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java index 816c58573..38cc115dc 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 @@ -6,10 +6,10 @@ package edu.ie3.datamodel.io.source.csv; import edu.ie3.datamodel.io.connectors.CsvFileConnector.TimeSeriesReadingData; -import edu.ie3.datamodel.io.csv.FileNamingStrategy; import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme; import edu.ie3.datamodel.io.factory.SimpleEntityData; 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.TimeSeriesContainer; import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; @@ -43,11 +43,13 @@ public class CsvTimeSeriesSource extends CsvDataSource implements TimeSeriesSour * * @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 */ public CsvTimeSeriesSource( - String csvSep, String folderPath, FileNamingStrategy fileNamingStrategy) { - super(csvSep, folderPath, fileNamingStrategy); + String csvSep, + String folderPath, + EntityPersistenceNamingStrategy entityPersistenceNamingStrategy) { + super(csvSep, folderPath, entityPersistenceNamingStrategy); } /** 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 b21550346..1003e6df7 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; @@ -42,7 +42,7 @@ 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 * @param weatherFactory factory to transfer field to value mapping into actual java object * instances * @param coordinateFactory factory to build coordinate id to coordinate mapping @@ -50,14 +50,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); } @@ -67,7 +68,7 @@ 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 * @param coordinateSource a coordinate source to map ids to points * @param weatherFactory factory to transfer field to value mapping into actual java object * instances @@ -75,10 +76,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/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/connectors/CsvFileConnectorTest.groovy index 98e16618d..1931d8ae3 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", @@ -173,8 +173,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")) @@ -192,8 +192,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[], ",") @@ -206,8 +206,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: @@ -234,8 +234,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) @@ -251,8 +251,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 7ad0715aa..988eabaae 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/csv/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy index 68f829280..38d876abd 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.csv +import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy import edu.ie3.datamodel.models.BdewLoadProfile import edu.ie3.datamodel.models.UniqueEntity import edu.ie3.datamodel.models.input.MeasurementUnitInput diff --git a/src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy similarity index 99% rename from src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy rename to src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index 08a119836..bc644fdc1 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/file/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -3,7 +3,7 @@ * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ -package edu.ie3.datamodel.io.file +package edu.ie3.datamodel.io.naming import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme import edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation 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 5c32dbcdb..66bf5050c 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.getFileName(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.getFileName(LineResult).get().trim().replaceAll("\\W", "_") + def key_chp = entityPersistenceNamingStrategy.getFileName(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.getFileName(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,7 +270,7 @@ class InfluxDbSinkIT extends Specification { } //Always return an empty Optional for results - class EmptyFileNamingStrategy extends FileNamingStrategy { + class EmptyFileNamingStrategy extends EntityPersistenceNamingStrategy { @Override Optional getResultEntityFileName(Class resultEntityClass) { 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 a796c9965..36abde09b 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,15 +62,15 @@ 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 DataSource should contain a valid connector after initialization"() { 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..89d734596 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 e4c8554b4..560e3583a 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 { String coordinatesFolderPath = testParticipantsBaseFolderPath.concat(File.separator).concat("coordinates") String csvSep = "," - FileNamingStrategy fileNamingStrategy = new FileNamingStrategy() + 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/CsvTimeSeriesSourceIT.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceIT.groovy index 9e221b89d..89b7be0b4 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 @@ -7,7 +7,7 @@ package edu.ie3.datamodel.io.source.csv import static edu.ie3.datamodel.models.StandardUnits.* import edu.ie3.datamodel.io.connectors.CsvFileConnector -import edu.ie3.datamodel.io.csv.FileNamingStrategy +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy import edu.ie3.datamodel.io.csv.timeseries.ColumnScheme import edu.ie3.datamodel.io.factory.timeseries.TimeBasedSimpleValueFactory import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries @@ -28,7 +28,7 @@ class CsvTimeSeriesSourceIT extends Specification implements CsvTestDataMeta { CsvTimeSeriesSource source def setup() { - source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy()) + source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy()) } def "The csv time series source is able to provide an individual time series from given field to object function"() { 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 3bc1b33d2..c76ffa95e 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,9 +5,10 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.io.naming.EntityPersistenceNamingStrategy + import static edu.ie3.datamodel.models.StandardUnits.* -import edu.ie3.datamodel.io.csv.FileNamingStrategy import edu.ie3.datamodel.io.factory.timeseries.TimeBasedSimpleValueFactory import edu.ie3.datamodel.io.source.IdCoordinateSource import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue @@ -24,7 +25,7 @@ import java.time.ZoneId class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def "The csv time series source is able to provide a valid time series mapping from files"() { given: - def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy()) + def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy()) def expectedMapping = [ new TimeSeriesMapping.Entry(UUID.fromString("58167015-d760-4f90-8109-f2ebd94cda91"), UUID.fromString("b86e95b0-e579-4a80-a534-37c7a470a409"), UUID.fromString("9185b8c1-86ba-4a16-8dea-5ac898e8caa5")), new TimeSeriesMapping.Entry(UUID.fromString("9a9ebfda-dc26-4a40-b9ca-25cd42f6cc3f"), UUID.fromString("c7ebcc6c-55fc-479b-aa6b-6fa82ccac6b8"), UUID.fromString("3fbfaa97-cff4-46d4-95ba-a95665e87c26")), @@ -45,7 +46,7 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def defaultCoordinate = GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.4116482, 51.4843281)) def coordinateSource = Mock(IdCoordinateSource) coordinateSource.getCoordinate(5) >> defaultCoordinate - def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new FileNamingStrategy()) + def source = new CsvTimeSeriesSource(";", timeSeriesFolderPath, new EntityPersistenceNamingStrategy()) def factory = new TimeBasedSimpleValueFactory(EnergyPriceValue) 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'") 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"() { From 214aab486b43f5f451645468d74f94b60413a743 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 9 Mar 2021 15:31:14 +0100 Subject: [PATCH 06/24] #279 Replaced FileNamingStrategy with EntityPersistenceNamingStrategy in few files in the latest code --- .../io/connectors/CsvFileConnector.java | 32 +++++++++++-------- .../EntityPersistenceNamingStrategy.java | 5 +-- .../csv/CsvTimeSeriesMappingSource.java | 8 +++-- .../io/source/csv/CsvTimeSeriesSource.java | 26 +++++++-------- .../HierarchicFileNamingStrategyTest.groovy | 1 + ...EntityPersistenceNamingStrategyTest.groovy | 8 ++--- .../csv/CsvTimeSeriesMappingSourceIT.groovy | 4 +-- .../source/csv/CsvTimeSeriesSourceIT.groovy | 6 ++-- .../source/csv/CsvTimeSeriesSourceTest.groovy | 9 +++--- 9 files changed, 54 insertions(+), 45 deletions(-) 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 41e466474..b5e3a9f2f 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.getIdCoordinateFileName(); 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,9 +363,9 @@ 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 + entityPersistenceNamingStrategy .getFileName(timeSeries) .orElseThrow( () -> @@ -382,9 +386,9 @@ 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 + entityPersistenceNamingStrategy .getFileName(clz) .orElseThrow( () -> @@ -511,4 +515,4 @@ public String toString() { + '}'; } } -} \ No newline at end of file +} diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index f7c8a937a..27c65bda7 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -9,6 +9,7 @@ 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.AssetInput; import edu.ie3.datamodel.models.input.AssetTypeInput; @@ -20,7 +21,6 @@ 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.mapping.TimeSeriesMapping; import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput; import edu.ie3.datamodel.models.value.*; import edu.ie3.util.StringUtils; @@ -185,7 +185,8 @@ public Optional getFileName(Class cls) { return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class)); if (OperatorInput.class.isAssignableFrom(cls)) return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); - if (TimeSeriesMapping.Entry.class.isAssignableFrom(cls)) return getTimeSeriesMappingFileName(); + if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) + return getTimeSeriesMappingFileName(); logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); return Optional.empty(); } 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 971a60c16..e540a12c3 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,7 @@ 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 * @param metaInformation The given meta information * @throws SourceException If the given meta information are not supported * @return The source @@ -41,7 +41,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 +51,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), PValue.class, @@ -62,7 +62,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), SValue.class, @@ -73,7 +73,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), EnergyPriceValue.class, @@ -84,7 +84,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatAndSValue.class, @@ -95,7 +95,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatAndPValue.class, @@ -106,7 +106,7 @@ public static CsvTimeSeriesSource getSource( return new CsvTimeSeriesSource<>( csvSep, folderPath, - fileNamingStrategy, + entityPersistenceNamingStrategy, metaInformation.getUuid(), metaInformation.getFullFilePath(), HeatDemandValue.class, @@ -122,7 +122,7 @@ 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 * @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 +131,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 { @@ -217,4 +217,4 @@ private Optional> buildTimeBasedValue( new SimpleTimeBasedValueData<>(fieldToValues, valueClass); return factory.get(factoryData); } -} \ No newline at end of file +} diff --git a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy index f59c9aa7c..bb82a4e85 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.csv +import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.BdewLoadProfile import edu.ie3.datamodel.models.UniqueEntity diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index bc644fdc1..d368773ad 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -39,7 +39,7 @@ 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.mapping.TimeSeriesMapping +import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.timeseries.repetitive.LoadProfileInput import edu.ie3.datamodel.models.timeseries.repetitive.RepetitiveTimeSeries import edu.ie3.datamodel.models.value.EnergyPriceValue @@ -591,7 +591,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(TimeSeriesMapping.Entry) + Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) then: res.present @@ -603,7 +603,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") when: - Optional res = strategy.getFileName(TimeSeriesMapping.Entry) + Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) then: res.present @@ -655,7 +655,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { LineGraphicInput || Optional.empty() WecCharacteristicInput || Optional.empty() EvCharacteristicInput || Optional.empty() - TimeSeriesMapping.Entry || Optional.empty() + TimeSeriesMappingSource.MappingEntry || Optional.empty() } def "A simple file naming strategy does return empty sub directory path for any result class"() { 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 a81c7ba90..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) 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 fe5a11115..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 From ce6ced54516f7a6c7d9d2bdf5018a0fe02b5b709 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Wed, 10 Mar 2021 12:47:47 +0100 Subject: [PATCH 07/24] #279 Modified javadocs and uml documentation to reflect replacement of FileNamingStrategy with EntityPersistenceNamingStrategy --- docs/readthedocs/io/csvfiles.rst | 23 +++--- docs/uml/main/DataSinkClassDiagram.puml | 8 +- docs/uml/main/DataSourceClassDiagram.puml | 14 ++-- .../EntityPersistenceNamingStrategy.java | 19 +++-- .../naming/HierarchicFileNamingStrategy.java | 2 +- .../ie3/datamodel/io/sink/CsvFileSink.java | 4 +- .../io/source/csv/CsvTimeSeriesSource.java | 6 +- .../io/source/csv/CsvWeatherSource.java | 6 +- .../HierarchicFileNamingStrategyTest.groovy | 76 +++++++++---------- 9 files changed, 83 insertions(+), 75 deletions(-) diff --git a/docs/readthedocs/io/csvfiles.rst b/docs/readthedocs/io/csvfiles.rst index a8f9d570e..e3db32e7a 100644 --- a/docs/readthedocs/io/csvfiles.rst +++ b/docs/readthedocs/io/csvfiles.rst @@ -4,25 +4,26 @@ 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 names of 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. **EntityPersistenceNamingStrategy**: - 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`_. + A basic naming strategy that is able to add prefix and suffix to the names of the data sinks. 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 data sinks 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 +225,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 +274,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 0116aa8ca..f359919cf 100644 --- a/docs/uml/main/DataSourceClassDiagram.puml +++ b/docs/uml/main/DataSourceClassDiagram.puml @@ -111,7 +111,7 @@ TimeSeriesSource <|-- DataSource 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) } @@ -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 @@ -178,7 +178,7 @@ Class CsvSystemParticipantSource { - PvInputFactory pvInputFactory - StorageInputFactory storageInputFactory - WecInputFactory wecInputFactory - + CsvSystemParticipantSource(String, String, FileNamingStrategy, TypeSource, ThermalSource, RawGridSource) + + CsvSystemParticipantSource(String, String, EntityPersistenceNamingStrategy, TypeSource, ThermalSource, RawGridSource) } SystemParticipantsSource <|.. CsvSystemParticipantSource CsvDataSource <|-- CsvSystemParticipantSource @@ -188,7 +188,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 @@ -196,10 +196,10 @@ CsvDataSource <|-- CsvGraphicSource Class CsvFileConnector { - Map, BufferedCsvWriter> entityWriters - Map timeSeriesWriters - - FileNamingStrategy fileNamingStrategy + - EntityPersistenceNamingStrategy entityPersistenceNamingStrategy - String baseFolderName - {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/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index 27c65bda7..d56936d7c 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -34,8 +34,8 @@ import org.apache.logging.log4j.Logger; /** - * Provides an easy to use standard way to name files, tables or anything other data sink that is - * used in order to persist entities. Normal use cases are e.g., I/O operations with .csv files or + * Provides an easy to use standard way to name files, tables or any other data sink that is used in + * order to persist entities. 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} * @@ -81,25 +81,28 @@ public class EntityPersistenceNamingStrategy { private final String prefix; private final String suffix; - /** Constructor for building the file names without provided files with prefix and suffix */ + /** + * Constructor for building the names of the data sinks without provided entities with prefix and + * suffix + */ public EntityPersistenceNamingStrategy() { this("", ""); } /** - * Constructor for building the file names + * Constructor for building the names of the data sinks * - * @param prefix Prefix of the files + * @param prefix Prefix of the data sinks */ public EntityPersistenceNamingStrategy(String prefix) { this(prefix, ""); } /** - * Constructor for building the file names + * Constructor for building the names of the data sinks * - * @param prefix Prefix of the files - * @param suffix Suffixes of the files + * @param prefix Prefix of the data sinks + * @param suffix Suffixes of the data sinks */ public EntityPersistenceNamingStrategy(String prefix, String suffix) { this.prefix = preparePrefix(prefix); diff --git a/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java index 0b5ee4c67..5df0b2927 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategy.java @@ -19,7 +19,7 @@ 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 EntityPersistenceNamingStrategy { 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 daab9b542..c7b8c1eb9 100644 --- a/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java +++ b/src/main/java/edu/ie3/datamodel/io/sink/CsvFileSink.java @@ -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 entityPersistenceNamingStrategy 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 @@ -98,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 entityPersistenceNamingStrategy 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 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 e540a12c3..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 @@ -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 entityPersistenceNamingStrategy 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 @@ -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 entityPersistenceNamingStrategy 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 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 b15780a2f..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 @@ -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 entityPersistenceNamingStrategy 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 @@ -69,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 entityPersistenceNamingStrategy 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 diff --git a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy index bb82a4e85..092b8fa3f 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/csv/HierarchicFileNamingStrategyTest.groovy @@ -57,8 +57,8 @@ 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: @@ -68,8 +68,8 @@ class HierarchicFileNamingStrategyTest extends Specification { !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: @@ -99,8 +99,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: @@ -132,8 +132,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 input assets models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -165,8 +165,8 @@ class HierarchicFileNamingStrategyTest extends Specification { 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 directory paths for all asset characteristics models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -182,8 +182,8 @@ class HierarchicFileNamingStrategyTest extends Specification { 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 "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all asset characteristics models"() { + given: "a naming strategy without pre- or suffixes" def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: @@ -199,8 +199,8 @@ class HierarchicFileNamingStrategyTest extends Specification { EvCharacteristicInput || "test_grid" + File.separator + "input" + File.separator + "global" + File.separator + "ev_characteristic_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: @@ -224,8 +224,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: @@ -248,8 +248,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: @@ -264,8 +264,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: @@ -280,8 +280,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: @@ -297,8 +297,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: @@ -314,7 +314,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) @@ -331,7 +331,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 = [ @@ -352,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 + "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 = [ @@ -373,7 +373,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) @@ -390,7 +390,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) @@ -409,7 +409,7 @@ 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) @@ -421,8 +421,8 @@ class HierarchicFileNamingStrategyTest extends Specification { !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: @@ -433,8 +433,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: @@ -445,8 +445,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: @@ -458,7 +458,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: @@ -469,7 +469,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: From bbb8b5b1a86079564f0a28a06ed3d8ba8be671d6 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Wed, 10 Mar 2021 13:05:48 +0100 Subject: [PATCH 08/24] #279 Fixed Codacy Analysis Issues and renamed some strings to account for refactoring of FileNamingStrategy --- ...EntityPersistenceNamingStrategyTest.groovy | 44 +++++++++---------- .../HierarchicFileNamingStrategyTest.groovy | 3 +- .../io/source/csv/CsvRawGridSourceTest.groovy | 4 +- 3 files changed, 26 insertions(+), 25 deletions(-) rename src/test/groovy/edu/ie3/datamodel/io/{csv => naming}/HierarchicFileNamingStrategyTest.groovy (99%) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index d368773ad..108cd3bbe 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -274,7 +274,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy should recognize if empty strings are passed in the prefix/suffix constructor and don't add underlines then"() { - given: "a file naming strategy" + given: "a naming strategy" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("", "") expect: @@ -283,7 +283,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy should correctly append and prepend underscores"() { - given: "a file naming strategy" + given: "a naming strategy" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("bla", "foo") expect: @@ -292,7 +292,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy should correctly append underscore, when only prefix is set"() { - given: "a file naming strategy" + given: "a naming strategy" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("bla") expect: @@ -301,7 +301,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy should return an empty optional on a invalid class"() { - given: "a file naming strategy" + given: "a naming strategy" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -312,7 +312,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all result models"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -343,7 +343,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy with pre- and suffixes should return valid strings for all result models"() { - given: "a file naming strategy with pre- or suffixes" + given: "a naming strategy with pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") when: @@ -374,7 +374,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all input assets models"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -407,7 +407,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all asset characteristics models"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -424,7 +424,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all input types models"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -449,7 +449,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for a Load Parameter Model"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -465,7 +465,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for a graphic input Model"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -560,7 +560,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() LoadProfileInput timeSeries = Mock(LoadProfileInput) timeSeries.uuid >> uuid - timeSeries.getType() >> type + timeSeries.type >> type when: Optional actual = strategy.getFileName(timeSeries) @@ -587,7 +587,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: @@ -599,7 +599,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy with pre- and suffix should return valid strings for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") when: @@ -611,7 +611,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return empty sub directory path for any model input class"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() when: @@ -659,7 +659,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return empty sub directory path for any result class"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() when: @@ -689,7 +689,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return empty sub directory path for load profile time series"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() def timeSeries = Mock(LoadProfileInput) @@ -701,7 +701,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return empty sub directory path for individual time series"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() def timeSeries = Mock(IndividualTimeSeries) @@ -713,7 +713,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all input classes"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() when: @@ -760,7 +760,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all result classes"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() when: @@ -791,7 +791,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return valid file path for load profile time series"() { - given: "a file naming strategy without pre- or suffixes" + given: "a naming strategy without pre- or suffixes" def strategy = new EntityPersistenceNamingStrategy() def timeSeries = Mock(LoadProfileInput) timeSeries.uuid >> uuid @@ -810,7 +810,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { } def "A simple file naming strategy does return valid file path for individual time series"() { - given: "a file naming strategy without pre- or suffixes" + 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 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 99% 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 092b8fa3f..d3d16ee7d 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.naming.HierarchicFileNamingStrategy import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.BdewLoadProfile 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 89d734596..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 @@ -743,7 +743,7 @@ 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, entityPersistenceNamingStrategy) - source = new CsvRawGridSource(csvSep, gridFolderPath+"_malformed", entityPersistenceNamingStrategy, typeSource) + source = new CsvRawGridSource(csvSep, gridFolderPath + "_malformed", entityPersistenceNamingStrategy, typeSource) when: "loading a total grid structure from file" def actual = source.getGridData() @@ -755,7 +755,7 @@ 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, entityPersistenceNamingStrategy) - source = new CsvRawGridSource(csvSep, gridFolderPath+"_empty", entityPersistenceNamingStrategy, typeSource) + source = new CsvRawGridSource(csvSep, gridFolderPath + "_empty", entityPersistenceNamingStrategy, typeSource) when: "loading a total grid structure from file" def actual = source.getGridData() From 993227d724b26b83239fa46c9c4576623ba13976 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Fri, 12 Mar 2021 11:37:50 +0100 Subject: [PATCH 09/24] #279 Codacy issue handling by reducing NPath Complexity of getFileName function --- .../EntityPersistenceNamingStrategy.java | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index d56936d7c..7eae4cbd7 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -11,10 +11,7 @@ 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.AssetInput; -import edu.ie3.datamodel.models.input.AssetTypeInput; -import edu.ie3.datamodel.models.input.OperatorInput; -import edu.ie3.datamodel.models.input.RandomLoadParameters; +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; @@ -172,12 +169,25 @@ private Optional getFilePath(String fileName, String subDirectories) { * @return The file name */ public Optional getFileName(Class cls) { + Optional inputEntityFileName = getInputEntityFileName(cls); + if (inputEntityFileName.isPresent()) return inputEntityFileName; + if (ResultEntity.class.isAssignableFrom(cls)) + return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); + logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); + return Optional.empty(); + } + + /** + * Get the the file name for all {@link InputEntity}s + * + * @param cls Targeted class of the given file + * @return The file name + */ + public Optional getInputEntityFileName(Class cls) { if (AssetTypeInput.class.isAssignableFrom(cls)) return getTypeFileName(cls.asSubclass(AssetTypeInput.class)); if (AssetInput.class.isAssignableFrom(cls)) return getAssetInputFileName(cls.asSubclass(AssetInput.class)); - if (ResultEntity.class.isAssignableFrom(cls)) - return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); if (CharacteristicInput.class.isAssignableFrom(cls)) return getAssetCharacteristicsFileName(cls.asSubclass(CharacteristicInput.class)); if (cls.equals(RandomLoadParameters.class)) { @@ -190,10 +200,19 @@ public Optional getFileName(Class cls) { return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) return getTimeSeriesMappingFileName(); - logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); return Optional.empty(); } + /** + * Get the the file name for all {@link ResultEntity}s + * + * @param resultEntityClass the result entity class a filename string should be generated from + * @return the filename string + */ + public Optional getResultEntityFileName(Class resultEntityClass) { + return Optional.of(buildResultEntityString(resultEntityClass)); + } + /** * Get the the file name for all {@link AssetTypeInput}s * @@ -216,16 +235,6 @@ public Optional getAssetInputFileName(Class assetI return Optional.of(addPrefixAndSuffix(assetInputString)); } - /** - * Get the the file name for all {@link ResultEntity}s - * - * @param resultEntityClass the result entity class a filename string should be generated from - * @return the filename string - */ - public Optional getResultEntityFileName(Class resultEntityClass) { - return Optional.of(buildResultEntityString(resultEntityClass)); - } - private String buildResultEntityString(Class resultEntityClass) { String resultEntityString = camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); From 571defaac28bc1add8cbc3d42830bb89e0e38052 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Fri, 12 Mar 2021 12:43:32 +0100 Subject: [PATCH 10/24] #279 Codacy issue handling by splitting test cases --- ...EntityPersistenceNamingStrategyTest.groovy | 215 +++++++++++++++--- 1 file changed, 179 insertions(+), 36 deletions(-) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index 108cd3bbe..b6e2cd283 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -610,7 +610,29 @@ class EntityPersistenceNamingStrategyTest extends Specification { res.get() == "prefix_time_series_mapping_suffix" } - def "A simple file naming strategy does return empty sub directory path for any model input class"() { + 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() + WecCharacteristicInput || Optional.empty() + EvCharacteristicInput || 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() @@ -631,30 +653,77 @@ class EntityPersistenceNamingStrategyTest extends Specification { 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() - NodeInput || Optional.empty() - MeasurementUnitInput || Optional.empty() - EvcsInput || Optional.empty() Transformer2WInput || Optional.empty() Transformer3WInput || Optional.empty() - CylindricalStorageInput || Optional.empty() - ThermalHouseInput || Optional.empty() - BmTypeInput || Optional.empty() - ChpTypeInput || Optional.empty() - EvTypeInput || Optional.empty() - HpTypeInput || Optional.empty() LineTypeInput || Optional.empty() - StorageTypeInput || Optional.empty() Transformer2WTypeInput || Optional.empty() Transformer3WTypeInput || Optional.empty() - WecTypeInput || Optional.empty() - WecTypeInput || Optional.empty() - RandomLoadParameters || 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() - WecCharacteristicInput || Optional.empty() - EvCharacteristicInput || 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() } @@ -712,7 +781,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { actual == Optional.empty() } - def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid file paths for all input classes"() { + 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() @@ -725,38 +794,112 @@ class EntityPersistenceNamingStrategyTest extends Specification { where: modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - 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" + 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 + WecCharacteristicInput || "wec_characteristic_input" EvCharacteristicInput || "ev_characteristic_input" 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" - NodeGraphicInput || "node_graphic_input" - LineGraphicInput || "line_graphic_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"() { From 974fd1d906a456de8411281bd23c33bf60902cd9 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Mar 2021 13:04:19 +0100 Subject: [PATCH 11/24] #279 Removed redundant function calls and split test cases --- .../EntityPersistenceNamingStrategy.java | 24 +++++++++---------- .../HierarchicFileNamingStrategyTest.groovy | 19 +++++++++++++-- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index 7eae4cbd7..d6006f53e 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -121,6 +121,14 @@ public EntityPersistenceNamingStrategy(String prefix, String suffix) { + suffix); } + public Pattern getLoadProfileTimeSeriesPattern() { + return loadProfileTimeSeriesPattern; + } + + public Pattern getIndividualTimeSeriesPattern() { + return individualTimeSeriesPattern; + } + /** * Prepares the prefix by appending an underscore and bringing it to lower case * @@ -436,19 +444,15 @@ 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 (getIndividualTimeSeriesPattern().matcher(withoutEnding).matches()) + if (individualTimeSeriesPattern.matcher(withoutEnding).matches()) return extractIndividualTimesSeriesMetaInformation(withoutEnding); - else if (getLoadProfileTimeSeriesPattern().matcher(withoutEnding).matches()) + else if (loadProfileTimeSeriesPattern.matcher(withoutEnding).matches()) return extractLoadProfileTimesSeriesMetaInformation(withoutEnding); else throw new IllegalArgumentException( "Unknown format of '" + fileName + "'. Cannot extract meta information."); } - public Pattern getIndividualTimeSeriesPattern() { - return individualTimeSeriesPattern; - } - /** * Extracts meta information from a valid file name for a individual time series * @@ -457,7 +461,7 @@ public Pattern getIndividualTimeSeriesPattern() { */ private IndividualTimeSeriesMetaInformation extractIndividualTimesSeriesMetaInformation( String fileName) { - Matcher matcher = getIndividualTimeSeriesPattern().matcher(fileName); + Matcher matcher = individualTimeSeriesPattern.matcher(fileName); if (!matcher.matches()) throw new IllegalArgumentException( "Cannot extract meta information on individual time series from '" + fileName + "'."); @@ -474,10 +478,6 @@ private IndividualTimeSeriesMetaInformation extractIndividualTimesSeriesMetaInfo UUID.fromString(matcher.group("uuid")), columnScheme); } - public Pattern getLoadProfileTimeSeriesPattern() { - return loadProfileTimeSeriesPattern; - } - /** * Extracts meta information from a valid file name for a load profile time series * @@ -486,7 +486,7 @@ public Pattern getLoadProfileTimeSeriesPattern() { */ private LoadProfileTimeSeriesMetaInformation extractLoadProfileTimesSeriesMetaInformation( String fileName) { - Matcher matcher = getLoadProfileTimeSeriesPattern().matcher(fileName); + Matcher matcher = loadProfileTimeSeriesPattern.matcher(fileName); if (!matcher.matches()) throw new IllegalArgumentException( "Cannot extract meta information on load profile time series from '" + fileName + "'."); diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy index d3d16ee7d..27f10e760 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy @@ -133,7 +133,7 @@ class HierarchicFileNamingStrategyTest extends Specification { ThermalHouseInput || "test_grid" + File.separator + "input" + File.separator + "thermal" } - def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all input assets models"() { + 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) @@ -155,11 +155,26 @@ 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" + EvcsInput || "test_grid" + File.separator + "input" + File.separator + "participants" + File.separator + "evcs_input" + } + + 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.getFilePath(modelClass) + + then: + res.present + res.get() == expectedString + + where: + 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" - 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" From bc53c8015940bdb4175b9a653131158e6752363a Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Mar 2021 13:22:39 +0100 Subject: [PATCH 12/24] #279 Split test cases to reduce the maximum number of methods in EntityPersistenceNamingStrategyTest --- ...ityPersistenceNamingStrategyPreTest.groovy | 529 ++++++++++++++++++ ...EntityPersistenceNamingStrategyTest.groovy | 460 --------------- 2 files changed, 529 insertions(+), 460 deletions(-) create mode 100644 src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy new file mode 100644 index 000000000..7bdd2b2a3 --- /dev/null +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy @@ -0,0 +1,529 @@ +/* + * © 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.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.characteristic.EvCharacteristicInput +import edu.ie3.datamodel.models.input.system.characteristic.WecCharacteristicInput +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 spock.lang.Specification + +import java.nio.file.Paths +import java.time.ZonedDateTime +import java.util.regex.Pattern + +class EntityPersistenceNamingStrategyPreTest 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.getFileName(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.getFileName(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.getFileName(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.getFileName(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 asset characteristics models"() { + given: "a naming strategy without pre- or suffixes" + EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() + + when: + Optional res = strategy.getFileName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + WecCharacteristicInput || "wec_characteristic_input" + EvCharacteristicInput || "ev_characteristic_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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(timeSeries) + + then: + !actual.present + } +} diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index b6e2cd283..dd709cef4 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -53,466 +53,6 @@ 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.getFileName(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.getFileName(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.getFileName(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.getFileName(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 asset characteristics models"() { - given: "a naming strategy without pre- or suffixes" - EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() - - when: - Optional res = strategy.getFileName(modelClass) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - EvCharacteristicInput || "ev_characteristic_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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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() From 669024b5cd1d31bed75bf424a776895900473951 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Mar 2021 13:28:52 +0100 Subject: [PATCH 13/24] #279 Removed unnecessary imports --- .../io/naming/EntityPersistenceNamingStrategyTest.groovy | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index dd709cef4..a8253fec8 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -5,9 +5,6 @@ */ 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.models.BdewLoadProfile import edu.ie3.datamodel.models.UniqueEntity import edu.ie3.datamodel.models.input.MeasurementUnitInput @@ -36,7 +33,6 @@ import edu.ie3.datamodel.models.result.connector.Transformer3WResult import edu.ie3.datamodel.models.result.system.* 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.io.source.TimeSeriesMappingSource @@ -47,9 +43,7 @@ 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 { From 94a878ea4ec28dff3aeb41264587a29382f4e51c Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Mar 2021 13:39:14 +0100 Subject: [PATCH 14/24] #279 Renamed the test case files --- ...eTest.groovy => EntityPersistenceNamingStrategyTest1.groovy} | 2 +- ...yTest.groovy => EntityPersistenceNamingStrategyTest2.groovy} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/groovy/edu/ie3/datamodel/io/naming/{EntityPersistenceNamingStrategyPreTest.groovy => EntityPersistenceNamingStrategyTest1.groovy} (99%) rename src/test/groovy/edu/ie3/datamodel/io/naming/{EntityPersistenceNamingStrategyTest.groovy => EntityPersistenceNamingStrategyTest2.groovy} (99%) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy similarity index 99% rename from src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy rename to src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy index 7bdd2b2a3..4ac410fb8 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyPreTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy @@ -65,7 +65,7 @@ import java.nio.file.Paths import java.time.ZonedDateTime import java.util.regex.Pattern -class EntityPersistenceNamingStrategyPreTest extends Specification { +class EntityPersistenceNamingStrategyTest1 extends Specification { def "The uuid pattern actually matches a valid uuid"() { given: diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy similarity index 99% rename from src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy rename to src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy index a8253fec8..e1eba3280 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy @@ -45,7 +45,7 @@ import tech.units.indriya.quantity.Quantities import java.time.ZonedDateTime -class EntityPersistenceNamingStrategyTest extends Specification { +class EntityPersistenceNamingStrategyTest2 extends Specification { def "A EntityPersistenceNamingStrategy without pre- or suffix should return valid file name for individual time series" () { given: From 4f60799296a01bfb03c2b8aa3d8493686c820c96 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Mon, 22 Mar 2021 14:11:00 +0100 Subject: [PATCH 15/24] #279 Deleted FileNamingStrategy and FileNamingStrategyTest --- .../datamodel/io/csv/FileNamingStrategy.java | 504 ----------- .../io/csv/FileNamingStrategyTest.groovy | 833 ------------------ 2 files changed, 1337 deletions(-) delete mode 100644 src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java delete mode 100644 src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy diff --git a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java deleted file mode 100644 index ec58a13da..000000000 --- a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * © 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.csv; - -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; -import edu.ie3.datamodel.models.input.AssetTypeInput; -import edu.ie3.datamodel.models.input.OperatorInput; -import edu.ie3.datamodel.models.input.RandomLoadParameters; -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 based on the class that should be processed - * e.g. when writing .csv files. Represents a flat dir with all files inside. To use a hierarchic - * directory structure one might consider using {@link HierarchicFileNamingStrategy} - * - * @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); - - 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 file names - * - * @param prefix Prefix of the files - * @param suffix Suffixes of the files - */ - public FileNamingStrategy(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); - } - - /** Constructor for building the file names without provided files with prefix and suffix */ - public FileNamingStrategy() { - this("", ""); - } - - /** - * Constructor for building the file names - * - * @param prefix Prefix of the files - */ - 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 - * - * @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(); - } - - public Pattern getIndividualTimeSeriesPattern() { - return individualTimeSeriesPattern; - } - - public Pattern getLoadProfileTimeSeriesPattern() { - return loadProfileTimeSeriesPattern; - } - - /** - * 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 - */ - 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( - getFileName(cls).orElseGet(() -> ""), getDirectoryPath(cls).orElseGet(() -> "")); - } - - /** - * 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( - getFileName(timeSeries).orElseGet(() -> ""), - getDirectoryPath(timeSeries).orElseGet(() -> "")); - } - - 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 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(); - } - - /** - * 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(); - } - - /** - * Returns the file name (and only the file name without any directories and extension). - * - * @param cls Targeted class of the given file - * @return The file name - */ - public Optional getFileName(Class cls) { - if (AssetTypeInput.class.isAssignableFrom(cls)) - return getTypeFileName(cls.asSubclass(AssetTypeInput.class)); - if (AssetInput.class.isAssignableFrom(cls)) - return getAssetInputFileName(cls.asSubclass(AssetInput.class)); - if (ResultEntity.class.isAssignableFrom(cls)) - return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); - if (CharacteristicInput.class.isAssignableFrom(cls)) - return getAssetCharacteristicsFileName(cls.asSubclass(CharacteristicInput.class)); - if (cls.equals(RandomLoadParameters.class)) { - String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); - return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); - } - if (GraphicInput.class.isAssignableFrom(cls)) - return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class)); - if (OperatorInput.class.isAssignableFrom(cls)) - return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); - if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) - return getTimeSeriesMappingFileName(); - logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); - return Optional.empty(); - } - - /** - * 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 getFileName(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(); - } - } - - /** - * 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 (getIndividualTimeSeriesPattern().matcher(withoutEnding).matches()) - return extractIndividualTimesSeriesMetaInformation(withoutEnding); - else if (getLoadProfileTimeSeriesPattern().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 = getIndividualTimeSeriesPattern().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 = getLoadProfileTimeSeriesPattern().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 file name for time series mapping - * - * @return The file name string - */ - public Optional getTimeSeriesMappingFileName() { - return Optional.of(addPrefixAndSuffix("time_series_mapping")); - } - - /** - * Get the the file name for all {@link GraphicInput}s - * - * @param graphicClass the graphic input class a filename string should be generated from - * @return the filename string - */ - public Optional getGraphicsInputFileName(Class graphicClass) { - String assetInputString = camelCaseToSnakeCase(graphicClass.getSimpleName()); - return Optional.of(addPrefixAndSuffix(assetInputString)); - } - - /** - * Get the the file name for all {@link CharacteristicInput}s - * - * @param assetCharClass the asset characteristics class a filename string should be generated - * from - * @return the filename string - */ - public Optional getAssetCharacteristicsFileName( - Class assetCharClass) { - String assetCharString = camelCaseToSnakeCase(assetCharClass.getSimpleName()); - return Optional.of(addPrefixAndSuffix(assetCharString)); - } - - /** - * Get the the file name for all {@link AssetTypeInput}s - * - * @param typeClass the asset type class a filename string should be generated from - * @return the filename string - */ - public Optional getTypeFileName(Class typeClass) { - String assetTypeString = camelCaseToSnakeCase(typeClass.getSimpleName()); - return Optional.of(addPrefixAndSuffix(assetTypeString)); - } - - /** - * Get the the file name for all {@link AssetInput}s - * - * @param assetInputClass the asset input class a filename string should be generated from - * @return the filename string - */ - public Optional getAssetInputFileName(Class assetInputClass) { - String assetInputString = camelCaseToSnakeCase(assetInputClass.getSimpleName()); - return Optional.of(addPrefixAndSuffix(assetInputString)); - } - - /** - * Get the the file name for all {@link OperatorInput}s - * - * @param operatorClass the asset input class a filename string should be generated from - * @return the filename string - */ - public Optional getOperatorInputFileName(Class operatorClass) { - String assetInputString = camelCaseToSnakeCase(operatorClass.getSimpleName()); - return Optional.of(addPrefixAndSuffix(assetInputString)); - } - - /** - * Get the the file name for all {@link ResultEntity}s - * - * @param resultEntityClass the result entity class a filename string should be generated from - * @return the filename string - */ - public Optional getResultEntityFileName(Class resultEntityClass) { - return Optional.of(buildResultEntityString(resultEntityClass)); - } - - /** - * Get the the file name for coordinates - * - * @return the filename string - */ - public String getIdCoordinateFileName() { - return addPrefixAndSuffix("coordinates"); - } - - private String buildResultEntityString(Class resultEntityClass) { - String resultEntityString = - camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); - return addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX)); - } - - /** - * 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 = "((? res = strategy.getFileName(String) - - then: - !res.present - } - - def "A FileNamingStrategy without pre- or suffixes should return valid strings for all result models"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(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 FileNamingStrategy with pre- and suffixes should return valid strings for all result models"() { - given: "a file naming strategy with pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy("prefix", "suffix") - - when: - Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for all input assets models"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for all asset characteristics models"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(modelClass) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - EvCharacteristicInput || "ev_characteristic_input" - } - - def "A FileNamingStrategy without pre- or suffixes should return valid strings for all input types models"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for a Load Parameter Model"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(modelClass) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - RandomLoadParameters || "random_load_parameters_input" - } - - def "A FileNamingStrategy without pre- or suffixes should return valid strings for a graphic input Model"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(modelClass) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - NodeGraphicInput || "node_graphic_input" - LineGraphicInput || "line_graphic_input" - } - - def "A FileNamingStrategy without pre- or suffix should return empty Optional, if the content of the time series is not covered"() { - given: - FileNamingStrategy strategy = new FileNamingStrategy() - 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.getFileName(timeSeries) - - then: - !actual.present - } - - def "A FileNamingStrategy without pre- or suffix should return empty Optional, if the time series is empty"() { - given: - FileNamingStrategy strategy = new FileNamingStrategy() - def entries = [] as SortedSet - IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) - timeSeries.uuid >> UUID.randomUUID() - timeSeries.entries >> entries - - when: - Optional actual = strategy.getFileName(timeSeries) - - then: - !actual.present - } - - def "A FileNamingStrategy without pre- or suffix should return valid file name for individual time series" () { - given: - FileNamingStrategy strategy = new FileNamingStrategy() - 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.getFileName(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 FileNamingStrategy with pre- or suffix should return valid file name for individual time series" () { - given: - FileNamingStrategy strategy = new FileNamingStrategy("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.getFileName(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 FileNamingStrategy without pre- or suffix should return valid file name for load profile input" () { - given: - FileNamingStrategy strategy = new FileNamingStrategy() - LoadProfileInput timeSeries = Mock(LoadProfileInput) - timeSeries.uuid >> uuid - timeSeries.getType() >> type - - when: - Optional actual = strategy.getFileName(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 FileNamingStrategy returns empty Optional, when there is no naming defined for a given time series class"() { - given: - FileNamingStrategy fileNamingStrategy = new FileNamingStrategy() - RepetitiveTimeSeries timeSeries = Mock(RepetitiveTimeSeries) - - when: - Optional fileName = fileNamingStrategy.getFileName(timeSeries) - - then: - !fileName.present - } - - def "A FileNamingStrategy without pre- or suffixes should return valid strings for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy() - - when: - Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) - - then: - res.present - res.get() == "time_series_mapping" - } - - def "A FileNamingStrategy with pre- and suffix should return valid strings for time series mapping"() { - given: "a file naming strategy without pre- or suffixes" - FileNamingStrategy strategy = new FileNamingStrategy("prefix", "suffix") - - when: - Optional res = strategy.getFileName(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 any model input class"() { - given: "a file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - - 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() - LineInput || Optional.empty() - SwitchInput || Optional.empty() - NodeInput || Optional.empty() - MeasurementUnitInput || Optional.empty() - EvcsInput || Optional.empty() - Transformer2WInput || Optional.empty() - Transformer3WInput || Optional.empty() - CylindricalStorageInput || Optional.empty() - ThermalHouseInput || Optional.empty() - BmTypeInput || Optional.empty() - ChpTypeInput || Optional.empty() - EvTypeInput || Optional.empty() - HpTypeInput || Optional.empty() - LineTypeInput || Optional.empty() - StorageTypeInput || Optional.empty() - Transformer2WTypeInput || Optional.empty() - Transformer3WTypeInput || Optional.empty() - WecTypeInput || Optional.empty() - WecTypeInput || Optional.empty() - RandomLoadParameters || Optional.empty() - NodeGraphicInput || Optional.empty() - LineGraphicInput || Optional.empty() - WecCharacteristicInput || Optional.empty() - EvCharacteristicInput || Optional.empty() - TimeSeriesMappingSource.MappingEntry || Optional.empty() - } - - def "A simple file naming strategy does return empty sub directory path for any result class"() { - given: "a file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - - 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 file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - 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 file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - def timeSeries = Mock(IndividualTimeSeries) - - when: - def actual = strategy.getDirectoryPath(timeSeries) - - then: - actual == Optional.empty() - } - - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all input classes"() { - given: "a file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - - when: - def res = strategy.getFilePath(modelClass as Class) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - 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" - EvCharacteristicInput || "ev_characteristic_input" - 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" - NodeGraphicInput || "node_graphic_input" - LineGraphicInput || "line_graphic_input" - } - - def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all result classes"() { - given: "a file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - - 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 file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - 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 file naming strategy without pre- or suffixes" - def strategy = new FileNamingStrategy() - 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" - } -} From cb09f8f6d893f421cf064af96f30c63fcb51f5af Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 00:50:25 +0200 Subject: [PATCH 16/24] Revert "#279 Deleted FileNamingStrategy and FileNamingStrategyTest" This reverts commit 4f60799296a01bfb03c2b8aa3d8493686c820c96. --- .../datamodel/io/csv/FileNamingStrategy.java | 504 +++++++++++ .../io/csv/FileNamingStrategyTest.groovy | 833 ++++++++++++++++++ 2 files changed, 1337 insertions(+) create mode 100644 src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java create mode 100644 src/test/groovy/edu/ie3/datamodel/io/csv/FileNamingStrategyTest.groovy diff --git a/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java new file mode 100644 index 000000000..ec58a13da --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/io/csv/FileNamingStrategy.java @@ -0,0 +1,504 @@ +/* + * © 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.csv; + +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; +import edu.ie3.datamodel.models.input.AssetTypeInput; +import edu.ie3.datamodel.models.input.OperatorInput; +import edu.ie3.datamodel.models.input.RandomLoadParameters; +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 based on the class that should be processed + * e.g. when writing .csv files. Represents a flat dir with all files inside. To use a hierarchic + * directory structure one might consider using {@link HierarchicFileNamingStrategy} + * + * @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); + + 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 file names + * + * @param prefix Prefix of the files + * @param suffix Suffixes of the files + */ + public FileNamingStrategy(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); + } + + /** Constructor for building the file names without provided files with prefix and suffix */ + public FileNamingStrategy() { + this("", ""); + } + + /** + * Constructor for building the file names + * + * @param prefix Prefix of the files + */ + 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 + * + * @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(); + } + + public Pattern getIndividualTimeSeriesPattern() { + return individualTimeSeriesPattern; + } + + public Pattern getLoadProfileTimeSeriesPattern() { + return loadProfileTimeSeriesPattern; + } + + /** + * 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 + */ + 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( + getFileName(cls).orElseGet(() -> ""), getDirectoryPath(cls).orElseGet(() -> "")); + } + + /** + * 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( + getFileName(timeSeries).orElseGet(() -> ""), + getDirectoryPath(timeSeries).orElseGet(() -> "")); + } + + 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 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(); + } + + /** + * 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(); + } + + /** + * Returns the file name (and only the file name without any directories and extension). + * + * @param cls Targeted class of the given file + * @return The file name + */ + public Optional getFileName(Class cls) { + if (AssetTypeInput.class.isAssignableFrom(cls)) + return getTypeFileName(cls.asSubclass(AssetTypeInput.class)); + if (AssetInput.class.isAssignableFrom(cls)) + return getAssetInputFileName(cls.asSubclass(AssetInput.class)); + if (ResultEntity.class.isAssignableFrom(cls)) + return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); + if (CharacteristicInput.class.isAssignableFrom(cls)) + return getAssetCharacteristicsFileName(cls.asSubclass(CharacteristicInput.class)); + if (cls.equals(RandomLoadParameters.class)) { + String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); + return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); + } + if (GraphicInput.class.isAssignableFrom(cls)) + return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class)); + if (OperatorInput.class.isAssignableFrom(cls)) + return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); + if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) + return getTimeSeriesMappingFileName(); + logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); + return Optional.empty(); + } + + /** + * 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 getFileName(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(); + } + } + + /** + * 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 (getIndividualTimeSeriesPattern().matcher(withoutEnding).matches()) + return extractIndividualTimesSeriesMetaInformation(withoutEnding); + else if (getLoadProfileTimeSeriesPattern().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 = getIndividualTimeSeriesPattern().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 = getLoadProfileTimeSeriesPattern().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 file name for time series mapping + * + * @return The file name string + */ + public Optional getTimeSeriesMappingFileName() { + return Optional.of(addPrefixAndSuffix("time_series_mapping")); + } + + /** + * Get the the file name for all {@link GraphicInput}s + * + * @param graphicClass the graphic input class a filename string should be generated from + * @return the filename string + */ + public Optional getGraphicsInputFileName(Class graphicClass) { + String assetInputString = camelCaseToSnakeCase(graphicClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the the file name for all {@link CharacteristicInput}s + * + * @param assetCharClass the asset characteristics class a filename string should be generated + * from + * @return the filename string + */ + public Optional getAssetCharacteristicsFileName( + Class assetCharClass) { + String assetCharString = camelCaseToSnakeCase(assetCharClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetCharString)); + } + + /** + * Get the the file name for all {@link AssetTypeInput}s + * + * @param typeClass the asset type class a filename string should be generated from + * @return the filename string + */ + public Optional getTypeFileName(Class typeClass) { + String assetTypeString = camelCaseToSnakeCase(typeClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetTypeString)); + } + + /** + * Get the the file name for all {@link AssetInput}s + * + * @param assetInputClass the asset input class a filename string should be generated from + * @return the filename string + */ + public Optional getAssetInputFileName(Class assetInputClass) { + String assetInputString = camelCaseToSnakeCase(assetInputClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the the file name for all {@link OperatorInput}s + * + * @param operatorClass the asset input class a filename string should be generated from + * @return the filename string + */ + public Optional getOperatorInputFileName(Class operatorClass) { + String assetInputString = camelCaseToSnakeCase(operatorClass.getSimpleName()); + return Optional.of(addPrefixAndSuffix(assetInputString)); + } + + /** + * Get the the file name for all {@link ResultEntity}s + * + * @param resultEntityClass the result entity class a filename string should be generated from + * @return the filename string + */ + public Optional getResultEntityFileName(Class resultEntityClass) { + return Optional.of(buildResultEntityString(resultEntityClass)); + } + + /** + * Get the the file name for coordinates + * + * @return the filename string + */ + public String getIdCoordinateFileName() { + return addPrefixAndSuffix("coordinates"); + } + + private String buildResultEntityString(Class resultEntityClass) { + String resultEntityString = + camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); + return addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX)); + } + + /** + * 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 = "((? res = strategy.getFileName(String) + + then: + !res.present + } + + def "A FileNamingStrategy without pre- or suffixes should return valid strings for all result models"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(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 FileNamingStrategy with pre- and suffixes should return valid strings for all result models"() { + given: "a file naming strategy with pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for all input assets models"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for all asset characteristics models"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + WecCharacteristicInput || "wec_characteristic_input" + EvCharacteristicInput || "ev_characteristic_input" + } + + def "A FileNamingStrategy without pre- or suffixes should return valid strings for all input types models"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(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 FileNamingStrategy without pre- or suffixes should return valid strings for a Load Parameter Model"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + RandomLoadParameters || "random_load_parameters_input" + } + + def "A FileNamingStrategy without pre- or suffixes should return valid strings for a graphic input Model"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(modelClass) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + NodeGraphicInput || "node_graphic_input" + LineGraphicInput || "line_graphic_input" + } + + def "A FileNamingStrategy without pre- or suffix should return empty Optional, if the content of the time series is not covered"() { + given: + FileNamingStrategy strategy = new FileNamingStrategy() + 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.getFileName(timeSeries) + + then: + !actual.present + } + + def "A FileNamingStrategy without pre- or suffix should return empty Optional, if the time series is empty"() { + given: + FileNamingStrategy strategy = new FileNamingStrategy() + def entries = [] as SortedSet + IndividualTimeSeries timeSeries = Mock(IndividualTimeSeries) + timeSeries.uuid >> UUID.randomUUID() + timeSeries.entries >> entries + + when: + Optional actual = strategy.getFileName(timeSeries) + + then: + !actual.present + } + + def "A FileNamingStrategy without pre- or suffix should return valid file name for individual time series" () { + given: + FileNamingStrategy strategy = new FileNamingStrategy() + 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.getFileName(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 FileNamingStrategy with pre- or suffix should return valid file name for individual time series" () { + given: + FileNamingStrategy strategy = new FileNamingStrategy("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.getFileName(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 FileNamingStrategy without pre- or suffix should return valid file name for load profile input" () { + given: + FileNamingStrategy strategy = new FileNamingStrategy() + LoadProfileInput timeSeries = Mock(LoadProfileInput) + timeSeries.uuid >> uuid + timeSeries.getType() >> type + + when: + Optional actual = strategy.getFileName(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 FileNamingStrategy returns empty Optional, when there is no naming defined for a given time series class"() { + given: + FileNamingStrategy fileNamingStrategy = new FileNamingStrategy() + RepetitiveTimeSeries timeSeries = Mock(RepetitiveTimeSeries) + + when: + Optional fileName = fileNamingStrategy.getFileName(timeSeries) + + then: + !fileName.present + } + + def "A FileNamingStrategy without pre- or suffixes should return valid strings for time series mapping"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy() + + when: + Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) + + then: + res.present + res.get() == "time_series_mapping" + } + + def "A FileNamingStrategy with pre- and suffix should return valid strings for time series mapping"() { + given: "a file naming strategy without pre- or suffixes" + FileNamingStrategy strategy = new FileNamingStrategy("prefix", "suffix") + + when: + Optional res = strategy.getFileName(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 any model input class"() { + given: "a file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + + 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() + LineInput || Optional.empty() + SwitchInput || Optional.empty() + NodeInput || Optional.empty() + MeasurementUnitInput || Optional.empty() + EvcsInput || Optional.empty() + Transformer2WInput || Optional.empty() + Transformer3WInput || Optional.empty() + CylindricalStorageInput || Optional.empty() + ThermalHouseInput || Optional.empty() + BmTypeInput || Optional.empty() + ChpTypeInput || Optional.empty() + EvTypeInput || Optional.empty() + HpTypeInput || Optional.empty() + LineTypeInput || Optional.empty() + StorageTypeInput || Optional.empty() + Transformer2WTypeInput || Optional.empty() + Transformer3WTypeInput || Optional.empty() + WecTypeInput || Optional.empty() + WecTypeInput || Optional.empty() + RandomLoadParameters || Optional.empty() + NodeGraphicInput || Optional.empty() + LineGraphicInput || Optional.empty() + WecCharacteristicInput || Optional.empty() + EvCharacteristicInput || Optional.empty() + TimeSeriesMappingSource.MappingEntry || Optional.empty() + } + + def "A simple file naming strategy does return empty sub directory path for any result class"() { + given: "a file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + + 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 file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + 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 file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + def timeSeries = Mock(IndividualTimeSeries) + + when: + def actual = strategy.getDirectoryPath(timeSeries) + + then: + actual == Optional.empty() + } + + def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all input classes"() { + given: "a file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + + when: + def res = strategy.getFilePath(modelClass as Class) + + then: + res.present + res.get() == expectedString + + where: + modelClass || expectedString + WecCharacteristicInput || "wec_characteristic_input" + 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" + EvCharacteristicInput || "ev_characteristic_input" + 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" + NodeGraphicInput || "node_graphic_input" + LineGraphicInput || "line_graphic_input" + } + + def "A FileNamingStrategy without pre- or suffixes should return valid file paths for all result classes"() { + given: "a file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + + 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 file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + 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 file naming strategy without pre- or suffixes" + def strategy = new FileNamingStrategy() + 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" + } +} From 756f88a7f1584b158e00385e2d7ac5b87c89586f Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 17:39:52 +0200 Subject: [PATCH 17/24] #279 Merged the test case files into a single file --- ...ntityPersistenceNamingStrategyTest.groovy} | 470 +++++++++++++++- ...ntityPersistenceNamingStrategyTest2.groovy | 509 ------------------ 2 files changed, 469 insertions(+), 510 deletions(-) rename src/test/groovy/edu/ie3/datamodel/io/naming/{EntityPersistenceNamingStrategyTest1.groovy => EntityPersistenceNamingStrategyTest.groovy} (54%) delete mode 100644 src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy similarity index 54% rename from src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy rename to src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index 4ac410fb8..9b506a22a 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest1.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -8,6 +8,9 @@ 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 @@ -59,13 +62,18 @@ 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 EntityPersistenceNamingStrategyTest1 extends Specification { +class EntityPersistenceNamingStrategyTest extends Specification { def "The uuid pattern actually matches a valid uuid"() { given: @@ -526,4 +534,464 @@ class EntityPersistenceNamingStrategyTest1 extends Specification { 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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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() + WecCharacteristicInput || Optional.empty() + EvCharacteristicInput || 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 + WecCharacteristicInput || "wec_characteristic_input" + EvCharacteristicInput || "ev_characteristic_input" + 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/naming/EntityPersistenceNamingStrategyTest2.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy deleted file mode 100644 index e1eba3280..000000000 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest2.groovy +++ /dev/null @@ -1,509 +0,0 @@ -/* - * © 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.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.* -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 -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.* -import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult -import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult -import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries -import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue -import edu.ie3.datamodel.io.source.TimeSeriesMappingSource -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.time.ZonedDateTime - -class EntityPersistenceNamingStrategyTest2 extends Specification { - - 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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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.getFileName(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() - WecCharacteristicInput || Optional.empty() - EvCharacteristicInput || 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 - WecCharacteristicInput || "wec_characteristic_input" - EvCharacteristicInput || "ev_characteristic_input" - 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" - } -} From 8fb60a7d32b37a506d894eb0f9e706c522068b7f Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 17:42:53 +0200 Subject: [PATCH 18/24] #279 Merged the test case files into a single file --- .../io/naming/EntityPersistenceNamingStrategyTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index 9b506a22a..57efacfdf 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -539,7 +539,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { given: EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() def entries = [ - new TimeBasedValue(ZonedDateTime.now(), new EnergyPriceValue(Quantities.getQuantity(500d, PowerSystemUnits.EURO_PER_MEGAWATTHOUR)))] as SortedSet + 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 @@ -978,7 +978,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { 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 + 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 From 7fc9c68b4ed0fa73807c334a2e062e85afa55ba3 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 17:53:21 +0200 Subject: [PATCH 19/24] #279 Updated documentation and comments to reflect the change from FileNamingStrategyTest to EntityPersistenceNamingStrategy --- docs/readthedocs/io/csvfiles.rst | 7 +++---- .../io/naming/EntityPersistenceNamingStrategy.java | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/readthedocs/io/csvfiles.rst b/docs/readthedocs/io/csvfiles.rst index e3db32e7a..6c041f5d9 100644 --- a/docs/readthedocs/io/csvfiles.rst +++ b/docs/readthedocs/io/csvfiles.rst @@ -4,8 +4,8 @@ csv files Naming of files =============== -A naming strategy provides a mapping between model classes and the names of the data sinks, in which the serialized -representation of several objects of this class can be found. +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. **EntityPersistenceNamingStrategy**: @@ -22,8 +22,7 @@ Default naming strategy ======================= There is a default mapping from model class to naming of data sinks 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 EntityPersistenceNamingStrategy("prefix","suffix")`. +You may extend / alter the naming with pre- or suffix by calling :code: `new EntityPersistenceNamingStrategy("prefix","suffix")`. Input ----- diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index d6006f53e..dda9b7384 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -31,10 +31,10 @@ import org.apache.logging.log4j.Logger; /** - * Provides an easy to use standard way to name files, tables or any other data sink that is used in - * order to persist entities. 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} + * 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 From a9b5dbbbad33ed9ca35224c64586dfd4553d5024 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 22:12:22 +0200 Subject: [PATCH 20/24] #279 Changed several function names to indicate that entity name is being found and updated the documentation for those functions --- .../EntityPersistenceNamingStrategy.java | 22 ++++++++----------- .../ie3/datamodel/io/sink/InfluxDbSink.java | 2 +- .../datamodel/io/sink/InfluxDbSinkIT.groovy | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index dda9b7384..ff4582a5e 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -180,7 +180,7 @@ public Optional getFileName(Class cls) { Optional inputEntityFileName = getInputEntityFileName(cls); if (inputEntityFileName.isPresent()) return inputEntityFileName; if (ResultEntity.class.isAssignableFrom(cls)) - return getResultEntityFileName(cls.asSubclass(ResultEntity.class)); + return getResultEntityName(cls.asSubclass(ResultEntity.class)); logger.error("There is no naming strategy defined for {}", cls.getSimpleName()); return Optional.empty(); } @@ -193,7 +193,7 @@ public Optional getFileName(Class cls) { */ public Optional getInputEntityFileName(Class cls) { if (AssetTypeInput.class.isAssignableFrom(cls)) - return getTypeFileName(cls.asSubclass(AssetTypeInput.class)); + return getTypeEntityName(cls.asSubclass(AssetTypeInput.class)); if (AssetInput.class.isAssignableFrom(cls)) return getAssetInputFileName(cls.asSubclass(AssetInput.class)); if (CharacteristicInput.class.isAssignableFrom(cls)) @@ -217,17 +217,19 @@ public Optional getInputEntityFileName(Class cls * @param resultEntityClass the result entity class a filename string should be generated from * @return the filename string */ - public Optional getResultEntityFileName(Class resultEntityClass) { - return Optional.of(buildResultEntityString(resultEntityClass)); + public Optional getResultEntityName(Class resultEntityClass) { + String resultEntityString = + camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); + return Optional.of(addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX))); } /** - * Get the the file name for all {@link AssetTypeInput}s + * Get the the entity name for all {@link AssetTypeInput}s * - * @param typeClass the asset type class a filename string should be generated from + * @param typeClass the asset type class a entity name string should be generated from * @return the filename string */ - public Optional getTypeFileName(Class typeClass) { + public Optional getTypeEntityName(Class typeClass) { String assetTypeString = camelCaseToSnakeCase(typeClass.getSimpleName()); return Optional.of(addPrefixAndSuffix(assetTypeString)); } @@ -243,12 +245,6 @@ public Optional getAssetInputFileName(Class assetI return Optional.of(addPrefixAndSuffix(assetInputString)); } - private String buildResultEntityString(Class resultEntityClass) { - String resultEntityString = - camelCaseToSnakeCase(resultEntityClass.getSimpleName().replace("Result", "")); - return addPrefixAndSuffix(resultEntityString.concat(RES_ENTITY_SUFFIX)); - } - /** * Get the the file name for all {@link CharacteristicInput}s * 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 f4ddd7102..3eef91eae 100644 --- a/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java +++ b/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java @@ -109,7 +109,7 @@ public void flush() { */ private Optional transformToPoint(ResultEntity entity) { Optional measurementName = - entityPersistenceNamingStrategy.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.", 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 e0fe33bbd..5fe68a86b 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy @@ -272,7 +272,7 @@ class InfluxDbSinkIT extends Specification { //Always return an empty Optional for results class EmptyFileNamingStrategy extends EntityPersistenceNamingStrategy { @Override - Optional getResultEntityFileName(Class resultEntityClass) { + Optional getResultEntityName(Class resultEntityClass) { return Optional.empty() } From 9cf9e05da6f448d5e58fcddd651b2155efd975d3 Mon Sep 17 00:00:00 2001 From: ahamshubham Date: Tue, 30 Mar 2021 22:36:34 +0200 Subject: [PATCH 21/24] #279 Changed several function names to indicate that entity name is being found and updated the documentation for those functions --- .../io/connectors/CsvFileConnector.java | 2 +- .../EntityPersistenceNamingStrategy.java | 76 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) 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 b5e3a9f2f..4c40e79d2 100644 --- a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java +++ b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java @@ -253,7 +253,7 @@ public Map> initTimeSeriesReader( * @throws FileNotFoundException If the file is not present */ public BufferedReader initIdCoordinateReader() throws FileNotFoundException { - String filePath = entityPersistenceNamingStrategy.getIdCoordinateFileName(); + String filePath = entityPersistenceNamingStrategy.getIdCoordinateEntityName(); return initReader(filePath); } diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index ff4582a5e..fa13005e8 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -177,7 +177,7 @@ private Optional getFilePath(String fileName, String subDirectories) { * @return The file name */ public Optional getFileName(Class cls) { - Optional inputEntityFileName = getInputEntityFileName(cls); + Optional inputEntityFileName = getInputEntityName(cls); if (inputEntityFileName.isPresent()) return inputEntityFileName; if (ResultEntity.class.isAssignableFrom(cls)) return getResultEntityName(cls.asSubclass(ResultEntity.class)); @@ -186,36 +186,36 @@ public Optional getFileName(Class cls) { } /** - * Get the the file name for all {@link InputEntity}s + * Get the name for all {@link InputEntity}s * - * @param cls Targeted class of the given file - * @return The file name + * @param cls Targeted class of the given entity + * @return The entity name */ - public Optional getInputEntityFileName(Class cls) { + public Optional getInputEntityName(Class cls) { if (AssetTypeInput.class.isAssignableFrom(cls)) return getTypeEntityName(cls.asSubclass(AssetTypeInput.class)); if (AssetInput.class.isAssignableFrom(cls)) - return getAssetInputFileName(cls.asSubclass(AssetInput.class)); + return getAssetInputEntityName(cls.asSubclass(AssetInput.class)); if (CharacteristicInput.class.isAssignableFrom(cls)) - return getAssetCharacteristicsFileName(cls.asSubclass(CharacteristicInput.class)); + return getAssetCharacteristicsEntityName(cls.asSubclass(CharacteristicInput.class)); if (cls.equals(RandomLoadParameters.class)) { String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); } if (GraphicInput.class.isAssignableFrom(cls)) - return getGraphicsInputFileName(cls.asSubclass(GraphicInput.class)); + return getGraphicsInputEntityName(cls.asSubclass(GraphicInput.class)); if (OperatorInput.class.isAssignableFrom(cls)) - return getOperatorInputFileName(cls.asSubclass(OperatorInput.class)); + return getOperatorInputEntityName(cls.asSubclass(OperatorInput.class)); if (TimeSeriesMappingSource.MappingEntry.class.isAssignableFrom(cls)) - return getTimeSeriesMappingFileName(); + return getTimeSeriesMappingEntityName(); return Optional.empty(); } /** - * Get the the file name for all {@link ResultEntity}s + * Get the entity name for all {@link ResultEntity}s * - * @param resultEntityClass the result entity class a filename string should be generated from - * @return the filename string + * @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 = @@ -224,10 +224,10 @@ public Optional getResultEntityName(Class result } /** - * Get the the entity name for all {@link AssetTypeInput}s + * Get the entity name for all {@link AssetTypeInput}s * - * @param typeClass the asset type class a entity name string should be generated from - * @return the filename string + * @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()); @@ -235,24 +235,24 @@ public Optional getTypeEntityName(Class typeCl } /** - * Get the the file name for all {@link AssetInput}s + * Get the entity name for all {@link AssetInput}s * - * @param assetInputClass the asset input class a filename string should be generated from - * @return the filename string + * @param assetInputClass the asset input class an entity name string should be generated from + * @return the entity name string */ - public Optional getAssetInputFileName(Class assetInputClass) { + public Optional getAssetInputEntityName(Class assetInputClass) { String assetInputString = camelCaseToSnakeCase(assetInputClass.getSimpleName()); return Optional.of(addPrefixAndSuffix(assetInputString)); } /** - * Get the the file name for all {@link CharacteristicInput}s + * Get the entity name for all {@link CharacteristicInput}s * - * @param assetCharClass the asset characteristics class a filename string should be generated + * @param assetCharClass the asset characteristics class an entity name string should be generated * from - * @return the filename string + * @return the entity name string */ - public Optional getAssetCharacteristicsFileName( + public Optional getAssetCharacteristicsEntityName( Class assetCharClass) { String assetCharString = camelCaseToSnakeCase(assetCharClass.getSimpleName()); return Optional.of(addPrefixAndSuffix(assetCharString)); @@ -290,33 +290,33 @@ private String addPrefixAndSuffix(String s) { } /** - * Get the the file name for all {@link GraphicInput}s + * Get the entity name for all {@link GraphicInput}s * - * @param graphicClass the graphic input class a filename string should be generated from - * @return the filename string + * @param graphicClass the graphic input class an entity name string should be generated from + * @return the entity name string */ - public Optional getGraphicsInputFileName(Class graphicClass) { + public Optional getGraphicsInputEntityName(Class graphicClass) { String assetInputString = camelCaseToSnakeCase(graphicClass.getSimpleName()); return Optional.of(addPrefixAndSuffix(assetInputString)); } /** - * Get the the file name for all {@link OperatorInput}s + * Get the entity name for all {@link OperatorInput}s * - * @param operatorClass the asset input class a filename string should be generated from - * @return the filename string + * @param operatorClass the asset input class an entity name string should be generated from + * @return the entity name string */ - public Optional getOperatorInputFileName(Class operatorClass) { + public Optional getOperatorInputEntityName(Class operatorClass) { String assetInputString = camelCaseToSnakeCase(operatorClass.getSimpleName()); return Optional.of(addPrefixAndSuffix(assetInputString)); } /** - * Get the file name for time series mapping + * Get the entity name for time series mapping * - * @return The file name string + * @return The entity name string */ - public Optional getTimeSeriesMappingFileName() { + public Optional getTimeSeriesMappingEntityName() { return Optional.of(addPrefixAndSuffix("time_series_mapping")); } @@ -492,11 +492,11 @@ private LoadProfileTimeSeriesMetaInformation extractLoadProfileTimesSeriesMetaIn } /** - * Get the the file name for coordinates + * Get the entity name for coordinates * - * @return the filename string + * @return the entity name string */ - public String getIdCoordinateFileName() { + public String getIdCoordinateEntityName() { return addPrefixAndSuffix("coordinates"); } } From 63d6cf0780c2add3b317c96cda6c63d48e36c70f Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 31 Mar 2021 09:34:05 +0200 Subject: [PATCH 22/24] Renaming methods --- .../io/connectors/CsvFileConnector.java | 4 +- .../EntityPersistenceNamingStrategy.java | 41 +++++++++----- .../ie3/datamodel/io/sink/InfluxDbSink.java | 2 +- ...EntityPersistenceNamingStrategyTest.groovy | 53 ++++++------------- .../HierarchicFileNamingStrategyTest.groovy | 5 +- .../datamodel/io/sink/InfluxDbSinkIT.groovy | 10 ++-- 6 files changed, 54 insertions(+), 61 deletions(-) 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 4c40e79d2..a63fceb05 100644 --- a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java +++ b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java @@ -366,7 +366,7 @@ CsvFileDefinition buildFileDefinition(T timeSeries, String[] headLineElements, S String directoryPath = entityPersistenceNamingStrategy.getDirectoryPath(timeSeries).orElse(""); String fileName = entityPersistenceNamingStrategy - .getFileName(timeSeries) + .getEntityName(timeSeries) .orElseThrow( () -> new ConnectorException( @@ -389,7 +389,7 @@ private CsvFileDefinition buildFileDefinition( String directoryPath = entityPersistenceNamingStrategy.getDirectoryPath(clz).orElse(""); String fileName = entityPersistenceNamingStrategy - .getFileName(clz) + .getEntityName(clz) .orElseThrow( () -> new ConnectorException( diff --git a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java index fa13005e8..e1211de2a 100644 --- a/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java +++ b/src/main/java/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategy.java @@ -155,14 +155,32 @@ private static String prepareSuffix(String suffix) { * * @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( - getFileName(cls).orElseGet(() -> ""), getDirectoryPath(cls).orElseGet(() -> "")); + 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()) @@ -171,14 +189,14 @@ private Optional getFilePath(String fileName, String subDirectories) { } /** - * Returns the file name (and only the file name without any directories and extension). + * Returns the name of the entity, that should be used for persistence. * * @param cls Targeted class of the given file - * @return The file name + * @return The name of the entity */ - public Optional getFileName(Class cls) { - Optional inputEntityFileName = getInputEntityName(cls); - if (inputEntityFileName.isPresent()) return inputEntityFileName; + 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()); @@ -191,14 +209,12 @@ public Optional getFileName(Class cls) { * @param cls Targeted class of the given entity * @return The entity name */ - public Optional getInputEntityName(Class cls) { + 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 (CharacteristicInput.class.isAssignableFrom(cls)) - return getAssetCharacteristicsEntityName(cls.asSubclass(CharacteristicInput.class)); - if (cls.equals(RandomLoadParameters.class)) { + if (RandomLoadParameters.class.isAssignableFrom(cls)) { String loadParamString = camelCaseToSnakeCase(cls.getSimpleName()); return Optional.of(addPrefixAndSuffix(loadParamString.concat("_input"))); } @@ -208,6 +224,7 @@ public Optional getInputEntityName(Class 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(); } @@ -346,7 +363,7 @@ 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( - getFileName(timeSeries).orElseGet(() -> ""), + getEntityName(timeSeries).orElseGet(() -> ""), getDirectoryPath(timeSeries).orElseGet(() -> "")); } @@ -361,7 +378,7 @@ Optional getFilePath(T timeSeries) { * @return A file name for this particular time series */ public , E extends TimeSeriesEntry, V extends Value> - Optional getFileName(T timeSeries) { + Optional getEntityName(T timeSeries) { if (timeSeries instanceof IndividualTimeSeries) { Optional maybeFirstElement = timeSeries.getEntries().stream().findFirst(); if (maybeFirstElement.isPresent()) { 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 3eef91eae..6164a1cb3 100644 --- a/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java +++ b/src/main/java/edu/ie3/datamodel/io/sink/InfluxDbSink.java @@ -168,7 +168,7 @@ private Optional transformToPoint(ResultEntity entity, String measurement private , V extends Value> Set transformToPoints( TimeSeries timeSeries) { if (timeSeries.getEntries().isEmpty()) return Collections.emptySet(); - Optional measurementName = entityPersistenceNamingStrategy.getFileName(timeSeries); + Optional measurementName = entityPersistenceNamingStrategy.getEntityName(timeSeries); if (!measurementName.isPresent()) { String valueClassName = timeSeries.getEntries().iterator().next().getValue().getClass().getSimpleName(); diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy index 57efacfdf..f8c3d9672 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/EntityPersistenceNamingStrategyTest.groovy @@ -33,8 +33,6 @@ 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.characteristic.EvCharacteristicInput -import edu.ie3.datamodel.models.input.system.characteristic.WecCharacteristicInput 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 @@ -327,7 +325,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(String) + Optional res = strategy.getEntityName(String) then: !res.present @@ -338,7 +336,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -369,7 +367,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") when: - Optional res = strategy.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -400,7 +398,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -428,29 +426,12 @@ class EntityPersistenceNamingStrategyTest extends Specification { ThermalHouseInput || "thermal_house_input" } - def "A EntityPersistenceNamingStrategy without pre- or suffixes should return valid strings for all asset characteristics models"() { - given: "a naming strategy without pre- or suffixes" - EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() - - when: - Optional res = strategy.getFileName(modelClass) - - then: - res.present - res.get() == expectedString - - where: - modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - EvCharacteristicInput || "ev_characteristic_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.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -475,7 +456,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -491,7 +472,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(modelClass) + Optional res = strategy.getEntityName(modelClass) then: res.present @@ -514,7 +495,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { timeSeries.entries >> entries when: - Optional actual = strategy.getFileName(timeSeries) + Optional actual = strategy.getEntityName(timeSeries) then: !actual.present @@ -529,7 +510,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { timeSeries.entries >> entries when: - Optional actual = strategy.getFileName(timeSeries) + Optional actual = strategy.getEntityName(timeSeries) then: !actual.present @@ -545,7 +526,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { timeSeries.entries >> entries when: - Optional actual = strategy.getFileName(timeSeries) + Optional actual = strategy.getEntityName(timeSeries) then: actual.present @@ -566,7 +547,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { timeSeries.entries >> entries when: - Optional actual = strategy.getFileName(timeSeries) + Optional actual = strategy.getEntityName(timeSeries) then: actual.present @@ -585,7 +566,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { timeSeries.type >> type when: - Optional actual = strategy.getFileName(timeSeries) + Optional actual = strategy.getEntityName(timeSeries) then: actual.present @@ -602,7 +583,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { RepetitiveTimeSeries timeSeries = Mock(RepetitiveTimeSeries) when: - Optional fileName = entityPersistenceNamingStrategy.getFileName(timeSeries) + Optional fileName = entityPersistenceNamingStrategy.getEntityName(timeSeries) then: !fileName.present @@ -613,7 +594,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy() when: - Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) + Optional res = strategy.getEntityName(TimeSeriesMappingSource.MappingEntry) then: res.present @@ -625,7 +606,7 @@ class EntityPersistenceNamingStrategyTest extends Specification { EntityPersistenceNamingStrategy strategy = new EntityPersistenceNamingStrategy("prefix", "suffix") when: - Optional res = strategy.getFileName(TimeSeriesMappingSource.MappingEntry) + Optional res = strategy.getEntityName(TimeSeriesMappingSource.MappingEntry) then: res.present @@ -650,8 +631,6 @@ class EntityPersistenceNamingStrategyTest extends Specification { HpTypeInput || Optional.empty() StorageTypeInput || Optional.empty() WecTypeInput || Optional.empty() - WecCharacteristicInput || Optional.empty() - EvCharacteristicInput || Optional.empty() } def "A simple file naming strategy does return empty sub directory path for other system model input classes"() { @@ -872,8 +851,6 @@ class EntityPersistenceNamingStrategyTest extends Specification { where: modelClass || expectedString - WecCharacteristicInput || "wec_characteristic_input" - EvCharacteristicInput || "ev_characteristic_input" BmTypeInput || "bm_type_input" ChpTypeInput || "chp_type_input" EvTypeInput || "ev_type_input" diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy index 27f10e760..4443f986d 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy @@ -6,7 +6,6 @@ package edu.ie3.datamodel.io.naming import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy -import edu.ie3.datamodel.io.naming.HierarchicFileNamingStrategy import edu.ie3.datamodel.io.source.TimeSeriesMappingSource import edu.ie3.datamodel.models.BdewLoadProfile import edu.ie3.datamodel.models.UniqueEntity @@ -63,7 +62,7 @@ class HierarchicFileNamingStrategyTest extends Specification { def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) when: - def res = strategy.getFileName(String) + def res = strategy.getEntityName(String) then: !res.present @@ -431,7 +430,7 @@ class HierarchicFileNamingStrategyTest extends Specification { def timeSeries = Mock(RepetitiveTimeSeries) when: - def fileName = strategy.getFileName(timeSeries) + def fileName = strategy.getEntityName(timeSeries) then: !fileName.present 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 5fe68a86b..e7252af42 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/sink/InfluxDbSinkIT.groovy @@ -73,7 +73,7 @@ class InfluxDbSinkIT extends Specification { when: sink.persist(lineResult1) sink.flush() - def key = entityPersistenceNamingStrategy.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 = entityPersistenceNamingStrategy.getFileName(LineResult).get().trim().replaceAll("\\W", "_") - def key_chp = entityPersistenceNamingStrategy.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 = entityPersistenceNamingStrategy.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) @@ -277,7 +277,7 @@ class InfluxDbSinkIT extends Specification { } @Override - , E extends TimeSeriesEntry, V extends Value> Optional getFileName(T timeSeries) { + , E extends TimeSeriesEntry, V extends Value> Optional getEntityName(T timeSeries) { return Optional.empty() } } From 80c9d4df41a502d00bd15cdb87371764b0c7385d Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 31 Mar 2021 09:44:23 +0200 Subject: [PATCH 23/24] Adapting documentation --- docs/readthedocs/io/csvfiles.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/readthedocs/io/csvfiles.rst b/docs/readthedocs/io/csvfiles.rst index 6c041f5d9..a3b9f251d 100644 --- a/docs/readthedocs/io/csvfiles.rst +++ b/docs/readthedocs/io/csvfiles.rst @@ -9,7 +9,7 @@ within e.g. the data sinks, in which the serialized representation of several ob Currently we offer two different, pre-defined naming strategies, which you might extend to fit your needs: 1. **EntityPersistenceNamingStrategy**: - A basic naming strategy that is able to add prefix and suffix to the names of the data sinks. A flat folder structure + 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 EntityPersistenceNamingStrategy. Additionally, the `Default directory hierarchy`_ is taken @@ -20,9 +20,9 @@ strategy you like into :code:`CsvDataSource` and :code:`CsvFileSink`. Default naming strategy ======================= -There is a default mapping from model class to naming of data sinks 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 EntityPersistenceNamingStrategy("prefix","suffix")`. +You may extend / alter the naming with pre- or suffix by calling :code:`new EntityPersistenceNamingStrategy("prefix","suffix")`. Input ----- From a33889c0a88d0965841b0a7f03fd2a6360ff092e Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 31 Mar 2021 09:47:48 +0200 Subject: [PATCH 24/24] Removing the last not working tests --- .../HierarchicFileNamingStrategyTest.groovy | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy index 4443f986d..c2de9934c 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/naming/HierarchicFileNamingStrategyTest.groovy @@ -22,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 @@ -180,40 +178,6 @@ class HierarchicFileNamingStrategyTest extends Specification { ThermalHouseInput || "test_grid" + File.separator + "input" + File.separator + "thermal" + File.separator + "thermal_house_input" } - def "A HierarchicFileNamingStrategy without pre- or suffixes should return valid directory paths for all asset characteristics 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 HierarchicFileNamingStrategy without pre- or suffixes should return valid file paths for all asset characteristics models"() { - given: "a naming strategy without pre- or suffixes" - def strategy = new HierarchicFileNamingStrategy(defaultHierarchy) - - when: - def res = strategy.getFilePath(modelClass as Class) - - 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" - } - 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)