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 package com.rapiddweller.model.data;
28
29 import com.rapiddweller.common.Escalator;
30 import com.rapiddweller.common.LoggerEscalator;
31 import com.rapiddweller.common.NullSafeComparator;
32 import com.rapiddweller.common.Operation;
33 import com.rapiddweller.common.operation.FirstArgSelector;
34
35
36
37
38
39
40
41
42
43 public class FeatureDetail<E> {
44
45 private static final Escalator escalator = new LoggerEscalator();
46
47
48
49 private final String name;
50 private final Class<E> type;
51 private final Operation<E, E> combinator;
52 private final boolean constraint;
53 private final boolean deprecated;
54 private E value;
55
56
57
58
59
60
61
62
63
64
65 public FeatureDetail(String name, Class<E> type, boolean constraint) {
66 this(name, type, constraint, new FirstArgSelector<>());
67 }
68
69
70
71
72
73
74
75
76
77 public FeatureDetail(String name, Class<E> type, boolean constraint,
78 Operation<E, E> combinator) {
79 this(name, type, constraint, combinator, false);
80 }
81
82
83
84
85
86
87
88
89
90
91 public FeatureDetail(String name, Class<E> type, boolean constraint,
92 Operation<E, E> combinator, boolean deprecated) {
93 this.name = name;
94 this.type = type;
95 this.value = null;
96 this.constraint = constraint;
97 this.combinator = combinator;
98 this.deprecated = deprecated;
99 }
100
101
102
103
104
105
106
107
108 public String getName() {
109 return name;
110 }
111
112
113
114
115
116
117 public Class<E> getType() {
118 return type;
119 }
120
121
122
123
124
125
126 public E getValue() {
127 return value;
128 }
129
130
131
132
133
134
135 public void setValue(E value) {
136 if (deprecated && value != null) {
137 escalator.escalate("Feature '" + name + "' is deprecated",
138 getClass(), value);
139 }
140 if (value != null && !(type.isAssignableFrom(value.getClass()))) {
141 throw new IllegalArgumentException(
142 "Tried to assign a value of type '" +
143 value.getClass().getName()
144 + "'to detail '" + name + "' of type '" + type +
145 "'");
146 }
147 this.value = value;
148 }
149
150
151
152
153
154
155
156 @SuppressWarnings("unchecked")
157 public E combineWith(E otherValue) {
158 return combinator.perform(this.value, otherValue);
159 }
160
161
162
163
164
165
166 public boolean isConstraint() {
167 return constraint;
168 }
169
170
171
172
173
174
175 public String getDescription() {
176 return name + '=' + value + " (" + type + ')';
177 }
178
179
180
181
182
183
184
185
186
187 public boolean isDeprecated() {
188 return deprecated;
189 }
190
191 @Override
192 public String toString() {
193 return name + '=' + value;
194 }
195
196 @SuppressWarnings("unchecked")
197 @Override
198 public boolean equals(Object o) {
199 if (this == o) {
200 return true;
201 }
202 if (o == null || getClass() != o.getClass()) {
203 return false;
204 }
205 final FeatureDetail<E> that = (FeatureDetail<E>) o;
206 return (name.equals(that.name)
207 && NullSafeComparator.equals(this.value, that.value));
208 }
209
210 @Override
211 public int hashCode() {
212 int result;
213 result = name.hashCode();
214 result = 29 * result + (value != null ? value.hashCode() : 0);
215 return result;
216 }
217
218 }