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 gov.nist.secauto.metaschema.databind.model;
28
29 import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
30 import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider;
31 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
32 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
33 import gov.nist.secauto.metaschema.core.model.IFlagDefinition;
34 import gov.nist.secauto.metaschema.core.model.IModule;
35 import gov.nist.secauto.metaschema.core.model.ModuleScopeEnum;
36 import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.InternalModelSource;
37 import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained;
38 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
39 import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
40 import gov.nist.secauto.metaschema.databind.model.annotations.Constants;
41 import gov.nist.secauto.metaschema.databind.model.annotations.JsonFieldValueKeyFlag;
42 import gov.nist.secauto.metaschema.databind.model.annotations.JsonKey;
43 import gov.nist.secauto.metaschema.databind.model.annotations.NullJavaTypeAdapter;
44 import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
45
46 import java.lang.reflect.Field;
47 import java.util.Locale;
48 import java.util.Map;
49 import java.util.Set;
50
51 import javax.xml.namespace.QName;
52
53 import edu.umd.cs.findbugs.annotations.NonNull;
54 import edu.umd.cs.findbugs.annotations.Nullable;
55 import nl.talsmasoftware.lazy4j.Lazy;
56
57 class DefaultFlagProperty
58 extends AbstractFlagProperty {
59
60
61 @NonNull
62 private final Field field;
63 @NonNull
64 private final BoundFlag flag;
65 @NonNull
66 private final IDataTypeAdapter<?> javaTypeAdapter;
67 @Nullable
68 private final Object defaultValue;
69 @NonNull
70 private final Lazy<InternalFlagDefinition> definition;
71
72
73
74
75
76
77
78
79
80
81 public DefaultFlagProperty(
82 @NonNull Field field,
83 @NonNull IClassBinding parentClassBinding) {
84 super(parentClassBinding);
85 this.field = ObjectUtils.requireNonNull(field, "field");
86 this.flag = ObjectUtils.requireNonNull(field.getAnnotation(BoundFlag.class));
87
88 Class<? extends IDataTypeAdapter<?>> adapterClass = ObjectUtils.notNull(this.flag.typeAdapter());
89 if (NullJavaTypeAdapter.class.equals(adapterClass)) {
90 this.javaTypeAdapter = MetaschemaDataTypeProvider.DEFAULT_DATA_TYPE;
91 } else {
92 this.javaTypeAdapter = ObjectUtils.requireNonNull(
93 parentClassBinding.getBindingContext().getJavaTypeAdapterInstance(adapterClass));
94 }
95
96 String defaultString = this.flag.defaultValue();
97 this.defaultValue = Constants.NULL_VALUE.equals(defaultString) ? null
98 : getJavaTypeAdapter().parse(defaultString);
99 this.definition = ObjectUtils.notNull(Lazy.lazy(() -> new InternalFlagDefinition()));
100 }
101
102 @Override
103 @NonNull
104 public Field getField() {
105 return field;
106 }
107
108 @NonNull
109 private BoundFlag getFlagAnnotation() {
110 return flag;
111 }
112
113 public Object getDefaultValue() {
114 return this.defaultValue;
115 }
116
117 @Override
118 public boolean isJsonKey() {
119 return getField().isAnnotationPresent(JsonKey.class);
120 }
121
122 @Override
123 public boolean isJsonValueKey() {
124 return getField().isAnnotationPresent(JsonFieldValueKeyFlag.class);
125 }
126
127 @Override
128 public boolean isRequired() {
129 return getFlagAnnotation().required();
130 }
131
132 @NonNull
133 protected final IDataTypeAdapter<?> getJavaTypeAdapter() {
134 return javaTypeAdapter;
135 }
136
137 @Override
138 public String getFormalName() {
139 return ModelUtil.resolveToString(getFlagAnnotation().formalName());
140 }
141
142 @Override
143 public MarkupLine getDescription() {
144 return ModelUtil.resolveToMarkupLine(getFlagAnnotation().description());
145 }
146
147 @Override
148 public String getUseName() {
149 return ModelUtil.resolveToString(getFlagAnnotation().useName());
150 }
151
152 @Override
153 public String getXmlNamespace() {
154 return ModelUtil.resolveOptionalNamespace(getFlagAnnotation().namespace(), getParentClassBinding());
155 }
156
157 @Override
158 public MarkupMultiline getRemarks() {
159 return ModelUtil.resolveToMarkupMultiline(getFlagAnnotation().remarks());
160 }
161
162 @Override
163 public IFlagDefinition getDefinition() {
164 return ObjectUtils.notNull(definition.get());
165 }
166
167 @Override
168 public Object defaultValue() {
169 return getDefaultValue();
170 }
171
172 @SuppressWarnings("null")
173 @Override
174 public String toCoordinates() {
175 return String.format("%s Instance(%s): %s:%s",
176 getModelType().name().toLowerCase(Locale.ROOT),
177 getName(),
178 getParentClassBinding().getBoundClass().getName(),
179 getField().getName());
180 }
181
182 private final class InternalFlagDefinition implements IFlagDefinition {
183 private final Lazy<IValueConstrained> constraints;
184
185 private InternalFlagDefinition() {
186 this.constraints = Lazy.lazy(() -> new ValueConstraintSupport(
187 getField().getAnnotation(ValueConstraints.class),
188 InternalModelSource.instance()));
189 }
190
191 @SuppressWarnings("null")
192 @Override
193 public IValueConstrained getConstraintSupport() {
194 return constraints.get();
195 }
196
197 @Override
198 public String getFormalName() {
199 return DefaultFlagProperty.this.getFormalName();
200 }
201
202 @Override
203 public MarkupLine getDescription() {
204 return DefaultFlagProperty.this.getDescription();
205 }
206
207 @Override
208 public @NonNull Map<QName, Set<String>> getProperties() {
209
210 throw new UnsupportedOperationException();
211 }
212
213 @Override
214 public IDataTypeAdapter<?> getJavaTypeAdapter() {
215 return DefaultFlagProperty.this.getJavaTypeAdapter();
216 }
217
218 @Override
219 public Object getDefaultValue() {
220 return DefaultFlagProperty.this.getDefaultValue();
221 }
222
223 @Override
224 public boolean isInline() {
225 return true;
226 }
227
228 @Override
229 public IBoundFlagInstance getInlineInstance() {
230 return DefaultFlagProperty.this;
231 }
232
233 @Override
234 public String getName() {
235 return getJavaFieldName();
236 }
237
238 @Override
239 public String getUseName() {
240
241 return null;
242 }
243
244 @Override
245 public MarkupMultiline getRemarks() {
246 return DefaultFlagProperty.this.getRemarks();
247 }
248
249 @Override
250 public String toCoordinates() {
251 return DefaultFlagProperty.this.toCoordinates();
252 }
253
254 @Override
255 public @NonNull ModuleScopeEnum getModuleScope() {
256
257 return ModuleScopeEnum.INHERITED;
258 }
259
260 @Override
261 public IModule getContainingModule() {
262 return DefaultFlagProperty.this.getContainingModule();
263 }
264 }
265 }