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