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 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 IBoundModule module,
48 @NonNull IBindingContext bindingContext) {
49 this.clazz = clazz;
50 this.annotation = annotation;
51 this.bindingContext = bindingContext;
52 this.module = module;
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 @NonNull
71 public A getAnnotation() {
72 return annotation;
73 }
74
75 @Override
76 @NonNull
77 public IBoundModule getContainingModule() {
78 return module;
79 }
80
81 @Override
82 @NonNull
83 public IBindingContext getBindingContext() {
84 return bindingContext;
85 }
86
87 @SuppressWarnings("null")
88 @Override
89 public final QName getXmlQName() {
90 return qname.get();
91 }
92
93 @SuppressWarnings("null")
94 @Override
95 public final QName getDefinitionQName() {
96 return definitionQName.get();
97 }
98
99 @Override
100 public Method getBeforeDeserializeMethod() {
101 return beforeDeserializeMethod;
102 }
103
104 @Override
105 public Method getAfterDeserializeMethod() {
106 return afterDeserializeMethod;
107 }
108
109
110
111
112
113
114
115 @Override
116 public IBoundObject deepCopyItem(IBoundObject item, IBoundObject parentInstance) throws BindingException {
117 IBoundObject instance = newInstance(item::getMetaschemaData);
118
119 callBeforeDeserialize(instance, parentInstance);
120
121 deepCopyItemInternal(item, instance);
122
123 callAfterDeserialize(instance, parentInstance);
124
125 return instance;
126 }
127
128 protected void deepCopyItemInternal(@NonNull IBoundObject fromObject, @NonNull IBoundObject toObject)
129 throws BindingException {
130 for (IBoundInstanceFlag instance : getFlagInstances()) {
131 instance.deepCopy(fromObject, toObject);
132 }
133 }
134 }