Skip to content

Commit ca892b6

Browse files
Merge branch 'dev' into df/#1131-psdm-update-for-tap-water-demand
2 parents 64b7da7 + 557ee8c commit ca892b6

File tree

18 files changed

+1281
-16
lines changed

18 files changed

+1281
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3535
- Fix spotless deprecations [#1123](https://github.com/ie3-institute/PowerSystemDataModel/issues/1223)
3636
- Refactored `CongestionResult`, removed `ModelResultEntity` [#1234](https://github.com/ie3-institute/PowerSystemDataModel/issues/1234)
3737
- Replaced `LoadProfileInput` with `LoadProfileTimeSeries` [#1228](https://github.com/ie3-institute/PowerSystemDataModel/issues/1228)
38+
- Enhance `CsvDataSource` [#1246](https://github.com/ie3-institute/PowerSystemDataModel/issues/1246)
3839

3940
## [5.1.0] - 2024-06-24
4041

src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.nio.charset.StandardCharsets;
1818
import java.nio.file.Path;
1919
import java.util.*;
20+
import java.util.function.Function;
2021
import java.util.stream.Stream;
2122
import org.slf4j.Logger;
2223
import org.slf4j.LoggerFactory;
@@ -34,10 +35,17 @@ public class CsvFileConnector implements DataConnector {
3435
private final Map<Class<? extends Entity>, BufferedCsvWriter> entityWriters = new HashMap<>();
3536
private final Map<UUID, BufferedCsvWriter> timeSeriesWriters = new HashMap<>();
3637
private final Path baseDirectory;
38+
private final Optional<Function<String, InputStream>> customInputStream;
3739
private static final String FILE_ENDING = ".csv";
3840

3941
public CsvFileConnector(Path baseDirectory) {
4042
this.baseDirectory = baseDirectory;
43+
this.customInputStream = Optional.empty();
44+
}
45+
46+
public CsvFileConnector(Path baseDirectory, Function<String, InputStream> inputStreamSupplier) {
47+
this.baseDirectory = baseDirectory;
48+
this.customInputStream = Optional.ofNullable(inputStreamSupplier);
4149
}
4250

4351
/** Returns the base directory of this connector. */
@@ -159,9 +167,17 @@ public synchronized <C extends Entity> void closeEntityWriter(Class<C> clz) thro
159167
* @throws FileNotFoundException if no file with the provided file name can be found
160168
*/
161169
public BufferedReader initReader(Path filePath) throws FileNotFoundException {
162-
File fullPath = baseDirectory.resolve(filePath.toString() + FILE_ENDING).toFile();
163-
return new BufferedReader(
164-
new InputStreamReader(new FileInputStream(fullPath), StandardCharsets.UTF_8), 16384);
170+
Path fullPath = baseDirectory.resolve(filePath.toString() + FILE_ENDING);
171+
172+
InputStream inputStream;
173+
174+
if (customInputStream.isPresent()) {
175+
inputStream = customInputStream.get().apply(fullPath.toString());
176+
} else {
177+
inputStream = new FileInputStream(fullPath.toFile());
178+
}
179+
180+
return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8), 16384);
165181
}
166182

167183
@Override

src/main/java/edu/ie3/datamodel/io/source/EntitySource.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,24 @@
99
import edu.ie3.datamodel.exceptions.FailedValidationException;
1010
import edu.ie3.datamodel.exceptions.SourceException;
1111
import edu.ie3.datamodel.exceptions.ValidationException;
12+
import edu.ie3.datamodel.io.connectors.CsvFileConnector;
1213
import edu.ie3.datamodel.io.factory.EntityData;
1314
import edu.ie3.datamodel.io.factory.EntityFactory;
15+
import edu.ie3.datamodel.io.naming.FileNamingStrategy;
16+
import edu.ie3.datamodel.io.source.csv.CsvDataSource;
1417
import edu.ie3.datamodel.models.Entity;
1518
import edu.ie3.datamodel.models.UniqueEntity;
1619
import edu.ie3.datamodel.utils.QuadFunction;
1720
import edu.ie3.datamodel.utils.TriFunction;
1821
import edu.ie3.datamodel.utils.Try;
1922
import edu.ie3.datamodel.utils.Try.Failure;
23+
import java.io.IOException;
24+
import java.net.URI;
25+
import java.net.URISyntaxException;
26+
import java.net.URL;
27+
import java.nio.file.FileSystem;
28+
import java.nio.file.FileSystems;
29+
import java.nio.file.Path;
2030
import java.util.*;
2131
import java.util.function.BiFunction;
2232
import java.util.function.Function;
@@ -34,6 +44,9 @@
3444
public abstract class EntitySource {
3545
protected static final Logger log = LoggerFactory.getLogger(EntitySource.class);
3646

47+
// file system for build-in entities
48+
private static FileSystem jarFileSystem = null;
49+
3750
// convenience collectors
3851

3952
protected static <T extends UniqueEntity> Collector<T, ?, Map<UUID, T>> toMap() {
@@ -94,6 +107,47 @@ protected static <C> Try<Void, ValidationException> validate(
94107
.orElse(Try.Success.empty()));
95108
}
96109

110+
/**
111+
* Method to get a source for the build in entities.
112+
*
113+
* @param subdirectory from the resource folder
114+
* @return a new {@link CsvDataSource}
115+
*/
116+
protected static CsvDataSource getBuildInSource(Class<?> clazz, String subdirectory)
117+
throws SourceException {
118+
try {
119+
URL url = clazz.getResource(subdirectory);
120+
121+
if (url == null) {
122+
throw new SourceException("Resources not found for: " + subdirectory);
123+
}
124+
125+
URI uri = url.toURI();
126+
CsvFileConnector connector;
127+
128+
switch (url.getProtocol()) {
129+
case "file" -> connector = new CsvFileConnector(Path.of(uri));
130+
case "jar" -> {
131+
// handling resources in jar
132+
String[] array = uri.toString().split("!");
133+
134+
if (jarFileSystem == null) {
135+
jarFileSystem = FileSystems.newFileSystem(URI.create(array[0]), Collections.emptyMap());
136+
}
137+
138+
connector =
139+
new CsvFileConnector(jarFileSystem.getPath(array[1]), clazz::getResourceAsStream);
140+
}
141+
default -> throw new SourceException(
142+
"Protocol " + url.getProtocol() + " is nor supported!");
143+
}
144+
145+
return new CsvDataSource(",", connector, new FileNamingStrategy());
146+
} catch (URISyntaxException | IOException e) {
147+
throw new SourceException(e);
148+
}
149+
}
150+
97151
/**
98152
* Universal method to get a map: uuid to {@link UniqueEntity}.
99153
*

src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ public CsvDataSource(String csvSep, Path directoryPath, FileNamingStrategy fileN
5454
this.fileNamingStrategy = fileNamingStrategy;
5555
}
5656

57+
public CsvDataSource(
58+
String csvSep, CsvFileConnector connector, FileNamingStrategy fileNamingStrategy) {
59+
this.csvSep = csvSep;
60+
this.connector = connector;
61+
this.fileNamingStrategy = fileNamingStrategy;
62+
}
63+
5764
@Override
5865
public Optional<Set<String>> getSourceFields(Class<? extends Entity> entityClass)
5966
throws SourceException {
@@ -85,6 +92,15 @@ public Stream<Map<String, String>> getSourceData(Class<? extends Entity> entityC
8592
return buildStreamWithFieldsToAttributesMap(entityClass, true).getOrThrow();
8693
}
8794

95+
/**
96+
* @param filePath to the csv file
97+
* @return a stream of maps that represent the rows in the csv file
98+
* @throws SourceException on error while reading the source file
99+
*/
100+
public Stream<Map<String, String>> getSourceData(Path filePath) throws SourceException {
101+
return buildStreamWithFieldsToAttributesMap(filePath, true).getOrThrow();
102+
}
103+
88104
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
89105

90106
/** Returns the set {@link FileNamingStrategy}. */
@@ -231,23 +247,20 @@ protected String[] parseCsvRow(String csvRow, String csvSep) {
231247
protected Try<Stream<Map<String, String>>, SourceException> buildStreamWithFieldsToAttributesMap(
232248
Class<? extends Entity> entityClass, boolean allowFileNotExisting) {
233249
return getFilePath(entityClass)
234-
.flatMap(
235-
path -> buildStreamWithFieldsToAttributesMap(entityClass, path, allowFileNotExisting));
250+
.flatMap(path -> buildStreamWithFieldsToAttributesMap(path, allowFileNotExisting));
236251
}
237252

238253
/**
239254
* Reads the first line (considered to be the headline with headline fields) and returns a stream
240255
* of (fieldName to fieldValue) mapping where each map represents one row of the .csv file. Since
241256
* the returning stream is a parallel stream, the order of the elements cannot be guaranteed.
242257
*
243-
* @param entityClass the entity class that should be build
244258
* @param filePath the path of the file to read
245259
* @return a try containing either a parallel stream of maps, where each map represents one row of
246260
* the csv file with the mapping (fieldName to fieldValue) or an exception
247261
*/
248-
protected <T extends Entity>
249-
Try<Stream<Map<String, String>>, SourceException> buildStreamWithFieldsToAttributesMap(
250-
Class<T> entityClass, Path filePath, boolean allowFileNotExisting) {
262+
protected Try<Stream<Map<String, String>>, SourceException> buildStreamWithFieldsToAttributesMap(
263+
Path filePath, boolean allowFileNotExisting) {
251264
try (BufferedReader reader = connector.initReader(filePath)) {
252265
final String[] headline = parseCsvRow(reader.readLine(), csvSep);
253266

@@ -264,9 +277,7 @@ Try<Stream<Map<String, String>>, SourceException> buildStreamWithFieldsToAttribu
264277
return Failure.of(new SourceException("Unable to find file '" + filePath + "'.", e));
265278
}
266279
} catch (IOException e) {
267-
return Failure.of(
268-
new SourceException(
269-
"Cannot read file to build entity '" + entityClass.getSimpleName() + "'", e));
280+
return Failure.of(new SourceException("Cannot read file '" + filePath + "'.", e));
270281
}
271282
}
272283

src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ protected IndividualTimeSeries<V> buildIndividualTimeSeries(
163163
throws SourceException {
164164
Try<Stream<TimeBasedValue<V>>, SourceException> timeBasedValues =
165165
dataSource
166-
.buildStreamWithFieldsToAttributesMap(TimeBasedValue.class, filePath, false)
166+
.buildStreamWithFieldsToAttributesMap(filePath, false)
167167
.flatMap(
168168
stream ->
169169
Try.scanStream(stream.map(fieldToValueFunction), "TimeBasedValue<V>")
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
SuSa,SuSu,SuWd,TrSa,TrSu,TrWd,WiSa,WiSu,WiWd,quarterHour
2+
74.6,68.8,71.5,75.8,68.3,73.0,70.0,63.2,65.5,0
3+
76.2,67.4,69.0,76.7,66.5,70.1,73.0,61.0,62.6,1
4+
77.7,65.7,66.3,77.7,64.6,67.1,75.9,58.9,59.6,2
5+
78.5,63.5,63.5,78.5,62.6,64.5,77.6,57.0,57.0,3
6+
77.9,60.9,60.9,78.5,60.3,62.3,77.1,55.3,54.8,4
7+
76.3,58.0,58.6,77.8,57.9,60.6,75.0,53.7,53.1,5
8+
74.1,55.4,56.6,76.6,55.5,59.2,72.1,52.1,51.7,6
9+
71.9,53.3,55.1,74.7,53.3,57.9,69.1,50.5,50.5,7
10+
70.2,52.0,54.2,72.6,51.2,56.7,66.8,48.7,49.4,8
11+
68.9,51.4,53.7,70.4,49.5,55.6,65.1,46.9,48.5,9
12+
67.9,51.0,53.4,68.5,48.0,54.7,64.1,45.2,47.9,10
13+
67.3,50.5,53.3,67.3,46.7,54.2,63.5,43.9,47.7,11
14+
66.9,49.6,53.1,67.0,45.7,54.1,63.4,43.0,47.9,12
15+
66.7,48.5,53.2,67.5,44.9,54.6,63.6,42.5,48.7,13
16+
66.8,47.5,54.1,68.3,44.3,55.8,64.0,42.2,50.2,14
17+
67.3,46.7,56.1,69.1,43.9,57.9,64.5,42.0,52.3,15
18+
68.0,46.4,59.4,69.7,43.6,60.9,65.0,41.9,55.1,16
19+
69.0,46.5,63.3,70.1,43.5,64.4,65.6,41.8,58.2,17
20+
70.0,46.6,67.2,70.5,43.6,68.0,66.3,41.8,61.2,18
21+
71.0,46.7,70.1,71.0,43.9,71.0,67.3,42.0,63.5,19
22+
71.8,46.6,71.4,71.8,44.5,73.2,68.5,42.6,65.0,20
23+
72.4,46.3,71.6,72.5,45.1,74.7,69.9,43.4,66.0,21
24+
72.8,46.0,71.2,73.0,45.6,75.7,71.4,44.4,67.1,22
25+
72.9,45.8,71.0,72.9,45.8,76.6,72.9,45.8,69.1,23
26+
73.0,45.9,71.5,72.2,45.6,77.7,74.4,47.4,72.5,24
27+
73.9,46.3,73.1,72.2,45.3,79.3,76.8,49.0,77.1,25
28+
77.0,47.2,75.9,74.4,45.2,81.9,81.0,50.4,82.9,26
29+
83.2,48.6,80.4,80.4,45.8,86.0,87.8,51.4,89.7,27
30+
93.3,50.5,86.6,91.0,47.2,91.9,98.0,51.8,97.6,28
31+
106.2,52.6,95.1,105.2,49.1,100.4,110.7,51.7,107.3,29
32+
120.5,54.3,106.3,121.2,51.0,111.9,124.8,51.2,119.9,30
33+
134.5,55.1,120.5,137.4,52.3,127.1,139.2,50.5,136.4,31
34+
147.2,54.8,137.8,152.1,52.8,145.9,153.0,49.6,157.1,32
35+
157.8,53.9,156.3,164.9,52.9,166.2,165.4,49.0,179.5,33
36+
166.2,53.2,173.4,175.1,53.1,185.2,175.9,48.8,200.5,34
37+
171.9,53.3,186.9,182.2,54.2,200.0,184.1,49.5,216.8,35
38+
175.0,54.7,195.0,186.1,56.4,208.5,189.5,51.3,226.2,36
39+
176.1,57.2,198.7,187.5,59.5,212.1,192.8,53.8,230.0,37
40+
176.3,60.0,199.8,187.7,62.7,212.6,195.1,56.8,230.4,38
41+
176.6,62.6,200.0,187.8,65.4,212.1,197.1,59.8,229.9,39
42+
177.7,64.5,200.6,188.7,67.2,212.2,199.8,62.6,230.0,40
43+
179.4,65.9,201.9,190.1,68.5,213.1,202.7,65.1,231.2,41
44+
181.3,67.0,203.6,191.9,69.6,214.6,205.4,67.2,233.0,42
45+
183.1,68.2,205.6,193.4,71.0,216.8,207.4,69.1,235.5,43
46+
184.4,69.7,207.6,194.5,73.1,219.2,208.4,70.8,238.1,44
47+
185.2,71.4,209.1,195.1,75.6,221.2,208.3,72.2,240.0,45
48+
185.3,73.2,209.6,195.3,78.2,222.0,207.4,73.5,240.4,46
49+
185.0,74.7,208.4,195.3,80.4,220.5,205.6,74.7,238.3,47
50+
184.1,76.0,205.1,194.9,81.9,216.3,203.0,76.0,233.0,48
51+
182.4,77.0,200.0,193.9,82.8,209.8,199.7,77.3,225.1,49
52+
179.7,77.8,193.8,191.7,83.2,201.9,195.6,78.4,215.7,50
53+
175.7,78.5,186.9,187.8,83.2,193.4,190.6,79.4,205.6,51
54+
170.1,79.1,179.9,181.9,82.8,185.0,184.6,80.1,195.7,52
55+
163.1,79.5,173.4,174.1,82.1,177.4,177.5,80.5,186.7,53
56+
154.6,79.3,168.1,164.8,80.9,170.9,168.9,80.3,179.2,54
57+
144.8,78.5,164.4,154.2,79.4,166.3,158.8,79.4,173.8,55
58+
133.9,76.8,163.0,142.6,77.5,163.9,147.2,77.8,171.0,56
59+
122.7,74.4,163.5,130.9,75.3,163.6,134.8,75.7,170.7,57
60+
112.0,71.8,165.4,119.8,73.1,165.1,122.7,73.4,172.7,58
61+
102.8,69.1,168.2,110.3,71.0,168.2,112.1,71.0,176.6,59
62+
95.7,66.8,171.5,102.7,69.2,172.5,103.8,68.9,182.1,60
63+
90.4,64.8,174.6,96.9,67.6,177.3,97.4,67.0,188.2,61
64+
86.4,63.1,177.2,92.1,66.1,181.4,92.6,65.2,193.9,62
65+
83.2,61.7,178.5,87.8,64.5,184.1,88.8,63.5,198.1,63
66+
80.3,60.4,178.2,83.6,62.8,184.5,85.6,62.0,200.1,64
67+
77.8,59.7,176.8,79.7,61.5,183.6,83.3,61.2,200.7,65
68+
75.9,59.7,175.1,76.9,61.2,182.1,82.4,61.8,200.9,66
69+
74.7,60.7,173.8,75.7,62.6,181.3,83.2,64.5,201.8,67
70+
74.4,63.0,173.2,76.5,65.9,181.5,85.8,69.5,204.0,68
71+
74.8,66.0,172.4,78.6,70.4,181.7,89.5,76.0,205.8,69
72+
75.6,69.2,170.2,81.1,75.0,180.0,93.4,82.6,205.5,70
73+
76.6,71.9,165.4,83.2,78.5,174.7,96.2,87.8,200.9,71
74+
77.6,73.9,157.1,84.1,80.1,164.8,97.4,90.8,190.7,72
75+
78.5,75.1,146.1,84.3,80.4,151.5,97.4,92.1,176.6,73
76+
79.1,76.0,133.8,84.1,80.2,137.0,96.8,92.3,160.5,74
77+
79.4,76.6,121.5,84.1,80.4,123.3,96.2,92.5,144.8,75
78+
79.4,77.3,110.1,84.7,81.4,112.1,96.3,93.1,131.3,76
79+
79.4,78.2,100.5,85.8,83.1,103.4,96.8,94.0,120.1,77
80+
79.6,79.2,93.2,87.3,85.1,97.3,97.2,94.6,111.3,78
81+
80.4,80.4,88.8,88.8,86.9,93.4,97.2,94.4,104.6,79
82+
81.9,81.6,87.4,90.1,88.1,91.6,96.3,93.0,100.0,80
83+
83.9,82.9,88.1,91.2,88.7,91.1,94.8,90.8,96.7,81
84+
85.7,83.8,89.6,91.7,88.6,91.1,92.8,88.0,94.1,82
85+
86.9,84.1,90.6,91.6,87.8,90.6,90.6,85.0,91.6,83
86+
87.0,83.7,90.2,90.6,86.4,89.2,88.5,82.1,88.5,84
87+
86.3,82.7,88.5,89.0,84.4,87.2,86.4,79.4,85.2,85
88+
84.9,81.2,86.3,87.1,82.0,85.0,84.3,76.9,82.1,86
89+
83.2,79.4,84.1,85.0,79.4,83.2,82.2,74.7,79.4,87
90+
81.3,77.5,82.4,83.1,76.7,82.1,80.1,72.8,77.6,88
91+
79.3,75.5,81.2,81.2,74.1,81.7,78.0,71.1,76.4,89
92+
77.4,73.3,80.3,79.4,71.5,81.6,75.9,69.3,75.6,90
93+
75.7,71.0,79.4,77.6,69.1,81.3,73.8,67.3,74.7,91
94+
74.1,68.6,78.4,75.7,67.0,80.6,71.7,65.0,73.7,92
95+
72.7,66.4,77.2,73.8,65.3,79.5,69.7,62.6,72.3,93
96+
71.3,64.6,75.7,71.9,64.1,77.9,67.6,60.4,70.5,94
97+
70.1,63.5,73.8,70.1,63.5,75.7,65.4,58.9,68.2,95

0 commit comments

Comments
 (0)