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
386 if(!s.startsWith("'")){
387 continue;
388 }
389
390 s = s.substring(1);
391 String fieldName = StringUtils.substringBefore(s, "'");
392
393 if(fieldNames.contains(fieldName)){
394 fieldNames.add(fieldName);
395 }
396
397 }
398 return fieldNames;
399 }
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 @SuppressWarnings("boxing")
418 private static String createRule(InputField field, Constraint constraint, String booleanStatement, View view,
419 String validationState, StateMapping stateMapping) {
420 String rule = "";
421 int constraintCount = 0;
422 if (constraint instanceof BaseConstraint && ((BaseConstraint) constraint).getApplyClientSide()) {
423 if (constraint instanceof SimpleConstraint) {
424 if (((SimpleConstraint) constraint).getRequired() != null && ((SimpleConstraint) constraint)
425 .getRequired()) {
426 rule = rule + "required: function(element){\nreturn (" + booleanStatement + ");}";
427
428 String showIndicatorScript = "";
429 for (String checkedField : parseOutFields(booleanStatement)) {
430 showIndicatorScript = showIndicatorScript +
431 "setupShowReqIndicatorCheck('" + checkedField + "', '" + field.getBindingInfo()
432 .getBindingPath() + "', " + "function(){\nreturn (" + booleanStatement + ");});\n";
433 }
434 addScriptToPage(view, field, showIndicatorScript);
435
436 constraintCount++;
437 }
438
439 if (((SimpleConstraint) constraint).getMinLength() != null) {
440 if (constraintCount > 0) {
441 rule = rule + ",\n";
442 }
443 rule = rule
444 + "minLengthConditional: ["
445 + ((SimpleConstraint) constraint).getMinLength()
446 + ", function(){return "
447 + booleanStatement
448 + ";}]";
449 constraintCount++;
450 }
451
452 if (((SimpleConstraint) constraint).getMaxLength() != null) {
453 if (constraintCount > 0) {
454 rule = rule + ",\n";
455 }
456 rule = rule
457 + "maxLengthConditional: ["
458 + ((SimpleConstraint) constraint).getMaxLength()
459 + ", function(){return "
460 + booleanStatement
461 + ";}]";
462 constraintCount++;
463 }
464
465 if (((SimpleConstraint) constraint).getExclusiveMin() != null) {
466 if (constraintCount > 0) {
467 rule = rule + ",\n";
468 }
469 rule = rule
470 + "minExclusive: ["
471 + ((SimpleConstraint) constraint).getExclusiveMin()
472 + ", function(){return "
473 + booleanStatement
474 + ";}]";
475 constraintCount++;
476 }
477
478 if (((SimpleConstraint) constraint).getInclusiveMax() != null) {
479 if (constraintCount > 0) {
480 rule = rule + ",\n";
481 }
482 rule = rule
483 + "maxInclusive: ["
484 + ((SimpleConstraint) constraint).getInclusiveMax()
485 + ", function(){return "
486 + booleanStatement
487 + ";}]";
488 constraintCount++;
489 }
490
491 rule = "jQuery('[name=\""
492 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
493 + "\"]').rules(\"add\", {"
494 + rule
495 + "\n});";
496 } else if (constraint instanceof ValidCharactersConstraint) {
497 String regexMethod = "";
498 String methodName = "";
499 if (StringUtils.isNotEmpty(((ValidCharactersConstraint) constraint).getValue())) {
500 regexMethod = ClientValidationUtils.getRegexMethodWithBooleanCheck(field,
501 (ValidCharactersConstraint) constraint) + "\n";
502 methodName = "validChar-" + field.getBindingInfo().getBindingPath() + methodKey;
503 methodKey++;
504 } else {
505 if (StringUtils.isNotEmpty(((ValidCharactersConstraint) constraint).getMessageKey())) {
506 methodName = ((ValidCharactersConstraint) constraint).getMessageKey();
507 }
508 }
509
510 if (StringUtils.isNotEmpty(methodName)) {
511 rule = regexMethod
512 + "jQuery('[name=\""
513 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
514 + "\"]').rules(\"add\", {\n\""
515 + methodName
516 + "\" : function(element){return ("
517 + booleanStatement
518 + ");}\n});";
519 }
520 } else if (constraint instanceof PrerequisiteConstraint) {
521 processPrerequisiteConstraint(field, (PrerequisiteConstraint) constraint, view, booleanStatement);
522 } else if (constraint instanceof CaseConstraint) {
523 processCaseConstraint(field, view, (CaseConstraint) constraint, booleanStatement, validationState,
524 stateMapping);
525 } else if (constraint instanceof MustOccurConstraint) {
526 processMustOccurConstraint(field, view, (MustOccurConstraint) constraint, booleanStatement);
527 }
528 }
529
530 return rule;
531 }
532
533
534
535
536
537
538
539
540
541 public static void processPrerequisiteConstraint(InputField field, PrerequisiteConstraint constraint, View view) {
542 processPrerequisiteConstraint(field, constraint, view, "true");
543 }
544
545
546
547
548
549
550
551
552
553
554 public static void processPrerequisiteConstraint(InputField field, PrerequisiteConstraint constraint, View view,
555 String booleanStatement) {
556 if (constraint != null && constraint.getApplyClientSide().booleanValue()) {
557 String dependsClass = "dependsOn-" + ScriptUtils.escapeName(constraint.getPropertyName());
558 String addClass = "jQuery('[name=\""
559 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
560 + "\"]').addClass('"
561 + dependsClass
562 + "');"
563 +
564 "jQuery('[name=\""
565 + ScriptUtils.escapeName(constraint.getPropertyName())
566 + "\"]').addClass('"
567 + "dependsOn-"
568 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
569 + "');";
570
571 addScriptToPage(view, field, addClass
572 + getPrerequisiteStatement(field, view, constraint, booleanStatement)
573 + getPostrequisiteStatement(field, constraint, booleanStatement));
574
575
576 String showIndicatorScript = "setupShowReqIndicatorCheck('" + ScriptUtils.escapeName(
577 field.getBindingInfo().getBindingPath()) + "', '" + ScriptUtils.escapeName(
578 constraint.getPropertyName()) + "', " + "function(){\nreturn (coerceValue('" + ScriptUtils
579 .escapeName(field.getBindingInfo().getBindingPath()) + "') && " + booleanStatement + ");});\n";
580
581 addScriptToPage(view, field, showIndicatorScript);
582 }
583 }
584
585
586
587
588
589
590
591
592
593
594
595
596
597 private static String getPrerequisiteStatement(InputField field, View view, PrerequisiteConstraint constraint,
598 String booleanStatement) {
599 methodKey++;
600
601 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
602
603 String message = "";
604 if (StringUtils.isEmpty(constraint.getMessageKey())) {
605 message = messageService.getMessageText(UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "prerequisite");
606 message = MessageStructureUtils.translateStringMessage(message);
607 } else {
608 message = generateMessageText(constraint.getMessageNamespaceCode(),
609 constraint.getMessageComponentCode(), constraint.getMessageKey(),
610 constraint.getValidationMessageParams());
611 }
612
613 if (StringUtils.isEmpty(message)) {
614 message = "prerequisite - No message";
615 } else {
616 InputField requiredField = (InputField) view.getViewIndex().getDataFieldByPath(
617 constraint.getPropertyName());
618 if (requiredField != null && StringUtils.isNotEmpty(requiredField.getLabel())) {
619 message = MessageFormat.format(message, requiredField.getLabel());
620 } else {
621 String genericFieldLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
622 message = MessageFormat.format(message, genericFieldLabel);
623 }
624 }
625
626
627 String methodName = "prConstraint-"
628 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
629 + methodKey;
630
631 String addClass = "jQuery('[name=\""
632 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
633 + "\"]').addClass('"
634 + methodName
635 + "');\n";
636
637 String method = "\njQuery.validator.addMethod(\"" + methodName + "\", function(value, element) {\n" +
638 " if(" + booleanStatement + "){ return (this.optional(element) || (coerceValue('" + ScriptUtils
639 .escapeName(constraint.getPropertyName()) + "')));}else{return true;} " +
640 "}, \"" + message + "\");";
641
642 String ifStatement = "if(occursBefore('"
643 + ScriptUtils.escapeName(constraint.getPropertyName())
644 + "','"
645 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
646 +
647 "')){"
648 + addClass
649 + method
650 + "}";
651
652 return ifStatement;
653 }
654
655
656
657
658
659
660
661
662
663
664
665
666 private static String getPostrequisiteStatement(InputField field, PrerequisiteConstraint constraint,
667 String booleanStatement) {
668 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
669
670
671 String message = "";
672 if (StringUtils.isEmpty(constraint.getMessageKey())) {
673 message = messageService.getMessageText(UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + "postrequisite");
674 message = MessageStructureUtils.translateStringMessage(message);
675 } else {
676 message = generateMessageText(constraint.getMessageNamespaceCode(), constraint.getMessageComponentCode(),
677 constraint.getMessageKey(), constraint.getValidationMessageParams());
678 }
679
680 if (StringUtils.isEmpty(constraint.getMessageKey())) {
681 if (StringUtils.isNotEmpty(field.getLabel())) {
682 message = MessageFormat.format(message, field.getLabel());
683 } else {
684 String genericFieldLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
685 message = MessageFormat.format(message, genericFieldLabel);
686 }
687 }
688
689 String function = "function(element){\n" +
690 "return (coerceValue('"
691 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
692 + "') && "
693 + booleanStatement
694 + ");}";
695 String postStatement = "\nelse if(occursBefore('"
696 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
697 + "','"
698 + ScriptUtils.escapeName(constraint.getPropertyName())
699 +
700 "')){\njQuery('[name=\""
701 + ScriptUtils.escapeName(constraint.getPropertyName())
702 +
703 "\"]').rules(\"add\", { required: \n"
704 + function
705 + ", \nmessages: {\nrequired: \""
706 + message
707 + "\"}});}\n";
708
709 return postStatement;
710
711 }
712
713
714
715
716
717
718
719
720
721
722
723
724 public static void processMustOccurConstraint(InputField field, View view, MustOccurConstraint mc,
725 String booleanStatement) {
726 methodKey++;
727 mustOccursPathNames = new ArrayList<List<String>>();
728
729 String methodName = "moConstraint-"
730 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
731 + methodKey;
732 String method = "\njQuery.validator.addMethod(\"" + methodName + "\", function(value, element) {\n" +
733 " if("
734 + booleanStatement
735 + "){return (this.optional(element) || ("
736 + getMustOccurStatement(field, mc)
737 + "));}else{return true;}"
738 +
739 "}, \""
740 + getMustOccursMessage(view, mc)
741 + "\");";
742 String rule = method
743 + "jQuery('[name=\""
744 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
745 + "\"]').rules(\"add\", {\n\""
746 + methodName
747 + "\": function(element){return ("
748 + booleanStatement
749 + ");}\n});";
750 addScriptToPage(view, field, rule);
751 }
752
753
754
755
756
757
758
759
760
761
762
763 @SuppressWarnings("boxing")
764 private static String getMustOccurStatement(InputField field, MustOccurConstraint constraint) {
765 String statement = "";
766 List<String> attributePaths = new ArrayList<String>();
767 if (constraint != null && constraint.getApplyClientSide()) {
768 String array = "[";
769 if (constraint.getPrerequisiteConstraints() != null) {
770 for (int i = 0; i < constraint.getPrerequisiteConstraints().size(); i++) {
771 field.getControl().addStyleClass("dependsOn-" + constraint.getPrerequisiteConstraints().get(i)
772 .getPropertyName());
773 array = array + "'" + ScriptUtils.escapeName(constraint.getPrerequisiteConstraints().get(i)
774 .getPropertyName()) + "'";
775 attributePaths.add(constraint.getPrerequisiteConstraints().get(i).getPropertyName());
776 if (i + 1 != constraint.getPrerequisiteConstraints().size()) {
777 array = array + ",";
778 }
779
780 }
781 }
782 array = array + "]";
783 statement = "mustOccurTotal(" + array + ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
784
785 if (constraint.getMin() != null) {
786 attributePaths.add(constraint.getMin().toString());
787 } else {
788 attributePaths.add(null);
789 }
790
791 if (constraint.getMax() != null) {
792 attributePaths.add(constraint.getMax().toString());
793 } else {
794 attributePaths.add(null);
795 }
796
797 mustOccursPathNames.add(attributePaths);
798 if (StringUtils.isEmpty(statement)) {
799 statement = "0";
800 }
801 if (constraint.getMustOccurConstraints() != null) {
802 for (MustOccurConstraint mc : constraint.getMustOccurConstraints()) {
803 statement = "mustOccurCheck(" + statement + " + " + getMustOccurStatement(field, mc) +
804 ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
805 }
806 } else {
807 statement = "mustOccurCheck(" + statement +
808 ", " + constraint.getMin() + ", " + constraint.getMax() + ")";
809 }
810 }
811 return statement;
812 }
813
814
815
816
817
818
819
820
821
822
823 private static String getMustOccursMessage(View view, MustOccurConstraint constraint) {
824 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
825
826 String message = "";
827 if (StringUtils.isNotEmpty(constraint.getMessageKey())) {
828 message = generateMessageText(constraint.getMessageNamespaceCode(), constraint.getMessageComponentCode(),
829 constraint.getMessageKey(), constraint.getValidationMessageParams());
830 } else {
831 String and = messageService.getMessageText(AND_MSG_KEY);
832 String or = messageService.getMessageText(OR_MSG_KEY);
833 String all = messageService.getMessageText(ALL_MSG_KEY);
834 String mustOccursMsgEqualMinMax = messageService.getMessageText(
835 UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + MUSTOCCURS_MSG_EQUAL_KEY);
836 String atMost = messageService.getMessageText(ATMOST_MSG_KEY);
837 String genericLabel = messageService.getMessageText(GENERIC_FIELD_MSG_KEY);
838 String mustOccursMsg = messageService.getMessageText(
839 UifConstants.Messages.VALIDATION_MSG_KEY_PREFIX + MUSTOCCURS_MSG_KEY);
840
841 String statement = "";
842 for (int i = 0; i < mustOccursPathNames.size(); i++) {
843 String andedString = "";
844
845 List<String> paths = mustOccursPathNames.get(i);
846 if (!paths.isEmpty()) {
847
848 String min = paths.get(paths.size() - 2);
849 String max = paths.get(paths.size() - 1);
850 for (int j = 0; j < paths.size() - 2; j++) {
851 InputField field = (InputField) view.getViewIndex().getDataFieldByPath(paths.get(j).trim());
852 String label = genericLabel;
853 if (field != null && StringUtils.isNotEmpty(field.getLabel())) {
854 label = field.getLabel();
855 }
856 if (min.equals(max)) {
857 if (j == 0) {
858 andedString = label;
859 } else if (j == paths.size() - 3) {
860 andedString = andedString + " " + and + " " + label;
861 } else {
862 andedString = andedString + ", " + label;
863 }
864 } else {
865 andedString = andedString + "(" + label + ")";
866 }
867 }
868 if (min.equals(max)) {
869 andedString = "(" + andedString + ")";
870 }
871
872 if (StringUtils.isNotBlank(andedString) && !andedString.equals("()")) {
873 if (StringUtils.isNotEmpty(min) && StringUtils.isNotEmpty(max) && !min.equals(max)) {
874 andedString = MessageFormat.format(mustOccursMsg, min + "-" + max) + " " + andedString;
875 } else if (StringUtils.isNotEmpty(min)
876 && StringUtils.isNotEmpty(max)
877 && min.equals(max)
878 && i == 0) {
879 andedString = mustOccursMsgEqualMinMax + " " + andedString;
880 } else if (StringUtils.isNotEmpty(min)
881 && StringUtils.isNotEmpty(max)
882 && min.equals(max)
883 && i != 0) {
884
885 } else if (StringUtils.isNotEmpty(min)) {
886 andedString = MessageFormat.format(mustOccursMsg, min) + " " + andedString;
887 } else if (StringUtils.isNotEmpty(max)) {
888 andedString = MessageFormat.format(mustOccursMsg, atMost + " " + max) + " " + andedString;
889 }
890 }
891 }
892 if (StringUtils.isNotEmpty(andedString)) {
893 if (StringUtils.isNotBlank(statement)) {
894 statement = statement + " " + or.toUpperCase() + " " + andedString;
895 } else {
896 statement = andedString;
897 }
898 }
899 }
900 if (StringUtils.isNotEmpty(statement)) {
901 message = statement;
902 message = message.replace(")(", " " + or + " ");
903 }
904 }
905
906 return message;
907 }
908
909
910
911
912
913
914
915
916
917 @SuppressWarnings("boxing")
918 public static void processAndApplyConstraints(InputField field, View view, Object model) {
919 methodKey = 0;
920 String validationState = ConstraintStateUtils.getClientViewValidationState(model, view);
921 StateMapping stateMapping = view.getStateMapping();
922
923 if (view instanceof FormView && ((FormView) view).isValidateClientSide()) {
924 SimpleConstraint simpleConstraint = ConstraintStateUtils.getApplicableConstraint(
925 field.getSimpleConstraint(), validationState, stateMapping);
926 if (simpleConstraint != null && simpleConstraint.getApplyClientSide()) {
927
928 if ((simpleConstraint.getRequired() != null) && (simpleConstraint.getRequired().booleanValue())) {
929 field.getControl().addStyleClass("required");
930 }
931
932 if (simpleConstraint.getExclusiveMin() != null) {
933 if (field.getControl() instanceof TextControl
934 && ((TextControl) field.getControl()).getDatePicker() != null) {
935 ((TextControl) field.getControl()).getDatePicker().getTemplateOptions().put("minDate",
936 simpleConstraint.getExclusiveMin());
937 } else {
938 String rule = "jQuery('[name=\""
939 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
940 + "\"]').rules(\"add\", {\n minExclusive: ["
941 + simpleConstraint.getExclusiveMin()
942 + "]});";
943 addScriptToPage(view, field, rule);
944 }
945 }
946
947 if (simpleConstraint.getInclusiveMax() != null) {
948 if (field.getControl() instanceof TextControl
949 && ((TextControl) field.getControl()).getDatePicker() != null) {
950 ((TextControl) field.getControl()).getDatePicker().getTemplateOptions().put("maxDate",
951 simpleConstraint.getInclusiveMax());
952 } else {
953 String rule = "jQuery('[name=\""
954 + ScriptUtils.escapeName(field.getBindingInfo().getBindingPath())
955 + "\"]').rules(\"add\", {\n maxInclusive: ["
956 + simpleConstraint.getInclusiveMax()
957 + "]});";
958 addScriptToPage(view, field, rule);
959 }
960 }
961 }
962
963 ValidCharactersConstraint validCharactersConstraint = ConstraintStateUtils.getApplicableConstraint(
964 field.getValidCharactersConstraint(), validationState, stateMapping);
965
966 if (validCharactersConstraint != null && validCharactersConstraint.getApplyClientSide()) {
967 if (StringUtils.isNotEmpty(validCharactersConstraint.getValue())) {
968
969 addScriptToPage(view, field, ClientValidationUtils.getRegexMethod(field,
970 validCharactersConstraint));
971 field.getControl().addStyleClass(
972 "validChar-" + field.getBindingInfo().getBindingPath() + methodKey);
973 methodKey++;
974 } else {
975
976 if (StringUtils.isNotEmpty(validCharactersConstraint.getMessageKey())) {
977 field.getControl().addStyleClass(validCharactersConstraint.getMessageKey());
978 }
979 }
980 }
981
982 CaseConstraint caseConstraint = ConstraintStateUtils.getApplicableConstraint(field.getCaseConstraint(),
983 validationState, stateMapping);
984 if (caseConstraint != null && caseConstraint.getApplyClientSide()) {
985 processCaseConstraint(field, view, caseConstraint, null, validationState, stateMapping);
986 }
987
988 if (field.getDependencyConstraints() != null) {
989 for (PrerequisiteConstraint prc : field.getDependencyConstraints()) {
990 prc = ConstraintStateUtils.getApplicableConstraint(prc, validationState, stateMapping);
991 if (prc != null) {
992 processPrerequisiteConstraint(field, prc, view);
993 }
994 }
995 }
996
997 if (field.getMustOccurConstraints() != null) {
998 for (MustOccurConstraint mc : field.getMustOccurConstraints()) {
999 mc = ConstraintStateUtils.getApplicableConstraint(mc, validationState, stateMapping);
1000 if (mc != null) {
1001 processMustOccurConstraint(field, view, mc, "true");
1002 }
1003 }
1004 }
1005
1006 }
1007 }
1008
1009 }