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 }