001: package org.andromda.cartridges.jsf;
002:
003: import java.util.ArrayList;
004: import java.util.Arrays;
005: import java.util.Collection;
006: import java.util.Iterator;
007: import java.util.LinkedHashMap;
008: import java.util.List;
009: import java.util.Map;
010: import java.util.regex.Pattern;
011:
012: import org.andromda.cartridges.jsf.metafacades.JSFAttribute;
013: import org.andromda.cartridges.jsf.metafacades.JSFParameter;
014: import org.andromda.metafacades.uml.AttributeFacade;
015: import org.andromda.metafacades.uml.ClassifierFacade;
016: import org.andromda.metafacades.uml.FrontEndAction;
017: import org.andromda.metafacades.uml.FrontEndParameter;
018: import org.andromda.metafacades.uml.ModelElementFacade;
019: import org.andromda.metafacades.uml.OperationFacade;
020: import org.andromda.metafacades.uml.ParameterFacade;
021: import org.andromda.metafacades.uml.UMLMetafacadeUtils;
022: import org.andromda.utils.StringUtilsHelper;
023: import org.apache.commons.lang.ObjectUtils;
024: import org.apache.commons.lang.StringUtils;
025:
026: /**
027: * Utilties for use within the JSF cartridge.
028: *
029: * @author Chad Brandon
030: */
031: public class JSFUtils {
032: /**
033: * Converts the argument into a web resource name, this means: all lowercase
034: * characters and words are separated with dashes.
035: *
036: * @param string any string
037: * @return the string converted to a value that would be well-suited for a
038: * web file name
039: */
040: public static String toWebResourceName(final String string) {
041: return StringUtilsHelper.separate(string, "-").toLowerCase();
042: }
043:
044: private static final Pattern VALIDATOR_TAGGEDVALUE_PATTERN = Pattern
045: .compile("\\w+(\\(\\w+=[^,)]*(,\\w+=[^,)]*)*\\))?");
046:
047: /**
048: * Reads the validator arguments from the the given tagged value.
049: *
050: * @return returns a list of String instances or an empty list
051: * @throws IllegalArgumentException when the input string does not match the required pattern
052: */
053: public static List parseValidatorArgs(String validatorTaggedValue) {
054: if (validatorTaggedValue == null) {
055: throw new IllegalArgumentException(
056: "Validator tagged value cannot be null");
057: }
058:
059: // check if the input tagged value matches the required pattern
060: if (!VALIDATOR_TAGGEDVALUE_PATTERN
061: .matcher(validatorTaggedValue).matches()) {
062: throw new IllegalArgumentException(
063: "Illegal validator tagged value (this tag is used to specify custom validators "
064: + "and might look like myValidator(myVar=myArg,myVar2=myArg2), perhaps you wanted to use "
065: + "@andromda.presentation.view.field.format?): "
066: + validatorTaggedValue);
067: }
068:
069: final List validatorArgs = new ArrayList();
070:
071: // only keep what is between parentheses (if any)
072: int left = validatorTaggedValue.indexOf('(');
073: if (left > -1) {
074: final int right = validatorTaggedValue.indexOf(')');
075: validatorTaggedValue = validatorTaggedValue.substring(
076: left + 1, right);
077:
078: final String[] pairs = validatorTaggedValue.split(",");
079: for (int i = 0; i < pairs.length; i++) {
080: final String pair = pairs[i];
081: final int equalsIndex = pair.indexOf('=');
082:
083: // it's possible the argument is the empty string
084: if (equalsIndex < pair.length() - 1) {
085: validatorArgs.add(pair.substring(equalsIndex + 1));
086: } else {
087: validatorArgs.add("");
088: }
089: }
090: }
091: return validatorArgs;
092: }
093:
094: /**
095: * Reads the validator variable names from the the given tagged value.
096: *
097: * @return never null, returns a list of String instances
098: * @throws IllegalArgumentException when the input string does not match the required pattern
099: */
100: public static List parseValidatorVars(String validatorTaggedValue) {
101: if (validatorTaggedValue == null) {
102: throw new IllegalArgumentException(
103: "Validator tagged value cannot be null");
104: }
105:
106: // check if the input tagged value matches the required pattern
107: if (!VALIDATOR_TAGGEDVALUE_PATTERN
108: .matcher(validatorTaggedValue).matches()) {
109: throw new IllegalArgumentException(
110: "Illegal validator tagged value: "
111: + validatorTaggedValue);
112: }
113:
114: final List validatorVars = new ArrayList();
115:
116: // only keep what is between parentheses (if any)
117: int left = validatorTaggedValue.indexOf('(');
118: if (left > -1) {
119: int right = validatorTaggedValue.indexOf(')');
120: validatorTaggedValue = validatorTaggedValue.substring(
121: left + 1, right);
122:
123: final String[] pairs = validatorTaggedValue.split(",");
124: for (int i = 0; i < pairs.length; i++) {
125: final String pair = pairs[i];
126: final int equalsIndex = pair.indexOf('=');
127: validatorVars.add(pair.substring(0, equalsIndex));
128: }
129: }
130: return validatorVars;
131: }
132:
133: /**
134: * Parses the validator name for a tagged value.
135: *
136: * @throws IllegalArgumentException when the input string does not match the required pattern
137: */
138: public static String parseValidatorName(
139: final String validatorTaggedValue) {
140: if (validatorTaggedValue == null) {
141: throw new IllegalArgumentException(
142: "Validator tagged value cannot be null");
143: }
144:
145: // check if the input tagged value matches the required pattern
146: if (!VALIDATOR_TAGGEDVALUE_PATTERN
147: .matcher(validatorTaggedValue).matches()) {
148: throw new IllegalArgumentException(
149: "Illegal validator tagged value: "
150: + validatorTaggedValue);
151: }
152:
153: final int leftParen = validatorTaggedValue.indexOf('(');
154: return (leftParen == -1) ? validatorTaggedValue
155: : validatorTaggedValue.substring(0, leftParen);
156: }
157:
158: /**
159: * Constructs a string representing an array initialization in Java.
160: *
161: * @param name the name to give the array.
162: * @param count the number of items to give the array.
163: * @return A String representing Java code for the initialization of an array.
164: */
165: public static String constructDummyArrayDeclaration(
166: final String name, final int count) {
167: final StringBuffer array = new StringBuffer("new Object[] {");
168: for (int ctr = 1; ctr <= count; ctr++) {
169: array.append("\"" + name + "-" + ctr + "\"");
170: if (ctr != count) {
171: array.append(", ");
172: }
173: }
174: array.append("}");
175: return array.toString();
176: }
177:
178: /**
179: * @return this field's date format
180: */
181: public static String getDateFormat(String format) {
182: format = StringUtils.trimToEmpty(format);
183: return format.endsWith(STRICT) ? getToken(format, 1, 2)
184: : getToken(format, 0, 1);
185: }
186:
187: private static final String STRICT = "strict";
188:
189: /**
190: * @return <code>true</code> if this field's value needs to conform to a strict date format, <code>false</code> otherwise
191: */
192: public static boolean isStrictDateFormat(String format) {
193: return strictDateTimeFormat ? strictDateTimeFormat : STRICT
194: .equalsIgnoreCase(getToken(format, 0, 2));
195: }
196:
197: /**
198: * Indicates if the given <code>format</code> is an email format.
199: *
200: * @return <code>true</code> if this field is to be formatted as an email address, <code>false</code> otherwise
201: */
202: public static boolean isEmailFormat(String format) {
203: return "email"
204: .equalsIgnoreCase(JSFUtils.getToken(format, 0, 2));
205: }
206:
207: /**
208: * Indicates if the given <code>format</code> is an equal format.
209: *
210: * @return <code>true</code> if this field is to be formatted as an email address, <code>false</code> otherwise
211: */
212: public static boolean isEqualFormat(String format) {
213: return "equal"
214: .equalsIgnoreCase(JSFUtils.getToken(format, 0, 2));
215: }
216:
217: /**
218: * Indicates if the given <code>format</code> is a creditcard format.
219: *
220: * @return <code>true</code> if this field is to be formatted as a credit card, <code>false</code> otherwise
221: */
222: public static boolean isCreditCardFormat(final String format) {
223: return "creditcard".equalsIgnoreCase(JSFUtils.getToken(format,
224: 0, 2));
225: }
226:
227: /**
228: * Indicates if the given <code>format</code> is a pattern format.
229: *
230: * @return <code>true</code> if this field's value needs to respect a certain pattern, <code>false</code> otherwise
231: */
232: public static boolean isPatternFormat(final String format) {
233: return "pattern".equalsIgnoreCase(JSFUtils.getToken(format, 0,
234: 2));
235: }
236:
237: /**
238: * Indicates if the given <code>format</code> is a minlength format.
239: *
240: * @return <code>true</code> if this field's value needs to consist of at least a certain
241: * number of characters, <code>false</code> otherwise
242: */
243: public static boolean isMinLengthFormat(final String format) {
244: return "minlength".equalsIgnoreCase(JSFUtils.getToken(format,
245: 0, 2));
246: }
247:
248: /**
249: * Indicates if the given <code>format</code> is a maxlength format.
250: *
251: * @return <code>true</code> if this field's value needs to consist of at maximum a certain
252: * number of characters, <code>false</code> otherwise
253: */
254: public static boolean isMaxLengthFormat(String format) {
255: return "maxlength".equalsIgnoreCase(JSFUtils.getToken(format,
256: 0, 2));
257: }
258:
259: /**
260: * @return the i-th space delimited token read from the argument String, where i does not exceed the specified limit
261: */
262: public static String getToken(String string, int index, int limit) {
263: String token = null;
264: if (string != null && string.length() > 0) {
265: final String[] tokens = string.split("[\\s]+", limit);
266: token = index >= tokens.length ? null : tokens[index];
267: }
268: return token;
269: }
270:
271: /**
272: * Retrieves the input format (if one is defined), for the given
273: * <code>element</code>.
274: * @param element the model element for which to retrieve the input format.
275: * @return the input format.
276: */
277: public static String getInputFormat(final ModelElementFacade element) {
278: final Object value = element
279: .findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
280: final String format = value == null ? null : String
281: .valueOf(value);
282: return format == null ? null : format.trim();
283: }
284:
285: /**
286: * Indicates if the given <code>format</code> is a range format.
287: *
288: * @return <code>true</code> if this field's value needs to be in a specific range, <code>false</code> otherwise
289: */
290: public static boolean isRangeFormat(final String format) {
291: return "range"
292: .equalsIgnoreCase(JSFUtils.getToken(format, 0, 2));
293: }
294:
295: /**
296: * @return <code>true</code> if the type of this field is a byte, <code>false</code> otherwise
297: */
298: public static boolean isByte(final ClassifierFacade type) {
299: return UMLMetafacadeUtils.isType(type,
300: JSFProfile.BYTE_TYPE_NAME);
301: }
302:
303: /**
304: * @return <code>true</code> if the type of this field is a short, <code>false</code> otherwise
305: */
306: public static boolean isShort(final ClassifierFacade type) {
307: return UMLMetafacadeUtils.isType(type,
308: JSFProfile.SHORT_TYPE_NAME);
309: }
310:
311: /**
312: * @return <code>true</code> if the type of this field is an integer, <code>false</code> otherwise
313: */
314: public static boolean isInteger(final ClassifierFacade type) {
315: return UMLMetafacadeUtils.isType(type,
316: JSFProfile.INTEGER_TYPE_NAME);
317: }
318:
319: /**
320: * @return <code>true</code> if the type of this field is a long integer, <code>false</code> otherwise
321: */
322: public static boolean isLong(final ClassifierFacade type) {
323: return UMLMetafacadeUtils.isType(type,
324: JSFProfile.LONG_TYPE_NAME);
325: }
326:
327: /**
328: * @return <code>true</code> if the type of this field is a floating point, <code>false</code> otherwise
329: */
330: public static boolean isFloat(final ClassifierFacade type) {
331: return UMLMetafacadeUtils.isType(type,
332: JSFProfile.FLOAT_TYPE_NAME);
333: }
334:
335: /**
336: * @return <code>true</code> if the type of this field is a double precision floating point, <code>false</code> otherwise
337: */
338: public static boolean isDouble(final ClassifierFacade type) {
339: return UMLMetafacadeUtils.isType(type,
340: JSFProfile.DOUBLE_TYPE_NAME);
341: }
342:
343: /**
344: * @return <code>true</code> if the type of this field is a date, <code>false</code> otherwise
345: */
346: public static boolean isDate(final ClassifierFacade type) {
347: return type != null && type.isDateType();
348: }
349:
350: /**
351: * @return <code>true</code> if the type of this field is a time, <code>false</code> otherwise
352: */
353: public static boolean isTime(final ClassifierFacade type) {
354: return UMLMetafacadeUtils.isType(type,
355: JSFProfile.TIME_TYPE_NAME);
356: }
357:
358: /**
359: * @return <code>true</code> if the type of this field is a URL, <code>false</code> otherwise
360: */
361: public static boolean isUrl(final ClassifierFacade type) {
362: return UMLMetafacadeUtils
363: .isType(type, JSFProfile.URL_TYPE_NAME);
364: }
365:
366: /**
367: * @return <code>true</code> if the type of this field is a String, <code>false</code> otherwise
368: */
369: public static boolean isString(final ClassifierFacade type) {
370: return type != null && type.isStringType();
371: }
372:
373: /**
374: * Indicates if the given element is read-only or not.
375: *
376: * @param element the element to check.
377: * @return true/false
378: */
379: public static boolean isReadOnly(final ModelElementFacade element) {
380: boolean readOnly = false;
381: if (element != null) {
382: final Object value = element
383: .findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_READONLY);
384: readOnly = Boolean.valueOf(ObjectUtils.toString(value))
385: .booleanValue();
386: }
387: return readOnly;
388: }
389:
390: /**
391: * Retrieves the "equal" value from the given element (if one is present).
392: *
393: * @param element the element from which to retrieve the equal value.
394: * @return the "equal" value.
395: */
396: public static java.lang.String getEqual(
397: final ModelElementFacade element) {
398: String equal = null;
399: if (element != null) {
400: final Object value = element
401: .findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_EQUAL);
402: equal = value == null ? null : value.toString();
403: }
404: return equal;
405: }
406:
407: /**
408: * Retrieves the "validwhen" value from the given element (if one is present).
409: *
410: * @param element the element from which to retrieve the validwhen value.
411: * @return the "validwhen" value.
412: */
413: public static java.lang.String getValidWhen(
414: final ModelElementFacade element) {
415: String validWhen = null;
416: if (element != null) {
417: final Object value = element
418: .findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_VALIDWHEN);
419: validWhen = value == null ? null
420: : '(' + value.toString() + ')';
421: }
422: return validWhen;
423: }
424:
425: /**
426: * @return the lower limit for this field's value's range
427: */
428: public static String getRangeStart(final String format) {
429: return JSFUtils.getToken(format, 1, 3);
430: }
431:
432: /**
433: * @return the upper limit for this field's value's range
434: */
435: public static String getRangeEnd(final String format) {
436: return JSFUtils.getToken(format, 2, 3);
437: }
438:
439: /**
440: * @return the minimum number of characters this field's value must consist of
441: */
442: public static String getMinLengthValue(final String format) {
443: return JSFUtils.getToken(format, 1, 2);
444: }
445:
446: /**
447: * @return the maximum number of characters this field's value must consist of
448: */
449: public static String getMaxLengthValue(final String format) {
450: return JSFUtils.getToken(format, 1, 2);
451: }
452:
453: /**
454: * @return the pattern this field's value must respect
455: */
456: public static String getPatternValue(final String format) {
457: return '^' + JSFUtils.getToken(format, 1, 2) + '$';
458: }
459:
460: /**
461: * Retrieves the validator types as a collection from the given
462: * <code>element</code> (if any can be retrieved).
463: *
464: * @param element the element from which to retrieve the types.
465: * @param type the type of the element.
466: * @return the collection of validator types.
467: */
468: public static java.util.Collection getValidatorTypes(
469: final ModelElementFacade element,
470: final ClassifierFacade type) {
471: final Collection validatorTypesList = new ArrayList();
472: if (element != null && type != null) {
473: final String format = JSFUtils.getInputFormat(element);
474: final boolean isRangeFormat = format != null
475: && isRangeFormat(format);
476: if (element instanceof AttributeFacade) {
477: if (((AttributeFacade) element).isRequired()) {
478: validatorTypesList.add("required");
479: }
480: } else if (element instanceof JSFParameter) {
481: if (((JSFParameter) element).isRequired()) {
482: validatorTypesList.add("required");
483: }
484: }
485: if (JSFUtils.isByte(type)) {
486: validatorTypesList.add("byte");
487: } else if (JSFUtils.isShort(type)) {
488: validatorTypesList.add("short");
489: } else if (JSFUtils.isInteger(type)) {
490: validatorTypesList.add("integer");
491: } else if (JSFUtils.isLong(type)) {
492: validatorTypesList.add("long");
493: } else if (JSFUtils.isFloat(type)) {
494: validatorTypesList.add("float");
495: } else if (JSFUtils.isDouble(type)) {
496: validatorTypesList.add("double");
497: } else if (JSFUtils.isDate(type)) {
498: validatorTypesList.add("date");
499: } else if (JSFUtils.isTime(type)) {
500: validatorTypesList.add("time");
501: } else if (JSFUtils.isUrl(type)) {
502: validatorTypesList.add("url");
503: }
504:
505: if (isRangeFormat) {
506: if (JSFUtils.isInteger(type) || JSFUtils.isShort(type)
507: || JSFUtils.isLong(type)) {
508: validatorTypesList.add("intRange");
509: }
510: if (JSFUtils.isFloat(type)) {
511: validatorTypesList.add("floatRange");
512: }
513: if (JSFUtils.isDouble(type)) {
514: validatorTypesList.add("doubleRange");
515: }
516: }
517:
518: if (format != null) {
519: if (JSFUtils.isString(type)
520: && JSFUtils.isEmailFormat(format)) {
521: validatorTypesList.add("email");
522: } else if (JSFUtils.isString(type)
523: && JSFUtils.isCreditCardFormat(format)) {
524: validatorTypesList.add("creditCard");
525: } else {
526: Collection formats = element
527: .findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
528: for (final Iterator formatIterator = formats
529: .iterator(); formatIterator.hasNext();) {
530: String additionalFormat = String
531: .valueOf(formatIterator.next());
532: if (JSFUtils
533: .isMinLengthFormat(additionalFormat)) {
534: validatorTypesList.add("minlength");
535: } else if (JSFUtils
536: .isMaxLengthFormat(additionalFormat)) {
537: validatorTypesList.add("maxlength");
538: } else if (JSFUtils
539: .isPatternFormat(additionalFormat)) {
540: validatorTypesList.add("mask");
541: }
542: }
543: }
544: }
545:
546: if (JSFUtils.getValidWhen(element) != null) {
547: validatorTypesList.add("validwhen");
548: }
549: if (JSFUtils.getEqual(element) != null) {
550: validatorTypesList.add("equal");
551: }
552: }
553:
554: // - custom (paramterized) validators are allowed here
555: final Collection taggedValues = element
556: .findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
557: for (final Iterator iterator = taggedValues.iterator(); iterator
558: .hasNext();) {
559: String validator = String.valueOf(iterator.next());
560: validatorTypesList.add(JSFUtils
561: .parseValidatorName(validator));
562: }
563: return validatorTypesList;
564: }
565:
566: /**
567: * Gets the validator variables for the given <code>element</code> (if they can
568: * be retrieved).
569: *
570: * @param element the element from which to retrieve the variables
571: * @param type the type of the element.
572: * @return the collection of validator variables.
573: */
574: public static java.util.Collection getValidatorVars(
575: final ModelElementFacade element,
576: final ClassifierFacade type) {
577: final Map vars = new LinkedHashMap();
578: if (element != null && type != null) {
579: final String format = JSFUtils.getInputFormat(element);
580: if (format != null) {
581: final boolean isRangeFormat = JSFUtils
582: .isRangeFormat(format);
583:
584: if (isRangeFormat) {
585: final String min = "min";
586: final String max = "max";
587: vars.put(min, Arrays.asList(new Object[] { min,
588: JSFUtils.getRangeStart(format) }));
589: vars.put(max, Arrays.asList(new Object[] { max,
590: JSFUtils.getRangeEnd(format) }));
591: } else {
592: final Collection formats = element
593: .findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
594: for (final Iterator formatIterator = formats
595: .iterator(); formatIterator.hasNext();) {
596: final String additionalFormat = String
597: .valueOf(formatIterator.next());
598: final String minlength = "minlength";
599: final String maxlength = "maxlength";
600: final String mask = "mask";
601: if (JSFUtils
602: .isMinLengthFormat(additionalFormat)) {
603: vars
604: .put(
605: minlength,
606: Arrays
607: .asList(new Object[] {
608: minlength,
609: JSFUtils
610: .getMinLengthValue(additionalFormat) }));
611: } else if (JSFUtils
612: .isMaxLengthFormat(additionalFormat)) {
613: vars
614: .put(
615: maxlength,
616: Arrays
617: .asList(new Object[] {
618: maxlength,
619: JSFUtils
620: .getMaxLengthValue(additionalFormat) }));
621: } else if (JSFUtils
622: .isPatternFormat(additionalFormat)) {
623: vars
624: .put(
625: mask,
626: Arrays
627: .asList(new Object[] {
628: mask,
629: JSFUtils
630: .getPatternValue(additionalFormat) }));
631: }
632: }
633: }
634: }
635: String inputFormat;
636: if (element instanceof JSFAttribute) {
637: inputFormat = ((JSFAttribute) element).getFormat();
638: } else if (element instanceof JSFParameter) {
639: inputFormat = ((JSFParameter) element).getFormat();
640: } else {
641: throw new RuntimeException(
642: "'element' is an invalid type, it must be either an instance of '"
643: + JSFAttribute.class.getName()
644: + "' or '"
645: + JSFParameter.class.getName() + "'");
646: }
647: if (JSFUtils.isDate(type)) {
648: final String datePatternStrict = "datePatternStrict";
649: if (format != null
650: && JSFUtils.isStrictDateFormat(format)) {
651: vars.put(datePatternStrict, Arrays
652: .asList(new Object[] { datePatternStrict,
653: inputFormat }));
654: } else {
655: final String datePattern = "datePattern";
656: vars.put(datePattern, Arrays.asList(new Object[] {
657: datePattern, inputFormat }));
658: }
659: }
660: if (JSFUtils.isTime(type)) {
661: final String timePattern = "timePattern";
662: vars.put(timePattern, Arrays.asList(new Object[] {
663: timePattern, inputFormat }));
664: }
665:
666: final String validWhen = JSFUtils.getValidWhen(element);
667: if (validWhen != null) {
668: final String test = "test";
669: vars.put(test, Arrays.asList(new Object[] { test,
670: validWhen }));
671: }
672:
673: final String equal = JSFUtils.getEqual(element);
674: if (equal != null) {
675: final String fieldName = "fieldName";
676: vars.put(fieldName, Arrays.asList(new Object[] {
677: fieldName, equal }));
678: }
679: }
680:
681: // - custom (parameterized) validators are allowed here
682: // in this case we will reuse the validator arg values
683: final Collection taggedValues = element
684: .findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
685: for (final Iterator iterator = taggedValues.iterator(); iterator
686: .hasNext();) {
687: final String validator = String.valueOf(iterator.next());
688:
689: // - guaranteed to be of the same length
690: final List validatorVars = JSFUtils
691: .parseValidatorVars(validator);
692: final List validatorArgs = JSFUtils
693: .parseValidatorArgs(validator);
694:
695: for (int ctr = 0; ctr < validatorVars.size(); ctr++) {
696: final String validatorVar = (String) validatorVars
697: .get(ctr);
698: final String validatorArg = (String) validatorArgs
699: .get(ctr);
700: vars.put(validatorVar, Arrays.asList(new Object[] {
701: validatorVar, validatorArg }));
702: }
703: }
704: return vars.values();
705: }
706:
707: /**
708: * Gets the validator args for the <code>element</code> and the given <code>validatorType</code>.
709: *
710: * @param element the element for which to retrieve the arguments.
711: * @param validatorType the validator type name.
712: * @return the validator args as a collection.
713: */
714: public static java.util.Collection getValidatorArgs(
715: final ModelElementFacade element,
716: final java.lang.String validatorType) {
717: final Collection args = new ArrayList();
718: if ("intRange".equals(validatorType)
719: || "floatRange".equals(validatorType)
720: || "doubleRange".equals(validatorType)) {
721: args.add("${var:min}");
722: args.add("${var:max}");
723: } else if ("minlength".equals(validatorType)) {
724: args.add("${var:minlength}");
725: } else if ("maxlength".equals(validatorType)) {
726: args.add("${var:maxlength}");
727: } else if ("date".equals(validatorType)) {
728: final String validatorFormat = JSFUtils
729: .getInputFormat(element);
730: if (JSFUtils.isStrictDateFormat(validatorFormat)) {
731: args.add("${var:datePatternStrict}");
732: } else {
733: args.add("${var:datePattern}");
734: }
735: } else if ("time".equals(validatorType)) {
736: args.add("${var:timePattern}");
737: } else if ("equal".equals(validatorType)) {
738: ModelElementFacade equalParameter = null;
739: final String equal = JSFUtils.getEqual(element);
740: if (element instanceof ParameterFacade) {
741: final FrontEndParameter parameter = (FrontEndParameter) element;
742: final OperationFacade operation = parameter
743: .getOperation();
744: if (operation != null) {
745: equalParameter = operation.findParameter(equal);
746: }
747: if (equalParameter == null) {
748: final FrontEndAction action = parameter.getAction();
749: if (action != null) {
750: equalParameter = action.findParameter(equal);
751: }
752: }
753: } else if (element instanceof AttributeFacade) {
754: final AttributeFacade attribute = (AttributeFacade) element;
755: final ClassifierFacade owner = attribute.getOwner();
756: if (owner != null) {
757: equalParameter = owner.findAttribute(equal);
758: }
759: }
760: args.add(equalParameter);
761: args.add("${var:fieldName}");
762: }
763:
764: // custom (paramterized) validators are allowed here
765: final Collection taggedValues = element
766: .findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS);
767: for (final Iterator iterator = taggedValues.iterator(); iterator
768: .hasNext();) {
769: final String validator = String.valueOf(iterator.next());
770: if (validatorType.equals(JSFUtils
771: .parseValidatorName(validator))) {
772: args.addAll(JSFUtils.parseValidatorArgs(validator));
773: }
774: }
775: return args;
776: }
777:
778: /**
779: * Whether or not date patterns should be treated as strict.
780: */
781: private static boolean strictDateTimeFormat;
782:
783: /**
784: * Sets whether or not the dattern patterns should be treated as strict.
785: *
786: * @param strictDateTimeFormat
787: */
788: public void setStrictDateTimeFormat(
789: final boolean strictDateTimeFormat) {
790: JSFUtils.strictDateTimeFormat = strictDateTimeFormat;
791: }
792:
793: /**
794: * Indicates whether or not the format for this element is a strict date
795: * format.
796: * @return true/false
797: */
798: public static boolean isStrictDateFormat(
799: final ModelElementFacade element) {
800: final String format = JSFUtils.getInputFormat(element);
801: return JSFUtils.isStrictDateFormat(format);
802: }
803:
804: /**
805: * Gets the format string for the given <code>element</code>.
806: *
807: * @param element the element for which to retrieve the format.
808: * @param type the type of the element.
809: * @return the format string (if one is present otherwise null).
810: */
811: public static String getFormat(final ModelElementFacade element,
812: final ClassifierFacade type,
813: final String defaultDateFormat,
814: final String defaultTimeFormat) {
815: String format = null;
816: if (element != null && type != null) {
817: format = JSFUtils.getInputFormat(element);
818: if (format == null) {
819: if (type.isTimeType()) {
820: format = defaultTimeFormat;
821: } else if (type.isDateType()) {
822: format = defaultDateFormat;
823: }
824: } else if (type.isDateType()) {
825: format = JSFUtils.getDateFormat(format);
826: }
827: }
828: return format;
829: }
830:
831: /**
832: * The JSP view type.
833: */
834: private static final String VIEW_TYPE_JSP = "jsp";
835:
836: /**
837: * The facelet view type.
838: */
839: private static final String VIEW_TYPE_FACELETS = "facelets";
840:
841: /**
842: * Stores the view type
843: */
844: private String viewType;
845:
846: /**
847: * Sets the view type to use.
848: *
849: * @param viewType the view type.
850: */
851: public void setViewType(final String viewType) {
852: this .viewType = viewType;
853: }
854:
855: /**
856: * Gets the current view type.
857: *
858: * @return the view type.
859: */
860: public String getViewType() {
861: return this .viewType;
862: }
863:
864: /**
865: * The XHTML extension.
866: */
867: private static final String EXTENSION_XHTML = "xhtml";
868:
869: /**
870: * Gets the extension for the current view type.
871: *
872: * @return the view type extension.
873: */
874: public String getViewExtension() {
875: String extension;
876: if (VIEW_TYPE_JSP.equals(this .viewType)) {
877: extension = this .viewType;
878: } else if (VIEW_TYPE_FACELETS.equals(this .viewType)) {
879: extension = EXTENSION_XHTML;
880: } else {
881: throw new RuntimeException("'" + this .viewType
882: + "' is not a valid viewType, the options are '"
883: + VIEW_TYPE_JSP + "' or '" + VIEW_TYPE_FACELETS
884: + "'");
885: }
886: return extension;
887: }
888: }
|