-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDictionaryProcessor.java
More file actions
116 lines (101 loc) · 5.07 KB
/
DictionaryProcessor.java
File metadata and controls
116 lines (101 loc) · 5.07 KB
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
package blue.language.merge.processor;
import blue.language.*;
import blue.language.merge.MergingProcessor;
import blue.language.merge.NodeResolver;
import blue.language.model.Node;
import blue.language.utils.NodeToMapListOrValue;
import blue.language.utils.Types;
import java.util.Map;
import static blue.language.utils.Types.isSubtype;
public class DictionaryProcessor implements MergingProcessor {
@Override
public void process(Node target, Node source, NodeProvider nodeProvider, NodeResolver nodeResolver) {
if ((source.getKeyType() != null || source.getValueType() != null) && !Types.isDictionaryType(source.getType(), nodeProvider)) {
throw new IllegalArgumentException("Source node with keyType or valueType must have a Dictionary type");
}
processKeyType(target, source, nodeProvider);
processValueType(target, source, nodeProvider);
if ((target.getKeyType() != null || target.getValueType() != null) && source.getProperties() != null) {
for (Map.Entry<String, Node> entry : source.getProperties().entrySet()) {
if (target.getKeyType() != null) {
validateKeyType(entry.getKey(), target.getKeyType(), nodeProvider);
}
if (target.getValueType() != null) {
validateValueType(entry.getValue(), target.getValueType(), nodeProvider);
}
}
}
}
private void processKeyType(Node target, Node source, NodeProvider nodeProvider) {
Node targetKeyType = target.getKeyType();
Node sourceKeyType = source.getKeyType();
if (targetKeyType == null) {
if (sourceKeyType != null) {
validateBasicKeyType(sourceKeyType, nodeProvider);
target.keyType(sourceKeyType);
}
} else if (sourceKeyType != null) {
validateBasicKeyType(sourceKeyType, nodeProvider);
boolean isSubtype = isSubtype(sourceKeyType, targetKeyType, nodeProvider);
if (!isSubtype) {
String errorMessage = String.format("The source key type '%s' is not a subtype of the target key type '%s'.",
NodeToMapListOrValue.get(sourceKeyType), NodeToMapListOrValue.get(targetKeyType));
throw new IllegalArgumentException(errorMessage);
}
target.keyType(sourceKeyType);
}
}
private void processValueType(Node target, Node source, NodeProvider nodeProvider) {
Node targetValueType = target.getValueType();
Node sourceValueType = source.getValueType();
if (targetValueType == null) {
if (sourceValueType != null) {
target.valueType(sourceValueType);
}
} else if (sourceValueType != null) {
boolean isSubtype = isSubtype(sourceValueType, targetValueType, nodeProvider);
if (!isSubtype) {
String errorMessage = String.format("The source value type '%s' is not a subtype of the target value type '%s'.",
NodeToMapListOrValue.get(sourceValueType), NodeToMapListOrValue.get(targetValueType));
throw new IllegalArgumentException(errorMessage);
}
target.valueType(sourceValueType);
}
}
private void validateBasicKeyType(Node keyType, NodeProvider nodeProvider) {
if (!Types.isBasicType(keyType, nodeProvider)) {
throw new IllegalArgumentException("Dictionary key type must be a basic type");
}
}
private void validateKeyType(String key, Node keyType, NodeProvider nodeProvider) {
if (Types.isTextType(keyType, nodeProvider)) {
return;
}
if (Types.isIntegerType(keyType, nodeProvider)) {
try {
Integer.parseInt(key);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Key '" + key + "' is not a valid Integer.");
}
} else if (Types.isNumberType(keyType, nodeProvider)) {
try {
Double.parseDouble(key);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Key '" + key + "' is not a valid Number.");
}
} else if (Types.isBooleanType(keyType, nodeProvider)) {
if (!key.equalsIgnoreCase("true") && !key.equalsIgnoreCase("false")) {
throw new IllegalArgumentException("Key '" + key + "' is not a valid Boolean.");
}
} else {
throw new IllegalArgumentException("Unsupported key type: " + keyType.getName());
}
}
private void validateValueType(Node value, Node valueType, NodeProvider nodeProvider) {
if (value.getType() != null && !isSubtype(value.getType(), valueType, nodeProvider)) {
String errorMessage = String.format("Value of type '%s' is not a subtype of the dictionary's value type '%s'.",
NodeToMapListOrValue.get(value.getType()), NodeToMapListOrValue.get(valueType));
throw new IllegalArgumentException(errorMessage);
}
}
}