1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import org.apache.commons.lang.ClassUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.rice.core.api.uif.DataType;
21 import org.kuali.rice.core.api.util.ClassLoaderUtils;
22 import org.kuali.rice.core.web.format.Formatter;
23 import org.kuali.rice.krad.datadictionary.control.ControlDefinition;
24 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
25 import org.kuali.rice.krad.datadictionary.exception.ClassValidationException;
26 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
27 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
28 import org.kuali.rice.krad.datadictionary.validation.ValidationPattern;
29 import org.kuali.rice.krad.datadictionary.validation.capability.CaseConstrainable;
30 import org.kuali.rice.krad.datadictionary.validation.capability.Formatable;
31 import org.kuali.rice.krad.datadictionary.validation.capability.HierarchicallyConstrainable;
32 import org.kuali.rice.krad.datadictionary.validation.capability.MustOccurConstrainable;
33 import org.kuali.rice.krad.datadictionary.validation.capability.PrerequisiteConstrainable;
34 import org.kuali.rice.krad.datadictionary.validation.capability.ValidCharactersConstrainable;
35 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
36 import org.kuali.rice.krad.datadictionary.validation.constraint.LookupConstraint;
37 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
38 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
39 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
40 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
41 import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
42 import org.kuali.rice.krad.uif.control.Control;
43 import org.kuali.rice.krad.util.ObjectUtils;
44
45 import java.beans.PropertyEditor;
46 import java.util.List;
47
48
49
50
51
52
53
54
55 @BeanTag(name = "attributeDefinition")
56 public class AttributeDefinition extends AttributeDefinitionBase implements CaseConstrainable, PrerequisiteConstrainable, Formatable, HierarchicallyConstrainable, MustOccurConstrainable, ValidCharactersConstrainable {
57 private static final long serialVersionUID = -2490613377818442742L;
58
59 protected Boolean forceUppercase = Boolean.FALSE;
60
61 protected DataType dataType;
62
63 protected Boolean unique;
64
65
66 @Deprecated
67 protected ValidationPattern validationPattern;
68
69 protected ControlDefinition control;
70
71
72 protected Control controlField;
73
74 protected String formatterClass;
75 protected PropertyEditor propertyEditor;
76
77 protected AttributeSecurity attributeSecurity;
78
79 protected Boolean dynamic;
80
81
82 protected String customValidatorClass;
83 protected ValidCharactersConstraint validCharactersConstraint;
84 protected CaseConstraint caseConstraint;
85 protected List<PrerequisiteConstraint> dependencyConstraints;
86 protected List<MustOccurConstraint> mustOccurConstraints;
87
88 protected LookupConstraint lookupDefinition;
89 protected String lookupContextPath;
90
91
92 protected String childEntryName;
93
94 private KeyValuesFinder optionsFinder;
95
96 protected String alternateDisplayAttributeName;
97 protected String additionalDisplayAttributeName;
98
99 public AttributeDefinition() {
100 super();
101 }
102
103
104
105
106
107
108 public void setForceUppercase(Boolean forceUppercase) {
109 this.forceUppercase = forceUppercase;
110 }
111
112
113
114
115
116
117
118
119
120
121
122 @BeanTagAttribute(name = "forceUppercase")
123 public Boolean getForceUppercase() {
124 return this.forceUppercase;
125 }
126
127
128
129
130 @BeanTagAttribute(name = "maxLength")
131 public Integer getMaxLength() {
132 return this.getSimpleConstraint().getMaxLength();
133 }
134
135
136
137
138
139
140 public void setMaxLength(Integer maxLength) {
141 this.getSimpleConstraint().setMaxLength(maxLength);
142 }
143
144
145
146
147 @BeanTagAttribute(name = "exclusiveMin")
148 public String getExclusiveMin() {
149 return this.getSimpleConstraint().getExclusiveMin();
150 }
151
152
153
154
155
156
157 public void setExclusiveMin(String exclusiveMin) {
158 this.getSimpleConstraint().setExclusiveMin(exclusiveMin);
159 }
160
161
162
163
164 @BeanTagAttribute(name = "inclusiveMax")
165 public String getInclusiveMax() {
166 return this.getSimpleConstraint().getInclusiveMax();
167 }
168
169
170
171
172
173
174 public void setInclusiveMax(String inclusiveMax) {
175 this.getSimpleConstraint().setInclusiveMax(inclusiveMax);
176 }
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 public void setValidationPattern(ValidationPattern validationPattern) {
216 this.validationPattern = validationPattern;
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 public ValidationPattern getValidationPattern() {
260 return this.validationPattern;
261 }
262
263
264
265
266 @BeanTagAttribute(name = "oldControl", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
267 public ControlDefinition getControl() {
268 return control;
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310 public void setControl(ControlDefinition control) {
311 if (control == null) {
312 throw new IllegalArgumentException("invalid (null) control");
313 }
314 this.control = control;
315 }
316
317 public boolean hasFormatterClass() {
318 return (formatterClass != null);
319 }
320
321 @Override
322 @BeanTagAttribute(name = "formatterClass")
323 public String getFormatterClass() {
324 return formatterClass;
325 }
326
327
328
329
330
331
332
333
334 public void setFormatterClass(String formatterClass) {
335 if (formatterClass == null) {
336 throw new IllegalArgumentException("invalid (null) formatterClass");
337 }
338 this.formatterClass = formatterClass;
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352
353 @BeanTagAttribute(name = "propertyEditor", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
354 public PropertyEditor getPropertyEditor() {
355 return propertyEditor;
356 }
357
358
359
360
361
362
363 public void setPropertyEditor(PropertyEditor propertyEditor) {
364 this.propertyEditor = propertyEditor;
365 }
366
367
368
369
370
371
372 public void setPropertyEditorClass(Class<? extends PropertyEditor> propertyEditorClass) {
373 this.propertyEditor = ObjectUtils.newInstance(propertyEditorClass);
374 }
375
376
377
378
379
380
381
382 @Override
383 @Deprecated
384 public void completeValidation(Class<?> rootObjectClass, Class<?> otherObjectClass) {
385 try {
386 if (!DataDictionary.isPropertyOf(rootObjectClass, getName())) {
387 throw new AttributeValidationException("property '"
388 + getName()
389 + "' is not a property of class '"
390 + rootObjectClass.getName()
391 + "' ("
392 + ""
393 + ")");
394 }
395
396
397 if (getControl() == null && getControlField() == null) {
398 throw new AttributeValidationException("property '"
399 + getName()
400 + "' in class '"
401 + rootObjectClass.getName()
402 + " does not have a control defined");
403 }
404
405 if (getControl() != null) {
406 getControl().completeValidation(rootObjectClass, otherObjectClass);
407 }
408
409 if (attributeSecurity != null) {
410 attributeSecurity.completeValidation(rootObjectClass, otherObjectClass);
411 }
412
413 if (validationPattern != null) {
414 validationPattern.completeValidation();
415 }
416
417 if (formatterClass != null) {
418 try {
419 Class formatterClassObject = ClassUtils.getClass(ClassLoaderUtils.getDefaultClassLoader(),
420 getFormatterClass());
421 if (!Formatter.class.isAssignableFrom(formatterClassObject)) {
422 throw new ClassValidationException("formatterClass is not a valid instance of "
423 + Formatter.class.getName()
424 + " instead was: "
425 + formatterClassObject.getName());
426 }
427 } catch (ClassNotFoundException e) {
428 throw new ClassValidationException("formatterClass could not be found: " + getFormatterClass(), e);
429 }
430 }
431 } catch (RuntimeException ex) {
432 Logger.getLogger(getClass()).error(
433 "Unable to validate attribute " + rootObjectClass + "." + getName() + ": " + ex.getMessage(), ex);
434 throw ex;
435 }
436 }
437
438
439
440
441
442
443
444 public void completeValidation(Class rootObjectClass, Class otherObjectClass, ValidationTrace tracer) {
445 tracer.addBean(this.getClass().getSimpleName(), "Attribute: " + getName());
446 try {
447 if (!DataDictionary.isPropertyOf(rootObjectClass, getName())) {
448 String currentValues[] = {"property = " + getName(), "class = " + rootObjectClass.getName()};
449 tracer.createError("Property is not found in class", currentValues);
450 }
451
452
453 if (getControl() == null && getControlField() == null) {
454 String currentValues[] = {"property = " + getName(), "class = " + rootObjectClass.getName()};
455 tracer.createError("Property does not have a control defined in the class", currentValues);
456 }
457
458 if (getControl() != null) {
459
460 }
461
462 if (attributeSecurity != null) {
463 attributeSecurity.completeValidation(rootObjectClass, otherObjectClass, tracer.getCopy());
464 }
465
466 if (validationPattern != null) {
467
468 }
469
470 if (formatterClass != null) {
471 try {
472 Class formatterClassObject = ClassUtils.getClass(ClassLoaderUtils.getDefaultClassLoader(),
473 getFormatterClass());
474 if (!Formatter.class.isAssignableFrom(formatterClassObject)) {
475 String currentValues[] = {"formatterClassObject = " + formatterClassObject.getName()};
476 tracer.createError("FormatterClass is not a valid instance", currentValues);
477 }
478 } catch (ClassNotFoundException e) {
479 String currentValues[] = {"class = " + getFormatterClass()};
480 tracer.createError("FormatterClass could not be found", currentValues);
481 }
482 }
483 } catch (RuntimeException ex) {
484 String currentValues[] =
485 {"attribute = " + rootObjectClass + "." + getName(), "Exception = " + ex.getMessage()};
486 tracer.createError("Unable to validate attribute", currentValues);
487 }
488 }
489
490
491
492
493 @Override
494 public String toString() {
495 return "AttributeDefinition for attribute " + getName();
496 }
497
498
499
500
501 @BeanTagAttribute(name = "attributeSecurity", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
502 public AttributeSecurity getAttributeSecurity() {
503 return this.attributeSecurity;
504 }
505
506
507
508
509 public void setAttributeSecurity(AttributeSecurity attributeSecurity) {
510 this.attributeSecurity = attributeSecurity;
511 }
512
513
514
515
516 public Boolean getUnique() {
517 return this.unique;
518 }
519
520
521
522
523 public void setUnique(Boolean unique) {
524 this.unique = unique;
525 }
526
527
528
529
530
531
532
533
534 @BeanTagAttribute(name = "control", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
535 public Control getControlField() {
536 return this.controlField;
537 }
538
539
540
541
542
543
544 public void setControlField(Control controlField) {
545 this.controlField = controlField;
546 }
547
548
549
550
551 @BeanTagAttribute(name = "minLength")
552 public Integer getMinLength() {
553 return this.getSimpleConstraint().getMinLength();
554 }
555
556
557
558
559
560
561 public void setMinLength(Integer minLength) {
562 this.getSimpleConstraint().setMinLength(minLength);
563 }
564
565
566
567
568 @BeanTagAttribute(name = "dataType", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
569 public DataType getDataType() {
570 return simpleConstraint.getDataType();
571 }
572
573
574
575
576 public void setDataType(DataType dataType) {
577 simpleConstraint.setDataType(dataType);
578 }
579
580 public void setDataType(String dataType) {
581 simpleConstraint.setDataType(DataType.valueOf(dataType));
582 }
583
584
585
586
587 @BeanTagAttribute(name = "customValidatorClass")
588 public String getCustomValidatorClass() {
589 return this.customValidatorClass;
590 }
591
592
593
594
595 public void setCustomValidatorClass(String customValidatorClass) {
596 this.customValidatorClass = customValidatorClass;
597 }
598
599
600
601
602 @Override
603 @BeanTagAttribute(name = "validChractersConstraint", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
604 public ValidCharactersConstraint getValidCharactersConstraint() {
605 return this.validCharactersConstraint;
606 }
607
608
609
610
611 public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
612 this.validCharactersConstraint = validCharactersConstraint;
613 }
614
615
616
617
618 @Override
619 @BeanTagAttribute(name = "caseConstraint", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
620 public CaseConstraint getCaseConstraint() {
621 return this.caseConstraint;
622 }
623
624
625
626
627 public void setCaseConstraint(CaseConstraint caseConstraint) {
628 this.caseConstraint = caseConstraint;
629 }
630
631
632
633
634 @Override
635 @BeanTagAttribute(name = "prerequisteConstraint", type = BeanTagAttribute.AttributeType.LISTBEAN)
636 public List<PrerequisiteConstraint> getPrerequisiteConstraints() {
637 return this.dependencyConstraints;
638 }
639
640
641
642
643 public void setPrerequisiteConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
644 this.dependencyConstraints = dependencyConstraints;
645 }
646
647
648
649
650 @Override
651 @BeanTagAttribute(name = "mustOccurConstraints", type = BeanTagAttribute.AttributeType.LISTBEAN)
652 public List<MustOccurConstraint> getMustOccurConstraints() {
653 return this.mustOccurConstraints;
654 }
655
656
657
658
659 public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
660 this.mustOccurConstraints = mustOccurConstraints;
661 }
662
663
664
665
666 public LookupConstraint getLookupDefinition() {
667 return this.lookupDefinition;
668 }
669
670
671
672
673 public void setLookupDefinition(LookupConstraint lookupDefinition) {
674 this.lookupDefinition = lookupDefinition;
675 }
676
677
678
679
680 public String getLookupContextPath() {
681 return this.lookupContextPath;
682 }
683
684
685
686
687 public void setLookupContextPath(String lookupContextPath) {
688 this.lookupContextPath = lookupContextPath;
689 }
690
691
692
693
694 @BeanTagAttribute(name = "childEntryName")
695 public String getChildEntryName() {
696 return this.childEntryName;
697 }
698
699
700
701
702 public void setChildEntryName(String childEntryName) {
703 this.childEntryName = childEntryName;
704 }
705
706
707
708
709
710
711
712
713
714 @BeanTagAttribute(name = "optionFinder", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
715 public KeyValuesFinder getOptionsFinder() {
716 return this.optionsFinder;
717 }
718
719
720
721
722
723
724 public void setOptionsFinder(KeyValuesFinder optionsFinder) {
725 this.optionsFinder = optionsFinder;
726 }
727
728
729
730
731
732
733
734 public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
735 this.optionsFinder = ObjectUtils.newInstance(optionsFinderClass);
736 }
737
738 public void setAdditionalDisplayAttributeName(String additionalDisplayAttributeName) {
739 this.additionalDisplayAttributeName = additionalDisplayAttributeName;
740 }
741
742 @BeanTagAttribute(name = "additionalDisplayAttributeName")
743 public String getAdditionalDisplayAttributeName() {
744 return this.additionalDisplayAttributeName;
745 }
746
747 public void setAlternateDisplayAttributeName(String alternateDisplayAttributeName) {
748 this.alternateDisplayAttributeName = alternateDisplayAttributeName;
749 }
750
751 @BeanTagAttribute(name = "alternateDisplayAttributeName")
752 public String getAlternateDisplayAttributeName() {
753 return this.alternateDisplayAttributeName;
754 }
755
756
757
758
759
760
761 public List<PrerequisiteConstraint> getDependencyConstraints() {
762 return dependencyConstraints;
763 }
764
765
766
767
768
769
770 public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
771 this.dependencyConstraints = dependencyConstraints;
772 }
773
774 }