-
Notifications
You must be signed in to change notification settings - Fork 5
/
GraphicSource.java
218 lines (190 loc) · 9.5 KB
/
GraphicSource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
* © 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.source;
import edu.ie3.datamodel.exceptions.GraphicSourceException;
import edu.ie3.datamodel.exceptions.SourceException;
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.models.input.NodeInput;
import edu.ie3.datamodel.models.input.OperatorInput;
import edu.ie3.datamodel.models.input.connector.LineInput;
import edu.ie3.datamodel.models.input.connector.type.LineTypeInput;
import edu.ie3.datamodel.models.input.container.GraphicElements;
import edu.ie3.datamodel.models.input.graphics.GraphicInput;
import edu.ie3.datamodel.models.input.graphics.LineGraphicInput;
import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput;
import edu.ie3.datamodel.utils.Try;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Implementation that provides the capability to build entities of type {@link GraphicInput} from
* different data sources e.g. .csv files or databases
*
* @version 0.1
* @since 08.04.20
*/
public class GraphicSource extends EntitySource {
// general fields
private final TypeSource typeSource;
private final RawGridSource rawGridSource;
// factories
private final LineGraphicInputFactory lineGraphicInputFactory;
private final NodeGraphicInputFactory nodeGraphicInputFactory;
public GraphicSource(TypeSource typeSource, RawGridSource rawGridSource, DataSource dataSource) {
this.typeSource = typeSource;
this.rawGridSource = rawGridSource;
this.dataSource = dataSource;
this.lineGraphicInputFactory = new LineGraphicInputFactory();
this.nodeGraphicInputFactory = new NodeGraphicInputFactory();
}
/** Returns the graphic elements of the grid or throws a {@link SourceException} */
public GraphicElements getGraphicElements() throws SourceException {
// read all needed entities
/// start with types and operators
Set<OperatorInput> operators = typeSource.getOperators();
Set<LineTypeInput> lineTypes = typeSource.getLineTypes();
Set<NodeInput> nodes = rawGridSource.getNodes(operators);
Set<LineInput> lines = rawGridSource.getLines(nodes, lineTypes, operators);
Try<Set<NodeGraphicInput>> nodeGraphics = Try.of(() -> getNodeGraphicInput(nodes));
Try<Set<LineGraphicInput>> lineGraphics = Try.of(() -> getLineGraphicInput(lines));
List<SourceException> exceptions =
(List<SourceException>) Try.getExceptions(List.of(nodeGraphics, lineGraphics));
if (!exceptions.isEmpty()) {
throw new GraphicSourceException(
exceptions.size() + "error(s) occurred while initializing graphic elements. ",
exceptions);
} else {
// if everything is fine, return a GraphicElements instance
// getOrThrow should not throw an exception in this context, because all exception are
// filtered and thrown before
return new GraphicElements(nodeGraphics.getOrThrow(), lineGraphics.getOrThrow());
}
}
/**
* If the set of {@link NodeInput} entities is not exhaustive for all available {@link
* NodeGraphicInput} entities or if an error during the building process occurs a {@link
* SourceException} is thrown, else all entities that has been able to be built are returned.
*/
public Set<NodeGraphicInput> getNodeGraphicInput() throws SourceException {
return getNodeGraphicInput(rawGridSource.getNodes(typeSource.getOperators()));
}
public Set<NodeGraphicInput> getNodeGraphicInput(Set<NodeInput> nodes) throws SourceException {
return Try.scanCollection(
buildNodeGraphicEntityData(nodes)
.filter(Optional::isPresent)
.map(Optional::get)
.map(nodeGraphicInputFactory::get)
.collect(Collectors.toSet()),
NodeGraphicInput.class)
.getOrThrow(SourceException.class);
}
/**
* If the set of {@link LineInput} entities is not exhaustive for all available {@link
* LineGraphicInput} entities or if an error during the building process occurs a {@link
* SourceException} is thrown, else all entities that has been able to be built are returned.
*/
public Set<LineGraphicInput> getLineGraphicInput() throws SourceException {
Set<OperatorInput> operators = typeSource.getOperators();
return getLineGraphicInput(
rawGridSource.getLines(
rawGridSource.getNodes(operators), typeSource.getLineTypes(), operators));
}
public Set<LineGraphicInput> getLineGraphicInput(Set<LineInput> lines) throws SourceException {
return Try.scanCollection(
buildLineGraphicEntityData(lines)
.filter(Optional::isPresent)
.map(Optional::get)
.map(lineGraphicInputFactory::get)
.collect(Collectors.toSet()),
LineGraphicInput.class)
.getOrThrow(SourceException.class);
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// build EntityData
/**
* Builds a stream of {@link NodeGraphicInputEntityData} instances that can be consumed by a
* {@link NodeGraphicInputFactory} to build instances of {@link NodeGraphicInput} entities. This
* method depends on corresponding instances of {@link NodeInput} entities that are represented by
* a corresponding {@link NodeGraphicInput} entity. The determination of matching {@link
* NodeInput} and {@link NodeGraphicInput} entities is carried out by the UUID of the {@link
* NodeInput} entity. Hence it is crucial to only pass over collections that are pre-checked for
* the uniqueness of the UUIDs of the nodes they contain. No further sanity checks are included in
* this method. If no UUID of a {@link NodeInput} entity can be found for a {@link
* NodeGraphicInputEntityData} instance, an empty optional is included in the stream and warning
* is logged.
*
* @param nodes a set of nodes with unique uuids
* @return a stream of optional {@link NodeGraphicInput} entities
*/
protected Stream<Optional<NodeGraphicInputEntityData>> buildNodeGraphicEntityData(
Set<NodeInput> nodes) {
return dataSource
.getSourceData(NodeGraphicInput.class)
.map(fieldsToAttributes -> buildNodeGraphicEntityData(fieldsToAttributes, nodes));
}
protected Optional<NodeGraphicInputEntityData> buildNodeGraphicEntityData(
Map<String, String> fieldsToAttributes, Set<NodeInput> nodes) {
// get the node of the entity
String nodeUuid = fieldsToAttributes.get(NODE);
Optional<NodeInput> node = findFirstEntityByUuid(nodeUuid, nodes);
// if the node is not present we return an empty element and
// log a warning
if (node.isEmpty()) {
logSkippingWarning(
NodeGraphicInput.class.getSimpleName(),
fieldsToAttributes.get("uuid"),
"no id (graphic entities don't have one)",
NODE + ": " + nodeUuid);
return Optional.empty();
}
// remove fields that are passed as objects to constructor
fieldsToAttributes.keySet().remove(NODE);
return Optional.of(new NodeGraphicInputEntityData(fieldsToAttributes, node.get()));
}
/**
* Builds a stream of {@link LineGraphicInputEntityData} instances that can be consumed by a
* {@link LineGraphicInputFactory} to build instances of {@link LineGraphicInput} entities. This
* method depends on corresponding instances of {@link LineInput} entities that are represented by
* a corresponding {@link LineGraphicInput} entity. The determination of matching {@link
* LineInput} and {@link LineGraphicInput} entities is carried out by the UUID of the {@link
* LineInput} entity. Hence it is crucial to only pass over collections that are pre-checked for
* the uniqueness of the UUIDs of the nodes they contain. No further sanity checks are included in
* this method. If no UUID of a {@link LineInput} entity can be found for a {@link
* LineGraphicInputEntityData} instance, an empty optional is included in the stream and warning
* is logged.
*
* @param lines a set of lines with unique uuids
* @return a stream of optional {@link LineGraphicInput} entities
*/
protected Stream<Optional<LineGraphicInputEntityData>> buildLineGraphicEntityData(
Set<LineInput> lines) {
return dataSource
.getSourceData(LineGraphicInput.class)
.map(fieldsToAttributes -> buildLineGraphicEntityData(fieldsToAttributes, lines));
}
protected Optional<LineGraphicInputEntityData> buildLineGraphicEntityData(
Map<String, String> fieldsToAttributes, Set<LineInput> lines) {
// get the node of the entity
String lineUuid = fieldsToAttributes.get("line");
Optional<LineInput> line = findFirstEntityByUuid(lineUuid, lines);
// if the node is not present we return an empty element and
// log a warning
if (line.isEmpty()) {
logSkippingWarning(
LineGraphicInput.class.getSimpleName(),
fieldsToAttributes.get("uuid"),
"no id (graphic entities don't have one)",
"line: " + lineUuid);
return Optional.empty();
}
// remove fields that are passed as objects to constructor
fieldsToAttributes.keySet().remove("line");
return Optional.of(new LineGraphicInputEntityData(fieldsToAttributes, line.get()));
}
}