1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.rapiddweller.model.data;
28
29 import com.rapiddweller.common.ConfigurationError;
30 import com.rapiddweller.platform.java.BeanDescriptorProvider;
31 import com.rapiddweller.script.PrimitiveType;
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
34
35 import java.util.HashMap;
36 import java.util.Map;
37
38
39
40
41
42
43
44
45 public class DataModel {
46
47 private final Logger logger = LogManager.getLogger(DataModel.class);
48
49 private final Map<String, DescriptorProvider> providers;
50
51 private boolean acceptUnknownPrimitives;
52
53
54
55
56 public DataModel() {
57 this.acceptUnknownPrimitives = false;
58 this.providers = new HashMap<>();
59 new PrimitiveDescriptorProvider(this);
60 new BeanDescriptorProvider(this);
61 }
62
63 private static TypeDescriptor searchCaseInsensitive(
64 DescriptorProvider provider, String name) {
65 for (TypeDescriptor type : provider.getTypeDescriptors()) {
66 if (type.getName().equals(name)) {
67 return type;
68 }
69 }
70 return null;
71 }
72
73
74
75
76
77
78 public void setAcceptUnknownPrimitives(boolean acceptUnknownPrimitives) {
79 this.acceptUnknownPrimitives = acceptUnknownPrimitives;
80 }
81
82
83
84
85
86
87 public void addDescriptorProvider(DescriptorProvider provider) {
88 addDescriptorProvider(provider, true);
89 }
90
91
92
93
94
95
96
97 public void addDescriptorProvider(DescriptorProvider provider,
98 boolean validate) {
99 providers.put(provider.getId(), provider);
100 provider.setDataModel(this);
101 if (validate) {
102 validate();
103 }
104 }
105
106
107
108
109
110
111
112 public DescriptorProvider getDescriptorProvider(String id) {
113 return providers.get(id);
114 }
115
116
117
118
119
120
121 public void removeDescriptorProvider(String id) {
122 providers.remove(id);
123 }
124
125
126
127
128
129
130
131 public TypeDescriptor getTypeDescriptor(String typeId) {
132 if (typeId == null) {
133 return null;
134 }
135 String namespace = null;
136 String name = typeId;
137 if (typeId.contains(":")) {
138 int i = typeId.indexOf(':');
139 namespace = typeId.substring(0, i);
140 name = typeId.substring(i + 1);
141 }
142 return getTypeDescriptor(namespace, name);
143 }
144
145
146
147
148
149
150
151
152 public TypeDescriptor getTypeDescriptor(String namespace, String name) {
153 if (name == null) {
154 return null;
155 }
156 if (namespace != null) {
157 DescriptorProvider provider = providers.get(namespace);
158 if (provider != null) {
159
160 TypeDescriptor typeDescriptor =
161 provider.getTypeDescriptor(name);
162 if (typeDescriptor != null) {
163 return typeDescriptor;
164 } else {
165
166 return searchCaseInsensitive(provider, name);
167 }
168 }
169 }
170
171 for (DescriptorProvider provider : providers.values()) {
172 TypeDescriptor descriptor = provider.getTypeDescriptor(name);
173 if (descriptor != null) {
174 return descriptor;
175 }
176 }
177
178 for (DescriptorProvider provider : providers.values()) {
179 TypeDescriptor descriptor = searchCaseInsensitive(provider, name);
180 if (descriptor != null) {
181 return descriptor;
182 }
183 }
184 return null;
185 }
186
187
188
189
190
191
192 public void validate() {
193 for (DescriptorProvider provider : providers.values()) {
194 for (TypeDescriptor desc : provider.getTypeDescriptors()) {
195 validate(desc);
196 }
197 }
198 }
199
200 private void validate(TypeDescriptor type) {
201 logger.debug("validating " + type);
202 if (type instanceof SimpleTypeDescriptor) {
203 validate((SimpleTypeDescriptor) type);
204 } else if (type instanceof ComplexTypeDescriptor) {
205 validate((ComplexTypeDescriptor) type);
206 } else if (type instanceof ArrayTypeDescriptor) {
207 validate((ArrayTypeDescriptor) type);
208 } else {
209 throw new UnsupportedOperationException(
210 "Descriptor type not supported: " + type.getClass());
211 }
212 }
213
214 private void validate(SimpleTypeDescriptor desc) {
215 PrimitiveType primitiveType = desc.getPrimitiveType();
216 if (primitiveType == null && !acceptUnknownPrimitives) {
217 throw new ConfigurationError(
218 "No primitive type defined for simple type: " +
219 desc.getName());
220 }
221 }
222
223 private void validate(ComplexTypeDescriptor desc) {
224 for (ComponentDescriptor component : desc.getComponents()) {
225 TypeDescriptor type = component.getTypeDescriptor();
226 if (type == null) {
227 throw new ConfigurationError(
228 "Type of component is not defined: " + desc.getName());
229 } else if (!(type instanceof ComplexTypeDescriptor)) {
230 validate(type);
231 }
232 }
233 }
234
235 private void validate(ArrayTypeDescriptor desc) {
236 for (ArrayElementDescriptor element : desc.getElements()) {
237 TypeDescriptor type = element.getTypeDescriptor();
238 if (!(type instanceof ComplexTypeDescriptor)) {
239 validate(type);
240 }
241 }
242 }
243
244
245
246
247
248
249
250 public SimpleTypeDescriptor getPrimitiveTypeDescriptor(Class<?> javaType) {
251 PrimitiveDescriptorProvider primitiveProvider =
252 (PrimitiveDescriptorProvider) providers
253 .get(PrimitiveDescriptorProvider.NAMESPACE);
254 return primitiveProvider.getPrimitiveTypeDescriptor(javaType);
255 }
256
257
258
259
260
261
262 public BeanDescriptorProvider getBeanDescriptorProvider() {
263 return (BeanDescriptorProvider) providers
264 .get(BeanDescriptorProvider.NAMESPACE);
265 }
266
267 }