-
Notifications
You must be signed in to change notification settings - Fork 5
/
EntityData.java
189 lines (173 loc) · 6.72 KB
/
EntityData.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
/*
* © 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.factory;
import static edu.ie3.util.quantities.PowerSystemUnits.KILOVOLT;
import edu.ie3.datamodel.exceptions.FactoryException;
import edu.ie3.datamodel.exceptions.VoltageLevelException;
import edu.ie3.datamodel.models.UniqueEntity;
import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils;
import edu.ie3.datamodel.models.voltagelevels.VoltageLevel;
import java.util.*;
import javax.measure.quantity.ElectricPotential;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.geojson.GeoJsonReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.units.indriya.ComparableQuantity;
/**
* Data used by {@link EntityFactory} to create an instance of an entity than can be created based
* only on a mapping of fieldName to value. This class can be used whenever no additional data is
* needed, but also functions as a parent class for extensions.
*
* @version 0.1
* @since 28.01.20
*/
public class EntityData extends FactoryData {
private static final Logger logger = LoggerFactory.getLogger(EntityData.class);
private static final GeoJsonReader geoJsonReader = new GeoJsonReader();
/**
* Creates a new EntityData object
*
* @param fieldsToAttributes attribute map: field name to value
* @param entityClass class of the entity to be created with this data
*/
public EntityData(
Map<String, String> fieldsToAttributes, Class<? extends UniqueEntity> entityClass) {
super(fieldsToAttributes, entityClass);
}
/**
* Creates a new EntityData object based on a given {@link FactoryData} object
*
* @param factoryData The factory data object to use attributes of
*/
protected EntityData(FactoryData factoryData) {
super(factoryData.getFieldsToValues(), factoryData.getTargetClass());
}
@Override
@SuppressWarnings("unchecked cast")
public Class<? extends UniqueEntity> getTargetClass() {
return (Class<? extends UniqueEntity>) super.getTargetClass();
}
/**
* Returns boolean value for given field name. Throws {@link FactoryException} if field does not
* exist, or field value is null or empty.
*
* @param field field name
* @return true if value is "1" or "true", false otherwise
*/
public boolean getBoolean(String field) {
final String value = getField(field);
if (value == null || value.trim().isEmpty())
throw new FactoryException(String.format("Field \"%s\" is null or empty", field));
return value.trim().equals("1") || value.trim().equalsIgnoreCase("true");
}
/**
* Parses and returns a geometry from field value of given field name. Throws {@link
* FactoryException} if field does not exist or parsing fails.
*
* @param field field name
* @return Geometry if field value is not empty, empty Optional otherwise
*/
private Optional<Geometry> getGeometry(String field) {
String value = getField(field);
try {
if (value.trim().isEmpty()) return Optional.empty();
else return Optional.of(geoJsonReader.read(value));
} catch (ParseException pe) {
throw new FactoryException(
String.format(
"Exception while trying to parse geometry of field \"%s\" with value \"%s\"",
field, value),
pe);
}
}
/**
* Parses and returns a geometrical LineString from field value of given field name. Throws {@link
* FactoryException} if field does not exist or parsing fails.
*
* @param field field name
* @return LineString if field value is not empty, empty Optional otherwise
*/
public Optional<LineString> getLineString(String field) {
Optional<Geometry> geom = getGeometry(field);
if (geom.isPresent()) {
if (geom.get() instanceof LineString lineString) return Optional.of(lineString);
else
throw new FactoryException(
"Geometry is of type "
+ geom.getClass().getSimpleName()
+ ", but type LineString is required");
} else return Optional.empty();
}
/**
* Parses and returns a geometrical Point from field value of given field name. Throws {@link
* FactoryException} if field does not exist or parsing fails.
*
* @param field field name
* @return Point if field value is not empty, empty Optional otherwise
*/
public Optional<Point> getPoint(String field) {
Optional<Geometry> geom = getGeometry(field);
if (geom.isPresent()) {
if (geom.get() instanceof Point point) return Optional.of(point);
else
throw new FactoryException(
"Geometry is of type "
+ geom.getClass().getSimpleName()
+ ", but type Point is required");
} else return Optional.empty();
}
/**
* Parses and returns a voltage level from field value of given field name. Throws {@link
* FactoryException} if field does not exist or parsing fails.
*
* @param voltLvlField name of the field containing the voltage level
* @param ratedVoltField name of the field containing the rated voltage
* @return Voltage level
*/
public VoltageLevel getVoltageLvl(String voltLvlField, String ratedVoltField) {
try {
final String voltLvlId = getField(voltLvlField);
final ComparableQuantity<ElectricPotential> vRated = getQuantity(ratedVoltField, KILOVOLT);
return parseToGermanVoltLvlOrIndividual(voltLvlId, vRated);
} catch (IllegalArgumentException iae) {
throw new FactoryException("VoltageLevel could not be parsed", iae);
}
}
/**
* Parses the given voltage level information to German voltage level or builds an individual one,
* if no suitable one can be found.
*
* @param voltLvlId Identifier of the voltage level
* @param vRated Foreseen rated voltage
* @return A suitable German {@link edu.ie3.datamodel.models.voltagelevels.CommonVoltageLevel} or
* an individual one
*/
private VoltageLevel parseToGermanVoltLvlOrIndividual(
String voltLvlId, ComparableQuantity<ElectricPotential> vRated) {
try {
return GermanVoltageLevelUtils.parse(voltLvlId, vRated);
} catch (VoltageLevelException e) {
logger.warn(
"Cannot parse ({}, {}) to common German voltage level. Build an individual one.",
voltLvlId,
vRated);
return new VoltageLevel(voltLvlId, vRated);
}
}
@Override
public String toString() {
return "EntityData{"
+ "fieldsToAttributes="
+ getFieldsToValues()
+ ", targetClass="
+ getTargetClass()
+ '}';
}
}