1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model.annotations;
7
8 import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
9 import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider;
10 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
11 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
12 import gov.nist.secauto.metaschema.core.model.IAttributable;
13 import gov.nist.secauto.metaschema.core.model.IBoundObject;
14 import gov.nist.secauto.metaschema.core.model.IMetaschemaData;
15 import gov.nist.secauto.metaschema.core.model.IModule;
16 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
17 import gov.nist.secauto.metaschema.databind.IBindingContext;
18 import gov.nist.secauto.metaschema.databind.model.IGroupAs;
19 import gov.nist.secauto.metaschema.databind.model.impl.DefaultGroupAs;
20
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.Field;
23 import java.net.URI;
24 import java.util.Arrays;
25 import java.util.LinkedHashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import edu.umd.cs.findbugs.annotations.NonNull;
31 import edu.umd.cs.findbugs.annotations.Nullable;
32
33 public final class ModelUtil {
34
35
36 public static final String NO_STRING_VALUE = "##none";
37 public static final String DEFAULT_STRING_VALUE = "##default";
38
39
40
41
42
43
44
45 public static final String NULL_VALUE = "\u0000";
46
47 private ModelUtil() {
48
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 @NonNull
65 public static <A extends Annotation> A getAnnotation(
66 @NonNull Class<?> clazz,
67 Class<A> annotationClass) {
68 A annotation = clazz.getAnnotation(annotationClass);
69 if (annotation == null) {
70 throw new IllegalArgumentException(
71 String.format("Class '%s' is missing the '%s' annotation.",
72 clazz.getName(),
73 annotationClass.getName()));
74 }
75 return annotation;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 @NonNull
92 public static <A extends Annotation> A getAnnotation(
93 @NonNull Field javaField,
94 Class<A> annotationClass) {
95 A annotation = javaField.getAnnotation(annotationClass);
96 if (annotation == null) {
97 throw new IllegalArgumentException(
98 String.format("Field '%s' is missing the '%s' annotation.",
99 javaField.toGenericString(),
100 annotationClass.getName()));
101 }
102 return annotation;
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 @Nullable
117 public static String resolveNoneOrDefault(@Nullable String value, @Nullable String defaultValue) {
118 String retval;
119 if (value == null || DEFAULT_STRING_VALUE.equals(value)) {
120 retval = defaultValue;
121 } else if (NO_STRING_VALUE.equals(value)) {
122 retval = null;
123 } else {
124 retval = value;
125 }
126 return retval;
127 }
128
129
130
131
132
133
134
135
136
137 @Nullable
138 public static String resolveNoneOrValue(@NonNull String value) {
139 return NO_STRING_VALUE.equals(value) ? null : value;
140 }
141
142
143
144
145
146
147
148
149
150 @Nullable
151 public static MarkupLine resolveToMarkupLine(@NonNull String value) {
152 return resolveNoneOrValue(value) == null ? null : MarkupLine.fromMarkdown(value);
153 }
154
155
156
157
158
159
160
161
162
163 @Nullable
164 public static MarkupMultiline resolveToMarkupMultiline(@NonNull String value) {
165 return resolveNoneOrValue(value) == null ? null : MarkupMultiline.fromMarkdown(value);
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 @NonNull
184 public static IDataTypeAdapter<?> getDataTypeAdapter(
185 @NonNull Class<? extends IDataTypeAdapter<?>> adapterClass,
186 @NonNull IBindingContext bindingContext) {
187 IDataTypeAdapter<?> retval;
188 if (NullJavaTypeAdapter.class.equals(adapterClass)) {
189 retval = MetaschemaDataTypeProvider.DEFAULT_DATA_TYPE;
190 } else {
191 retval = bindingContext.getJavaTypeAdapterInstance(adapterClass);
192 if (retval == null) {
193 throw new IllegalArgumentException("Unable to get type adapter instance for class: " + adapterClass.getName());
194 }
195 }
196 return retval;
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 @Nullable
215 public static Object resolveDefaultValue(@NonNull String defaultValue, IDataTypeAdapter<?> adapter) {
216 Object retval = null;
217 if (!NULL_VALUE.equals(defaultValue)) {
218 retval = adapter.parse(defaultValue);
219 }
220 return retval;
221 }
222
223
224
225
226
227
228
229
230
231
232
233 public static Integer resolveDefaultInteger(int value) {
234 return value == Integer.MIN_VALUE ? null : value;
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249 @NonNull
250 public static IGroupAs resolveDefaultGroupAs(
251 @NonNull GroupAs groupAs,
252 @NonNull IModule module) {
253 return NULL_VALUE.equals(groupAs.name())
254 ? IGroupAs.SINGLETON_GROUP_AS
255 : new DefaultGroupAs(groupAs, module);
256 }
257
258 public static String toLocation(@NonNull IBoundObject obj) {
259 IMetaschemaData data = obj.getMetaschemaData();
260
261 String retval = "";
262 if (data != null) {
263 int line = data.getLine();
264 if (line > -1) {
265 retval = line + ":" + data.getColumn();
266 }
267 }
268 return retval;
269 }
270
271 public static String toLocation(@NonNull IBoundObject obj, @Nullable URI uri) {
272 String retval = uri == null ? "" : uri.toASCIIString();
273
274 String location = toLocation(obj);
275 if (!location.isEmpty()) {
276 retval = retval.isEmpty() ? location : retval + "@" + location;
277 }
278 return retval;
279 }
280
281 public static Map.Entry<IAttributable.Key, Set<String>> toPropertyEntry(@NonNull Property property) {
282 String name = property.name();
283 String namespace = property.namespace();
284 @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
285 IAttributable.Key key = IAttributable.key(namespace, name);
286
287 String[] values = property.values();
288 List<String> valueList = Arrays.asList(values);
289 @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
290 Set<String> valueSet = new LinkedHashSet<>(valueList);
291
292 return Map.entry(key, CollectionUtil.unmodifiableSet(valueSet));
293 }
294 }