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.benerator.engine.expression.ScriptExpression;
30 import com.rapiddweller.common.operation.AndOperation;
31 import com.rapiddweller.common.operation.OrOperation;
32 import com.rapiddweller.script.Expression;
33 import com.rapiddweller.script.expression.ConstantExpression;
34 import com.rapiddweller.script.expression.TypeConvertingExpression;
35
36
37
38
39
40
41
42
43
44 public class InstanceDescriptor extends FeatureDescriptor {
45
46
47
48
49 public static final String TYPE = "type";
50
51
52
53
54 public static final String UNIQUE = "unique";
55
56
57
58 public static final String NULLABLE = "nullable";
59
60
61
62 public static final String MIN_COUNT = "minCount";
63
64
65
66 public static final String MAX_COUNT = "maxCount";
67
68
69
70 public static final String CONTAINER = "container";
71
72
73
74
75 public static final String COUNT_GRANULARITY = "countGranularity";
76
77
78
79 public static final String COUNT_DISTRIBUTION = "countDistribution";
80
81
82
83 public static final String COUNT = "count";
84
85
86
87 public static final String NULL_QUOTA = "nullQuota";
88
89
90
91 public static final String MODE = "mode";
92
93
94 private InstanceDescriptor parent;
95 private TypeDescriptor localType;
96
97
98
99
100
101
102
103
104
105 public InstanceDescriptor(String name, DescriptorProvider provider) {
106 this(name, provider, null, null);
107 }
108
109
110
111
112
113
114
115
116 public InstanceDescriptor(String name, DescriptorProvider provider,
117 String typeName) {
118 this(name, provider, typeName, null);
119 }
120
121
122
123
124
125
126
127
128 public InstanceDescriptor(String name, DescriptorProvider provider,
129 TypeDescriptor localType) {
130 this(name, provider, null, localType);
131 }
132
133
134
135
136
137
138
139
140
141 protected InstanceDescriptor(String name, DescriptorProvider provider,
142 String typeName, TypeDescriptor localType) {
143 super(name, provider);
144 this.localType = localType;
145
146 addConstraint(TYPE, String.class, null);
147 setType(typeName);
148
149
150 addConstraint(UNIQUE, Boolean.class, new OrOperation());
151 addConstraint(NULLABLE, Boolean.class, new AndOperation());
152 addConstraint(MIN_COUNT, Expression.class, null);
153 addConstraint(MAX_COUNT, Expression.class, null);
154 addConstraint(CONTAINER, String.class, null);
155
156
157 addConfig(COUNT, Expression.class);
158 addConfig(COUNT_GRANULARITY, Expression.class);
159 addConfig(COUNT_DISTRIBUTION, String.class);
160 addConfig(NULL_QUOTA, Double.class);
161 addConfig(MODE, Mode.class);
162 }
163
164
165
166
167
168
169
170
171 public void setParent(InstanceDescriptor parent) {
172 this.parent = parent;
173 }
174
175 @Override
176 public String getName() {
177 String result = super.getName();
178 return (result != null ? result : getType());
179 }
180
181
182
183
184
185
186 public String getType() {
187 String type = (String) getDetailValue(TYPE);
188 return (type == null && parent != null ? parent.getType() : type);
189 }
190
191
192
193
194
195
196 public void setType(String type) {
197 setDetailValue(TYPE, type);
198 }
199
200
201
202
203
204
205 public TypeDescriptor getTypeDescriptor() {
206 if (getLocalType() != null) {
207 return getLocalType();
208 }
209 TypeDescriptor type = null;
210 if (getType() != null) {
211 type = getDataModel().getTypeDescriptor(getType());
212 }
213 return type;
214 }
215
216
217
218
219
220
221 public TypeDescriptor getLocalType() {
222 if (localType == null && parent != null &&
223 parent.getLocalType() != null) {
224 localType = getLocalType(
225 parent.getLocalType() instanceof ComplexTypeDescriptor);
226 }
227 return localType;
228 }
229
230
231
232
233
234
235 public void setLocalType(TypeDescriptor localType) {
236 this.localType = localType;
237 if (localType != null) {
238 setType(null);
239 }
240 }
241
242
243
244
245
246
247
248 public TypeDescriptor getLocalType(boolean complexType) {
249 if (localType != null) {
250 return localType;
251 }
252 if (complexType) {
253 localType =
254 new ComplexTypeDescriptor(getName(), provider, getType());
255 } else {
256 localType =
257 new SimpleTypeDescriptor(getName(), provider, getType());
258 }
259 setType(null);
260 return localType;
261 }
262
263
264
265
266
267
268 public Boolean isUnique() {
269 return (Boolean) getDetailValue(UNIQUE);
270 }
271
272
273
274
275
276
277 public void setUnique(Boolean unique) {
278 setDetailValue(UNIQUE, unique);
279 }
280
281
282
283
284
285
286 public Uniqueness getUniqueness() {
287 Boolean unique = isUnique();
288 return (unique != null ?
289 (unique ? Uniqueness.SIMPLE : Uniqueness.NONE) : null);
290 }
291
292
293
294
295
296
297 public Boolean isNullable() {
298 Boolean value = (Boolean) super.getDetailValue(NULLABLE);
299 if (value == null && parent != null) {
300 FeatureDetail<?> detail = parent.getConfiguredDetail(NULLABLE);
301 if (detail.getValue() != null && !(Boolean) detail.getValue()) {
302 value = (Boolean) detail.getValue();
303 }
304 }
305 return value;
306 }
307
308
309
310
311
312
313 public void setNullable(Boolean nullable) {
314 setDetailValue(NULLABLE, nullable);
315 }
316
317
318
319
320
321
322 @SuppressWarnings("unchecked")
323 public Expression<Long> getMinCount() {
324 return (Expression<Long>) getDetailValue(MIN_COUNT);
325 }
326
327
328
329
330
331
332 public void setMinCount(Expression<Long> minCount) {
333 setDetailValue(MIN_COUNT, minCount);
334 }
335
336
337
338
339
340
341 @SuppressWarnings("unchecked")
342 public Expression<Long> getMaxCount() {
343 return (Expression<Long>) getDetailValue(MAX_COUNT);
344 }
345
346
347
348
349
350
351 public void setMaxCount(Expression<Long> maxCount) {
352 setDetailValue(MAX_COUNT, maxCount);
353 }
354
355
356
357
358
359
360 public String getContainer() {
361 return (String) getDetailValue(CONTAINER);
362 }
363
364
365
366
367
368
369 public void setContainer(String container) {
370 setDetailValue(CONTAINER, container);
371 }
372
373
374
375
376
377
378 @SuppressWarnings("unchecked")
379 public Expression<Long> getCount() {
380 return (Expression<Long>) getDetailValue(COUNT);
381 }
382
383
384
385
386
387
388 public void setCount(Expression<Long> count) {
389 setDetailValue(COUNT, count);
390 }
391
392
393
394
395
396
397 public String getCountDistribution() {
398 return (String) getDetailValue(COUNT_DISTRIBUTION);
399 }
400
401
402
403
404
405
406 public void setCountDistribution(String distribution) {
407 setDetailValue(COUNT_DISTRIBUTION, distribution);
408 }
409
410
411
412
413
414
415 @SuppressWarnings("unchecked")
416 public Expression<Long> getCountGranularity() {
417 return (Expression<Long>) getDetailValue(COUNT_GRANULARITY);
418 }
419
420
421
422
423
424
425 public void setCountGranularity(Expression<Long> distribution) {
426 setDetailValue(COUNT_GRANULARITY, distribution);
427 }
428
429
430
431
432
433
434 public Double getNullQuota() {
435 return (Double) getDetailValue(NULL_QUOTA);
436 }
437
438
439
440
441
442
443 public void setNullQuota(Double nullQuota) {
444 setDetailValue(NULL_QUOTA, nullQuota);
445 }
446
447
448
449
450
451
452 public Mode getMode() {
453 return (Mode) getDetailValue(MODE);
454 }
455
456
457
458
459
460
461 public void setMode(Mode mode) {
462 setDetailValue(MODE, mode);
463 }
464
465 @Override
466 public Object getDetailValue(String name) {
467 Object value = super.getDetailValue(name);
468 if (value == null && parent != null && parent.supportsDetail(name)) {
469 FeatureDetail<?> detail = parent.getConfiguredDetail(name);
470 if (detail.isConstraint()) {
471 value = detail.getValue();
472 }
473 }
474 return value;
475 }
476
477 @Override
478 public void setDetailValue(String detailName, Object detailValue) {
479 if (COUNT.equals(detailName) || MIN_COUNT.equals(detailName) ||
480 MAX_COUNT.equals(detailName) ||
481 COUNT_GRANULARITY.equals(detailName)) {
482 FeatureDetail<Object> detail = getConfiguredDetail(detailName);
483 if (detail == null) {
484 throw new UnsupportedOperationException(
485 getClass().getSimpleName() +
486 " does not support detail type: " + detailName);
487 }
488 if (detailValue instanceof Expression) {
489 detail.setValue(new TypeConvertingExpression<>(
490 (Expression<?>) detailValue, Long.class));
491 } else if (detailValue == null) {
492 detail.setValue(null);
493 } else if (detailValue instanceof String) {
494 detail.setValue(new TypeConvertingExpression<>(
495 new ScriptExpression<>((String) detailValue),
496 Long.class));
497 } else {
498 detail.setValue(new TypeConvertingExpression<>(
499 new ConstantExpression<>(detailValue), Long.class));
500 }
501 } else {
502 super.setDetailValue(detailName, detailValue);
503 }
504 }
505
506
507
508
509
510
511
512
513
514 public InstanceDescriptor withCount(long count) {
515 setCount(new ConstantExpression<>(count));
516 return this;
517 }
518
519
520
521
522
523
524
525 public InstanceDescriptor withMinCount(long minCount) {
526 setMinCount(new ConstantExpression<>(minCount));
527 return this;
528 }
529
530
531
532
533
534
535
536 public InstanceDescriptor withMaxCount(long maxCount) {
537 setMaxCount(new ConstantExpression<>(maxCount));
538 return this;
539 }
540
541
542
543
544
545
546
547 public InstanceDescriptor withNullQuota(double nullQuota) {
548 setNullQuota(nullQuota);
549 return this;
550 }
551
552
553
554
555
556
557
558 public InstanceDescriptor withUnique(boolean unique) {
559 setUnique(unique);
560 return this;
561 }
562
563
564
565
566
567
568 public boolean overwritesParent() {
569 return parent != null;
570 }
571
572 @Override
573 public String toString() {
574 return getName() + "[details=" + renderDetails() + ", type=" +
575 getTypeDescriptor() + "]";
576 }
577
578 }