1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model.impl;
7
8 import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
9 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
10 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
11 import gov.nist.secauto.metaschema.core.model.AbstractInlineFlagDefinition;
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.IModule;
15 import gov.nist.secauto.metaschema.core.model.ISource;
16 import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained;
17 import gov.nist.secauto.metaschema.core.model.constraint.ValueConstraintSet;
18 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
19 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
20 import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionFlag;
21 import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModel;
22 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag;
23 import gov.nist.secauto.metaschema.databind.model.IBoundModule;
24 import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
25 import gov.nist.secauto.metaschema.databind.model.annotations.JsonFieldValueKeyFlag;
26 import gov.nist.secauto.metaschema.databind.model.annotations.JsonKey;
27 import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil;
28 import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
29
30 import java.lang.reflect.Field;
31 import java.util.Arrays;
32 import java.util.LinkedHashMap;
33 import java.util.Map;
34 import java.util.Optional;
35 import java.util.Set;
36 import java.util.stream.Collectors;
37
38 import edu.umd.cs.findbugs.annotations.NonNull;
39 import edu.umd.cs.findbugs.annotations.Nullable;
40 import nl.talsmasoftware.lazy4j.Lazy;
41
42
43
44
45
46 public class InstanceFlagInline
47 extends AbstractInlineFlagDefinition<IBoundDefinitionModel<IBoundObject>, IBoundDefinitionFlag, IBoundInstanceFlag>
48 implements IBoundInstanceFlag {
49 @NonNull
50 private final Field javaField;
51 @NonNull
52 private final BoundFlag annotation;
53 @NonNull
54 private final IDataTypeAdapter<?> javaTypeAdapter;
55 @Nullable
56 private final Object defaultValue;
57 @NonNull
58 private final Lazy<IValueConstrained> constraints;
59 @NonNull
60 private final Lazy<Map<IAttributable.Key, Set<String>>> properties;
61
62
63
64
65
66
67
68
69
70 public InstanceFlagInline(
71 @NonNull Field javaField,
72 @NonNull IBoundDefinitionModel<IBoundObject> parent) {
73 super(parent);
74 FieldSupport.bindField(javaField);
75 this.javaField = javaField;
76 this.annotation = ModelUtil.getAnnotation(javaField, BoundFlag.class);
77 Class<? extends IDataTypeAdapter<?>> adapterClass = ObjectUtils.notNull(getAnnotation().typeAdapter());
78 this.javaTypeAdapter = ModelUtil.getDataTypeAdapter(
79 adapterClass,
80 parent.getBindingContext());
81 this.defaultValue = ModelUtil.resolveDefaultValue(getAnnotation().defaultValue(), this.javaTypeAdapter);
82
83 IModule module = parent.getContainingModule();
84 ISource source = module.getSource();
85
86 this.constraints = ObjectUtils.notNull(Lazy.lazy(() -> {
87 IValueConstrained retval = new ValueConstraintSet(source);
88 ValueConstraints valueAnnotation = getAnnotation().valueConstraints();
89 ConstraintSupport.parse(valueAnnotation, source, retval);
90 return retval;
91 }));
92 this.properties = ObjectUtils.notNull(
93 Lazy.lazy(() -> CollectionUtil.unmodifiableMap(ObjectUtils.notNull(
94 Arrays.stream(annotation.properties())
95 .map(ModelUtil::toPropertyEntry)
96 .collect(
97 Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v2, LinkedHashMap::new))))));
98 }
99
100
101
102
103
104
105 @Override
106 @NonNull
107 public Field getField() {
108 return javaField;
109 }
110
111
112
113
114
115
116 @NonNull
117 private BoundFlag getAnnotation() {
118 return annotation;
119 }
120
121 @Override
122 public IBoundModule getContainingModule() {
123 return getContainingDefinition().getContainingModule();
124 }
125
126
127
128
129
130 @SuppressWarnings("null")
131 @Override
132 @NonNull
133 public IValueConstrained getConstraintSupport() {
134 return constraints.get();
135 }
136
137 @Override
138 public boolean isRequired() {
139 return getAnnotation().required();
140 }
141
142 @Override
143 public Object getDefaultValue() {
144 return defaultValue;
145 }
146
147 @Override
148 public boolean isJsonKey() {
149 return getField().isAnnotationPresent(JsonKey.class);
150 }
151
152 @Override
153 public boolean isJsonValueKey() {
154 return getField().isAnnotationPresent(JsonFieldValueKeyFlag.class);
155 }
156
157 @Override
158 public IDataTypeAdapter<?> getJavaTypeAdapter() {
159 return javaTypeAdapter;
160 }
161
162 @Override
163 @Nullable
164 public String getFormalName() {
165 return ModelUtil.resolveNoneOrValue(getAnnotation().formalName());
166 }
167
168 @Override
169 @Nullable
170 public MarkupLine getDescription() {
171 return ModelUtil.resolveToMarkupLine(getAnnotation().description());
172 }
173
174 @Override
175 public String getName() {
176 return ObjectUtils.notNull(
177 Optional.ofNullable(ModelUtil.resolveNoneOrValue(getAnnotation().name())).orElse(getField().getName()));
178 }
179
180 @Override
181 public Integer getUseIndex() {
182 return getAnnotation().useIndex();
183 }
184
185 @Override
186 public Map<Key, Set<String>> getProperties() {
187 return ObjectUtils.notNull(properties.get());
188 }
189
190 @Override
191 @Nullable
192 public MarkupMultiline getRemarks() {
193 return ModelUtil.resolveToMarkupMultiline(getAnnotation().remarks());
194 }
195
196
197
198
199 }