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 java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.kuali.rice.core.api.data.DataType;
25 import org.kuali.rice.core.api.util.ConcreteKeyValue;
26 import org.kuali.rice.core.api.util.KeyValue;
27 import org.kuali.rice.core.api.util.type.TypeUtils;
28 import org.kuali.rice.krad.bo.DataObjectRelationship;
29 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
30 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
31 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
32 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
33 import org.kuali.rice.krad.datadictionary.state.StateMapping;
34 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
35 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
36 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
37 import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
38 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
39 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
40 import org.kuali.rice.krad.datadictionary.validator.Validator;
41 import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
42 import org.kuali.rice.krad.service.DataDictionaryService;
43 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
44 import org.kuali.rice.krad.uif.CssConstants;
45 import org.kuali.rice.krad.uif.UifConstants;
46 import org.kuali.rice.krad.uif.UifPropertyPaths;
47 import org.kuali.rice.krad.uif.component.Component;
48 import org.kuali.rice.krad.uif.component.DelayedCopy;
49 import org.kuali.rice.krad.uif.control.Control;
50 import org.kuali.rice.krad.uif.control.MultiValueControlBase;
51 import org.kuali.rice.krad.uif.control.SelectControl;
52 import org.kuali.rice.krad.uif.control.TextAreaControl;
53 import org.kuali.rice.krad.uif.control.TextControl;
54 import org.kuali.rice.krad.uif.control.UifKeyValuesFinder;
55 import org.kuali.rice.krad.uif.element.Action;
56 import org.kuali.rice.krad.uif.element.FieldValidationMessages;
57 import org.kuali.rice.krad.uif.element.Label;
58 import org.kuali.rice.krad.uif.element.Link;
59 import org.kuali.rice.krad.uif.element.Message;
60 import org.kuali.rice.krad.uif.element.ValidationMessages;
61 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
62 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleRestriction;
63 import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
64 import org.kuali.rice.krad.uif.util.ClientValidationUtils;
65 import org.kuali.rice.krad.uif.util.ComponentFactory;
66 import org.kuali.rice.krad.uif.util.ComponentUtils;
67 import org.kuali.rice.krad.uif.util.ConstraintStateUtils;
68 import org.kuali.rice.krad.uif.util.ContextUtils;
69 import org.kuali.rice.krad.uif.util.LifecycleElement;
70 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
71 import org.kuali.rice.krad.uif.util.ViewModelUtils;
72 import org.kuali.rice.krad.uif.view.View;
73 import org.kuali.rice.krad.uif.view.ViewModel;
74 import org.kuali.rice.krad.uif.widget.QuickFinder;
75 import org.kuali.rice.krad.uif.widget.Suggest;
76 import org.kuali.rice.krad.util.KRADConstants;
77 import org.kuali.rice.krad.util.KRADUtils;
78 import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
79 import org.kuali.rice.krad.web.form.UifFormBase;
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 @BeanTags({@BeanTag(name = "input", parent = "Uif-InputField"),
100 @BeanTag(name = "inputLabelTop", parent = "Uif-InputField-LabelTop"),
101 @BeanTag(name = "inputLabelRight", parent = "Uif-InputField-LabelRight"),
102 @BeanTag(name = "checkboxInput", parent = "Uif-CheckboxInputField")})
103 public class InputFieldBase extends DataFieldBase implements InputField {
104 private static final long serialVersionUID = -3703656713706343840L;
105
106
107 private ValidCharactersConstraint validCharactersConstraint;
108 private CaseConstraint caseConstraint;
109 private List<PrerequisiteConstraint> dependencyConstraints;
110 private List<MustOccurConstraint> mustOccurConstraints;
111 private SimpleConstraint simpleConstraint;
112 private DataType dataType;
113
114
115 private Control control;
116
117 private boolean inlineEdit;
118 private boolean ajaxInlineEdit;
119
120 private KeyValuesFinder optionsFinder;
121
122 private boolean uppercaseValue;
123 private boolean disableNativeAutocomplete;
124
125 @DelayedCopy
126 private FieldValidationMessages validationMessages;
127
128
129 private String constraintText;
130 private String instructionalText;
131
132 private Message constraintMessage;
133 private Message instructionalMessage;
134
135 private String helperText;
136
137 private AttributeQuery attributeQuery;
138
139
140 private boolean enableAutoDirectInquiry;
141
142 private QuickFinder quickfinder;
143 private boolean enableAutoQuickfinder;
144
145 private Suggest suggest;
146
147 private boolean widgetInputOnly;
148
149 private boolean renderInputAddonGroup;
150 private List<String> postInputCssClasses;
151 private List<Component> postInputAddons;
152
153 public InputFieldBase() {
154 super();
155
156 simpleConstraint = new SimpleConstraint();
157
158 enableAutoDirectInquiry = true;
159 enableAutoQuickfinder = true;
160 }
161
162
163
164
165 @Override
166 public void performInitialization(Object model) {
167 super.performInitialization(model);
168
169 if ((StringUtils.isNotBlank(constraintText) || (getPropertyExpression("constraintText") != null)) && (
170 constraintMessage
171 == null)) {
172 constraintMessage = ComponentFactory.getConstraintMessage();
173 }
174
175 if ((StringUtils.isNotBlank(instructionalText) || (getPropertyExpression("instructionalText") != null)) && (
176 instructionalMessage
177 == null)) {
178 instructionalMessage = ComponentFactory.getInstructionalMessage();
179 }
180 }
181
182
183
184
185 @Override
186 public void afterEvaluateExpression() {
187
188
189 if (getReadOnly() == null) {
190 Component parent = ViewLifecycle.getPhase().getParent();
191 setReadOnly(parent == null ? null : parent.getReadOnly());
192 }
193
194 super.afterEvaluateExpression();
195 }
196
197
198
199
200 @Override
201 public void performApplyModel(Object model, LifecycleElement parent) {
202 super.performApplyModel(model, parent);
203
204
205
206 if (StringUtils.isNotBlank(instructionalText) && instructionalMessage != null && StringUtils.isBlank(
207 instructionalMessage.getMessageText())) {
208 instructionalMessage.setMessageText(instructionalText);
209 }
210
211
212 if (StringUtils.isNotBlank(constraintText) && constraintMessage != null && StringUtils.isBlank(
213 constraintMessage.getMessageText())) {
214 constraintMessage.setMessageText(constraintText);
215 }
216
217
218 List<KeyValue> fieldOptions = new ArrayList<KeyValue>();
219
220
221 if ((control != null) && control instanceof MultiValueControlBase) {
222 MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
223 if ((multiValueControl.getOptions() != null) && !multiValueControl.getOptions().isEmpty()) {
224 fieldOptions = multiValueControl.getOptions();
225 }
226 }
227
228
229 if (control instanceof TextAreaControl) {
230 setMultiLineReadOnlyDisplay(true);
231 }
232
233
234 if (fieldOptions.isEmpty() && (optionsFinder != null)) {
235 if (optionsFinder instanceof UifKeyValuesFinder) {
236 fieldOptions = ((UifKeyValuesFinder) optionsFinder).getKeyValues((ViewModel) model, this);
237
238
239 if (((UifKeyValuesFinder) optionsFinder).isAddBlankOption()) {
240 fieldOptions.add(0, new ConcreteKeyValue("", ""));
241 }
242 } else {
243 fieldOptions = optionsFinder.getKeyValues();
244 }
245
246 if ((control != null) && control instanceof MultiValueControlBase) {
247 ((MultiValueControlBase) control).setOptions(fieldOptions);
248 }
249 }
250
251 if (enableAutoDirectInquiry && this.getInquiry() == null && hasAutoInquiryRelationship()) {
252 setInquiry(ComponentFactory.getInquiry());
253 }
254
255 if (enableAutoQuickfinder && this.getQuickfinder() == null && hasAutoQuickfinderRelationship()) {
256 setQuickfinder(ComponentFactory.getQuickFinder());
257 ContextUtils.pushAllToContextDeep(quickfinder, this.getContext());
258 }
259
260
261 if (Boolean.TRUE.equals(getReadOnly())
262 && !fieldOptions.isEmpty()
263 && StringUtils.isBlank(getReadOnlyDisplayReplacement())
264 && StringUtils.isBlank(getReadOnlyDisplaySuffix())
265 && StringUtils.isBlank(getReadOnlyDisplayReplacementPropertyName())
266 && StringUtils.isBlank(getReadOnlyDisplaySuffixPropertyName())) {
267
268 Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
269
270
271 if ((fieldValue != null) && (TypeUtils.isSimpleType(fieldValue.getClass()))) {
272 for (KeyValue keyValue : fieldOptions) {
273 if (StringUtils.equals(fieldValue.toString(), keyValue.getKey())) {
274 setReadOnlyDisplayReplacement(keyValue.getValue());
275 break;
276 }
277 }
278 }
279 }
280
281 if(control != null && quickfinder != null && quickfinder.getQuickfinderAction() != null) {
282 String disabledExpression = control.getPropertyExpression("disabled");
283 if(StringUtils.isNotBlank(disabledExpression)) {
284 quickfinder.getQuickfinderAction().getPropertyExpressions().put("disabled", disabledExpression);
285 } else {
286 quickfinder.getQuickfinderAction().setDisabled(control.isDisabled());
287 }
288 }
289
290 }
291
292
293
294
295 @Override
296 public void performFinalize(Object model, LifecycleElement parent) {
297 super.performFinalize(model, parent);
298
299 setupIds();
300
301 this.addDataAttribute(UifConstants.DataAttributes.ROLE, UifConstants.RoleTypes.INPUT_FIELD);
302
303 boolean ajaxInlineEditRefresh = ajaxInlineEdit && ((UifFormBase)model).getUpdateComponentId() != null &&
304 ((UifFormBase)model).getUpdateComponentId().equals(this.getId());
305
306
307 if ((Boolean.TRUE.equals(getReadOnly()) && !inlineEdit && !ajaxInlineEditRefresh) || getControl() == null) {
308 return;
309 }
310
311 if (StringUtils.isNotBlank(helperText) && (getControl() != null)) {
312 getControl().getCssClasses().add(CssConstants.Classes.HAS_HELPER);
313 }
314
315 DataDictionaryService dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
316 if (this.getDictionaryObjectEntry() != null && this.getDictionaryAttributeName() != null) {
317 AttributeDefinition ad = dataDictionaryService.getAttributeDefinition(this.getDictionaryObjectEntry(),
318 this.getDictionaryAttributeName());
319
320 Map<String, String> propertyExpressions = this.getPropertyExpressions();
321
322 if (propertyExpressions.containsKey(UifPropertyPaths.DICTIONARY_ATTR_NAME)) {
323
324
325 copyFromAttributeDefinition(ad);
326 }
327
328 if (ad.getForceUppercase() || uppercaseValue) {
329 Object currentPropertyValue = ObjectPropertyUtils.getPropertyValue(model,
330 getBindingInfo().getBindingPath());
331 if (currentPropertyValue instanceof String) {
332 String uppercasedValue = ((String) currentPropertyValue).toUpperCase();
333 ObjectPropertyUtils.setPropertyValue(model, getBindingInfo().getBindingPath(), uppercasedValue);
334 }
335 }
336 }
337
338
339 if ((suggest != null) && suggest.isSuggestConfigured()) {
340 setDisableNativeAutocomplete(true);
341 }
342
343
344 adjustPrerequisiteConstraintBinding(dependencyConstraints);
345
346
347 adjustMustOccurConstraintBinding(mustOccurConstraints);
348
349
350 if (caseConstraint != null) {
351 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(caseConstraint.getPropertyName());
352 caseConstraint.setPropertyName(propertyName);
353 }
354
355 View view = ViewLifecycle.getView();
356
357 setupFieldQuery(view);
358
359
360
361 String path = view.getStateObjectBindingPath();
362 Object stateObject;
363
364 if (StringUtils.isNotBlank(path)) {
365 stateObject = ObjectPropertyUtils.getPropertyValue(model, path);
366 } else {
367 stateObject = model;
368 }
369 StateMapping stateMapping = view.getStateMapping();
370 String nextStateReqIndicator = (String) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryBean(
371 UifConstants.REQUIRED_NEXT_STATE_INDICATOR_ID);
372
373 if (stateMapping != null) {
374 String validationState = ConstraintStateUtils.getClientViewValidationState(model, view);
375 SimpleConstraint appliedSimpleConstraint = ConstraintStateUtils.getApplicableConstraint(
376 this.getSimpleConstraint(), validationState, stateMapping);
377
378 if (appliedSimpleConstraint != null
379 && appliedSimpleConstraint.getRequired() != null
380 && appliedSimpleConstraint.getRequired()) {
381 SimpleConstraint prevConstraint = ConstraintStateUtils.getApplicableConstraint(
382 this.getSimpleConstraint(), stateMapping.getCurrentState(stateObject), stateMapping);
383 if (prevConstraint == null || prevConstraint.getRequired() == null || !prevConstraint.getRequired()) {
384 this.getFieldLabel().setRequiredIndicator(nextStateReqIndicator);
385 }
386 }
387 }
388
389 ClientValidationUtils.processAndApplyConstraints(this, view, model);
390
391 if (inlineEdit || ajaxInlineEdit) {
392 this.addDataAttribute(UifConstants.DataAttributes.INLINE_EDIT, "true");
393 }
394
395
396 if (validationMessages != null) {
397
398 if (inlineEdit || ajaxInlineEdit) {
399 validationMessages.setUseTooltip(false);
400 }
401
402 validationMessages.generateMessages(view, model, this);
403 }
404
405 addComponentPostMetadata();
406
407 if (this.getHelp() != null && StringUtils.isNotBlank(this.getHelp().getExternalHelpUrl())) {
408 this.setRenderInputAddonGroup(true);
409 }
410 }
411
412
413
414
415 protected void addComponentPostMetadata() {
416 ViewPostMetadata viewPostMetadata = ViewLifecycle.getViewPostMetadata();
417
418 viewPostMetadata.getInputFieldIds().add(this.getId());
419
420 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.LABEL, this.getLabel());
421
422 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.PATH, this.getName());
423
424 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.SIMPLE_CONSTRAINT,
425 this.getSimpleConstraint());
426
427 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.VALID_CHARACTER_CONSTRAINT,
428 this.getValidCharactersConstraint());
429
430 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.CASE_CONSTRAINT, this.getCaseConstraint());
431
432 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.MUST_OCCUR_CONSTRAINTS,
433 this.getMustOccurConstraints());
434
435 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.PREREQ_CONSTSTRAINTS,
436 this.getPrerequisiteConstraints());
437
438 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.INPUT_FIELD_ATTRIBUTE_QUERY,
439 attributeQuery);
440
441 if (this.suggest != null) {
442 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.SUGGEST, this.suggest.getPostData());
443 }
444
445 viewPostMetadata.addComponentPostData(this, UifConstants.PostMetadata.INPUT_FIELD_IS_UPPERCASE,
446 isUppercaseValue());
447
448 if ((isRender() || StringUtils.isNotBlank(getProgressiveRender())) && !isHidden() && (!Boolean.TRUE.equals(
449 getReadOnly()) || inlineEdit || ajaxInlineEdit)) {
450 viewPostMetadata.addAccessibleBindingPath(getBindingInfo().getBindingPath());
451 }
452 }
453
454
455
456
457
458
459
460
461
462 @Override
463 protected void processReadOnlyListDisplay(Object model, List<?> originalList) {
464
465 if ((control != null) && control instanceof MultiValueControlBase) {
466 List<String> newList = new ArrayList<String>();
467 List<KeyValue> fieldOptions = ((MultiValueControlBase) control).getOptions();
468
469 if (fieldOptions == null || fieldOptions.isEmpty()) {
470 return;
471 }
472
473 for (Object fieldValue : originalList) {
474 for (KeyValue keyValue : fieldOptions) {
475 if (fieldValue != null && StringUtils.equals(fieldValue.toString(), keyValue.getKey())) {
476 newList.add(keyValue.getValue());
477 break;
478 }
479 }
480 }
481 this.setReadOnlyDisplayReplacement(super.generateReadOnlyListDisplayReplacement(newList));
482 } else {
483 this.setReadOnlyDisplayReplacement(super.generateReadOnlyListDisplayReplacement(originalList));
484 }
485 }
486
487
488
489
490
491
492
493 @Override
494 protected void setAlternateAndAdditionalDisplayValue(View view, Object model) {
495
496 if (StringUtils.isNotBlank(getReadOnlyDisplayReplacement()) || StringUtils.isNotBlank(
497 getReadOnlyDisplaySuffix())) {
498 return;
499 }
500
501 if (isApplyMask()) {
502 if ((this.quickfinder != null) && StringUtils.isNotBlank(this.quickfinder.getDataObjectClassName())) {
503 setWidgetInputOnly(true);
504 } else {
505 String maintenanceAction = null;
506 if (view.getViewTypeName().equals(UifConstants.ViewType.MAINTENANCE)) {
507 maintenanceAction =((MaintenanceDocumentForm) model).getMaintenanceAction();
508 }
509
510 if ((!view.getViewTypeName().equals(UifConstants.ViewType.LOOKUP)) &&
511 (!KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction))) {
512 setReadOnly(true);
513 }
514 }
515 }
516
517 super.setAlternateAndAdditionalDisplayValue(view, model);
518 }
519
520
521
522
523
524
525 protected void adjustMustOccurConstraintBinding(List<MustOccurConstraint> mustOccurConstraints) {
526 if (mustOccurConstraints != null) {
527 for (MustOccurConstraint mustOccurConstraint : mustOccurConstraints) {
528 adjustPrerequisiteConstraintBinding(mustOccurConstraint.getPrerequisiteConstraints());
529 adjustMustOccurConstraintBinding(mustOccurConstraint.getMustOccurConstraints());
530 }
531 }
532 }
533
534
535
536
537
538
539 protected void adjustPrerequisiteConstraintBinding(List<PrerequisiteConstraint> prerequisiteConstraints) {
540 if (prerequisiteConstraints != null) {
541 for (PrerequisiteConstraint prerequisiteConstraint : prerequisiteConstraints) {
542 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(
543 prerequisiteConstraint.getPropertyName());
544 prerequisiteConstraint.setPropertyName(propertyName);
545 }
546 }
547 }
548
549
550
551
552
553
554
555
556
557 protected void setupFieldQuery(View view) {
558 if (getAttributeQuery() != null) {
559 getAttributeQuery().defaultQueryTarget(view.getViewHelperService());
560
561
562 getAttributeQuery().updateQueryFieldMapping(getBindingInfo());
563 getAttributeQuery().updateReturnFieldMapping(getBindingInfo());
564 getAttributeQuery().updateQueryMethodArgumentFieldList(getBindingInfo());
565
566
567 String script = "executeFieldQuery('" + getControl().getId() + "',";
568 script += "'" + getId() + "'," + getAttributeQuery().getQueryFieldMappingJsString() + ",";
569 script += getAttributeQuery().getQueryMethodArgumentFieldsJsString() + ",";
570 script += getAttributeQuery().getReturnFieldMappingJsString() + ");";
571
572
573 this.setRenderInfoMessageSpan(true);
574
575 if (StringUtils.isNotBlank(getControl().getOnBlurScript())) {
576 script = getControl().getOnBlurScript() + script;
577 }
578 getControl().setOnBlurScript(script);
579 }
580 }
581
582
583
584
585
586
587 protected void setupIds() {
588
589
590 setNestedComponentIdAndSuffix(getControl(), UifConstants.IdSuffixes.CONTROL);
591 setNestedComponentIdAndSuffix(getFieldLabel(), UifConstants.IdSuffixes.LABEL);
592 setNestedComponentIdAndSuffix(getInstructionalMessage(), UifConstants.IdSuffixes.INSTRUCTIONAL);
593 setNestedComponentIdAndSuffix(getConstraintMessage(), UifConstants.IdSuffixes.CONSTRAINT);
594 setNestedComponentIdAndSuffix(getQuickfinder(), UifConstants.IdSuffixes.QUICK_FINDER);
595 setNestedComponentIdAndSuffix(getSuggest(), UifConstants.IdSuffixes.SUGGEST);
596
597 if (this.getControl() != null) {
598 this.getControl().addDataAttribute(UifConstants.DataAttributes.CONTROL_FOR, this.getId());
599 }
600 }
601
602
603
604
605 @Override
606 public void copyFromAttributeDefinition(AttributeDefinition attributeDefinition) {
607 super.copyFromAttributeDefinition(attributeDefinition);
608
609
610 if (getMaxLength() == null) {
611 setMaxLength(attributeDefinition.getMaxLength());
612 }
613
614
615 if (getMinLength() == null) {
616 setMinLength(attributeDefinition.getMinLength());
617 }
618
619
620 if (getValidCharactersConstraint() == null) {
621 setValidCharactersConstraint(attributeDefinition.getValidCharactersConstraint());
622 }
623
624 if (getCaseConstraint() == null) {
625 setCaseConstraint(attributeDefinition.getCaseConstraint());
626 }
627
628 if (getDependencyConstraints() == null) {
629 setDependencyConstraints(attributeDefinition.getPrerequisiteConstraints());
630 }
631
632 if (getMustOccurConstraints() == null) {
633 setMustOccurConstraints(attributeDefinition.getMustOccurConstraints());
634 }
635
636
637 if (getRequired() == null) {
638 setRequired(attributeDefinition.isRequired());
639
640
641 if (getRequired() == null) {
642 setRequired(Boolean.FALSE);
643 }
644 }
645
646 if (getDataType() == null) {
647 setDataType(attributeDefinition.getDataType());
648
649 if (getDataType() == null
650 && control instanceof TextControl
651 && ((TextControl) control).getDatePicker() != null) {
652 setDataType(DataType.DATE);
653 }
654 }
655
656
657 if ((getControl() == null) && (attributeDefinition.getControlField() != null)) {
658 Control control = ComponentUtils.copy(attributeDefinition.getControlField());
659 setControl(control);
660 }
661
662
663 if (StringUtils.isEmpty(getConstraintText())) {
664 setConstraintText(attributeDefinition.getConstraintText());
665
666 if (constraintMessage == null) {
667 constraintMessage = ComponentFactory.getConstraintMessage();
668 }
669
670 getConstraintMessage().setMessageText(attributeDefinition.getConstraintText());
671 }
672
673
674 if (getOptionsFinder() == null) {
675 setOptionsFinder(attributeDefinition.getOptionsFinder());
676 }
677
678
679
680 if (this.getSimpleConstraint().getConstraintStateOverrides() == null) {
681 this.getSimpleConstraint().setConstraintStateOverrides(
682 attributeDefinition.getSimpleConstraint().getConstraintStateOverrides());
683 }
684
685 if (this.getSimpleConstraint().getStates().isEmpty()) {
686 this.getSimpleConstraint().setStates(attributeDefinition.getSimpleConstraint().getStates());
687 }
688
689 if (this.getSimpleConstraint().getMessageKey() == null) {
690 this.getSimpleConstraint().setMessageKey(attributeDefinition.getSimpleConstraint().getMessageKey());
691 }
692
693 if (this.getSimpleConstraint().getApplyClientSide() == null) {
694 this.getSimpleConstraint().setApplyClientSide(
695 attributeDefinition.getSimpleConstraint().getApplyClientSide());
696 }
697
698 if (this.getSimpleConstraint().getValidationMessageParams() == null) {
699 this.getSimpleConstraint().setValidationMessageParams(
700 attributeDefinition.getSimpleConstraint().getValidationMessageParams());
701 }
702 }
703
704
705
706
707 @Override
708 public boolean isInputAllowed() {
709 return true;
710 }
711
712
713
714
715 @Override
716 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.BYTYPE)
717 public Control getControl() {
718 return this.control;
719 }
720
721
722
723
724 @Override
725 public void setControl(Control control) {
726 this.control = control;
727 }
728
729
730
731
732 @BeanTagAttribute
733 public boolean isInlineEdit() {
734 return inlineEdit;
735 }
736
737
738
739
740 public void setInlineEdit(boolean inlineEdit) {
741 this.inlineEdit = inlineEdit;
742 }
743
744
745
746
747 @BeanTagAttribute
748 public boolean isAjaxInlineEdit() {
749 return ajaxInlineEdit;
750 }
751
752
753
754
755 public void setAjaxInlineEdit(boolean ajaxInlineEdit) {
756 this.ajaxInlineEdit = ajaxInlineEdit;
757 }
758
759
760
761
762 @Override
763 @ViewLifecycleRestriction
764 @BeanTagAttribute
765 public FieldValidationMessages getValidationMessages() {
766 return this.validationMessages;
767 }
768
769
770
771
772 @Override
773 public void setValidationMessages(FieldValidationMessages validationMessages) {
774 this.validationMessages = validationMessages;
775 }
776
777
778
779
780 @Override
781 @BeanTagAttribute
782 public KeyValuesFinder getOptionsFinder() {
783 return this.optionsFinder;
784 }
785
786
787
788
789 @Override
790 public void setOptionsFinder(KeyValuesFinder optionsFinder) {
791 this.optionsFinder = optionsFinder;
792 }
793
794
795
796
797 @Override
798 @BeanTagAttribute
799 public Class<? extends KeyValuesFinder> getOptionsFinderClass() {
800 if (this.optionsFinder != null) {
801 return this.optionsFinder.getClass();
802 } else {
803 return null;
804 }
805 }
806
807
808
809
810 @Override
811 public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
812 this.optionsFinder = KRADUtils.createNewObjectFromClass(optionsFinderClass);
813 }
814
815
816
817
818 @Override
819 @BeanTagAttribute
820 public boolean isEnableAutoDirectInquiry() {
821 return enableAutoDirectInquiry;
822 }
823
824
825
826
827 @Override
828 public void setEnableAutoDirectInquiry(boolean enableAutoDirectInquiry) {
829 this.enableAutoDirectInquiry = enableAutoDirectInquiry;
830 }
831
832
833
834
835 @Override
836 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.DIRECTORBYTYPE)
837 public QuickFinder getQuickfinder() {
838 return this.quickfinder;
839 }
840
841
842
843
844 @Override
845 public void setQuickfinder(QuickFinder quickfinder) {
846 this.quickfinder = quickfinder;
847 }
848
849
850
851
852 @Override
853 @BeanTagAttribute
854 public boolean isEnableAutoQuickfinder() {
855 return enableAutoQuickfinder;
856 }
857
858
859
860
861 @Override
862 public void setEnableAutoQuickfinder(boolean enableAutoQuickfinder) {
863 this.enableAutoQuickfinder = enableAutoQuickfinder;
864 }
865
866
867
868
869 @Override
870 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.DIRECTORBYTYPE)
871 public Suggest getSuggest() {
872 return suggest;
873 }
874
875
876
877
878 @Override
879 public void setSuggest(Suggest suggest) {
880 this.suggest = suggest;
881 }
882
883
884
885
886 @Override
887 @BeanTagAttribute
888 public boolean isWidgetInputOnly() {
889 return this.widgetInputOnly;
890 }
891
892
893
894
895 @Override
896 public void setWidgetInputOnly(boolean widgetInputOnly) {
897 this.widgetInputOnly = widgetInputOnly;
898 }
899
900
901
902
903 @Override
904 @BeanTagAttribute
905 public boolean isRenderInputAddonGroup() {
906 return renderInputAddonGroup;
907 }
908
909
910
911
912 @Override
913 public void setRenderInputAddonGroup(boolean renderInputAddonGroup) {
914 this.renderInputAddonGroup = renderInputAddonGroup;
915 }
916
917
918
919
920 @Override
921 @BeanTagAttribute
922 public List<String> getPostInputCssClasses() {
923 return postInputCssClasses;
924 }
925
926
927
928
929 @Override
930 public String getPostInputCssClassesAsString() {
931 if (postInputCssClasses != null) {
932 return StringUtils.join(postInputCssClasses, " ");
933 }
934
935 return "";
936 }
937
938
939
940
941 @Override
942 public void setPostInputCssClasses(List<String> postInputCssClasses) {
943 this.postInputCssClasses = postInputCssClasses;
944 }
945
946
947
948
949 @Override
950 @BeanTagAttribute
951 public List<Component> getPostInputAddons() {
952 return postInputAddons;
953 }
954
955
956
957
958 @Override
959 public void setPostInputAddons(List<Component> postInputAddons) {
960 this.postInputAddons = postInputAddons;
961 }
962
963
964
965
966 @Override
967 public void addPostInputAddon(Component addOn) {
968 if (postInputAddons == null) {
969 postInputAddons = new ArrayList<Component>();
970 }
971
972 postInputAddons.add(addOn);
973 }
974
975
976
977
978 @Override
979 @BeanTagAttribute
980 public String getInstructionalText() {
981 return this.instructionalText;
982 }
983
984
985
986
987 @Override
988 public void setInstructionalText(String instructionalText) {
989 this.instructionalText = instructionalText;
990 }
991
992
993
994
995 @Override
996 @BeanTagAttribute
997 public Message getInstructionalMessage() {
998 return this.instructionalMessage;
999 }
1000
1001
1002
1003
1004 @Override
1005 public void setInstructionalMessage(Message instructionalMessage) {
1006 this.instructionalMessage = instructionalMessage;
1007 }
1008
1009
1010
1011
1012 @Override
1013 @BeanTagAttribute
1014 public String getHelperText() {
1015 return helperText;
1016 }
1017
1018
1019
1020
1021 @Override
1022 public void setHelperText(String helperText) {
1023 this.helperText = helperText;
1024 }
1025
1026
1027
1028
1029 @Override
1030 @BeanTagAttribute
1031 public String getConstraintText() {
1032 return this.constraintText;
1033 }
1034
1035
1036
1037
1038 @Override
1039 public void setConstraintText(String constraintText) {
1040 this.constraintText = constraintText;
1041 }
1042
1043
1044
1045
1046 @Override
1047 @BeanTagAttribute
1048 public Message getConstraintMessage() {
1049 return this.constraintMessage;
1050 }
1051
1052
1053
1054
1055 @Override
1056 public void setConstraintMessage(Message constraintMessage) {
1057 this.constraintMessage = constraintMessage;
1058 }
1059
1060
1061
1062
1063 @Override
1064 @BeanTagAttribute
1065 public ValidCharactersConstraint getValidCharactersConstraint() {
1066 return this.validCharactersConstraint;
1067 }
1068
1069
1070
1071
1072 @Override
1073 public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
1074 this.validCharactersConstraint = validCharactersConstraint;
1075 }
1076
1077
1078
1079
1080 @Override
1081 @BeanTagAttribute
1082 public CaseConstraint getCaseConstraint() {
1083 return this.caseConstraint;
1084 }
1085
1086
1087
1088
1089 @Override
1090 public void setCaseConstraint(CaseConstraint caseConstraint) {
1091 this.caseConstraint = caseConstraint;
1092 }
1093
1094
1095
1096
1097 @Override
1098 @BeanTagAttribute
1099 public List<PrerequisiteConstraint> getDependencyConstraints() {
1100 return this.dependencyConstraints;
1101 }
1102
1103
1104
1105
1106 @Override
1107 public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
1108 this.dependencyConstraints = dependencyConstraints;
1109 }
1110
1111
1112
1113
1114 @Override
1115 public List<PrerequisiteConstraint> getPrerequisiteConstraints() {
1116 return dependencyConstraints;
1117 }
1118
1119
1120
1121
1122 @Override
1123 @BeanTagAttribute
1124 public List<MustOccurConstraint> getMustOccurConstraints() {
1125 return this.mustOccurConstraints;
1126 }
1127
1128
1129
1130
1131 @Override
1132 public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
1133 this.mustOccurConstraints = mustOccurConstraints;
1134 }
1135
1136
1137
1138
1139 @Override
1140 @BeanTagAttribute
1141 public SimpleConstraint getSimpleConstraint() {
1142 return this.simpleConstraint;
1143 }
1144
1145
1146
1147
1148 @Override
1149 public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
1150 this.simpleConstraint = simpleConstraint;
1151 }
1152
1153
1154
1155
1156 @Override
1157 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.SINGLEBEAN)
1158 public DataType getDataType() {
1159 return this.simpleConstraint.getDataType();
1160 }
1161
1162
1163
1164
1165 @Override
1166 public void setDataType(DataType dataType) {
1167 this.simpleConstraint.setDataType(dataType);
1168 }
1169
1170
1171
1172
1173 @Override
1174 public void setDataType(String dataType) {
1175 this.simpleConstraint.setDataType(DataType.valueOf(dataType));
1176 }
1177
1178
1179
1180
1181 @Override
1182 @BeanTagAttribute
1183 public Integer getMaxLength() {
1184 return simpleConstraint.getMaxLength();
1185 }
1186
1187
1188
1189
1190 @Override
1191 public void setMaxLength(Integer maxLength) {
1192 simpleConstraint.setMaxLength(maxLength);
1193 }
1194
1195
1196
1197
1198 @Override
1199 @BeanTagAttribute
1200 public Integer getMinLength() {
1201 return simpleConstraint.getMinLength();
1202 }
1203
1204
1205
1206
1207 @Override
1208 public void setMinLength(Integer minLength) {
1209 simpleConstraint.setMinLength(minLength);
1210 }
1211
1212
1213
1214
1215 @Override
1216 @BeanTagAttribute
1217 public Boolean getRequired() {
1218 return this.simpleConstraint.getRequired();
1219 }
1220
1221
1222
1223
1224 @Override
1225 public void setRequired(Boolean required) {
1226 this.simpleConstraint.setRequired(required);
1227 }
1228
1229
1230
1231
1232 @Override
1233 @BeanTagAttribute
1234 public String getExclusiveMin() {
1235 return simpleConstraint.getExclusiveMin();
1236 }
1237
1238
1239
1240
1241 @Override
1242 public void setExclusiveMin(String exclusiveMin) {
1243 simpleConstraint.setExclusiveMin(exclusiveMin);
1244 }
1245
1246
1247
1248
1249 @Override
1250 @BeanTagAttribute
1251 public String getInclusiveMax() {
1252 return simpleConstraint.getInclusiveMax();
1253 }
1254
1255
1256
1257
1258 @Override
1259 public void setInclusiveMax(String inclusiveMax) {
1260 simpleConstraint.setInclusiveMax(inclusiveMax);
1261 }
1262
1263
1264
1265
1266 @Override
1267 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.DIRECTORBYTYPE)
1268 public AttributeQuery getAttributeQuery() {
1269 return attributeQuery;
1270 }
1271
1272
1273
1274
1275 @Override
1276 public void setAttributeQuery(AttributeQuery attributeQuery) {
1277 this.attributeQuery = attributeQuery;
1278 }
1279
1280
1281
1282
1283 @Override
1284 @BeanTagAttribute
1285 public boolean isUppercaseValue() {
1286 return uppercaseValue;
1287 }
1288
1289
1290
1291
1292 @Override
1293 public void setUppercaseValue(boolean uppercaseValue) {
1294 this.uppercaseValue = uppercaseValue;
1295 }
1296
1297
1298
1299
1300 @Override
1301 @BeanTagAttribute
1302 public boolean isDisableNativeAutocomplete() {
1303 return disableNativeAutocomplete;
1304 }
1305
1306
1307
1308
1309 @Override
1310 public void setDisableNativeAutocomplete(boolean disableNativeAutocomplete) {
1311 this.disableNativeAutocomplete = disableNativeAutocomplete;
1312 }
1313
1314
1315
1316
1317 @Override
1318 public boolean isRenderFieldset() {
1319 return super.isRenderFieldset() || (quickfinder != null
1320 && quickfinder.isRender()
1321 && quickfinder.getQuickfinderAction() != null
1322 && quickfinder.getQuickfinderAction().isRender());
1323 }
1324
1325
1326
1327
1328 @Override
1329 public void completeValidation(ValidationTrace tracer) {
1330 tracer.addBean(this);
1331
1332
1333 if (getControl() == null) {
1334 if (Validator.checkExpressions(this, "control")) {
1335 String currentValues[] = {"propertyName =" + getPropertyName()};
1336 tracer.createWarning("Control should be set", currentValues);
1337 }
1338 }
1339
1340
1341 if (getControl() != null && !(getControl() instanceof TextControl
1342 || getControl() instanceof TextAreaControl
1343 || getControl() instanceof SelectControl)){
1344
1345 if (CollectionUtils.isNotEmpty(this.getPostInputAddons())) {
1346 String currentValues[] = {"propertyName =" + getPropertyName()};
1347 tracer.createWarning("Inputs which are not text or select should not use post input addons for "
1348 + "user experience reasons", currentValues);
1349 }
1350 }
1351
1352 super.completeValidation(tracer.getCopy());
1353 }
1354
1355
1356
1357
1358
1359
1360
1361 protected boolean hasAutoQuickfinderRelationship() {
1362 String propertyName = getBindingInfo().getBindingName();
1363
1364
1365 View view = ViewLifecycle.getView();
1366 Object model = ViewLifecycle.getModel();
1367 Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, this);
1368 Class<?> parentObjectClass = null;
1369 if (parentObject != null) {
1370 parentObjectClass = parentObject.getClass();
1371 }
1372
1373
1374 @SuppressWarnings("deprecation")
1375 DataObjectRelationship relationship = null;
1376 if (parentObject != null) {
1377 relationship = KRADServiceLocatorWeb.getLegacyDataAdapter().getDataObjectRelationship(parentObject,
1378 parentObjectClass, propertyName, "", true, true, false);
1379 }
1380
1381 return relationship != null;
1382 }
1383
1384 }