1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model.impl;
7
8 import gov.nist.secauto.metaschema.core.model.IBoundObject;
9 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
10 import gov.nist.secauto.metaschema.databind.IBindingContext;
11 import gov.nist.secauto.metaschema.databind.io.BindingException;
12 import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelComplex;
13 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceFlag;
14 import gov.nist.secauto.metaschema.databind.model.IBoundModule;
15
16 import java.lang.annotation.Annotation;
17 import java.lang.reflect.Method;
18
19 import javax.xml.namespace.QName;
20
21 import edu.umd.cs.findbugs.annotations.NonNull;
22 import edu.umd.cs.findbugs.annotations.Nullable;
23 import nl.talsmasoftware.lazy4j.Lazy;
24
25 public abstract class AbstractBoundDefinitionModelComplex<A extends Annotation>
26 implements IBoundDefinitionModelComplex {
27 @NonNull
28 private final Class<? extends IBoundObject> clazz;
29 @NonNull
30 private final A annotation;
31 @NonNull
32 private final IBindingContext bindingContext;
33 @NonNull
34 private final Lazy<IBoundModule> module;
35 @NonNull
36 private final Lazy<QName> qname;
37 @NonNull
38 private final Lazy<QName> definitionQName;
39 @Nullable
40 private final Method beforeDeserializeMethod;
41 @Nullable
42 private final Method afterDeserializeMethod;
43
44 protected AbstractBoundDefinitionModelComplex(
45 @NonNull Class<? extends IBoundObject> clazz,
46 @NonNull A annotation,
47 @NonNull Class<? extends IBoundModule> moduleClass,
48 @NonNull IBindingContext bindingContext) {
49 this.clazz = clazz;
50 this.annotation = annotation;
51 this.bindingContext = bindingContext;
52 this.module = ObjectUtils.notNull(Lazy.lazy(() -> bindingContext.registerModule(moduleClass)));
53 this.qname = ObjectUtils.notNull(Lazy.lazy(() -> getContainingModule().toModelQName(getEffectiveName())));
54 this.definitionQName = ObjectUtils.notNull(Lazy.lazy(() -> getContainingModule().toModelQName(getName())));
55 this.beforeDeserializeMethod = ClassIntrospector.getMatchingMethod(
56 clazz,
57 "beforeDeserialize",
58 Object.class);
59 this.afterDeserializeMethod = ClassIntrospector.getMatchingMethod(
60 clazz,
61 "afterDeserialize",
62 Object.class);
63 }
64
65 @Override
66 public Class<? extends IBoundObject> getBoundClass() {
67 return clazz;
68 }
69
70 public A getAnnotation() {
71 return annotation;
72 }
73
74 @Override
75 @NonNull
76 public IBoundModule getContainingModule() {
77 return ObjectUtils.notNull(module.get());
78 }
79
80 @Override
81 @NonNull
82 public IBindingContext getBindingContext() {
83 return bindingContext;
84 }
85
86 @SuppressWarnings("null")
87 @Override
88 public final QName getXmlQName() {
89 return qname.get();
90 }
91
92 @SuppressWarnings("null")
93 @Override
94 public final QName getDefinitionQName() {
95 return definitionQName.get();
96 }
97
98 @Override
99 public boolean isInline() {
100 return getBoundClass().getEnclosingClass() != null;
101 }
102
103 @Override
104 public Method getBeforeDeserializeMethod() {
105 return beforeDeserializeMethod;
106 }
107
108 @Override
109 public Method getAfterDeserializeMethod() {
110 return afterDeserializeMethod;
111 }
112
113
114
115
116
117
118
119 @Override
120 public IBoundObject deepCopyItem(IBoundObject item, IBoundObject parentInstance) throws BindingException {
121 IBoundObject instance = newInstance(item::getMetaschemaData);
122
123 callBeforeDeserialize(instance, parentInstance);
124
125 deepCopyItemInternal(item, instance);
126
127 callAfterDeserialize(instance, parentInstance);
128
129 return instance;
130 }
131
132 protected void deepCopyItemInternal(@NonNull IBoundObject fromObject, @NonNull IBoundObject toObject)
133 throws BindingException {
134 for (IBoundInstanceFlag instance : getFlagInstances()) {
135 instance.deepCopy(fromObject, toObject);
136 }
137 }
138 }