1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.field;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.uif.DataType;
20 import org.kuali.rice.core.api.util.ConcreteKeyValue;
21 import org.kuali.rice.core.api.util.KeyValue;
22 import org.kuali.rice.core.api.util.type.TypeUtils;
23 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
24 import org.kuali.rice.krad.datadictionary.state.StateMapping;
25 import org.kuali.rice.krad.datadictionary.validation.capability.CaseConstrainable;
26 import org.kuali.rice.krad.datadictionary.validation.capability.MustOccurConstrainable;
27 import org.kuali.rice.krad.datadictionary.validation.capability.PrerequisiteConstrainable;
28 import org.kuali.rice.krad.datadictionary.validation.capability.SimpleConstrainable;
29 import org.kuali.rice.krad.datadictionary.validation.capability.ValidCharactersConstrainable;
30 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
31 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
32 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
33 import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
34 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
35 import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
36 import org.kuali.rice.krad.datadictionary.validator.ErrorReport;
37 import org.kuali.rice.krad.datadictionary.validator.RDValidator;
38 import org.kuali.rice.krad.datadictionary.validator.TracerToken;
39 import org.kuali.rice.krad.uif.UifConstants;
40 import org.kuali.rice.krad.uif.component.Component;
41 import org.kuali.rice.krad.uif.control.Control;
42 import org.kuali.rice.krad.uif.control.MultiValueControlBase;
43 import org.kuali.rice.krad.uif.control.TextControl;
44 import org.kuali.rice.krad.uif.control.UifKeyValuesFinder;
45 import org.kuali.rice.krad.uif.element.Label;
46 import org.kuali.rice.krad.uif.element.Message;
47 import org.kuali.rice.krad.uif.element.ValidationMessages;
48 import org.kuali.rice.krad.uif.util.ClientValidationUtils;
49 import org.kuali.rice.krad.uif.util.ComponentFactory;
50 import org.kuali.rice.krad.uif.util.ComponentUtils;
51 import org.kuali.rice.krad.uif.util.ConstraintStateUtils;
52 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
53 import org.kuali.rice.krad.uif.view.View;
54 import org.kuali.rice.krad.uif.view.ViewModel;
55 import org.kuali.rice.krad.uif.widget.QuickFinder;
56 import org.kuali.rice.krad.uif.widget.Suggest;
57 import org.kuali.rice.krad.util.ObjectUtils;
58
59 import java.util.ArrayList;
60 import java.util.List;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public class InputField extends DataField implements SimpleConstrainable, CaseConstrainable, PrerequisiteConstrainable, MustOccurConstrainable, ValidCharactersConstrainable {
81 private static final long serialVersionUID = -3703656713706343840L;
82
83
84 private String customValidatorClass;
85 private ValidCharactersConstraint validCharactersConstraint;
86 private CaseConstraint caseConstraint;
87 private List<PrerequisiteConstraint> dependencyConstraints;
88 private List<MustOccurConstraint> mustOccurConstraints;
89 private SimpleConstraint simpleConstraint;
90 private DataType dataType;
91
92
93 private Control control;
94 private KeyValuesFinder optionsFinder;
95
96 private boolean uppercaseValue;
97
98 private ValidationMessages validationMessages;
99
100
101 private String constraintText;
102 private String instructionalText;
103
104 private Message constraintMessage;
105 private Message instructionalMessage;
106
107 private AttributeQuery attributeQuery;
108
109
110 private QuickFinder quickfinder;
111 private Suggest suggest;
112
113 public InputField() {
114 super();
115
116 simpleConstraint = new SimpleConstraint();
117 }
118
119
120
121
122
123
124
125
126
127
128
129 @Override
130 public void performInitialization(View view, Object model) {
131 super.performInitialization(view, model);
132
133 if ((StringUtils.isNotBlank(constraintText) || (getPropertyExpression("constraintText") != null)) && (
134 constraintMessage
135 == null)) {
136 constraintMessage = ComponentFactory.getConstraintMessage();
137 view.assignComponentIds(constraintMessage);
138 }
139
140 if ((StringUtils.isNotBlank(instructionalText) || (getPropertyExpression("instructionalText") != null)) && (
141 instructionalMessage
142 == null)) {
143 instructionalMessage = ComponentFactory.getInstructionalMessage();
144 view.assignComponentIds(instructionalMessage);
145 }
146 }
147
148
149
150
151 @Override
152 public void performApplyModel(View view, Object model, Component parent) {
153 super.performApplyModel(view, model, parent);
154
155
156
157 if (StringUtils.isNotBlank(instructionalText) && StringUtils.isBlank(instructionalMessage.getMessageText())) {
158 instructionalMessage.setMessageText(instructionalText);
159 }
160
161
162 if (StringUtils.isNotBlank(constraintText) && StringUtils.isBlank(constraintMessage.getMessageText())) {
163 constraintMessage.setMessageText(constraintText);
164 }
165
166
167 List<KeyValue> fieldOptions = new ArrayList<KeyValue>();
168
169
170 if ((control != null) && control instanceof MultiValueControlBase) {
171 MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
172 if ((multiValueControl.getOptions() != null) && !multiValueControl.getOptions().isEmpty()) {
173 fieldOptions = multiValueControl.getOptions();
174 }
175 }
176
177
178 if (fieldOptions.isEmpty() && (optionsFinder != null)) {
179 if (optionsFinder instanceof UifKeyValuesFinder) {
180 fieldOptions = ((UifKeyValuesFinder) optionsFinder).getKeyValues((ViewModel) model);
181
182
183 if (((UifKeyValuesFinder) optionsFinder).isAddBlankOption()) {
184 fieldOptions.add(0, new ConcreteKeyValue("", ""));
185 }
186 } else {
187 fieldOptions = optionsFinder.getKeyValues();
188 }
189
190 if ((control != null) && control instanceof MultiValueControlBase) {
191 ((MultiValueControlBase) control).setOptions(fieldOptions);
192 }
193 }
194
195
196 if (isReadOnly()
197 && !fieldOptions.isEmpty()
198 && StringUtils.isBlank(getReadOnlyDisplayReplacement())
199 && StringUtils.isBlank(getReadOnlyDisplaySuffix())
200 && StringUtils.isBlank(getReadOnlyDisplayReplacementPropertyName())
201 && StringUtils.isBlank(getReadOnlyDisplaySuffixPropertyName())) {
202
203 Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
204
205
206 if ((fieldValue != null) && (TypeUtils.isSimpleType(fieldValue.getClass()))) {
207 for (KeyValue keyValue : fieldOptions) {
208 if (StringUtils.equals(fieldValue.toString(), keyValue.getKey())) {
209 setReadOnlyDisplayReplacement(keyValue.getValue());
210 break;
211 }
212 }
213 }
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229 @Override
230 public void performFinalize(View view, Object model, Component parent) {
231 super.performFinalize(view, model, parent);
232
233 setupIds();
234 this.addDataAttribute("role", "InputField");
235
236
237 if (isReadOnly() || getControl() == null) {
238 return;
239 }
240
241
242 adjustPrerequisiteConstraintBinding(dependencyConstraints);
243
244
245 adjustMustOccurConstraintBinding(mustOccurConstraints);
246
247
248 if (caseConstraint != null) {
249 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(caseConstraint.getPropertyName());
250 caseConstraint.setPropertyName(propertyName);
251 }
252
253 setupFieldQuery();
254
255
256
257 String path = view.getStateObjectBindingPath();
258 Object stateObject;
259
260 if (StringUtils.isNotBlank(path)) {
261 stateObject = ObjectPropertyUtils.getPropertyValue(model, path);
262 } else {
263 stateObject = model;
264 }
265 StateMapping stateMapping = view.getStateMapping();
266
267 if (stateMapping != null) {
268 String validationState = ConstraintStateUtils.getClientViewValidationState(model, view);
269 SimpleConstraint appliedSimpleConstraint = ConstraintStateUtils.getApplicableConstraint(
270 this.getSimpleConstraint(), validationState, stateMapping);
271
272 if (appliedSimpleConstraint != null
273 && appliedSimpleConstraint.getRequired() != null
274 && appliedSimpleConstraint.getRequired()) {
275 SimpleConstraint prevConstraint = ConstraintStateUtils.getApplicableConstraint(
276 this.getSimpleConstraint(), stateMapping.getCurrentState(stateObject), stateMapping);
277 if (prevConstraint == null || prevConstraint.getRequired() == null || !prevConstraint.getRequired()) {
278 this.getFieldLabel().getRequiredMessage().setMessageText("**");
279 }
280 }
281 }
282
283 ClientValidationUtils.processAndApplyConstraints(this, view, model);
284 }
285
286
287
288
289
290
291 protected void adjustMustOccurConstraintBinding(List<MustOccurConstraint> mustOccurConstraints) {
292 if (mustOccurConstraints != null) {
293 for (MustOccurConstraint mustOccurConstraint : mustOccurConstraints) {
294 adjustPrerequisiteConstraintBinding(mustOccurConstraint.getPrerequisiteConstraints());
295 adjustMustOccurConstraintBinding(mustOccurConstraint.getMustOccurConstraints());
296 }
297 }
298 }
299
300
301
302
303
304
305 protected void adjustPrerequisiteConstraintBinding(List<PrerequisiteConstraint> prerequisiteConstraints) {
306 if (prerequisiteConstraints != null) {
307 for (PrerequisiteConstraint prerequisiteConstraint : prerequisiteConstraints) {
308 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(
309 prerequisiteConstraint.getPropertyName());
310 prerequisiteConstraint.setPropertyName(propertyName);
311 }
312 }
313 }
314
315
316
317
318
319
320 protected void setupFieldQuery() {
321 if (getAttributeQuery() != null) {
322
323 getAttributeQuery().updateQueryFieldMapping(getBindingInfo());
324 getAttributeQuery().updateReturnFieldMapping(getBindingInfo());
325 getAttributeQuery().updateQueryMethodArgumentFieldList(getBindingInfo());
326
327
328 String script = "executeFieldQuery('" + getControl().getId() + "',";
329 script += "'" + getId() + "'," + getAttributeQuery().getQueryFieldMappingJsString() + ",";
330 script += getAttributeQuery().getQueryMethodArgumentFieldsJsString() + ",";
331 script += getAttributeQuery().getReturnFieldMappingJsString() + ");";
332
333 if (StringUtils.isNotBlank(getControl().getOnBlurScript())) {
334 script = getControl().getOnBlurScript() + script;
335 }
336 getControl().setOnBlurScript(script);
337 }
338 }
339
340
341
342
343
344
345 protected void setupIds() {
346
347
348 setNestedComponentIdAndSuffix(getControl(), UifConstants.IdSuffixes.CONTROL);
349 setNestedComponentIdAndSuffix(getValidationMessages(), UifConstants.IdSuffixes.ERRORS);
350 setNestedComponentIdAndSuffix(getFieldLabel(), UifConstants.IdSuffixes.LABEL);
351 setNestedComponentIdAndSuffix(getInstructionalMessage(), UifConstants.IdSuffixes.INSTRUCTIONAL);
352 setNestedComponentIdAndSuffix(getConstraintMessage(), UifConstants.IdSuffixes.CONSTRAINT);
353 setNestedComponentIdAndSuffix(getQuickfinder(), UifConstants.IdSuffixes.QUICK_FINDER);
354 setNestedComponentIdAndSuffix(getSuggest(), UifConstants.IdSuffixes.SUGGEST);
355
356 if (this.getFieldLabel() != null) {
357 this.getFieldLabel().setLabelForComponentId(this.getControl().getId());
358 }
359
360 if (this.getControl() != null) {
361 this.getControl().addDataAttribute(UifConstants.DATA_ATTRIBUTE_CONTROL_FOR, this.getId());
362 }
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376 @Override
377 public void copyFromAttributeDefinition(View view, AttributeDefinition attributeDefinition) {
378 super.copyFromAttributeDefinition(view, attributeDefinition);
379
380
381 if (getMaxLength() == null) {
382 setMaxLength(attributeDefinition.getMaxLength());
383 }
384
385
386 if (getMinLength() == null) {
387 setMinLength(attributeDefinition.getMinLength());
388 }
389
390
391 if (getValidCharactersConstraint() == null) {
392 setValidCharactersConstraint(attributeDefinition.getValidCharactersConstraint());
393 }
394
395 if (getCaseConstraint() == null) {
396 setCaseConstraint(attributeDefinition.getCaseConstraint());
397 }
398
399 if (getDependencyConstraints() == null) {
400 setDependencyConstraints(attributeDefinition.getPrerequisiteConstraints());
401 }
402
403 if (getMustOccurConstraints() == null) {
404 setMustOccurConstraints(attributeDefinition.getMustOccurConstraints());
405 }
406
407
408 if (getRequired() == null) {
409 setRequired(attributeDefinition.isRequired());
410
411
412 if (getRequired() == null) {
413 setRequired(Boolean.FALSE);
414 }
415 }
416
417 if (getDataType() == null) {
418 setDataType(attributeDefinition.getDataType());
419
420 if (getDataType() == null
421 && control instanceof TextControl
422 && ((TextControl) control).getDatePicker() != null) {
423 setDataType(DataType.DATE);
424 }
425 }
426
427
428 if ((getControl() == null) && (attributeDefinition.getControlField() != null)) {
429 Control control = attributeDefinition.getControlField();
430 view.assignComponentIds(control);
431
432 setControl(ComponentUtils.copy(control));
433 }
434
435
436 if (StringUtils.isEmpty(getConstraintText())) {
437 setConstraintText(attributeDefinition.getConstraintText());
438
439 if (constraintMessage == null) {
440 constraintMessage = ComponentFactory.getConstraintMessage();
441 view.assignComponentIds(constraintMessage);
442 }
443 getConstraintMessage().setMessageText(attributeDefinition.getConstraintText());
444 }
445
446
447 if (getOptionsFinder() == null) {
448 setOptionsFinder(attributeDefinition.getOptionsFinder());
449 }
450
451
452
453 if (this.getSimpleConstraint().getConstraintStateOverrides() == null) {
454 this.getSimpleConstraint().setConstraintStateOverrides(
455 attributeDefinition.getSimpleConstraint().getConstraintStateOverrides());
456 }
457
458 if (this.getSimpleConstraint().getStates().isEmpty()) {
459 this.getSimpleConstraint().setStates(attributeDefinition.getSimpleConstraint().getStates());
460 }
461
462 if (this.getSimpleConstraint().getMessageKey() == null) {
463 this.getSimpleConstraint().setMessageKey(attributeDefinition.getSimpleConstraint().getMessageKey());
464 }
465
466 if (this.getSimpleConstraint().getApplyClientSide() == null) {
467 this.getSimpleConstraint().setApplyClientSide(
468 attributeDefinition.getSimpleConstraint().getApplyClientSide());
469 }
470
471 if (this.getSimpleConstraint().getValidationMessageParams() == null) {
472 this.getSimpleConstraint().setValidationMessageParams(
473 attributeDefinition.getSimpleConstraint().getValidationMessageParams());
474 }
475 }
476
477
478
479
480 @Override
481 public List<Component> getComponentsForLifecycle() {
482 List<Component> components = super.getComponentsForLifecycle();
483
484 components.add(instructionalMessage);
485 components.add(constraintMessage);
486 components.add(control);
487 components.add(validationMessages);
488 components.add(quickfinder);
489 components.add(suggest);
490
491 return components;
492 }
493
494
495
496
497 @Override
498 public boolean isInputAllowed() {
499 return true;
500 }
501
502
503
504
505
506
507
508
509
510
511
512
513
514 public Control getControl() {
515 return this.control;
516 }
517
518
519
520
521
522
523 public void setControl(Control control) {
524 this.control = control;
525 }
526
527
528
529
530
531
532
533
534 public ValidationMessages getValidationMessages() {
535 return this.validationMessages;
536 }
537
538
539
540
541
542
543 public void setValidationMessages(ValidationMessages validationMessages) {
544 this.validationMessages = validationMessages;
545 }
546
547
548
549
550
551
552
553
554
555 public KeyValuesFinder getOptionsFinder() {
556 return this.optionsFinder;
557 }
558
559
560
561
562
563
564 public void setOptionsFinder(KeyValuesFinder optionsFinder) {
565 this.optionsFinder = optionsFinder;
566 }
567
568
569
570
571
572
573
574 public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
575 this.optionsFinder = ObjectUtils.newInstance(optionsFinderClass);
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592 public QuickFinder getQuickfinder() {
593 return this.quickfinder;
594 }
595
596
597
598
599
600
601 public void setQuickfinder(QuickFinder quickfinder) {
602 this.quickfinder = quickfinder;
603 }
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620 public Suggest getSuggest() {
621 return suggest;
622 }
623
624
625
626
627
628
629 public void setSuggest(Suggest suggest) {
630 this.suggest = suggest;
631 }
632
633
634
635
636
637
638
639
640
641
642
643 public String getInstructionalText() {
644 return this.instructionalText;
645 }
646
647
648
649
650
651
652 public void setInstructionalText(String instructionalText) {
653 this.instructionalText = instructionalText;
654 }
655
656
657
658
659
660
661
662
663
664
665
666 public Message getInstructionalMessage() {
667 return this.instructionalMessage;
668 }
669
670
671
672
673
674
675
676
677
678
679
680 public void setInstructionalMessage(Message instructionalMessage) {
681 this.instructionalMessage = instructionalMessage;
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695 public String getConstraintText() {
696 return this.constraintText;
697 }
698
699
700
701
702
703
704 public void setConstraintText(String constraintText) {
705 this.constraintText = constraintText;
706 }
707
708
709
710
711
712
713
714
715
716
717
718 public Message getConstraintMessage() {
719 return this.constraintMessage;
720 }
721
722
723
724
725
726
727
728
729
730
731
732 public void setConstraintMessage(Message constraintMessage) {
733 this.constraintMessage = constraintMessage;
734 }
735
736
737
738
739
740
741 @Override
742 public ValidCharactersConstraint getValidCharactersConstraint() {
743 return this.validCharactersConstraint;
744 }
745
746
747
748
749
750
751 public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
752 this.validCharactersConstraint = validCharactersConstraint;
753 }
754
755
756
757
758
759
760 @Override
761 public CaseConstraint getCaseConstraint() {
762 return this.caseConstraint;
763 }
764
765
766
767
768
769
770 public void setCaseConstraint(CaseConstraint caseConstraint) {
771 this.caseConstraint = caseConstraint;
772 }
773
774
775
776
777
778
779 public List<PrerequisiteConstraint> getDependencyConstraints() {
780 return this.dependencyConstraints;
781 }
782
783
784
785
786
787
788 public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
789 this.dependencyConstraints = dependencyConstraints;
790 }
791
792
793
794
795
796
797 @Override
798 public List<MustOccurConstraint> getMustOccurConstraints() {
799 return this.mustOccurConstraints;
800 }
801
802
803
804
805
806
807 public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
808 this.mustOccurConstraints = mustOccurConstraints;
809 }
810
811
812
813
814
815
816
817
818
819
820
821 @Override
822 public SimpleConstraint getSimpleConstraint() {
823 return this.simpleConstraint;
824 }
825
826
827
828
829
830
831
832
833
834
835
836
837 public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
838 this.simpleConstraint = simpleConstraint;
839 }
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854 public Integer getMaxLength() {
855 return simpleConstraint.getMaxLength();
856 }
857
858
859
860
861
862
863 public void setMaxLength(Integer maxLength) {
864 simpleConstraint.setMaxLength(maxLength);
865 }
866
867
868
869
870
871
872
873
874
875
876
877
878
879 public Integer getMinLength() {
880 return simpleConstraint.getMinLength();
881 }
882
883
884
885
886
887
888 public void setMinLength(Integer minLength) {
889 simpleConstraint.setMinLength(minLength);
890 }
891
892
893
894
895 @Override
896 public Boolean getRequired() {
897 return this.simpleConstraint.getRequired();
898 }
899
900
901
902
903 @Override
904 public void setRequired(Boolean required) {
905 this.simpleConstraint.setRequired(required);
906 }
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922 public String getExclusiveMin() {
923 return simpleConstraint.getExclusiveMin();
924 }
925
926
927
928
929
930
931 public void setExclusiveMin(String exclusiveMin) {
932 simpleConstraint.setExclusiveMin(exclusiveMin);
933 }
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949 public String getInclusiveMax() {
950 return simpleConstraint.getInclusiveMax();
951 }
952
953
954
955
956
957
958 public void setInclusiveMax(String inclusiveMax) {
959 simpleConstraint.setInclusiveMax(inclusiveMax);
960 }
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976 public AttributeQuery getAttributeQuery() {
977 return attributeQuery;
978 }
979
980
981
982
983
984
985 public void setAttributeQuery(AttributeQuery attributeQuery) {
986 this.attributeQuery = attributeQuery;
987 }
988
989
990
991
992
993
994
995
996
997
998
999 public boolean isUppercaseValue() {
1000 return uppercaseValue;
1001 }
1002
1003
1004
1005
1006
1007
1008 public void setUppercaseValue(boolean uppercaseValue) {
1009 this.uppercaseValue = uppercaseValue;
1010 }
1011
1012
1013
1014
1015
1016
1017
1018 @Override
1019 public String getName() {
1020 return this.getBindingInfo().getBindingPath();
1021 }
1022
1023 @Override
1024 public List<PrerequisiteConstraint> getPrerequisiteConstraints() {
1025 return dependencyConstraints;
1026 }
1027
1028
1029
1030
1031
1032
1033
1034 public void setDataType(DataType dataType) {
1035 this.simpleConstraint.setDataType(dataType);
1036 }
1037
1038 public void setDataType(String dataType) {
1039 this.simpleConstraint.setDataType(DataType.valueOf(dataType));
1040 }
1041
1042
1043
1044
1045
1046
1047
1048
1049 public DataType getDataType() {
1050 return this.simpleConstraint.getDataType();
1051 }
1052
1053 @Override
1054 public boolean isRenderFieldset() {
1055 return super.isRenderFieldset() || (this.isInputAllowed()
1056 && quickfinder != null
1057 && quickfinder.isRender()
1058 && quickfinder.getQuickfinderAction() != null
1059 && quickfinder.getQuickfinderAction().isRender());
1060 }
1061
1062
1063
1064
1065 @Override
1066 public ArrayList<ErrorReport> completeValidation(TracerToken tracer) {
1067 ArrayList<ErrorReport> reports = new ArrayList<ErrorReport>();
1068 tracer.addBean(this);
1069
1070
1071 if (getControl() == null) {
1072 if (RDValidator.checkExpressions(this, "control")) {
1073 ErrorReport error = ErrorReport.createWarning("Control should be set",tracer);
1074 error.addCurrentValue("control =" + getConstraintText());
1075 reports.add(error);
1076 }
1077 }
1078
1079 reports.addAll(super.completeValidation(tracer.getCopy()));
1080
1081 return reports;
1082 }
1083 }