1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.util;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.krad.datadictionary.state.StateMapping;
20 import org.kuali.rice.krad.datadictionary.validation.constraint.BaseConstraint;
21 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
22 import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint;
23 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
24 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
25 import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
26 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
27 import org.kuali.rice.krad.datadictionary.validation.constraint.WhenConstraint;
28 import org.kuali.rice.krad.messages.MessageService;
29 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
30 import org.kuali.rice.krad.uif.UifConstants;
31 import org.kuali.rice.krad.uif.control.TextControl;
32 import org.kuali.rice.krad.uif.field.InputField;
33 import org.kuali.rice.krad.uif.view.FormView;
34 import org.kuali.rice.krad.uif.view.View;
35
36 import java.text.MessageFormat;
37 import java.util.ArrayList;
38 import java.util.EnumSet;
39 import java.util.List;
40
41
42
43
44
45
46
47
48
49
50 public class ClientValidationUtils {
51
52 private static int methodKey = 0;
53
54
55
56 private static List<List<String>> mustOccursPathNames;
57
58 public static final String LABEL_KEY_SPLIT_PATTERN = ",";
59
60 public static final String PREREQ_MSG_KEY = "prerequisite";
61 public static final String POSTREQ_MSG_KEY = "postrequisite";
62 public static final String MUSTOCCURS_MSG_KEY = "mustOccurs";
63 public static final String MUSTOCCURS_MSG_EQUAL_KEY = "mustOccursEqualMinMax";
64 public static final String GENERIC_FIELD_MSG_KEY = "general.genericFieldName";
65
66 public static final String ALL_MSG_KEY = "general.all";
67 public static final String ATMOST_MSG_KEY = "general.atMost";
68 public static final String AND_MSG_KEY = "general.and";
69 public static final String OR_MSG_KEY = "general.or";
70
71
72 public static enum ValidationMessageKeys {
73 REQUIRED("required"),
74 MIN_EXCLUSIVE("minExclusive"),
75 MAX_INCLUSIVE("maxInclusive"),
76 MIN_LENGTH("minLengthConditional"),
77 MAX_LENGTH("maxLengthConditional");
78
79 private ValidationMessageKeys(String name) {
80 this.name = name;
81 }
82
83 private final String name;
84
85 @Override
86 public String toString() {
87 return name;
88 }
89
90 public static boolean contains(String name) {
91 for (ValidationMessageKeys element : EnumSet.allOf(ValidationMessageKeys.class)) {
92 if (element.toString().equalsIgnoreCase(name)) {
93 return true;
94 }
95 }
96 return false;
97 }
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111 public static String generateMessageText(String namespace, String componentCode, String messageKey,
112 List<String> params) {
113 String message = "NO MESSAGE";
114 if (StringUtils.isNotEmpty(messageKey)) {
115 message = KRADServiceLocatorWeb.getMessageService().getMessageText(namespace, componentCode, messageKey);
116 if (params != null && !params.isEmpty() && StringUtils.isNotEmpty(message)) {
117 message = MessageFormat.format(message, params.toArray());
118 message = MessageStructureUtils.translateStringMessage(message);
119 }
120 }
121
122 if (StringUtils.isEmpty(message)) {
123 message = messageKey;
124 }
125
126
127 if (message.contains("\"")) {
128 message = message.replace("\"", """);
129 }
130 if (message.contains("'")) {
131 message = message.replace("'", "'");
132 }
133 if (message.contains("\\")) {
134 message = message.replace("\\", "\");
135 }
136
137 return message;
138 }
139
140
141
142
143
144
145
146 public static String generateValidatorMessagesOption() {
147 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
148
149 String mOption = "";
150 String keyValuePairs = "";
151 for (ValidationMessageKeys element : EnumSet.allOf(ValidationMessageKeys.class)) {
152 String key = element.toString();
153 String message = messageService.getMessageText(UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + key);
154
155 if (StringUtils.isNotEmpty(message)) {
156 message = MessageStructureUtils.translateStringMessage(message);
157 keyValuePairs = keyValuePairs + "\n" + key + ": '" + message + "',";
158 }
159 }
160
161 keyValuePairs = StringUtils.removeEnd(keyValuePairs, ",");
162 if (StringUtils.isNotEmpty(keyValuePairs)) {
163 mOption = "{" + keyValuePairs + "}";
164 }
165
166 return mOption;
167 }
168
169
170
171
172
173
174
175
176 public static String getRegexMethod(InputField field, ValidCharactersConstraint validCharactersConstraint) {
177 String message = generateMessageText(validCharactersConstraint.getMessageNamespaceCode(),
178 validCharactersConstraint.getMessageComponentCode(), validCharactersConstraint.getMessageKey(),
179 validCharactersConstraint.getValidationMessageParams());
180 String key = "validChar-" + field.getBindingInfo().getBindingPath() + methodKey;
181
182
183 String regex = validCharactersConstraint.getValue();
184 if (regex.contains("\\\\")) {
185 regex = regex.replaceAll("\\\\", "\\\\\\\\");
186 }
187 if (regex.contains("/")) {
188 regex = regex.replace("/", "\\/");
189 }
190
191 return "\njQuery.validator.addMethod(\""
192 + ScriptUtils.escapeName(key)
193 + "\", function(value, element) {\n "
194 + "return this.optional(element) || /"
195 + regex
196 + "/.test(value);"
197 + "}, \""
198 + message
199 + "\");";
200 }
201
202
203
204
205
206
207
208
209
210 public static String getRegexMethodWithBooleanCheck(InputField field,
211 ValidCharactersConstraint validCharactersConstraint) {
212 String message = generateMessageText(validCharactersConstraint.getMessageNamespaceCode(),
213 validCharactersConstraint.getMessageComponentCode(), validCharactersConstraint.getMessageKey(),
214 validCharactersConstraint.getValidationMessageParams());
215 String key = "validChar-" + field.getBindingInfo().getBindingPath() + methodKey;
216
217
218 String regex = validCharactersConstraint.getValue();
219 if (regex.contains("\\\\")) {
220 regex = regex.replaceAll("\\\\", "\\\\\\\\");
221 }
222 if (regex.contains("/")) {
223 regex = regex.replace("/", "\\/");
224 }
225
226 return "\njQuery.validator.addMethod(\""
227 + ScriptUtils.escapeName(key)
228 + "\", function(value, element, doCheck) {\n if(doCheck === false){return true;}else{"
229 + "return this.optional(element) || /"
230 + regex
231 + "/.test(value);}"
232 + "}, \""
233 + message
234 + "\");";
235 }
236
237
238
239
240
241
242
243
244
245
246
247 public static void processCaseConstraint(InputField field, View view, CaseConstraint constraint, String andedCase,
248 String validationState, StateMapping stateMapping) {
249 if (constraint.getOperator() == null) {
250 constraint.setOperator("equals");
251 }
252
253 String operator = "==";
254 if (constraint.getOperator().equalsIgnoreCase("not_equals") || constraint.getOperator().equalsIgnoreCase(
255 "not_equal")) {
256 operator = "!=";
257 } else if (constraint.getOperator().equalsIgnoreCase("greater_than_equal")) {
258 operator = ">=";
259 } else if (constraint.getOperator().equalsIgnoreCase("less_than_equal")) {
260 operator = "<=";
261 } else if (constraint.getOperator().equalsIgnoreCase("greater_than")) {
262 operator = ">";
263 } else if (constraint.getOperator().equalsIgnoreCase("less_than")) {
264 operator = "<";
265 } else if (constraint.getOperator().equalsIgnoreCase("has_value")) {
266 operator = "";
267 }
268
269
270 field.getControl().addStyleClass("dependsOn-" + ScriptUtils.escapeName(constraint.getPropertyName()));
271
272 if (constraint.getWhenConstraint() != null && !constraint.getWhenConstraint().isEmpty()) {
273
274 String fieldPath = constraint.getPropertyName();
275 for (WhenConstraint wc : constraint.getWhenConstraint()) {
276 wc = ConstraintStateUtils.getApplicableConstraint(wc, validationState, stateMapping);
277 if (wc != null) {
278 processWhenConstraint(field, view, constraint, wc, ScriptUtils.escapeName(fieldPath), operator,
279 andedCase, validationState, stateMapping);
280 }
281 }
282 }
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 private static void processWhenConstraint(InputField field, View view, CaseConstraint caseConstraint,
299 WhenConstraint wc, String fieldPath, String operator, String andedCase, String validationState,
300 StateMapping stateMapping) {
301 String ruleString = "";
302
303
304 String booleanStatement = "";
305 if (wc.getValues() != null) {
306
307 String caseStr = "";
308 if (!caseConstraint.isCaseSensitive()) {
309 caseStr = ".toUpperCase()";
310 }
311 for (int i = 0; i < wc.getValues().size(); i++) {
312 if (operator.isEmpty()) {
313
314 if (wc.getValues().get(i) instanceof String && ((String) wc.getValues().get(i)).equalsIgnoreCase(
315 "false")) {
316 booleanStatement = booleanStatement + "(coerceValue('" + fieldPath + "') == '')";
317 } else {
318 booleanStatement = booleanStatement + "(coerceValue('" + fieldPath + "') != '')";
319 }
320 } else {
321
322 booleanStatement = booleanStatement
323 + "(coerceValue('"
324 + fieldPath
325 + "')"
326 + caseStr
327 + " "
328 + operator
329 + " \""
330 + wc.getValues().get(i)
331 + "\""
332 + caseStr
333 + ")";
334 }
335 if ((i + 1) != wc.getValues().size()) {
336 booleanStatement = booleanStatement + " || ";
337 }
338 }
339
340 }
341
342 if (andedCase != null) {
343 booleanStatement = "(" + booleanStatement + ") && (" + andedCase + ")";
344 }
345
346 if (wc.getConstraint() != null && StringUtils.isNotEmpty(booleanStatement)) {
347 Constraint constraint = ConstraintStateUtils.getApplicableConstraint(wc.getConstraint(), validationState,
348 stateMapping);
349 if (constraint != null) {
350 ruleString = createRule(field, constraint, booleanStatement, view, validationState, stateMapping);
351 }
352 }
353
354 if (StringUtils.isNotEmpty(ruleString)) {
355 addScriptToPage(view, field, ruleString);
356 }
357 }
358
359
360
361
362
363
364
365 public static void addScriptToPage(View view, InputField field, String script) {
366 String prefixScript = "";
367
368 if (field.getOnDocumentReadyScript() != null) {
369 prefixScript = field.getOnDocumentReadyScript();
370 }
371 field.setOnDocumentReadyScript(prefixScript + "\n" + "runValidationScript(function(){" + script + "});");
372 }
373
374
375
376
377
378
379
380
381 private static List<String> parseOutFields(String statement) {
382 List<String> fieldNames = new ArrayList<String>();
383 String[] splits = StringUtils.splitByWholeSeparator(statement, "coerceValue('");
384 for (String s : splits) {
385 String fieldName = StringUtils.substringBefore(s, "'");
386 fieldNames.add(fieldName);
387 }
388 return fieldNames;
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 @SuppressWarnings("boxing")
408 private static String createRule(InputField field, Constraint constraint, String booleanStatement, View view,
409 String validationState, StateMapping stateMapping) {
410 String rule = "";
411 int constraintCount = 0;
412 if (constraint instanceof BaseConstraint && ((BaseConstraint) constraint).getApplyClientSide()) {
413 if (constraint instanceof SimpleConstraint) {
414 if (((SimpleConstraint) constraint).getRequired() != null && ((SimpleConstraint) constraint)
415 .getRequired()) {
416 rule = rule + "required: function(element){\nreturn (" + booleanStatement + ");}";
417
418 String showIndicatorScript = "";
419 for (String checkedField : parseOutFields(booleanStatement)) {
420 showIndicatorScript = showIndicatorScript +
421 "setupShowReqIndicatorCheck('" + checkedField + "', '" + field.getBindingInfo()
422 .getBindingPath() + "', " + "function(){\nreturn (" + booleanStatement + ");});\n";
423 }
424 addScriptToPage(view, field, showIndicatorScript);
425
426 constraintCount++;
427 }
428
429 if (((SimpleConstraint) constraint).getMinLength() != null) {
430 if (constraintCount > 0) {
431 rule = rule + ",\n";
432 }
433 rule = rule
434 + "minLengthConditional: ["
435 + ((SimpleConstraint) constraint).getMinLength()
436 + ", function(){return "
437 + booleanStatement
438 + ";}]";
439 constraintCount++;
440 }
441
442 if (((SimpleConstraint) constraint).getMaxLength() != null) {
443 if (constraintCount > 0) {
444 rule = rule + ",\n";
445 }
446 rule = rule
447 + "maxLengthConditional: ["
448 + ((SimpleConstraint) constraint).getMaxLength()
449 + ", function(){return "
450 + booleanStatement
451 + ";}]";
452 constraintCount++;
453 }
454
455 if (((SimpleConstraint) constraint).getExclusiveMin() != null) {
456 if (constraintCount > 0) {
457 rule = rule + ",\n";
458 }
459 rule = rule
460 + "minExclusive: ["
461 + ((SimpleConstraint) constraint).getExclusiveMin()
462 + ", function(){return "
463 + booleanStatement
464 + ";}]";
465 constraintCount++;
466 }
467
468 if (((SimpleConstraint) constraint).getInclusiveMax() != null) {
469 if (constraintCount > 0) {
470 rule = rule + ",\n";
471 }
472 rule = rule
473 + "maxInclusive: ["
474 + ((SimpleConstraint) constraint).getInclusiveMax()
475 + ", function(){return "
476 + booleanStatement
477 + ";}]";
478 constraintCount++;
479 }
480
481 rule = "jQuery('[name=\""
482 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
483 + "\"]').rules(\"add\", {"
484 + rule
485 + "\n});";
486 } else if (constraint instanceof ValidCharactersConstraint) {
487 String regexMethod = "";
488 String methodName = "";
489 if (StringUtils.isNotEmpty(((ValidCharactersConstraint) constraint).getValue())) {
490 regexMethod = ClientValidationUtils.getRegexMethodWithBooleanCheck(field,
491 (ValidCharactersConstraint) constraint) + "\n";
492 methodName = "validChar-" + field.getBindingInfo().getBindingPath() + methodKey;
493 methodKey++;
494 } else {
495 if (StringUtils.isNotEmpty(((ValidCharactersConstraint) constraint).getMessageKey())) {
496 methodName = ((ValidCharactersConstraint) constraint).getMessageKey();
497 }
498 }
499
500 if (StringUtils.isNotEmpty(methodName)) {
501 rule = regexMethod
502 + "jQuery('[name=\""
503 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
504 + "\"]').rules(\"add\", {\n\""
505 + methodName
506 + "\" : function(element){return ("
507 + booleanStatement
508 + ");}\n});";
509 }
510 } else if (constraint instanceof PrerequisiteConstraint) {
511 processPrerequisiteConstraint(field, (PrerequisiteConstraint) constraint, view, booleanStatement);
512 } else if (constraint instanceof CaseConstraint) {
513 processCaseConstraint(field, view, (CaseConstraint) constraint, booleanStatement, validationState,
514 stateMapping);
515 } else if (constraint instanceof MustOccurConstraint) {
516 processMustOccurConstraint(field, view, (MustOccurConstraint) constraint, booleanStatement);
517 }
518 }
519
520 return rule;
521 }
522
523
524
525
526
527
528
529
530
531 public static void processPrerequisiteConstraint(InputField field, PrerequisiteConstraint constraint, View view) {
532 processPrerequisiteConstraint(field, constraint, view, "true");
533 }
534
535
536
537
538
539
540
541
542
543
544 public static void processPrerequisiteConstraint(InputField field, PrerequisiteConstraint constraint, View view,
545 String booleanStatement) {
546 if (constraint != null && constraint.getApplyClientSide().booleanValue()) {
547 String dependsClass = "dependsOn-" + ScriptUtils.escapeName(constraint.getPropertyName());
548 String addClass = "jQuery('[name=\""
549 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
550 + "\"]').addClass('"
551 + dependsClass
552 + "');"
553 +
554 "jQuery('[name=\""
555 + ScriptUtils.escapeName(constraint.getPropertyName())
556 + "\"]').addClass('"
557 + "dependsOn-"
558 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
559 + "');";
560
561 addScriptToPage(view, field, addClass
562 + getPrerequisiteStatement(field, view, constraint, booleanStatement)
563 + getPostrequisiteStatement(field, constraint, booleanStatement));
564
565
566 String showIndicatorScript = "setupShowReqIndicatorCheck('" + ScriptUtils.escapeName(
567 field.getBindingInfo().getBindingPath()) + "', '" + ScriptUtils.escapeName(
568 constraint.getPropertyName()) + "', " + "function(){\nreturn (coerceValue('" + ScriptUtils
569 .escapeName(field.getBindingInfo().getBindingPath()) + "') && " + booleanStatement + ");});\n";
570
571 addScriptToPage(view, field, showIndicatorScript);
572 }
573 }
574
575
576
577
578
579
580
581
582
583
584
585
586
587 private static String getPrerequisiteStatement(InputField field, View view, PrerequisiteConstraint constraint,
588 String booleanStatement) {
589 methodKey++;
590
591 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
592
593 String message = "";
594 if (StringUtils.isEmpty(constraint.getMessageKey())) {
595 message = messageService.getMessageText(UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "prerequisite");
596 message = MessageStructureUtils.translateStringMessage(message);
597 } else {
598 message = generateMessageText(constraint.getMessageNamespaceCode(),
599 constraint.getMessageComponentCode(), constraint.getMessageKey(),
600 constraint.getValidationMessageParams());
601 }
602
603 if (StringUtils.isEmpty(message)) {
604 message = "prerequisite - No message";
605 } else {
606 InputField requiredField = (InputField) view.getViewIndex().getDataFieldByPath(
607 constraint.getPropertyName());
608 if (requiredField != null && StringUtils.isNotEmpty(requiredField.getLabel())) {
609 message = MessageFormat.format(message, requiredField.getLabel());
610 } else {
611 String genericFieldLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
612 message = MessageFormat.format(message, genericFieldLabel);
613 }
614 }
615
616
617 String methodName = "prConstraint-"
618 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
619 + methodKey;
620
621 String addClass = "jQuery('[name=\""
622 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
623 + "\"]').addClass('"
624 + methodName
625 + "');\n";
626
627 String method = "\njQuery.validator.addMethod(\"" + methodName + "\", function(value, element) {\n" +
628 " if(" + booleanStatement + "){ return (this.optional(element) || (coerceValue('" + ScriptUtils
629 .escapeName(constraint.getPropertyName()) + "')));}else{return true;} " +
630 "}, \"" + message + "\");";
631
632 String ifStatement = "if(occursBefore('"
633 + ScriptUtils.escapeName(constraint.getPropertyName())
634 + "','"
635 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
636 +
637 "')){"
638 + addClass
639 + method
640 + "}";
641
642 return ifStatement;
643 }
644
645
646
647
648
649
650
651
652
653
654
655
656 private static String getPostrequisiteStatement(InputField field, PrerequisiteConstraint constraint,
657 String booleanStatement) {
658 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
659
660
661 String message = "";
662 if (StringUtils.isEmpty(constraint.getMessageKey())) {
663 message = messageService.getMessageText(UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "postrequisite");
664 message = MessageStructureUtils.translateStringMessage(message);
665 } else {
666 message = generateMessageText(constraint.getMessageNamespaceCode(), constraint.getMessageComponentCode(),
667 constraint.getMessageKey(), constraint.getValidationMessageParams());
668 }
669
670 if (StringUtils.isEmpty(constraint.getMessageKey())) {
671 if (StringUtils.isNotEmpty(field.getLabel())) {
672 message = MessageFormat.format(message, field.getLabel());
673 } else {
674 String genericFieldLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
675 message = MessageFormat.format(message, genericFieldLabel);
676 }
677 }
678
679 String function = "function(element){\n" +
680 "return (coerceValue('"
681 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
682 + "') && "
683 + booleanStatement
684 + ");}";
685 String postStatement = "\nelse if(occursBefore('"
686 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
687 + "','"
688 + ScriptUtils.escapeName(constraint.getPropertyName())
689 +
690 "')){\njQuery('[name=\""
691 + ScriptUtils.escapeName(constraint.getPropertyName())
692 +
693 "\"]').rules(\"add\", { required: \n"
694 + function
695 + ", \nmessages: {\nrequired: \""
696 + message
697 + "\"}});}\n";
698
699 return postStatement;
700
701 }
702
703
704
705
706
707
708
709
710
711
712
713
714 public static void processMustOccurConstraint(InputField field, View view, MustOccurConstraint mc,
715 String booleanStatement) {
716 methodKey++;
717 mustOccursPathNames = new ArrayList<List<String>>();
718
719 String methodName = "moConstraint-"
720 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
721 + methodKey;
722 String method = "\njQuery.validator.addMethod(\"" + methodName + "\", function(value, element) {\n" +
723 " if("
724 + booleanStatement
725 + "){return (this.optional(element) || ("
726 + getMustOccurStatement(field, mc)
727 + "));}else{return true;}"
728 +
729 "}, \""
730 + getMustOccursMessage(view, mc)
731 + "\");";
732 String rule = method
733 + "jQuery('[name=\""
734 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
735 + "\"]').rules(\"add\", {\n\""
736 + methodName
737 + "\": function(element){return ("
738 + booleanStatement
739 + ");}\n});";
740 addScriptToPage(view, field, rule);
741 }
742
743
744
745
746
747
748
749
750
751
752
753 @SuppressWarnings("boxing")
754 private static String getMustOccurStatement(InputField field, MustOccurConstraint constraint) {
755 String statement = "";
756 List<String> attributePaths = new ArrayList<String>();
757 if (constraint != null && constraint.getApplyClientSide()) {
758 String array = "[";
759 if (constraint.getPrerequisiteConstraints() != null) {
760 for (int i = 0; i < constraint.getPrerequisiteConstraints().size(); i++) {
761 field.getControl().addStyleClass("dependsOn-" + constraint.getPrerequisiteConstraints().get(i)
762 .getPropertyName());
763 array = array + "'" + ScriptUtils.escapeName(constraint.getPrerequisiteConstraints().get(i)
764 .getPropertyName()) + "'";
765 attributePaths.add(constraint.getPrerequisiteConstraints().get(i).getPropertyName());
766 if (i + 1 != constraint.getPrerequisiteConstraints().size()) {
767 array = array + ",";
768 }
769
770 }
771 }
772 array = array + "]";
773 statement = "mustOccurTotal(" + array + ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
774
775 if (constraint.getMin() != null) {
776 attributePaths.add(constraint.getMin().toString());
777 } else {
778 attributePaths.add(null);
779 }
780
781 if (constraint.getMax() != null) {
782 attributePaths.add(constraint.getMax().toString());
783 } else {
784 attributePaths.add(null);
785 }
786
787 mustOccursPathNames.add(attributePaths);
788 if (StringUtils.isEmpty(statement)) {
789 statement = "0";
790 }
791 if (constraint.getMustOccurConstraints() != null) {
792 for (MustOccurConstraint mc : constraint.getMustOccurConstraints()) {
793 statement = "mustOccurCheck(" + statement + " + " + getMustOccurStatement(field, mc) +
794 ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
795 }
796 } else {
797 statement = "mustOccurCheck(" + statement +
798 ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
799 }
800 }
801 return statement;
802 }
803
804
805
806
807
808
809
810
811
812
813 private static String getMustOccursMessage(View view, MustOccurConstraint constraint) {
814 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
815
816 String message = "";
817 if (StringUtils.isNotEmpty(constraint.getMessageKey())) {
818 message = generateMessageText(constraint.getMessageNamespaceCode(), constraint.getMessageComponentCode(),
819 constraint.getMessageKey(), constraint.getValidationMessageParams());
820 } else {
821 String and = messageService.getMessageText(AND_MSG_KEY);
822 String or = messageService.getMessageText(OR_MSG_KEY);
823 String all = messageService.getMessageText(ALL_MSG_KEY);
824 String mustOccursMsgEqualMinMax = messageService.getMessageText(
825 UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + MUSTOCCURS_MSG_EQUAL_KEY);
826 String atMost = messageService.getMessageText(ATMOST_MSG_KEY);
827 String genericLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
828 String mustOccursMsg = messageService.getMessageText(
829 UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + MUSTOCCURS_MSG_KEY);
830
831 String statement = "";
832 for (int i = 0; i < mustOccursPathNames.size(); i++) {
833 String andedString = "";
834
835 List<String> paths = mustOccursPathNames.get(i);
836 if (!paths.isEmpty()) {
837
838 String min = paths.get(paths.size() - 2);
839 String max = paths.get(paths.size() - 1);
840 for (int j = 0; j < paths.size() - 2; j++) {
841 InputField field = (InputField) view.getViewIndex().getDataFieldByPath(paths.get(j).trim());
842 String label = genericLabel;
843 if (field != null && StringUtils.isNotEmpty(field.getLabel())) {
844 label = field.getLabel();
845 }
846 if (min.equals(max)) {
847 if (j == 0) {
848 andedString = label;
849 } else if (j == paths.size() - 3) {
850 andedString = andedString + " " + and + " " + label;
851 } else {
852 andedString = andedString + ", " + label;
853 }
854 } else {
855 andedString = andedString + "(" + label + ")";
856 }
857 }
858 if (min.equals(max)) {
859 andedString = "(" + andedString + ")";
860 }
861
862 if (StringUtils.isNotBlank(andedString) && !andedString.equals("()")) {
863 if (StringUtils.isNotEmpty(min) && StringUtils.isNotEmpty(max) && !min.equals(max)) {
864 andedString = MessageFormat.format(mustOccursMsg, min + "-" + max) + " " + andedString;
865 } else if (StringUtils.isNotEmpty(min)
866 && StringUtils.isNotEmpty(max)
867 && min.equals(max)
868 && i == 0) {
869 andedString = mustOccursMsgEqualMinMax + " " + andedString;
870 } else if (StringUtils.isNotEmpty(min)
871 && StringUtils.isNotEmpty(max)
872 && min.equals(max)
873 && i != 0) {
874
875 } else if (StringUtils.isNotEmpty(min)) {
876 andedString = MessageFormat.format(mustOccursMsg, min) + " " + andedString;
877 } else if (StringUtils.isNotEmpty(max)) {
878 andedString = MessageFormat.format(mustOccursMsg, atMost + " " + max) + " " + andedString;
879 }
880 }
881 }
882 if (StringUtils.isNotEmpty(andedString)) {
883 if (StringUtils.isNotBlank(statement)) {
884 statement = statement + " " + or.toUpperCase() + " " + andedString;
885 } else {
886 statement = andedString;
887 }
888 }
889 }
890 if (StringUtils.isNotEmpty(statement)) {
891 message = statement;
892 message = message.replace(")(", " " + or + " ");
893 }
894 }
895
896 return message;
897 }
898
899
900
901
902
903
904
905
906
907 @SuppressWarnings("boxing")
908 public static void processAndApplyConstraints(InputField field, View view, Object model) {
909 methodKey = 0;
910 String validationState = ConstraintStateUtils.getClientViewValidationState(model, view);
911 StateMapping stateMapping = view.getStateMapping();
912
913 if (view instanceof FormView && ((FormView) view).isValidateClientSide()) {
914 SimpleConstraint simpleConstraint = ConstraintStateUtils.getApplicableConstraint(
915 field.getSimpleConstraint(), validationState, stateMapping);
916 if (simpleConstraint != null && simpleConstraint.getApplyClientSide()) {
917
918 if ((simpleConstraint.getRequired() != null) && (simpleConstraint.getRequired().booleanValue())) {
919 field.getControl().addStyleClass("required");
920 }
921
922 if (simpleConstraint.getExclusiveMin() != null) {
923 if (field.getControl() instanceof TextControl
924 && ((TextControl) field.getControl()).getDatePicker() != null) {
925 ((TextControl) field.getControl()).getDatePicker().getTemplateOptions().put("minDate",
926 simpleConstraint.getExclusiveMin());
927 } else {
928 String rule = "jQuery('[name=\""
929 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
930 + "\"]').rules(\"add\", {\n minExclusive: ["
931 + simpleConstraint.getExclusiveMin()
932 + "]});";
933 addScriptToPage(view, field, rule);
934 }
935 }
936
937 if (simpleConstraint.getInclusiveMax() != null) {
938 if (field.getControl() instanceof TextControl
939 && ((TextControl) field.getControl()).getDatePicker() != null) {
940 ((TextControl) field.getControl()).getDatePicker().getTemplateOptions().put("maxDate",
941 simpleConstraint.getInclusiveMax());
942 } else {
943 String rule = "jQuery('[name=\""
944 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
945 + "\"]').rules(\"add\", {\n maxInclusive: ["
946 + simpleConstraint.getInclusiveMax()
947 + "]});";
948 addScriptToPage(view, field, rule);
949 }
950 }
951 }
952
953 ValidCharactersConstraint validCharactersConstraint = ConstraintStateUtils.getApplicableConstraint(
954 field.getValidCharactersConstraint(), validationState, stateMapping);
955
956 if (validCharactersConstraint != null && validCharactersConstraint.getApplyClientSide()) {
957 if (StringUtils.isNotEmpty(validCharactersConstraint.getValue())) {
958
959 addScriptToPage(view, field, ClientValidationUtils.getRegexMethod(field,
960 validCharactersConstraint));
961 field.getControl().addStyleClass(
962 "validChar-" + field.getBindingInfo().getBindingPath() + methodKey);
963 methodKey++;
964 } else {
965
966 if (StringUtils.isNotEmpty(validCharactersConstraint.getMessageKey())) {
967 field.getControl().addStyleClass(validCharactersConstraint.getMessageKey());
968 }
969 }
970 }
971
972 CaseConstraint caseConstraint = ConstraintStateUtils.getApplicableConstraint(field.getCaseConstraint(),
973 validationState, stateMapping);
974 if (caseConstraint != null && caseConstraint.getApplyClientSide()) {
975 processCaseConstraint(field, view, caseConstraint, null, validationState, stateMapping);
976 }
977
978 if (field.getDependencyConstraints() != null) {
979 for (PrerequisiteConstraint prc : field.getDependencyConstraints()) {
980 prc = ConstraintStateUtils.getApplicableConstraint(prc, validationState, stateMapping);
981 if (prc != null) {
982 processPrerequisiteConstraint(field, prc, view);
983 }
984 }
985 }
986
987 if (field.getMustOccurConstraints() != null) {
988 for (MustOccurConstraint mc : field.getMustOccurConstraints()) {
989 mc = ConstraintStateUtils.getApplicableConstraint(mc, validationState, stateMapping);
990 if (mc != null) {
991 processMustOccurConstraint(field, view, mc, "true");
992 }
993 }
994 }
995
996 }
997 }
998
999 }