1 package org.andromda.cartridges.jsf;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.Iterator;
7 import java.util.LinkedHashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.regex.Pattern;
11
12 import org.andromda.cartridges.jsf.metafacades.JSFAttribute;
13 import org.andromda.cartridges.jsf.metafacades.JSFParameter;
14 import org.andromda.metafacades.uml.AttributeFacade;
15 import org.andromda.metafacades.uml.ClassifierFacade;
16 import org.andromda.metafacades.uml.FrontEndAction;
17 import org.andromda.metafacades.uml.FrontEndParameter;
18 import org.andromda.metafacades.uml.ModelElementFacade;
19 import org.andromda.metafacades.uml.OperationFacade;
20 import org.andromda.metafacades.uml.ParameterFacade;
21 import org.andromda.metafacades.uml.UMLMetafacadeUtils;
22 import org.andromda.utils.StringUtilsHelper;
23 import org.apache.commons.lang.ObjectUtils;
24 import org.apache.commons.lang.StringUtils;
25
26
27 /**
28 * Utilties for use within the JSF cartridge.
29 *
30 * @author Chad Brandon
31 */
32 public class JSFUtils
33 {
34 /**
35 * Converts the argument into a web resource name, this means: all lowercase
36 * characters and words are separated with dashes.
37 *
38 * @param string any string
39 * @return the string converted to a value that would be well-suited for a
40 * web file name
41 */
42 public static String toWebResourceName(final String string)
43 {
44 return StringUtilsHelper.separate(
45 string,
46 "-").toLowerCase();
47 }
48
49 private static final Pattern VALIDATOR_TAGGEDVALUE_PATTERN =
50 Pattern.compile("\\w+(\\(\\w+=[^,)]*(,\\w+=[^,)]*)*\\))?");
51
52 /**
53 * Reads the validator arguments from the the given tagged value.
54 *
55 * @return returns a list of String instances or an empty list
56 * @throws IllegalArgumentException when the input string does not match the required pattern
57 */
58 public static List parseValidatorArgs(String validatorTaggedValue)
59 {
60 if (validatorTaggedValue == null)
61 {
62 throw new IllegalArgumentException("Validator tagged value cannot be null");
63 }
64
65
66 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
67 {
68 throw new IllegalArgumentException(
69 "Illegal validator tagged value (this tag is used to specify custom validators " +
70 "and might look like myValidator(myVar=myArg,myVar2=myArg2), perhaps you wanted to use " +
71 "@andromda.presentation.view.field.format?): " + validatorTaggedValue);
72 }
73
74 final List validatorArgs = new ArrayList();
75
76
77 int left = validatorTaggedValue.indexOf('(');
78 if (left > -1)
79 {
80 final int right = validatorTaggedValue.indexOf(')');
81 validatorTaggedValue = validatorTaggedValue.substring(
82 left + 1,
83 right);
84
85 final String[] pairs = validatorTaggedValue.split(",");
86 for (int i = 0; i < pairs.length; i++)
87 {
88 final String pair = pairs[i];
89 final int equalsIndex = pair.indexOf('=');
90
91
92 if (equalsIndex < pair.length() - 1)
93 {
94 validatorArgs.add(pair.substring(equalsIndex + 1));
95 }
96 else
97 {
98 validatorArgs.add("");
99 }
100 }
101 }
102 return validatorArgs;
103 }
104
105 /**
106 * Reads the validator variable names from the the given tagged value.
107 *
108 * @return never null, returns a list of String instances
109 * @throws IllegalArgumentException when the input string does not match the required pattern
110 */
111 public static List parseValidatorVars(String validatorTaggedValue)
112 {
113 if (validatorTaggedValue == null)
114 {
115 throw new IllegalArgumentException("Validator tagged value cannot be null");
116 }
117
118
119 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
120 {
121 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
122 }
123
124 final List validatorVars = new ArrayList();
125
126
127 int left = validatorTaggedValue.indexOf('(');
128 if (left > -1)
129 {
130 int right = validatorTaggedValue.indexOf(')');
131 validatorTaggedValue = validatorTaggedValue.substring(
132 left + 1,
133 right);
134
135 final String[] pairs = validatorTaggedValue.split(",");
136 for (int i = 0; i < pairs.length; i++)
137 {
138 final String pair = pairs[i];
139 final int equalsIndex = pair.indexOf('=');
140 validatorVars.add(pair.substring(
141 0,
142 equalsIndex));
143 }
144 }
145 return validatorVars;
146 }
147
148 /**
149 * Parses the validator name for a tagged value.
150 *
151 * @throws IllegalArgumentException when the input string does not match the required pattern
152 */
153 public static String parseValidatorName(final String validatorTaggedValue)
154 {
155 if (validatorTaggedValue == null)
156 {
157 throw new IllegalArgumentException("Validator tagged value cannot be null");
158 }
159
160
161 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
162 {
163 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
164 }
165
166 final int leftParen = validatorTaggedValue.indexOf('(');
167 return (leftParen == -1) ? validatorTaggedValue : validatorTaggedValue.substring(
168 0,
169 leftParen);
170 }
171
172 /**
173 * Constructs a string representing an array initialization in Java.
174 *
175 * @param name the name to give the array.
176 * @param count the number of items to give the array.
177 * @return A String representing Java code for the initialization of an array.
178 */
179 public static String constructDummyArrayDeclaration(
180 final String name,
181 final int count)
182 {
183 final StringBuffer array = new StringBuffer("new Object[] {");
184 for (int ctr = 1; ctr <= count; ctr++)
185 {
186 array.append("\"" + name + "-" + ctr + "\"");
187 if (ctr != count)
188 {
189 array.append(", ");
190 }
191 }
192 array.append("}");
193 return array.toString();
194 }
195
196 /**
197 * @return this field's date format
198 */
199 public static String getDateFormat(String format)
200 {
201 format = StringUtils.trimToEmpty(format);
202 return format.endsWith(STRICT) ? getToken(
203 format,
204 1,
205 2) : getToken(
206 format,
207 0,
208 1);
209 }
210
211 private static final String STRICT = "strict";
212
213 /**
214 * @return <code>true</code> if this field's value needs to conform to a strict date format, <code>false</code> otherwise
215 */
216 public static boolean isStrictDateFormat(String format)
217 {
218 return strictDateTimeFormat ? strictDateTimeFormat : STRICT.equalsIgnoreCase(getToken(
219 format,
220 0,
221 2));
222 }
223
224 /**
225 * Indicates if the given <code>format</code> is an email format.
226 *
227 * @return <code>true</code> if this field is to be formatted as an email address, <code>false</code> otherwise
228 */
229 public static boolean isEmailFormat(String format)
230 {
231 return "email".equalsIgnoreCase(JSFUtils.getToken(
232 format,
233 0,
234 2));
235 }
236
237 /**
238 * Indicates if the given <code>format</code> is an equal format.
239 *
240 * @return <code>true</code> if this field is to be formatted as an email address, <code>false</code> otherwise
241 */
242 public static boolean isEqualFormat(String format)
243 {
244 return "equal".equalsIgnoreCase(JSFUtils.getToken(
245 format,
246 0,
247 2));
248 }
249
250 /**
251 * Indicates if the given <code>format</code> is a creditcard format.
252 *
253 * @return <code>true</code> if this field is to be formatted as a credit card, <code>false</code> otherwise
254 */
255 public static boolean isCreditCardFormat(final String format)
256 {
257 return "creditcard".equalsIgnoreCase(JSFUtils.getToken(
258 format,
259 0,
260 2));
261 }
262
263 /**
264 * Indicates if the given <code>format</code> is a pattern format.
265 *
266 * @return <code>true</code> if this field's value needs to respect a certain pattern, <code>false</code> otherwise
267 */
268 public static boolean isPatternFormat(final String format)
269 {
270 return "pattern".equalsIgnoreCase(JSFUtils.getToken(
271 format,
272 0,
273 2));
274 }
275
276 /**
277 * Indicates if the given <code>format</code> is a minlength format.
278 *
279 * @return <code>true</code> if this field's value needs to consist of at least a certain
280 * number of characters, <code>false</code> otherwise
281 */
282 public static boolean isMinLengthFormat(final String format)
283 {
284 return "minlength".equalsIgnoreCase(JSFUtils.getToken(
285 format,
286 0,
287 2));
288 }
289
290 /**
291 * Indicates if the given <code>format</code> is a maxlength format.
292 *
293 * @return <code>true</code> if this field's value needs to consist of at maximum a certain
294 * number of characters, <code>false</code> otherwise
295 */
296 public static boolean isMaxLengthFormat(String format)
297 {
298 return "maxlength".equalsIgnoreCase(JSFUtils.getToken(
299 format,
300 0,
301 2));
302 }
303
304 /**
305 * @return the i-th space delimited token read from the argument String, where i does not exceed the specified limit
306 */
307 public static String getToken(
308 String string,
309 int index,
310 int limit)
311 {
312 String token = null;
313 if (string != null && string.length() > 0)
314 {
315 final String[] tokens = string.split(
316 "[\\s]+",
317 limit);
318 token = index >= tokens.length ? null : tokens[index];
319 }
320 return token;
321 }
322
323 /**
324 * Retrieves the input format (if one is defined), for the given
325 * <code>element</code>.
326 * @param element the model element for which to retrieve the input format.
327 * @return the input format.
328 */
329 public static String getInputFormat(final ModelElementFacade element)
330 {
331 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
332 final String format = value == null ? null : String.valueOf(value);
333 return format == null ? null : format.trim();
334 }
335
336 /**
337 * Indicates if the given <code>format</code> is a range format.
338 *
339 * @return <code>true</code> if this field's value needs to be in a specific range, <code>false</code> otherwise
340 */
341 public static boolean isRangeFormat(final String format)
342 {
343 return "range".equalsIgnoreCase(JSFUtils.getToken(
344 format,
345 0,
346 2));
347 }
348
349 /**
350 * @return <code>true</code> if the type of this field is a byte, <code>false</code> otherwise
351 */
352 public static boolean isByte(final ClassifierFacade type)
353 {
354 return UMLMetafacadeUtils.isType(
355 type,
356 JSFProfile.BYTE_TYPE_NAME);
357 }
358
359 /**
360 * @return <code>true</code> if the type of this field is a short, <code>false</code> otherwise
361 */
362 public static boolean isShort(final ClassifierFacade type)
363 {
364 return UMLMetafacadeUtils.isType(
365 type,
366 JSFProfile.SHORT_TYPE_NAME);
367 }
368
369 /**
370 * @return <code>true</code> if the type of this field is an integer, <code>false</code> otherwise
371 */
372 public static boolean isInteger(final ClassifierFacade type)
373 {
374 return UMLMetafacadeUtils.isType(
375 type,
376 JSFProfile.INTEGER_TYPE_NAME);
377 }
378
379 /**
380 * @return <code>true</code> if the type of this field is a long integer, <code>false</code> otherwise
381 */
382 public static boolean isLong(final ClassifierFacade type)
383 {
384 return UMLMetafacadeUtils.isType(
385 type,
386 JSFProfile.LONG_TYPE_NAME);
387 }
388
389 /**
390 * @return <code>true</code> if the type of this field is a floating point, <code>false</code> otherwise
391 */
392 public static boolean isFloat(final ClassifierFacade type)
393 {
394 return UMLMetafacadeUtils.isType(
395 type,
396 JSFProfile.FLOAT_TYPE_NAME);
397 }
398
399 /**
400 * @return <code>true</code> if the type of this field is a double precision floating point, <code>false</code> otherwise
401 */
402 public static boolean isDouble(final ClassifierFacade type)
403 {
404 return UMLMetafacadeUtils.isType(
405 type,
406 JSFProfile.DOUBLE_TYPE_NAME);
407 }
408
409 /**
410 * @return <code>true</code> if the type of this field is a date, <code>false</code> otherwise
411 */
412 public static boolean isDate(final ClassifierFacade type)
413 {
414 return type != null && type.isDateType();
415 }
416
417 /**
418 * @return <code>true</code> if the type of this field is a time, <code>false</code> otherwise
419 */
420 public static boolean isTime(final ClassifierFacade type)
421 {
422 return UMLMetafacadeUtils.isType(
423 type,
424 JSFProfile.TIME_TYPE_NAME);
425 }
426
427 /**
428 * @return <code>true</code> if the type of this field is a URL, <code>false</code> otherwise
429 */
430 public static boolean isUrl(final ClassifierFacade type)
431 {
432 return UMLMetafacadeUtils.isType(
433 type,
434 JSFProfile.URL_TYPE_NAME);
435 }
436
437 /**
438 * @return <code>true</code> if the type of this field is a String, <code>false</code> otherwise
439 */
440 public static boolean isString(final ClassifierFacade type)
441 {
442 return type != null && type.isStringType();
443 }
444
445 /**
446 * Indicates if the given element is read-only or not.
447 *
448 * @param element the element to check.
449 * @return true/false
450 */
451 public static boolean isReadOnly(final ModelElementFacade element)
452 {
453 boolean readOnly = false;
454 if (element != null)
455 {
456 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_READONLY);
457 readOnly = Boolean.valueOf(ObjectUtils.toString(value)).booleanValue();
458 }
459 return readOnly;
460 }
461
462 /**
463 * Retrieves the "equal" value from the given element (if one is present).
464 *
465 * @param element the element from which to retrieve the equal value.
466 * @param ownerParameter the optional owner parameter (specified if the element is an attribute).
467 * @return the "equal" value.
468 */
469 public static java.lang.String getEqual(final ModelElementFacade element, final ParameterFacade ownerParameter)
470 {
471 String equal = null;
472 if (element != null)
473 {
474 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_EQUAL);
475 equal = value == null ? null : value.toString();
476 if (StringUtils.isNotBlank(equal) && ownerParameter != null)
477 {
478 equal = ownerParameter.getName() + StringUtilsHelper.upperCamelCaseName(equal);
479 }
480 }
481 return equal;
482 }
483
484 /**
485 * Retrieves the "validwhen" value from the given element (if one is present).
486 *
487 * @param element the element from which to retrieve the validwhen value.
488 * @return the "validwhen" value.
489 */
490 public static java.lang.String getValidWhen(final ModelElementFacade element)
491 {
492 String validWhen = null;
493 if (element != null)
494 {
495 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_VALIDWHEN);
496 validWhen = value == null ? null : '(' + value.toString() + ')';
497 }
498 return validWhen;
499 }
500
501 /**
502 * @return the lower limit for this field's value's range
503 */
504 public static String getRangeStart(final String format)
505 {
506 return JSFUtils.getToken(
507 format,
508 1,
509 3);
510 }
511
512 /**
513 * @return the upper limit for this field's value's range
514 */
515 public static String getRangeEnd(final String format)
516 {
517 return JSFUtils.getToken(
518 format,
519 2,
520 3);
521 }
522
523 /**
524 * @return the minimum number of characters this field's value must consist of
525 */
526 public static String getMinLengthValue(final String format)
527 {
528 return JSFUtils.getToken(
529 format,
530 1,
531 2);
532 }
533
534 /**
535 * @return the maximum number of characters this field's value must consist of
536 */
537 public static String getMaxLengthValue(final String format)
538 {
539 return JSFUtils.getToken(
540 format,
541 1,
542 2);
543 }
544
545 /**
546 * @return the pattern this field's value must respect
547 */
548 public static String getPatternValue(final String format)
549 {
550 return '^' + JSFUtils.getToken(
551 format,
552 1,
553 2) + '$';
554 }
555
556 /**
557 * Retrieves the validator types as a collection from the given
558 * <code>element</code> (if any can be retrieved).
559 *
560 * @param element the element from which to retrieve the types.
561 * @param type the type of the element.
562 * @return the collection of validator types.
563 */
564 public static java.util.Collection getValidatorTypes(
565 final ModelElementFacade element,
566 final ClassifierFacade type)
567 {
568 final Collection validatorTypesList = new ArrayList();
569 if (element != null && type != null)
570 {
571 final String format = JSFUtils.getInputFormat(element);
572 final boolean isRangeFormat = format != null && isRangeFormat(format);
573 if (element instanceof AttributeFacade)
574 {
575 if (((AttributeFacade)element).isRequired())
576 {
577 validatorTypesList.add("required");
578 }
579 }
580 else if (element instanceof JSFParameter)
581 {
582 if (((JSFParameter)element).isRequired())
583 {
584 validatorTypesList.add("required");
585 }
586 }
587 if (JSFUtils.isByte(type))
588 {
589 validatorTypesList.add("byte");
590 }
591 else if (JSFUtils.isShort(type))
592 {
593 validatorTypesList.add("short");
594 }
595 else if (JSFUtils.isInteger(type))
596 {
597 validatorTypesList.add("integer");
598 }
599 else if (JSFUtils.isLong(type))
600 {
601 validatorTypesList.add("long");
602 }
603 else if (JSFUtils.isFloat(type))
604 {
605 validatorTypesList.add("float");
606 }
607 else if (JSFUtils.isDouble(type))
608 {
609 validatorTypesList.add("double");
610 }
611 else if (JSFUtils.isDate(type))
612 {
613 validatorTypesList.add("date");
614 }
615 else if (JSFUtils.isTime(type))
616 {
617 validatorTypesList.add("time");
618 }
619 else if (JSFUtils.isUrl(type))
620 {
621 validatorTypesList.add("url");
622 }
623
624 if (isRangeFormat)
625 {
626 if (JSFUtils.isInteger(type) || JSFUtils.isShort(type) || JSFUtils.isLong(type))
627 {
628 validatorTypesList.add("intRange");
629 }
630 if (JSFUtils.isFloat(type))
631 {
632 validatorTypesList.add("floatRange");
633 }
634 if (JSFUtils.isDouble(type))
635 {
636 validatorTypesList.add("doubleRange");
637 }
638 }
639
640 if (format != null)
641 {
642 if (JSFUtils.isString(type) && JSFUtils.isEmailFormat(format))
643 {
644 validatorTypesList.add("email");
645 }
646 else if (JSFUtils.isString(type) && JSFUtils.isCreditCardFormat(format))
647 {
648 validatorTypesList.add("creditCard");
649 }
650 else
651 {
652 Collection formats = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
653 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
654 {
655 String additionalFormat = String.valueOf(formatIterator.next());
656 if (JSFUtils.isMinLengthFormat(additionalFormat))
657 {
658 validatorTypesList.add("minlength");
659 }
660 else if (JSFUtils.isMaxLengthFormat(additionalFormat))
661 {
662 validatorTypesList.add("maxlength");
663 }
664 else if (JSFUtils.isPatternFormat(additionalFormat))
665 {
666 validatorTypesList.add("mask");
667 }
668 }
669 }
670 }
671
672 if (JSFUtils.getValidWhen(element) != null)
673 {
674 validatorTypesList.add("validwhen");
675 }
676 if (JSFUtils.getEqual(element, null) != null)
677 {
678 validatorTypesList.add("equal");
679 }
680 }
681
682
683 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
684 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
685 {
686 String validator = String.valueOf(iterator.next());
687 validatorTypesList.add(JSFUtils.parseValidatorName(validator));
688 }
689 return validatorTypesList;
690 }
691
692 /**
693 * Gets the validator variables for the given <code>element</code> (if they can
694 * be retrieved).
695 *
696 * @param element the element from which to retrieve the variables
697 * @param type the type of the element.
698 * @param ownerParameter the optional owner parameter (if the element is an attribute for example).
699 * @return the collection of validator variables.
700 */
701 public static java.util.Collection getValidatorVars(
702 final ModelElementFacade element,
703 final ClassifierFacade type,
704 final ParameterFacade ownerParameter)
705 {
706 final Map vars = new LinkedHashMap();
707 if (element != null && type != null)
708 {
709 final String format = JSFUtils.getInputFormat(element);
710 if (format != null)
711 {
712 final boolean isRangeFormat = JSFUtils.isRangeFormat(format);
713
714 if (isRangeFormat)
715 {
716 final String min = "min";
717 final String max = "max";
718 vars.put(
719 min,
720 Arrays.asList(new Object[] {min, JSFUtils.getRangeStart(format)}));
721 vars.put(
722 max,
723 Arrays.asList(new Object[] {max, JSFUtils.getRangeEnd(format)}));
724 }
725 else
726 {
727 final Collection formats = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
728 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
729 {
730 final String additionalFormat = String.valueOf(formatIterator.next());
731 final String minlength = "minlength";
732 final String maxlength = "maxlength";
733 final String mask = "mask";
734 if (JSFUtils.isMinLengthFormat(additionalFormat))
735 {
736 vars.put(
737 minlength,
738 Arrays.asList(new Object[] {minlength, JSFUtils.getMinLengthValue(additionalFormat)}));
739 }
740 else if (JSFUtils.isMaxLengthFormat(additionalFormat))
741 {
742 vars.put(
743 maxlength,
744 Arrays.asList(new Object[] {maxlength, JSFUtils.getMaxLengthValue(additionalFormat)}));
745 }
746 else if (JSFUtils.isPatternFormat(additionalFormat))
747 {
748 vars.put(
749 mask,
750 Arrays.asList(new Object[] {mask, JSFUtils.getPatternValue(additionalFormat)}));
751 }
752 }
753 }
754 }
755 String inputFormat;
756 if (element instanceof JSFAttribute)
757 {
758 inputFormat = ((JSFAttribute)element).getFormat();
759 }
760 else if (element instanceof JSFParameter)
761 {
762 inputFormat = ((JSFParameter)element).getFormat();
763 }
764 else
765 {
766 throw new RuntimeException("'element' is an invalid type, it must be either an instance of '" +
767 JSFAttribute.class.getName() + "' or '" + JSFParameter.class.getName() + "'");
768 }
769 if (JSFUtils.isDate(type))
770 {
771 final String datePatternStrict = "datePatternStrict";
772 if (format != null && JSFUtils.isStrictDateFormat(format))
773 {
774 vars.put(
775 datePatternStrict,
776 Arrays.asList(new Object[] {datePatternStrict, inputFormat}));
777 }
778 else
779 {
780 final String datePattern = "datePattern";
781 vars.put(
782 datePattern,
783 Arrays.asList(new Object[] {datePattern, inputFormat}));
784 }
785 }
786 if (JSFUtils.isTime(type))
787 {
788 final String timePattern = "timePattern";
789 vars.put(
790 timePattern,
791 Arrays.asList(new Object[] {timePattern, inputFormat}));
792 }
793
794 final String validWhen = JSFUtils.getValidWhen(element);
795 if (validWhen != null)
796 {
797 final String test = "test";
798 vars.put(
799 test,
800 Arrays.asList(new Object[] {test, validWhen}));
801 }
802
803 final String equal = JSFUtils.getEqual(element, ownerParameter);
804 if (equal != null)
805 {
806 final String fieldName = "fieldName";
807 vars.put(
808 fieldName,
809 Arrays.asList(new Object[] {fieldName, equal}));
810 }
811 }
812
813
814
815 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
816 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
817 {
818 final String validator = String.valueOf(iterator.next());
819
820
821 final List validatorVars = JSFUtils.parseValidatorVars(validator);
822 final List validatorArgs = JSFUtils.parseValidatorArgs(validator);
823
824 for (int ctr = 0; ctr < validatorVars.size(); ctr++)
825 {
826 final String validatorVar = (String)validatorVars.get(ctr);
827 final String validatorArg = (String)validatorArgs.get(ctr);
828 vars.put(
829 validatorVar,
830 Arrays.asList(new Object[] {validatorVar, validatorArg}));
831 }
832 }
833 return vars.values();
834 }
835
836 /**
837 * Gets the validator args for the <code>element</code> and the given <code>validatorType</code>.
838 *
839 * @param element the element for which to retrieve the arguments.
840 * @param validatorType the validator type name.
841 * @return the validator args as a collection.
842 */
843 public static java.util.Collection getValidatorArgs(
844 final ModelElementFacade element,
845 final java.lang.String validatorType)
846 {
847 final Collection args = new ArrayList();
848 if ("intRange".equals(validatorType) || "floatRange".equals(validatorType) ||
849 "doubleRange".equals(validatorType))
850 {
851 args.add("${var:min}");
852 args.add("${var:max}");
853 }
854 else if ("minlength".equals(validatorType))
855 {
856 args.add("${var:minlength}");
857 }
858 else if ("maxlength".equals(validatorType))
859 {
860 args.add("${var:maxlength}");
861 }
862 else if ("date".equals(validatorType))
863 {
864 final String validatorFormat = JSFUtils.getInputFormat(element);
865 if (JSFUtils.isStrictDateFormat(validatorFormat))
866 {
867 args.add("${var:datePatternStrict}");
868 }
869 else
870 {
871 args.add("${var:datePattern}");
872 }
873 }
874 else if ("time".equals(validatorType))
875 {
876 args.add("${var:timePattern}");
877 }
878 else if ("equal".equals(validatorType))
879 {
880 ModelElementFacade equalParameter = null;
881 final String equal = JSFUtils.getEqual(element, null);
882 if (element instanceof ParameterFacade)
883 {
884 final FrontEndParameter parameter = (FrontEndParameter)element;
885 final OperationFacade operation = parameter.getOperation();
886 if (operation != null)
887 {
888 equalParameter = operation.findParameter(equal);
889 }
890 if (equalParameter == null)
891 {
892 final FrontEndAction action = parameter.getAction();
893 if (action != null)
894 {
895 equalParameter = action.findParameter(equal);
896 }
897 }
898 }
899 else if (element instanceof AttributeFacade)
900 {
901 final AttributeFacade attribute = (AttributeFacade)element;
902 final ClassifierFacade owner = attribute.getOwner();
903 if (owner != null)
904 {
905 equalParameter = owner.findAttribute(equal);
906 }
907 }
908 args.add(equalParameter);
909 args.add("${var:fieldName}");
910 }
911
912
913 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
914 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
915 {
916 final String validator = String.valueOf(iterator.next());
917 if (validatorType.equals(JSFUtils.parseValidatorName(validator)))
918 {
919 args.addAll(JSFUtils.parseValidatorArgs(validator));
920 }
921 }
922 return args;
923 }
924
925 /**
926 * Whether or not date patterns should be treated as strict.
927 */
928 private static boolean strictDateTimeFormat;
929
930 /**
931 * Sets whether or not the dattern patterns should be treated as strict.
932 *
933 * @param strictDateTimeFormat
934 */
935 public void setStrictDateTimeFormat(final boolean strictDateTimeFormat)
936 {
937 JSFUtils.strictDateTimeFormat = strictDateTimeFormat;
938 }
939
940 /**
941 * Indicates whether or not the format for this element is a strict date
942 * format.
943 * @return true/false
944 */
945 public static boolean isStrictDateFormat(final ModelElementFacade element)
946 {
947 final String format = JSFUtils.getInputFormat(element);
948 return JSFUtils.isStrictDateFormat(format);
949 }
950
951 /**
952 * Gets the format string for the given <code>element</code>.
953 *
954 * @param element the element for which to retrieve the format.
955 * @param type the type of the element.
956 * @return the format string (if one is present otherwise null).
957 */
958 public static String getFormat(
959 final ModelElementFacade element,
960 final ClassifierFacade type,
961 final String defaultDateFormat,
962 final String defaultTimeFormat)
963 {
964 String format = null;
965 if (element != null && type != null)
966 {
967 format = JSFUtils.getInputFormat(element);
968 if (format == null)
969 {
970 if (type.isTimeType())
971 {
972 format = defaultTimeFormat;
973 }
974 else if (type.isDateType())
975 {
976 format = defaultDateFormat;
977 }
978 }
979 else if (type.isDateType())
980 {
981 format = JSFUtils.getDateFormat(format);
982 }
983 }
984 return format;
985 }
986
987 /**
988 * The JSP view type.
989 */
990 private static final String VIEW_TYPE_JSP = "jsp";
991
992 /**
993 * The facelet view type.
994 */
995 private static final String VIEW_TYPE_FACELETS = "facelets";
996
997 /**
998 * Stores the view type
999 */
1000 private String viewType;
1001
1002 /**
1003 * Sets the view type to use.
1004 *
1005 * @param viewType the view type.
1006 */
1007 public void setViewType(final String viewType)
1008 {
1009 this.viewType = viewType;
1010 }
1011
1012 /**
1013 * Gets the current view type.
1014 *
1015 * @return the view type.
1016 */
1017 public String getViewType()
1018 {
1019 return this.viewType;
1020 }
1021
1022 /**
1023 * The XHTML extension.
1024 */
1025 private static final String EXTENSION_XHTML = "xhtml";
1026
1027 /**
1028 * Gets the extension for the current view type.
1029 *
1030 * @return the view type extension.
1031 */
1032 public String getViewExtension()
1033 {
1034 String extension;
1035 if (VIEW_TYPE_JSP.equals(this.viewType))
1036 {
1037 extension = this.viewType;
1038 }
1039 else if (VIEW_TYPE_FACELETS.equals(this.viewType))
1040 {
1041 extension = EXTENSION_XHTML;
1042 }
1043 else
1044 {
1045 throw new RuntimeException("'" + this.viewType + "' is not a valid viewType, the options are '"
1046 + VIEW_TYPE_JSP + "' or '" + VIEW_TYPE_FACELETS + "'");
1047 }
1048 return extension;
1049 }
1050 }