Skip to content

Commit 0dfba3b

Browse files
Merge pull request #798 from ie3-institute/ms/#682-method-handleEntity-throws-Exception
Make ``handleEntity`` throw exceptions instead of returning empty optional
2 parents 348a20e + 0871294 commit 0dfba3b

File tree

15 files changed

+289
-314
lines changed

15 files changed

+289
-314
lines changed

src/main/java/edu/ie3/datamodel/exceptions/EntityProcessorException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Is thrown, when an something went wrong during entity field mapping creation in a {@link
1010
* edu.ie3.datamodel.io.processor.EntityProcessor}
1111
*/
12-
public class EntityProcessorException extends RuntimeException {
12+
public class EntityProcessorException extends Exception {
1313
public EntityProcessorException(final String message, final Throwable cause) {
1414
super(message, cause);
1515
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public abstract class Factory<C, D extends FactoryData, R> {
2828

2929
private final List<Class<? extends C>> supportedClasses;
3030

31+
@SafeVarargs
3132
protected Factory(Class<? extends C>... supportedClasses) {
3233
this.supportedClasses = Arrays.asList(supportedClasses);
3334
}
@@ -54,9 +55,9 @@ public Try<R, FactoryException> get(D data) {
5455
validateParameters(data, allFields.toArray((IntFunction<Set<String>[]>) Set[]::new));
5556

5657
// build the model
57-
return new Success<>(buildModel(data));
58+
return Success.of(buildModel(data));
5859
} catch (FactoryException e) {
59-
return new Failure<>(
60+
return Failure.of(
6061
new FactoryException(
6162
"An error occurred when creating instance of "
6263
+ data.getTargetClass().getSimpleName()

src/main/java/edu/ie3/datamodel/io/processor/EntityProcessor.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import edu.ie3.datamodel.exceptions.EntityProcessorException;
99
import edu.ie3.datamodel.models.StandardUnits;
1010
import edu.ie3.datamodel.models.UniqueEntity;
11+
import edu.ie3.datamodel.utils.Try;
12+
import edu.ie3.datamodel.utils.Try.*;
13+
import edu.ie3.util.exceptions.QuantityException;
1114
import java.lang.reflect.Method;
1215
import java.util.*;
1316
import javax.measure.Quantity;
@@ -37,7 +40,7 @@ public abstract class EntityProcessor<T extends UniqueEntity> extends Processor<
3740
*
3841
* @param registeredClass the class the entity processor should be able to handle
3942
*/
40-
protected EntityProcessor(Class<? extends T> registeredClass) {
43+
protected EntityProcessor(Class<? extends T> registeredClass) throws EntityProcessorException {
4144
super(registeredClass);
4245
this.fieldNameToMethod =
4346
mapFieldNameToGetter(registeredClass, Collections.singleton(NODE_INTERNAL));
@@ -51,7 +54,7 @@ protected EntityProcessor(Class<? extends T> registeredClass) {
5154
* @return an optional Map with fieldName to fieldValue or an empty optional if an error occurred
5255
* during processing
5356
*/
54-
public Optional<LinkedHashMap<String, String>> handleEntity(T entity) {
57+
public LinkedHashMap<String, String> handleEntity(T entity) throws EntityProcessorException {
5558
if (!registeredClass.equals(entity.getClass()))
5659
throw new EntityProcessorException(
5760
"Cannot process "
@@ -62,33 +65,32 @@ public Optional<LinkedHashMap<String, String>> handleEntity(T entity) {
6265
+ entity.getClass().getSimpleName()
6366
+ ".class!");
6467

65-
try {
66-
return Optional.of(processObject(entity, fieldNameToMethod));
67-
} catch (EntityProcessorException e) {
68-
logger.error("Cannot process the entity{}.", entity, e);
69-
return Optional.empty();
70-
}
68+
return processObject(entity, fieldNameToMethod);
7169
}
7270

7371
@Override
74-
protected Optional<String> handleProcessorSpecificQuantity(
72+
protected Try<String, QuantityException> handleProcessorSpecificQuantity(
7573
Quantity<?> quantity, String fieldName) {
7674
return switch (fieldName) {
7775
case "energy", "eConsAnnual", "eStorage":
78-
yield quantityValToOptionalString(
79-
quantity.asType(Energy.class).to(StandardUnits.ENERGY_IN));
76+
yield Success.of(
77+
quantityValToOptionalString(quantity.asType(Energy.class).to(StandardUnits.ENERGY_IN)));
8078
case "q":
81-
yield quantityValToOptionalString(
82-
quantity.asType(Power.class).to(StandardUnits.REACTIVE_POWER_IN));
79+
yield Success.of(
80+
quantityValToOptionalString(
81+
quantity.asType(Power.class).to(StandardUnits.REACTIVE_POWER_IN)));
8382
case "p", "pMax", "pOwn", "pThermal":
84-
yield quantityValToOptionalString(
85-
quantity.asType(Power.class).to(StandardUnits.ACTIVE_POWER_IN));
83+
yield Success.of(
84+
quantityValToOptionalString(
85+
quantity.asType(Power.class).to(StandardUnits.ACTIVE_POWER_IN)));
8686
default:
87-
log.error(
88-
"Cannot process quantity with value '{}' for field with name {} in input entity processing!",
89-
quantity,
90-
fieldName);
91-
yield Optional.empty();
87+
yield Failure.of(
88+
new QuantityException(
89+
"Cannot process quantity with value '"
90+
+ quantity
91+
+ "' for field with name "
92+
+ fieldName
93+
+ " in input entity processing!"));
9294
};
9395
}
9496

src/main/java/edu/ie3/datamodel/io/processor/Processor.java

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicInput;
1818
import edu.ie3.datamodel.models.profile.LoadProfile;
1919
import edu.ie3.datamodel.models.voltagelevels.VoltageLevel;
20+
import edu.ie3.datamodel.utils.Try;
21+
import edu.ie3.datamodel.utils.Try.*;
22+
import edu.ie3.util.exceptions.QuantityException;
2023
import java.beans.Introspector;
2124
import java.lang.reflect.InvocationTargetException;
2225
import java.lang.reflect.Method;
@@ -72,7 +75,7 @@ public abstract class Processor<T> {
7275
*
7376
* @param foreSeenClass Class and its children that are foreseen to be handled with this processor
7477
*/
75-
protected Processor(Class<? extends T> foreSeenClass) {
78+
protected Processor(Class<? extends T> foreSeenClass) throws EntityProcessorException {
7679
if (!getEligibleEntityClasses().contains(foreSeenClass))
7780
throw new EntityProcessorException(
7881
"Cannot register class '"
@@ -104,9 +107,10 @@ public int compare(String a, String b) {
104107
* Maps the foreseen table fields to the objects getters
105108
*
106109
* @param cls class to use for mapping
107-
* @return an array of strings of all field values of the class
110+
* @return a map of all field values of the class
108111
*/
109-
protected SortedMap<String, Method> mapFieldNameToGetter(Class<?> cls) {
112+
protected SortedMap<String, Method> mapFieldNameToGetter(Class<?> cls)
113+
throws EntityProcessorException {
110114
return mapFieldNameToGetter(cls, Collections.emptyList());
111115
}
112116

@@ -115,10 +119,10 @@ protected SortedMap<String, Method> mapFieldNameToGetter(Class<?> cls) {
115119
*
116120
* @param cls class to use for mapping
117121
* @param ignoreFields A collection of all field names to ignore during process
118-
* @return an array of strings of all field values of the class
122+
* @return a map of all field values of the class
119123
*/
120124
protected SortedMap<String, Method> mapFieldNameToGetter(
121-
Class<?> cls, Collection<String> ignoreFields) {
125+
Class<?> cls, Collection<String> ignoreFields) throws EntityProcessorException {
122126
try {
123127
final LinkedHashMap<String, Method> resFieldNameToMethod = new LinkedHashMap<>();
124128
Arrays.stream(Introspector.getBeanInfo(cls, Object.class).getPropertyDescriptors())
@@ -178,7 +182,7 @@ public static <V> SortedMap<String, V> putUuidFirst(Map<String, V> unsorted) {
178182
* @return Mapping from field name to value as String representation
179183
*/
180184
protected LinkedHashMap<String, String> processObject(
181-
Object object, Map<String, Method> fieldNameToGetter) {
185+
Object object, Map<String, Method> fieldNameToGetter) throws EntityProcessorException {
182186
try {
183187
LinkedHashMap<String, String> resultMap = new LinkedHashMap<>();
184188
for (Map.Entry<String, Method> entry : fieldNameToGetter.entrySet()) {
@@ -207,7 +211,8 @@ protected LinkedHashMap<String, String> processObject(
207211
* @param fieldName Name of the foreseen field
208212
* @return A String representation of the result
209213
*/
210-
protected String processMethodResult(Object methodReturnObject, Method method, String fieldName) {
214+
protected String processMethodResult(Object methodReturnObject, Method method, String fieldName)
215+
throws EntityProcessorException {
211216

212217
StringBuilder resultStringBuilder = new StringBuilder();
213218

@@ -232,15 +237,19 @@ protected String processMethodResult(Object methodReturnObject, Method method, S
232237
.map(
233238
o -> {
234239
if (o instanceof Quantity<?>) {
235-
return handleQuantity((Quantity<?>) o, fieldName);
240+
return Try.of(
241+
() -> handleQuantity((Quantity<?>) o, fieldName),
242+
EntityProcessorException.class);
236243
} else {
237-
throw new EntityProcessorException(
238-
"Handling of "
239-
+ o.getClass().getSimpleName()
240-
+ ".class instance wrapped into Optional is currently not supported by entity processors!");
244+
return Failure.of(
245+
new EntityProcessorException(
246+
"Handling of "
247+
+ o.getClass().getSimpleName()
248+
+ ".class instance wrapped into Optional is currently not supported by entity processors!"));
241249
}
242250
})
243-
.orElse(""));
251+
.orElse(Success.of("")) // (in case of empty optional)
252+
.getOrThrow());
244253
case "ZonedDateTime" -> resultStringBuilder.append(
245254
processZonedDateTime((ZonedDateTime) methodReturnObject));
246255
case "OperationTime" -> resultStringBuilder.append(
@@ -306,7 +315,8 @@ protected String processMethodResult(Object methodReturnObject, Method method, S
306315
* @return the resulting string of a VoltageLevel attribute value for the provided field or an
307316
* empty string when an invalid field name is provided
308317
*/
309-
protected String processVoltageLevel(VoltageLevel voltageLevel, String fieldName) {
318+
protected String processVoltageLevel(VoltageLevel voltageLevel, String fieldName)
319+
throws EntityProcessorException {
310320

311321
StringBuilder resultStringBuilder = new StringBuilder();
312322
if (fieldName.equalsIgnoreCase(VOLT_LVL)) resultStringBuilder.append(voltageLevel.getId());
@@ -324,21 +334,26 @@ protected String processVoltageLevel(VoltageLevel voltageLevel, String fieldName
324334
* @return an optional string with the normalized to {@link StandardUnits} value of the quantity
325335
* or empty if an error occurred during processing
326336
*/
327-
protected String handleQuantity(Quantity<?> quantity, String fieldName) {
328-
Optional<String> optQuant;
337+
protected String handleQuantity(Quantity<?> quantity, String fieldName)
338+
throws EntityProcessorException {
339+
Try<String, QuantityException> optQuant;
329340
if (specificQuantityFieldNames.contains(fieldName)) {
330341
optQuant = handleProcessorSpecificQuantity(quantity, fieldName);
331342
} else {
332-
optQuant = quantityValToOptionalString(quantity);
343+
optQuant = Success.of(quantityValToOptionalString(quantity));
333344
}
334-
return optQuant.orElseThrow(
335-
() ->
336-
new EntityProcessorException(
337-
"Unable to process quantity value for attribute '"
338-
+ fieldName
339-
+ "' in entity "
340-
+ getRegisteredClass().getSimpleName()
341-
+ ".class."));
345+
346+
return optQuant
347+
.transformF(
348+
e ->
349+
new EntityProcessorException(
350+
"Unable to process quantity value for attribute '"
351+
+ fieldName
352+
+ "' in entity "
353+
+ getRegisteredClass().getSimpleName()
354+
+ ".class.",
355+
e))
356+
.getOrThrow();
342357
}
343358

344359
/**
@@ -354,7 +369,7 @@ protected String handleQuantity(Quantity<?> quantity, String fieldName) {
354369
* @return an optional string with the normalized to {@link StandardUnits} value of the quantity
355370
* or empty if an error occurred during processing
356371
*/
357-
protected abstract Optional<String> handleProcessorSpecificQuantity(
372+
protected abstract Try<String, QuantityException> handleProcessorSpecificQuantity(
358373
Quantity<?> quantity, String fieldName);
359374

360375
protected String processUUIDArray(UUID[] uuids) {
@@ -406,8 +421,8 @@ protected String processZonedDateTime(ZonedDateTime zonedDateTime) {
406421
* @param quantity Quantity to convert
407422
* @return A string of the quantity's value
408423
*/
409-
protected Optional<String> quantityValToOptionalString(Quantity<?> quantity) {
410-
return Optional.of(Double.toString(quantity.getValue().doubleValue()));
424+
protected String quantityValToOptionalString(Quantity<?> quantity) {
425+
return Double.toString(quantity.getValue().doubleValue());
411426
}
412427

413428
/**

0 commit comments

Comments
 (0)