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