Skip to content

Commit 161d252

Browse files
authored
Merge pull request #50 from redlink-gmbh/umm/326-goal-template-api-impl
Goal template api impl / Goal SDK / AmoutOf-GoalTemplate
2 parents a137587 + c0115ca commit 161d252

51 files changed

Lines changed: 2693 additions & 133 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<module>studymanager-core</module>
1313
<module>studymanager-observation</module>
1414
<module>studymanager-intervention</module>
15+
<module>studymanager-goaltemplates</module>
1516
<module>studymanager-services</module>
1617
<module>studymanager</module>
1718
</modules>

studymanager-core/src/main/java/io/redlink/more/studymanager/core/factory/ComponentFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ public ComponentFactory<C,P> init(ComponentFactoryProperties componentProperties
3636

3737
public abstract String getTitle();
3838

39+
public abstract String getDescription();
40+
3941
public List<Value> getProperties() {
4042
return List.of();
4143
}
4244

4345
public abstract <P extends ComponentProperties> Class<P> getPropertyClass();
4446

45-
public abstract String getDescription();
46-
4747
//TODO remove in a next step (as soon as interventions impl is done in FE for new props
4848
public Map<String, Object> getDefaultProperties() {
4949
HashMap<String, Object> map = new HashMap<>();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright LBI-DHP and/or licensed to LBI-DHP under one or more
3+
* contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute
4+
* for Digital Health and Prevention -- A research institute of the
5+
* Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur
6+
* Förderung der wissenschaftlichen Forschung).
7+
* Licensed under the Elastic License 2.0.
8+
*/
9+
package io.redlink.more.studymanager.core.properties.model;
10+
11+
public class ConfigSection extends Value<Void> {
12+
public ConfigSection(String id) {
13+
super(id);
14+
}
15+
16+
@Override
17+
public Class<Void> getValueType() {
18+
return Void.class;
19+
}
20+
21+
@Override
22+
public String getType() {
23+
return "GROUPING";
24+
}
25+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.redlink.more.studymanager.core.properties.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonAlias;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
6+
7+
import java.util.Objects;
8+
9+
public class IntegerRange {
10+
11+
// Defines the lower set value of the range
12+
private final int lower;
13+
// Defines the upper set value of the range
14+
private final int upper;
15+
16+
@JsonCreator
17+
public IntegerRange(
18+
@JsonProperty("lower") @JsonAlias({"min"}) int lower,
19+
@JsonProperty("upper") @JsonAlias({"max"}) int upper) {
20+
this.lower = lower;
21+
this.upper = upper;
22+
}
23+
24+
public int getLower() {
25+
return lower;
26+
}
27+
28+
public int getUpper() {
29+
return upper;
30+
}
31+
32+
@Override
33+
public boolean equals(Object o) {
34+
if (o == null || getClass() != o.getClass()) return false;
35+
IntegerRange that = (IntegerRange) o;
36+
return lower == that.lower && upper == that.upper;
37+
}
38+
39+
@Override
40+
public int hashCode() {
41+
return Objects.hash(lower, upper);
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "IntegerRange{" +
47+
"lower=" + lower +
48+
", upper=" + upper +
49+
'}';
50+
}
51+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright LBI-DHP and/or licensed to LBI-DHP under one or more
3+
* contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute
4+
* for Digital Health and Prevention -- A research institute of the
5+
* Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur
6+
* Förderung der wissenschaftlichen Forschung).
7+
* Licensed under the Elastic License 2.0.
8+
*/
9+
package io.redlink.more.studymanager.core.properties.model;
10+
11+
import io.redlink.more.studymanager.core.validation.ValidationIssue;
12+
13+
public class IntegerRangeValue extends Value<IntegerRange> {
14+
15+
// Defines the minimum value of the range, not equal to IntegerRange.lower which defines the user set lower bound
16+
private int min = 0;
17+
// Defines the maximum value of the range, not equal to IntegerRange.upper which defines the user set upper bound
18+
private int max = Integer.MAX_VALUE;
19+
20+
public IntegerRangeValue(String id) {
21+
super(id);
22+
}
23+
24+
@Override
25+
public String getType() {
26+
return "INTEGER_RANGE";
27+
}
28+
29+
@Override
30+
public Class<IntegerRange> getValueType() {
31+
return IntegerRange.class;
32+
}
33+
34+
@Override
35+
public ValidationIssue doValidate(IntegerRange range) {
36+
if (range != null && range.getLower() > range.getUpper()) {
37+
return ValidationIssue.error(this, "Lower bound of RangeValue MUST NOT be higer as the upper bound (lower:" + range.getLower() + ", upper: " + range.getUpper() + ")");
38+
}
39+
if (range != null && (range.getLower() < getMin() || range.getUpper() > getMax())) {
40+
return ValidationIssue.error(this, "Value must between " + getMin() + " and " + getMax());
41+
}
42+
return ValidationIssue.NONE;
43+
}
44+
45+
public int getMin() {
46+
return min;
47+
}
48+
49+
public IntegerRangeValue setMin(int min) {
50+
this.min = min;
51+
return this;
52+
}
53+
54+
public int getMax() {
55+
return max;
56+
}
57+
58+
public IntegerRangeValue setMax(int max) {
59+
this.max = max;
60+
return this;
61+
}
62+
63+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.redlink.more.studymanager.core.properties.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
5+
import java.util.Objects;
6+
7+
public class NamedIntegerRange extends IntegerRange {
8+
9+
private String name;
10+
11+
@JsonCreator
12+
public NamedIntegerRange(String name, int lower, int upper) {
13+
super(lower, upper);
14+
this.name = name;
15+
}
16+
17+
public String getName() {
18+
return name;
19+
}
20+
21+
@Override
22+
public boolean equals(Object o) {
23+
if (o == null || getClass() != o.getClass()) return false;
24+
if (!super.equals(o)) return false;
25+
NamedIntegerRange that = (NamedIntegerRange) o;
26+
return Objects.equals(name, that.name);
27+
}
28+
29+
@Override
30+
public int hashCode() {
31+
return Objects.hash(super.hashCode(), name);
32+
}
33+
34+
@Override
35+
public String toString() {
36+
return "NamedIntegerRange{" +
37+
"name='" + name + '\'' +
38+
"lower=" + getLower() +
39+
", upper=" + getUpper() +
40+
'}';
41+
}
42+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright LBI-DHP and/or licensed to LBI-DHP under one or more
3+
* contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute
4+
* for Digital Health and Prevention -- A research institute of the
5+
* Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur
6+
* Förderung der wissenschaftlichen Forschung).
7+
* Licensed under the Elastic License 2.0.
8+
*/
9+
package io.redlink.more.studymanager.core.properties.model;
10+
11+
import io.redlink.more.studymanager.core.validation.ValidationIssue;
12+
13+
public class NamedIntegerRangeValue extends Value<NamedIntegerRange> {
14+
15+
private int min = 0;
16+
private int max = Integer.MAX_VALUE;
17+
18+
public NamedIntegerRangeValue(String id) {
19+
super(id);
20+
}
21+
22+
@Override
23+
public String getType() {
24+
return "INTEGER_RANGE";
25+
}
26+
27+
@Override
28+
public Class<NamedIntegerRange> getValueType() {
29+
return NamedIntegerRange.class;
30+
}
31+
32+
@Override
33+
public ValidationIssue doValidate(NamedIntegerRange namedRange) {
34+
if(namedRange != null && namedRange.getName() == null || namedRange.getName().isBlank()) {
35+
return ValidationIssue.error(this, "The name of the RangeValue MUST NOT be blank");
36+
}
37+
if(namedRange != null && namedRange.getLower() > namedRange.getUpper()) {
38+
return ValidationIssue.error(this, "Lower bound of RangeValue MUST NOT be higer as the upper bound (lower:" + namedRange.getLower() + ", upper: " + namedRange.getUpper() + ")");
39+
}
40+
if (namedRange != null && (namedRange.getLower() < getMin() || namedRange.getUpper() > getMax()) ) {
41+
return ValidationIssue.error(this, "Value must between " + getMin() + " and " + getMax());
42+
}
43+
return ValidationIssue.NONE;
44+
}
45+
46+
public int getMin() {
47+
return min;
48+
}
49+
50+
public NamedIntegerRangeValue setMin(int min) {
51+
this.min = min;
52+
return this;
53+
}
54+
55+
public int getMax() {
56+
return max;
57+
}
58+
59+
public NamedIntegerRangeValue setMax(int max) {
60+
this.max = max;
61+
return this;
62+
}
63+
64+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.redlink.more.studymanager.core.properties.model;
2+
3+
import io.redlink.more.studymanager.core.validation.ValidationIssue;
4+
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
import java.util.regex.Matcher;
8+
import java.util.regex.Pattern;
9+
10+
/**
11+
* Type that allows to refer other values via &lt;id&gt;. Before saving those MUST BE replaced with the actual values.
12+
* The validation will fail if the stored value contains any templates (&lt;id&gt;)
13+
*/
14+
public class StringTemplateValue extends StringValue {
15+
16+
17+
private static final Pattern TEMPLATE_PATTERN = Pattern.compile("<[(^>)]+>");
18+
private Set<String> allowList;
19+
20+
public StringTemplateValue(String id) {
21+
this(id, null);
22+
}
23+
24+
public StringTemplateValue(String id, Set<String> allowList) {
25+
super(id);
26+
this.allowList = allowList;
27+
}
28+
29+
@Override
30+
public String getType() {
31+
return "STRINGTEMPLATE";
32+
}
33+
34+
protected ValidationIssue doValidate(String value) {
35+
if (value == null) {
36+
return super.doValidate(value);
37+
}
38+
if (allowList != null) { //check that only allowed templates are used
39+
int start = 0;
40+
Matcher m = TEMPLATE_PATTERN.matcher(value);
41+
Set<String> notAllowed = new HashSet<>();
42+
while (m.find(start)) {
43+
String template = m.group(1);
44+
start = m.end();
45+
if (!allowList.contains(template)) {
46+
notAllowed.add(template);
47+
}
48+
}
49+
if (!notAllowed.isEmpty()) {
50+
return ValidationIssue.error(this, String.format(
51+
"The value contains the unknown templates %s (allowed are: %s)!", notAllowed, allowList));
52+
}
53+
}
54+
return super.doValidate(value);
55+
}
56+
57+
}

studymanager-core/src/main/java/io/redlink/more/studymanager/core/properties/model/Value.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
package io.redlink.more.studymanager.core.properties.model;
1010

1111
import com.fasterxml.jackson.annotation.JsonIgnore;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
1213
import io.redlink.more.studymanager.core.exception.ValueCastException;
1314
import io.redlink.more.studymanager.core.exception.ValueNonNullException;
1415
import io.redlink.more.studymanager.core.properties.ComponentProperties;
1516
import io.redlink.more.studymanager.core.validation.ValidationIssue;
17+
1618
import java.util.function.Function;
1719

1820
public abstract class Value<T> {
@@ -23,6 +25,7 @@ public abstract class Value<T> {
2325
private boolean required = false;
2426
private boolean immutable = false;
2527
private Function<T, ValidationIssue> validationFunction = (T t) -> ValidationIssue.NONE;
28+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
2629

2730
public Value(String id) {
2831
this.id = id;
@@ -55,8 +58,8 @@ protected ValidationIssue doValidate(T t) {
5558
public T getValue(ComponentProperties properties) {
5659
if (properties.containsKey(id)) {
5760
try {
58-
return getValueType().cast(properties.get(id));
59-
} catch (ClassCastException e) {
61+
return OBJECT_MAPPER.convertValue(properties.get(id), getValueType());
62+
} catch (ClassCastException | IllegalArgumentException e) {
6063
throw new ValueCastException(this, getValueType());
6164
}
6265
} else {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright LBI-DHP and/or licensed to LBI-DHP under one or more
3+
* contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute
4+
* for Digital Health and Prevention -- A research institute of the
5+
* Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur
6+
* Förderung der wissenschaftlichen Forschung).
7+
* Licensed under the Elastic License 2.0.
8+
*/
9+
package io.redlink.more.studymanager.core.properties.model;
10+
11+
public class ValueGroup extends Value<Void> {
12+
public ValueGroup(String id) {
13+
super(id);
14+
}
15+
16+
@Override
17+
public Class<Void> getValueType() {
18+
return Void.class;
19+
}
20+
21+
@Override
22+
public String getType() {
23+
return "GROUPING";
24+
}
25+
}

0 commit comments

Comments
 (0)