Skip to content

Commit 763d0a2

Browse files
committed
Added check for replaced field names in source
1 parent c0aade4 commit 763d0a2

File tree

6 files changed

+91
-21
lines changed

6 files changed

+91
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Extend Validation to EnergyManagement Systems. [#1356](https://github.com/ie3-institute/PowerSystemDataModel/issues/1356)
1111
- Added `CITATION.cff` [#1380](https://github.com/ie3-institute/PowerSystemDataModel/issues/1380)
12+
- Added check for replaced field names in sources [#1383](https://github.com/ie3-institute/PowerSystemDataModel/issues/1383)
1213

1314
### Fixed
1415
- Fixed handling of `CongestionResult.InputModelType` in `EntityProcessor` [#1325](https://github.com/ie3-institute/PowerSystemDataModel/issues/1325)

src/main/java/edu/ie3/datamodel/io/factory/Factory.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,36 @@ private void isSupportedClass(Class<?> desiredClass) {
111111
*/
112112
protected abstract List<Set<String>> getFields(Class<?> entityClass);
113113

114+
/**
115+
* Returns a map: old field name to new field name.
116+
*
117+
* @param entityClass class that can be used to specify the fields that are returned
118+
* @return map of replaced field names
119+
*/
120+
protected Map<String, String> getReplacedFields(Class<?> entityClass) {
121+
return Collections.emptyMap();
122+
}
123+
114124
/**
115125
* Method to find and return additional fields that were found in a source and are not used by the
116126
* data model. This method will return the minimal unused fields among all field sets, meaning
117127
* that the set of actual fields is compared to the field set with the least unused fields.
118128
*
119129
* @param actualFields found in the source
120130
* @param validFieldSets that contains at least all fields found in the source
131+
* @param replacedFields fields, that are replaced and therefore, reported as unused
121132
* @return a set of unused fields
122133
*/
123134
protected Set<String> getUnusedFields(
124-
Set<String> actualFields, List<Set<String>> validFieldSets) {
135+
Set<String> actualFields, List<Set<String>> validFieldSets, Set<String> replacedFields) {
125136
// checking for additional fields
126137
// and returning the set with the least additional fields
127138
return validFieldSets.stream()
128139
.map(
129140
s -> {
130141
Set<String> set = new HashSet<>(actualFields);
131142
set.removeAll(s);
143+
set.removeAll(replacedFields);
132144
return set;
133145
})
134146
.min(Comparator.comparing(Collection::size))
@@ -174,10 +186,30 @@ public Try<Void, ValidationException> validate(
174186
+ "' are possible (NOT case-sensitive!):\n"
175187
+ possibleOptions));
176188
} else {
177-
Set<String> unused = getUnusedFields(harmonizedActualFields, validFieldSets);
189+
// find all replaced fields
190+
Map<String, String> replacedFields = getReplacedFields(entityClass);
191+
192+
Set<String> unsupportedFields =
193+
actualFields.stream().filter(replacedFields::containsKey).collect(Collectors.toSet());
194+
195+
if (!unsupportedFields.isEmpty()) {
196+
List<String> strings =
197+
unsupportedFields.stream()
198+
.map(field -> field + " -> " + replacedFields.get(field))
199+
.toList();
200+
201+
log.warn(
202+
"The following field were renamed '{}'. Please rename field like: [{}]",
203+
unsupportedFields,
204+
String.join(", ", strings));
205+
}
206+
207+
// find all unused fields
208+
Set<String> unused =
209+
getUnusedFields(harmonizedActualFields, validFieldSets, replacedFields.keySet());
178210

179211
if (!unused.isEmpty()) {
180-
log.debug(
212+
log.info(
181213
"The following additional fields were found for entity class of '{}': {}",
182214
entityClass.getSimpleName(),
183215
unused);
@@ -216,6 +248,17 @@ protected static TreeSet<String> newSet(String... attributes) {
216248
return set;
217249
}
218250

251+
protected static Map.Entry<String, String> entry(String key, String value) {
252+
return new AbstractMap.SimpleEntry<>(key, value);
253+
}
254+
255+
@SafeVarargs
256+
protected static Map<String, String> newMap(Map.Entry<String, String>... attributes) {
257+
Map<String, String> map = new HashMap<>();
258+
Arrays.stream(attributes).forEach(e -> map.put(e.getKey(), e.getValue()));
259+
return map;
260+
}
261+
219262
/**
220263
* Expands a set of attributes with further attributes. This method should always be used when
221264
* returning attribute sets, i.e. through getting the needed fields. The set maintains a

src/main/java/edu/ie3/datamodel/io/factory/input/EmInputFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,9 @@ protected EmInput buildModel(
3838

3939
return new EmInput(uuid, id, operator, operationTime, controlStrategy, parentEm);
4040
}
41+
42+
@Override
43+
protected Map<String, String> getReplacedFields(Class<?> entityClass) {
44+
return newMap(entry("parentEm", CONTROLLING_EM));
45+
}
4146
}

src/main/java/edu/ie3/datamodel/io/factory/input/participant/SystemParticipantInputEntityFactory.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,24 @@ public abstract class SystemParticipantInputEntityFactory<
3030
T extends SystemParticipantInput, D extends SystemParticipantEntityData>
3131
extends AssetInputEntityFactory<T, D> {
3232

33+
private static final String NODE = "node";
34+
3335
private static final String Q_CHARACTERISTICS = "qCharacteristics";
3436

3537
public static final String CONTROLLING_EM = "controllingEm";
3638

39+
@SafeVarargs
3740
protected SystemParticipantInputEntityFactory(Class<? extends T>... allowedClasses) {
3841
super(allowedClasses);
3942
}
4043

4144
@Override
4245
protected List<Set<String>> getFields(Class<?> entityClass) {
4346
List<Set<String>> fields = new ArrayList<>(super.getFields(entityClass));
44-
for (Set<String> set : fields) set.add(Q_CHARACTERISTICS);
47+
for (Set<String> set : fields) {
48+
set.add(Q_CHARACTERISTICS);
49+
set.add(NODE);
50+
}
4551

4652
List<Set<String>> withEm =
4753
fields.stream().map(f -> (Set<String>) expandSet(f, CONTROLLING_EM)).toList();
@@ -51,6 +57,11 @@ protected List<Set<String>> getFields(Class<?> entityClass) {
5157
return fields;
5258
}
5359

60+
@Override
61+
protected Map<String, String> getReplacedFields(Class<?> entityClass) {
62+
return newMap(entry("em", CONTROLLING_EM));
63+
}
64+
5465
@Override
5566
protected T buildModel(
5667
D data, UUID uuid, String id, OperatorInput operator, OperationTime operationTime) {

src/test/groovy/edu/ie3/datamodel/io/factory/FactoryTest.groovy

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package edu.ie3.datamodel.io.factory
77

88
import edu.ie3.datamodel.exceptions.FactoryException
9+
import edu.ie3.datamodel.models.input.EmInput
910
import edu.ie3.datamodel.utils.Try
1011
import spock.lang.Shared
1112
import spock.lang.Specification
@@ -17,7 +18,7 @@ class FactoryTest extends Specification {
1718

1819
def "A Factory can return unused fields correctly"() {
1920
when:
20-
def unused = factory.getUnusedFields(actualFields as Set<String>, validFieldSets)
21+
def unused = factory.getUnusedFields(actualFields as Set<String>, validFieldSets, [] as Set<String>)
2122

2223
then:
2324
unused == expected as Set<String>
@@ -97,5 +98,14 @@ class FactoryTest extends Specification {
9798
["id", "time", "value1"] as Set<String>
9899
]
99100
}
101+
102+
@Override
103+
protected Map<String, String> getReplacedFields(Class<?> entityClass) {
104+
if (entityClass.isAssignableFrom(EmInput)) {
105+
return ["parentEm": "controllingEM"]
106+
} else {
107+
return [:]
108+
}
109+
}
100110
}
101111
}

src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/FixedFeedInInputFactoryTest.groovy

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,21 @@ class FixedFeedInInputFactoryTest extends Specification implements FactoryTestHe
8888
input.failure
8989
input.exception.get().message == "The provided fields [cosphi_rated, id, s_rated, uuid] are invalid for instance of 'FixedFeedInInput'. \n" +
9090
"The following fields (without complex objects e.g. nodes, operators, ...) to be passed to a constructor of 'FixedFeedInInput' are possible (NOT case-sensitive!):\n" +
91-
"0: [cosPhiRated, id, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, q_characteristics, s_rated, uuid]\n" +
92-
"1: [cosPhiRated, id, operatesFrom, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_from, q_characteristics, s_rated, uuid]\n" +
93-
"2: [cosPhiRated, id, operatesUntil, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_until, q_characteristics, s_rated, uuid]\n" +
94-
"3: [cosPhiRated, id, operatesFrom, operatesUntil, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_from, operates_until, q_characteristics, s_rated, uuid]\n" +
95-
"4: [cosPhiRated, id, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operator, q_characteristics, s_rated, uuid]\n" +
96-
"5: [cosPhiRated, id, operatesFrom, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_from, operator, q_characteristics, s_rated, uuid]\n" +
97-
"6: [cosPhiRated, id, operatesUntil, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
98-
"7: [cosPhiRated, id, operatesFrom, operatesUntil, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, operates_from, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
99-
"8: [controllingEm, cosPhiRated, id, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, q_characteristics, s_rated, uuid]\n" +
100-
"9: [controllingEm, cosPhiRated, id, operatesFrom, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_from, q_characteristics, s_rated, uuid]\n" +
101-
"10: [controllingEm, cosPhiRated, id, operatesUntil, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_until, q_characteristics, s_rated, uuid]\n" +
102-
"11: [controllingEm, cosPhiRated, id, operatesFrom, operatesUntil, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_from, operates_until, q_characteristics, s_rated, uuid]\n" +
103-
"12: [controllingEm, cosPhiRated, id, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operator, q_characteristics, s_rated, uuid]\n" +
104-
"13: [controllingEm, cosPhiRated, id, operatesFrom, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_from, operator, q_characteristics, s_rated, uuid]\n" +
105-
"14: [controllingEm, cosPhiRated, id, operatesUntil, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
106-
"15: [controllingEm, cosPhiRated, id, operatesFrom, operatesUntil, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, operates_from, operates_until, operator, q_characteristics, s_rated, uuid]\n"
91+
"0: [cosPhiRated, id, node, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, q_characteristics, s_rated, uuid]\n" +
92+
"1: [cosPhiRated, id, node, operatesFrom, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_from, q_characteristics, s_rated, uuid]\n" +
93+
"2: [cosPhiRated, id, node, operatesUntil, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_until, q_characteristics, s_rated, uuid]\n" +
94+
"3: [cosPhiRated, id, node, operatesFrom, operatesUntil, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_from, operates_until, q_characteristics, s_rated, uuid]\n" +
95+
"4: [cosPhiRated, id, node, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operator, q_characteristics, s_rated, uuid]\n" +
96+
"5: [cosPhiRated, id, node, operatesFrom, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_from, operator, q_characteristics, s_rated, uuid]\n" +
97+
"6: [cosPhiRated, id, node, operatesUntil, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
98+
"7: [cosPhiRated, id, node, operatesFrom, operatesUntil, operator, qCharacteristics, sRated, uuid] or [cos_phi_rated, id, node, operates_from, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
99+
"8: [controllingEm, cosPhiRated, id, node, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, q_characteristics, s_rated, uuid]\n" +
100+
"9: [controllingEm, cosPhiRated, id, node, operatesFrom, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_from, q_characteristics, s_rated, uuid]\n" +
101+
"10: [controllingEm, cosPhiRated, id, node, operatesUntil, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_until, q_characteristics, s_rated, uuid]\n" +
102+
"11: [controllingEm, cosPhiRated, id, node, operatesFrom, operatesUntil, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_from, operates_until, q_characteristics, s_rated, uuid]\n" +
103+
"12: [controllingEm, cosPhiRated, id, node, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operator, q_characteristics, s_rated, uuid]\n" +
104+
"13: [controllingEm, cosPhiRated, id, node, operatesFrom, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_from, operator, q_characteristics, s_rated, uuid]\n" +
105+
"14: [controllingEm, cosPhiRated, id, node, operatesUntil, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_until, operator, q_characteristics, s_rated, uuid]\n" +
106+
"15: [controllingEm, cosPhiRated, id, node, operatesFrom, operatesUntil, operator, qCharacteristics, sRated, uuid] or [controlling_em, cos_phi_rated, id, node, operates_from, operates_until, operator, q_characteristics, s_rated, uuid]\n"
107107
}
108108
}

0 commit comments

Comments
 (0)