-
Notifications
You must be signed in to change notification settings - Fork 5
/
CharacteristicInput.java
151 lines (133 loc) · 4.96 KB
/
CharacteristicInput.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
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.models.input.system.characteristic;
import edu.ie3.datamodel.exceptions.ParsingException;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import javax.measure.Quantity;
import javax.measure.Unit;
/**
* Describes characteristics of assets
*
* @param <A> Type of quantity, that applies to the abscissa
* @param <O> Type of quantity, that applies to the ordinate
*/
public abstract class CharacteristicInput<A extends Quantity<A>, O extends Quantity<O>>
implements Serializable {
protected final String characteristicPrefix;
protected final int decimalPlaces;
private final SortedSet<CharacteristicPoint<A, O>> points;
/**
* Constructor for the abstract class
*
* @param points Set of points that describe the characteristic
* @param characteristicPrefix Prefix, that prepends the actual characteristic
* @param decimalPlaces Desired amount of decimal places when de-serializing the characteristic
*/
protected CharacteristicInput(
SortedSet<CharacteristicPoint<A, O>> points, String characteristicPrefix, int decimalPlaces) {
this.points = Collections.unmodifiableSortedSet(points);
this.characteristicPrefix = characteristicPrefix;
this.decimalPlaces = decimalPlaces;
}
protected CharacteristicInput(
String input,
Unit<A> abscissaUnit,
Unit<O> ordinateUnit,
String characteristicPrefix,
int decimalPlaces)
throws ParsingException {
this.characteristicPrefix = characteristicPrefix;
this.decimalPlaces = decimalPlaces;
if (!input.startsWith(characteristicPrefix + ":{") || !input.endsWith("}"))
throw new ParsingException(
"Cannot parse '"
+ input
+ "' to characteristic. It has to be of the form '"
+ characteristicPrefix
+ ":{"
+ CharacteristicPoint.REQUIRED_FORMAT
+ ",...}'");
String coordinateList = extractCoordinateList(input);
this.points = buildCoordinatesFromString(coordinateList, abscissaUnit, ordinateUnit);
}
/**
* Builds a regex, that is suitable to match '[prefix]:{'
*
* @param prefix Unique prefix to an instance of the Characteristic
* @return The suitable regex
*/
public static String buildStartingRegex(String prefix) {
return "^" + prefix + ":\\{";
}
/**
* Extracts the point list from the given input
*
* @param input Input string for the whole characteristic
* @return The string list of points
*/
private String extractCoordinateList(String input) {
return input.replaceAll(buildStartingRegex(characteristicPrefix), "").replaceAll("}$", "");
}
/**
* Splits up a String of point definition and parses them to {@link CharacteristicPoint}
*
* @param input Comma-separated list of point definitions
* @param abscissaUnit Unit to use on the abscissa
* @param ordinateUnit Unit to use on the ordinate
* @return An unmodifiable sorted set of {@link CharacteristicPoint}s
* @throws ParsingException If one of the points cannot be parsed
*/
private SortedSet<CharacteristicPoint<A, O>> buildCoordinatesFromString(
String input, Unit<A> abscissaUnit, Unit<O> ordinateUnit) throws ParsingException {
/* Splits the points only at those commas, that are preceded by a ')' */
String[] entries = input.split("(?<=\\)),");
SortedSet<CharacteristicPoint<A, O>> parsedCoordinates = new TreeSet<>();
for (String entry : entries) {
try {
parsedCoordinates.add(new CharacteristicPoint<>(entry, abscissaUnit, ordinateUnit));
} catch (ParsingException pe) {
throw new ParsingException(
"Cannot parse '" + input + "' to Set of points as it contains a malformed point.", pe);
}
}
return Collections.unmodifiableSortedSet(parsedCoordinates);
}
public SortedSet<CharacteristicPoint<A, O>> getPoints() {
return points;
}
/**
* De-serialize the characteristic to a commonly understood string
*
* @return the characteristic as de-serialized string
*/
public String deSerialize() {
return characteristicPrefix
+ ":{"
+ points.stream()
.map(point -> point.deSerialize(decimalPlaces))
.collect(Collectors.joining(","))
+ "}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CharacteristicInput<?, ?> that)) return false;
points.iterator();
return decimalPlaces == that.decimalPlaces
&& characteristicPrefix.equals(that.characteristicPrefix)
&& points.equals(that.points);
}
@Override
public int hashCode() {
return Objects.hash(characteristicPrefix, decimalPlaces, points);
}
@Override
public String toString() {
return "CharacteristicInput{" + "points=" + points + '}';
}
}