1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model.impl;
7
8 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
9 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
10 import gov.nist.secauto.metaschema.core.model.IBoundObject;
11 import gov.nist.secauto.metaschema.core.model.IModule;
12 import gov.nist.secauto.metaschema.core.model.constraint.AssemblyConstraintSet;
13 import gov.nist.secauto.metaschema.core.model.constraint.IModelConstrained;
14 import gov.nist.secauto.metaschema.core.model.constraint.ISource;
15 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
16 import gov.nist.secauto.metaschema.databind.IBindingContext;
17 import gov.nist.secauto.metaschema.databind.io.BindingException;
18 import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly;
19 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModel;
20 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelAssembly;
21 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelChoiceGroup;
22 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelField;
23 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelNamed;
24 import gov.nist.secauto.metaschema.databind.model.IBoundModule;
25 import gov.nist.secauto.metaschema.databind.model.IBoundProperty;
26 import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints;
27 import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
28 import gov.nist.secauto.metaschema.databind.model.annotations.ModelUtil;
29 import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
30
31 import java.util.Map;
32
33 import javax.xml.namespace.QName;
34
35 import edu.umd.cs.findbugs.annotations.NonNull;
36 import edu.umd.cs.findbugs.annotations.Nullable;
37 import nl.talsmasoftware.lazy4j.Lazy;
38
39
40 public final class DefinitionAssembly
41 extends AbstractBoundDefinitionModelComplex<MetaschemaAssembly>
42 implements IBoundDefinitionModelAssembly,
43 IFeatureBoundContainerModelAssembly<
44 IBoundInstanceModel<?>,
45 IBoundInstanceModelNamed<?>,
46 IBoundInstanceModelField<?>,
47 IBoundInstanceModelAssembly,
48 IBoundInstanceModelChoiceGroup> {
49
50 @NonNull
51 private final Lazy<FlagContainerSupport> flagContainer;
52 @NonNull
53 private final Lazy<AssemblyModelContainerSupport> modelContainer;
54 @NonNull
55 private final Lazy<IModelConstrained> constraints;
56 @NonNull
57 private final Lazy<QName> xmlRootQName;
58 @NonNull
59 private final Lazy<Map<String, IBoundProperty<?>>> jsonProperties;
60
61 public static DefinitionAssembly newInstance(
62 @NonNull Class<? extends IBoundObject> clazz,
63 @NonNull IBindingContext bindingContext) {
64 MetaschemaAssembly annotation = ModelUtil.getAnnotation(clazz, MetaschemaAssembly.class);
65 Class<? extends IBoundModule> moduleClass = annotation.moduleClass();
66 return new DefinitionAssembly(clazz, annotation, moduleClass, bindingContext);
67 }
68
69 private DefinitionAssembly(
70 @NonNull Class<? extends IBoundObject> clazz,
71 @NonNull MetaschemaAssembly annotation,
72 @NonNull Class<? extends IBoundModule> moduleClass,
73 @NonNull IBindingContext bindingContext) {
74 super(clazz, annotation, moduleClass, bindingContext);
75
76 String rootLocalName = ModelUtil.resolveNoneOrDefault(getAnnotation().rootName(), null);
77 this.xmlRootQName = ObjectUtils.notNull(Lazy.lazy(() -> rootLocalName == null
78 ? null
79 : getContainingModule().toModelQName(rootLocalName)));
80 this.flagContainer = ObjectUtils.notNull(Lazy.lazy(() -> new FlagContainerSupport(this, null)));
81 this.modelContainer = ObjectUtils.notNull(Lazy.lazy(() -> new AssemblyModelContainerSupport(this)));
82
83 IModule module = getContainingModule();
84
85 this.constraints = ObjectUtils.notNull(Lazy.lazy(() -> {
86 IModelConstrained retval = new AssemblyConstraintSet();
87 ValueConstraints valueAnnotation = getAnnotation().valueConstraints();
88 ConstraintSupport.parse(valueAnnotation, ISource.modelSource(module), retval);
89
90 AssemblyConstraints assemblyAnnotation = getAnnotation().modelConstraints();
91 ConstraintSupport.parse(assemblyAnnotation, ISource.modelSource(module), retval);
92 return retval;
93 }));
94 this.jsonProperties = ObjectUtils.notNull(Lazy.lazy(() -> getJsonProperties(null)));
95
96 if (rootLocalName != null) {
97 bindingContext.registerBindingMatcher(this);
98 }
99 }
100
101 @Override
102 protected void deepCopyItemInternal(IBoundObject fromObject, IBoundObject toObject) throws BindingException {
103
104 super.deepCopyItemInternal(fromObject, toObject);
105
106 for (IBoundInstanceModel<?> instance : getModelInstances()) {
107 instance.deepCopy(fromObject, toObject);
108 }
109 }
110
111 @Override
112 public Map<String, IBoundProperty<?>> getJsonProperties() {
113 return ObjectUtils.notNull(jsonProperties.get());
114 }
115
116
117
118
119
120 @Override
121 @SuppressWarnings("null")
122 @NonNull
123 public FlagContainerSupport getFlagContainer() {
124 return flagContainer.get();
125 }
126
127 @Override
128 @SuppressWarnings("null")
129 @NonNull
130 public AssemblyModelContainerSupport getModelContainer() {
131 return modelContainer.get();
132 }
133
134 @Override
135 @NonNull
136 public IModelConstrained getConstraintSupport() {
137 return ObjectUtils.notNull(constraints.get());
138 }
139
140 @Override
141 @Nullable
142 public String getFormalName() {
143 return ModelUtil.resolveNoneOrValue(getAnnotation().formalName());
144 }
145
146 @Override
147 @Nullable
148 public MarkupLine getDescription() {
149 return ModelUtil.resolveToMarkupLine(getAnnotation().description());
150 }
151
152 @Override
153 @NonNull
154 public String getName() {
155 return getAnnotation().name();
156 }
157
158 @Override
159 @Nullable
160 public Integer getIndex() {
161 return ModelUtil.resolveDefaultInteger(getAnnotation().index());
162 }
163
164 @Override
165 @Nullable
166 public MarkupMultiline getRemarks() {
167 return ModelUtil.resolveToMarkupMultiline(getAnnotation().description());
168 }
169
170 @Override
171 @Nullable
172 public QName getRootXmlQName() {
173
174 return xmlRootQName.get();
175 }
176
177 @Override
178 public boolean isRoot() {
179
180
181 return getRootXmlQName() != null;
182 }
183
184 @Override
185 @Nullable
186 public String getRootName() {
187
188 QName qname = getRootXmlQName();
189 return qname == null ? null : qname.getLocalPart();
190 }
191
192 @Override
193 @Nullable
194 public Integer getRootIndex() {
195 return ModelUtil.resolveDefaultInteger(getAnnotation().rootIndex());
196 }
197
198
199
200
201 }