View Javadoc

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          // check if the input tagged value matches the required pattern
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          // only keep what is between parentheses (if any)
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                  // it's possible the argument is the empty string
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         // check if the input tagged value matches the required pattern
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         // only keep what is between parentheses (if any)
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         // check if the input tagged value matches the required pattern
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         // - custom (paramterized) validators are allowed here
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         // - custom (parameterized) validators are allowed here
814         //   in this case we will reuse the validator arg values
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             // - guaranteed to be of the same length
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         // custom (paramterized) validators are allowed here
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 }