1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model;
7
8 import gov.nist.secauto.metaschema.core.model.IBoundObject;
9 import gov.nist.secauto.metaschema.core.model.IModelInstanceAbsolute;
10 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
11 import gov.nist.secauto.metaschema.databind.io.BindingException;
12 import gov.nist.secauto.metaschema.databind.model.info.IModelInstanceCollectionInfo;
13
14 import java.lang.reflect.Field;
15 import java.lang.reflect.ParameterizedType;
16 import java.lang.reflect.Type;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.Map;
20
21 import edu.umd.cs.findbugs.annotations.NonNull;
22 import edu.umd.cs.findbugs.annotations.Nullable;
23
24
25
26
27
28
29
30 public interface IBoundInstanceModel<ITEM>
31 extends IBoundInstance<ITEM>, IModelInstanceAbsolute {
32
33
34
35
36
37
38
39
40 @NonNull
41 static Class<?> getItemType(@NonNull Field field) {
42 Type fieldType = field.getGenericType();
43 Class<?> rawType = ObjectUtils.notNull(
44 (Class<?>) (fieldType instanceof ParameterizedType ? ((ParameterizedType) fieldType).getRawType() : fieldType));
45
46 Class<?> itemType;
47 if (Map.class.isAssignableFrom(rawType)) {
48
49 itemType = ObjectUtils.notNull((Class<?>) ((ParameterizedType) fieldType).getActualTypeArguments()[1]);
50 } else if (List.class.isAssignableFrom(rawType)) {
51
52 itemType = ObjectUtils.notNull((Class<?>) ((ParameterizedType) fieldType).getActualTypeArguments()[0]);
53 } else {
54
55 itemType = rawType;
56 }
57 return itemType;
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 @NonNull
74 static <TYPE> Class<? extends TYPE> getItemType(@NonNull Field field, @NonNull Class<TYPE> expectedItemType) {
75 Type fieldType = field.getGenericType();
76 Class<?> rawType = ObjectUtils.notNull(
77 (Class<?>) (fieldType instanceof ParameterizedType ? ((ParameterizedType) fieldType).getRawType() : fieldType));
78
79 Class<?> itemType;
80 if (Map.class.isAssignableFrom(rawType)) {
81
82 itemType = ObjectUtils.notNull((Class<?>) ((ParameterizedType) fieldType).getActualTypeArguments()[1]);
83 } else if (List.class.isAssignableFrom(rawType)) {
84
85 itemType = ObjectUtils.notNull((Class<?>) ((ParameterizedType) fieldType).getActualTypeArguments()[0]);
86 } else {
87
88 itemType = rawType;
89 }
90 return ObjectUtils.notNull(itemType.asSubclass(expectedItemType));
91 }
92
93 @Override
94 @NonNull
95 IBoundDefinitionModelAssembly getContainingDefinition();
96
97 @Override
98 default Object getResolvedDefaultValue() {
99 return getMaxOccurs() == 1 ? getEffectiveDefaultValue() : getCollectionInfo().emptyValue();
100 }
101
102
103
104
105
106
107
108
109 @Override
110 @NonNull
111 default Collection<? extends Object> getItemValues(Object value) {
112 return getCollectionInfo().getItemsFromValue(value);
113 }
114
115
116
117
118
119
120
121 @NonNull
122 IModelInstanceCollectionInfo<ITEM> getCollectionInfo();
123
124
125
126
127
128
129
130
131 @Nullable
132 IBoundInstanceFlag getItemJsonKey(@NonNull Object item);
133
134 @Override
135 default void deepCopy(@NonNull IBoundObject fromInstance, @NonNull IBoundObject toInstance) throws BindingException {
136 Object value = getValue(fromInstance);
137 if (value != null) {
138 value = getCollectionInfo().deepCopyItems(fromInstance, toInstance);
139 }
140 setValue(toInstance, value);
141 }
142 }