001package org.andromda.cartridges.jsf2; 002 003import java.security.MessageDigest; 004import java.security.NoSuchAlgorithmException; 005import java.util.ArrayList; 006import java.util.Arrays; 007import java.util.Collection; 008import java.util.Date; 009import java.util.Iterator; 010import java.util.LinkedHashMap; 011import java.util.List; 012import java.util.Map; 013import java.util.regex.Pattern; 014import org.andromda.cartridges.jsf2.metafacades.JSFAttribute; 015import org.andromda.cartridges.jsf2.metafacades.JSFManageableEntityAttribute; 016import org.andromda.cartridges.jsf2.metafacades.JSFParameter; 017import org.andromda.metafacades.uml.AttributeFacade; 018import org.andromda.metafacades.uml.ClassifierFacade; 019import org.andromda.metafacades.uml.FrontEndAction; 020import org.andromda.metafacades.uml.FrontEndParameter; 021import org.andromda.metafacades.uml.ModelElementFacade; 022import org.andromda.metafacades.uml.OperationFacade; 023import org.andromda.metafacades.uml.ParameterFacade; 024import org.andromda.metafacades.uml.UMLMetafacadeUtils; 025import org.andromda.utils.StringUtilsHelper; 026import org.apache.commons.lang.ObjectUtils; 027import org.apache.commons.lang.StringUtils; 028import org.apache.commons.lang.time.FastDateFormat; 029 030/** 031 * Utilities for use within the JSF cartridge. 032 * 033 * @author Chad Brandon 034 */ 035public class JSFUtils 036{ 037 /** 038 * Converts the argument into a web resource name, this means: all lowercase 039 * characters and words are separated with dashes. 040 * 041 * @param string any string 042 * @return the string converted to a value that would be well-suited for a 043 * web file name 044 */ 045 public static String toWebResourceName(final String string) 046 { 047 return StringUtilsHelper.separate( 048 string, 049 "-").toLowerCase(); 050 } 051 052 private static final Pattern VALIDATOR_TAGGEDVALUE_PATTERN = 053 Pattern.compile("\\w+(\\(\\w+=[^,)]*(,\\w+=[^,)]*)*\\))?"); 054 055 private static final String ANNOTATION_VALIDATOR_PREFIX = "@"; 056 057 /** 058 * Reads the validator arguments from the the given tagged value. 059 * @param validatorTaggedValue 060 * @return returns a list of String instances or an empty list 061 * @throws IllegalArgumentException when the input string does not match the required pattern 062 */ 063 public static List<String> parseValidatorArgs(String validatorTaggedValue) 064 { 065 if (validatorTaggedValue == null) 066 { 067 throw new IllegalArgumentException("Validator tagged value cannot be null"); 068 } 069 070 final List<String> validatorArgs = new ArrayList<String>(); 071 072 //isn't it an annotation ? 073 if(!StringUtils.startsWith(validatorTaggedValue,ANNOTATION_VALIDATOR_PREFIX)) 074 { 075 076 // check if the input tagged value matches the required pattern 077 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches()) 078 { 079 throw new IllegalArgumentException( 080 "Illegal validator tagged value (this tag is used to specify custom validators " + 081 "and might look like myValidator(myVar=myArg,myVar2=myArg2), perhaps you wanted to use " + 082 "andromda_presentation_view_field_format?): " + validatorTaggedValue); 083 } 084 085 // only keep what is between parentheses (if any) 086 int left = validatorTaggedValue.indexOf('('); 087 if (left > -1) 088 { 089 final int right = validatorTaggedValue.indexOf(')'); 090 validatorTaggedValue = validatorTaggedValue.substring( 091 left + 1, 092 right); 093 094 final String[] pairs = validatorTaggedValue.split(","); 095 for (int i = 0; i < pairs.length; i++) 096 { 097 final String pair = pairs[i]; 098 final int equalsIndex = pair.indexOf('='); 099 100 // it's possible the argument is the empty string 101 if (equalsIndex < pair.length() - 1) 102 { 103 validatorArgs.add(pair.substring(equalsIndex + 1)); 104 } 105 else 106 { 107 validatorArgs.add(""); 108 } 109 } 110 } 111 } 112 return validatorArgs; 113 } 114 115 /** 116 * Reads the validator variable names from the the given tagged value. 117 * @param validatorTaggedValue 118 * @return never null, returns a list of String instances 119 * @throws IllegalArgumentException when the input string does not match the required pattern 120 */ 121 public static List<String> parseValidatorVars(String validatorTaggedValue) 122 { 123 if (validatorTaggedValue == null) 124 { 125 throw new IllegalArgumentException("Validator tagged value cannot be null"); 126 } 127 128 final List<String> validatorVars = new ArrayList<String>(); 129 130 //isn't it an annotation ? 131 if(!StringUtils.startsWith(validatorTaggedValue,ANNOTATION_VALIDATOR_PREFIX)) 132 { 133 134 // check if the input tagged value matches the required pattern 135 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches()) 136 { 137 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue); 138 } 139 140 // only keep what is between parentheses (if any) 141 int left = validatorTaggedValue.indexOf('('); 142 if (left > -1) 143 { 144 int right = validatorTaggedValue.indexOf(')'); 145 validatorTaggedValue = validatorTaggedValue.substring( 146 left + 1, 147 right); 148 149 final String[] pairs = validatorTaggedValue.split(","); 150 for (int i = 0; i < pairs.length; i++) 151 { 152 final String pair = pairs[i]; 153 final int equalsIndex = pair.indexOf('='); 154 validatorVars.add(pair.substring( 155 0, 156 equalsIndex)); 157 } 158 } 159 } 160 return validatorVars; 161 } 162 163 /** 164 * Parses the validator name for a tagged value. 165 * @param validatorTaggedValue 166 * @return validatorTaggedValue 167 * @throws IllegalArgumentException when the input string does not match the required pattern 168 */ 169 public static String parseValidatorName(final String validatorTaggedValue) 170 { 171 if (validatorTaggedValue == null) 172 { 173 throw new IllegalArgumentException("Validator tagged value cannot be null"); 174 } 175 176 //isn't it an annotation ? 177 if(StringUtils.startsWith(validatorTaggedValue, ANNOTATION_VALIDATOR_PREFIX)) 178 { 179 return validatorTaggedValue; 180 } 181 182 // check if the input tagged value matches the required pattern 183 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches()) 184 { 185 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue); 186 } 187 188 final int leftParen = validatorTaggedValue.indexOf('('); 189 return (leftParen == -1) ? validatorTaggedValue : validatorTaggedValue.substring( 190 0, 191 leftParen); 192 } 193 194 /** 195 * Constructs a string representing an array initialization in Java. 196 * 197 * @param name the name to give the array. 198 * @param count the number of items to give the array. 199 * @return A String representing Java code for the initialization of an array. 200 */ 201 public static String constructDummyArrayDeclaration( 202 final String name, 203 final int count) 204 { 205 final StringBuilder array = new StringBuilder("new Object[] {"); 206 for (int ctr = 1; ctr <= count; ctr++) 207 { 208 array.append("\"" + name + "-" + ctr + "\""); 209 if (ctr != count) 210 { 211 array.append(", "); 212 } 213 } 214 array.append("}"); 215 return array.toString(); 216 } 217 218 /** 219 * @param format 220 * @return this field's date format 221 */ 222 public static String getDateFormat(String format) 223 { 224 format = StringUtils.trimToEmpty(format); 225 return format.endsWith(STRICT) ? getToken(format, 1, 2) : getToken(format, 0, 1); 226 } 227 228 private static String defaultDateFormat = "MM/dd/yyyy HH:mm:ssZ"; 229 private static FastDateFormat df = FastDateFormat.getInstance(defaultDateFormat); 230 231 /** 232 * Returns the current Date in the specified format. 233 * 234 * @param format The format for the output date 235 * @return the current date in the specified format. 236 */ 237 public static String getDate(String format) 238 { 239 if (df == null || !format.equals(df.getPattern())) 240 { 241 df = FastDateFormat.getInstance(format); 242 } 243 return df.format(new Date()); 244 } 245 246 /** 247 * Returns the current Date 248 * 249 * @return the current date in the default format. 250 */ 251 public static String getDate() 252 { 253 return getDate(defaultDateFormat); 254 } 255 256 private static final String STRICT = "strict"; 257 258 /** 259 * @param format 260 * @return <code>true</code> if this field's value needs to conform to a 261 * strict date format, <code>false</code> otherwise 262 */ 263 public static boolean isStrictDateFormat(String format) 264 { 265 return strictDateTimeFormat ? strictDateTimeFormat : STRICT.equalsIgnoreCase(getToken( 266 format, 267 0, 268 2)); 269 } 270 271 /** 272 * Indicates if the given <code>format</code> is an email format. 273 * @param format 274 * @return <code>true</code> if this field is to be formatted as an email 275 * address, <code>false</code> otherwise 276 */ 277 public static boolean isEmailFormat(String format) 278 { 279 return "email".equalsIgnoreCase(JSFUtils.getToken( 280 format, 281 0, 282 2)); 283 } 284 285 /** 286 * Indicates if the given <code>format</code> is an equal format. 287 * @param format 288 * @return <code>true</code> if this field is to be formatted as an 289 * email address, <code>false</code> otherwise 290 */ 291 public static boolean isEqualFormat(String format) 292 { 293 return "equal".equalsIgnoreCase(JSFUtils.getToken(format, 0, 2)); 294 } 295 296 /** 297 * Indicates if the given <code>format</code> is a credit card format. 298 * @param format 299 * @return <code>true</code> if this field is to be formatted as a credit card, <code>false</code> otherwise 300 */ 301 public static boolean isCreditCardFormat(final String format) 302 { 303 return "creditcard".equalsIgnoreCase(JSFUtils.getToken(format, 0, 2)); 304 } 305 306 /** 307 * Indicates if the given <code>format</code> is a pattern format. 308 * @param format 309 * @return <code>true</code> if this field's value needs to respect a certain pattern, <code>false</code> otherwise 310 */ 311 public static boolean isPatternFormat(final String format) 312 { 313 return "pattern".equalsIgnoreCase(JSFUtils.getToken(format, 0, 2)); 314 } 315 316 /** 317 * Indicates if the given <code>format</code> is a minlength format. 318 * @param format 319 * @return <code>true</code> if this field's value needs to consist of at least a certain 320 * number of characters, <code>false</code> otherwise 321 */ 322 public static boolean isMinLengthFormat(final String format) 323 { 324 return "minlength".equalsIgnoreCase(JSFUtils.getToken( 325 format, 326 0, 327 2)); 328 } 329 330 /** 331 * Indicates if the given <code>format</code> is a maxlength format. 332 * @param format 333 * @return <code>true</code> if this field's value needs to consist of at maximum a certain 334 * number of characters, <code>false</code> otherwise 335 */ 336 public static boolean isMaxLengthFormat(String format) 337 { 338 return "maxlength".equalsIgnoreCase(JSFUtils.getToken( 339 format, 340 0, 341 2)); 342 } 343 344 /** 345 * @param string 346 * @param index 347 * @param limit 348 * @return the i-th space delimited token read from the argument String, where i does not exceed the specified limit 349 */ 350 public static String getToken( 351 String string, 352 int index, 353 int limit) 354 { 355 String token = null; 356 if (string != null && string.length() > 0) 357 { 358 final String[] tokens = string.split( 359 "[\\s]+", 360 limit); 361 token = index >= tokens.length ? null : tokens[index]; 362 } 363 return token; 364 } 365 366 /** 367 * Retrieves the input format (if one is defined), for the given 368 * <code>element</code>. 369 * @param element the model element for which to retrieve the input format. 370 * @return the input format. 371 */ 372 public static String getInputFormat(final ModelElementFacade element) 373 { 374 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_FORMAT); 375 final String format = value == null ? null : String.valueOf(value); 376 return format == null ? null : format.trim(); 377 } 378 379 /** 380 * Indicates if the given <code>format</code> is a range format. 381 * @param format 382 * @return <code>true</code> if this field's value needs to be in a specific range, <code>false</code> otherwise 383 */ 384 public static boolean isRangeFormat(final String format) 385 { 386 return "range".equalsIgnoreCase(JSFUtils.getToken( 387 format, 388 0, 389 2)); 390 } 391 392 /** 393 * @param type 394 * @return <code>true</code> if the type of this field is a byte, <code>false</code> otherwise 395 */ 396 public static boolean isByte(final ClassifierFacade type) 397 { 398 return isType( 399 type, 400 JSFProfile.BYTE_TYPE_NAME); 401 } 402 403 /** 404 * @param type 405 * @return <code>true</code> if the type of this field is a short, <code>false</code> otherwise 406 */ 407 public static boolean isShort(final ClassifierFacade type) 408 { 409 return isType( 410 type, 411 JSFProfile.SHORT_TYPE_NAME); 412 } 413 414 /** 415 * @param type 416 * @return <code>true</code> if the type of this field is an integer, <code>false</code> otherwise 417 */ 418 public static boolean isInteger(final ClassifierFacade type) 419 { 420 return isType( 421 type, 422 JSFProfile.INTEGER_TYPE_NAME); 423 } 424 425 /** 426 * @param type 427 * @return <code>true</code> if the type of this field is a long integer, <code>false</code> otherwise 428 */ 429 public static boolean isLong(final ClassifierFacade type) 430 { 431 return isType( 432 type, 433 JSFProfile.LONG_TYPE_NAME); 434 } 435 436 /** 437 * @param type 438 * @return <code>true</code> if the type of this field is a floating point, <code>false</code> otherwise 439 */ 440 public static boolean isFloat(final ClassifierFacade type) 441 { 442 return isType( 443 type, 444 JSFProfile.FLOAT_TYPE_NAME); 445 } 446 447 /** 448 * @param type 449 * @return <code>true</code> if the type of this field is a double precision floating point, 450 * <code>false</code> otherwise 451 */ 452 public static boolean isDouble(final ClassifierFacade type) 453 { 454 return isType( 455 type, 456 JSFProfile.DOUBLE_TYPE_NAME); 457 } 458 459 /** 460 * @param type 461 * @return <code>true</code> if the type of this field is a date, <code>false</code> otherwise 462 */ 463 public static boolean isDate(final ClassifierFacade type) 464 { 465 return type != null && type.isDateType(); 466 } 467 468 /** 469 * @param type 470 * @return <code>true</code> if the type of this field is a time, <code>false</code> otherwise 471 */ 472 public static boolean isTime(final ClassifierFacade type) 473 { 474 return isType( 475 type, 476 JSFProfile.TIME_TYPE_NAME); 477 } 478 479 /** 480 * @param type 481 * @return <code>true</code> if the type of this field is a URL, <code>false</code> otherwise 482 */ 483 public static boolean isUrl(final ClassifierFacade type) 484 { 485 return isType( 486 type, 487 JSFProfile.URL_TYPE_NAME); 488 } 489 490 private static boolean isType(final ClassifierFacade type, String typeName) 491 { 492 boolean isType = UMLMetafacadeUtils.isType( 493 type, 494 typeName); 495 if (!isType) 496 { 497 // - handle abstract types that are mapped to java types 498 if (type.getLanguageMappings() != null) 499 { 500 final String javaTypeName = type.getLanguageMappings() 501 .getTo(type.getFullyQualifiedName(true)); 502 if (javaTypeName != null) 503 { 504 isType = javaTypeName.replaceAll(".*\\.", "").equalsIgnoreCase( 505 type.getLanguageMappings().getTo(typeName)); 506 } 507 } 508 } 509 return isType; 510 } 511 512 /** 513 * @param type 514 * @return <code>true</code> if the type of this field is a String, 515 * <code>false</code> otherwise 516 */ 517 public static boolean isString(final ClassifierFacade type) 518 { 519 return type != null && type.isStringType(); 520 } 521 522 /** 523 * Indicates if the given element is read-only or not. 524 * 525 * @param element the element to check. 526 * @return true/false 527 */ 528 public static boolean isReadOnly(final ModelElementFacade element) 529 { 530 boolean readOnly = false; 531 if (element != null) 532 { 533 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_READONLY); 534 readOnly = Boolean.valueOf(ObjectUtils.toString(value)).booleanValue(); 535 } 536 return readOnly; 537 } 538 539 /** 540 * Retrieves the "equal" value from the given element (if one is present). 541 * 542 * @param element the element from which to retrieve the equal value. 543 * @return the "equal" value. 544 */ 545 public static String getEqual(final ModelElementFacade element) 546 { 547 String equal = null; 548 if (element != null) 549 { 550 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_EQUAL); 551 equal = value == null ? null : value.toString(); 552 } 553 return equal; 554 } 555 556 /** 557 * Retrieves the "equal" value from the given element (if one is present). 558 * 559 * @param element the element from which to retrieve the equal value. 560 * @param ownerParameter the optional owner parameter (specified if the element is an attribute). 561 * @return the "equal" value. 562 */ 563 public static String getEqual(final ModelElementFacade element, final ParameterFacade ownerParameter) 564 { 565 String equal = null; 566 if (element != null) 567 { 568 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_EQUAL); 569 equal = value == null ? null : value.toString(); 570 if (StringUtils.isNotBlank(equal) && ownerParameter != null) 571 { 572 equal = ownerParameter.getName() + StringUtilsHelper.upperCamelCaseName(equal); 573 } 574 } 575 return equal; 576 } 577 578 /** 579 * Retrieves the "validwhen" value from the given element (if one is present). 580 * 581 * @param element the element from which to retrieve the validwhen value. 582 * @return the "validwhen" value. 583 */ 584 public static String getValidWhen(final ModelElementFacade element) 585 { 586 String validWhen = null; 587 if (element != null) 588 { 589 final Object value = element.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_VALIDWHEN); 590 validWhen = value == null ? null : '(' + value.toString() + ')'; 591 } 592 return validWhen; 593 } 594 595 /** 596 * @param format 597 * @return the lower limit for this field's value's range 598 */ 599 public static String getRangeStart(final String format) 600 { 601 return JSFUtils.getToken( 602 format, 603 1, 604 3); 605 } 606 607 /** 608 * @param format 609 * @return the upper limit for this field's value's range 610 */ 611 public static String getRangeEnd(final String format) 612 { 613 return JSFUtils.getToken( 614 format, 615 2, 616 3); 617 } 618 619 /** 620 * @param format 621 * @return the minimum number of characters this field's value must consist of 622 */ 623 public static String getMinLengthValue(final String format) 624 { 625 return JSFUtils.getToken( 626 format, 627 1, 628 2); 629 } 630 631 /** 632 * @param format 633 * @return the maximum number of characters this field's value must consist of 634 */ 635 public static String getMaxLengthValue(final String format) 636 { 637 return JSFUtils.getToken( 638 format, 639 1, 640 2); 641 } 642 643 /** 644 * @param format 645 * @return the pattern this field's value must respect 646 */ 647 public static String getPatternValue(final String format) 648 { 649 return '^' + JSFUtils.getToken( 650 format, 651 1, 652 2) + '$'; 653 } 654 655 //validator strings 656 /** "required" */ 657 public static final String VT_REQUIRED="required"; 658 /** "url" */ 659 public static final String VT_URL="url"; 660 /** "intRange" */ 661 public static final String VT_INT_RANGE="intRange"; 662 /** "floatRange" */ 663 public static final String VT_FLOAT_RANGE="floatRange"; 664 /** "doubleRange" */ 665 public static final String VT_DOUBLE_RANGE="doubleRange"; 666 /** "email" */ 667 public static final String VT_EMAIL="email"; 668 /** "creditCard" */ 669 public static final String VT_CREDIT_CARD="creditCard"; 670 /** "minlength" */ 671 public static final String VT_MIN_LENGTH="minlength"; 672 /** "maxlength" */ 673 public static final String VT_MAX_LENGTH="maxlength"; 674 /** "mask" */ 675 public static final String VT_MASK="mask"; 676 /** "validwhen" */ 677 public static final String VT_VALID_WHEN="validwhen"; 678 /** "equal" */ 679 public static final String VT_EQUAL="equal"; 680 681 /** 682 * Retrieves the validator types as a collection from the given 683 * <code>element</code> (if any can be retrieved). 684 * 685 * @param element the element from which to retrieve the types. 686 * @param type the type of the element. 687 * @return the collection of validator types. 688 */ 689 public static Collection<String> getValidatorTypes( 690 final ModelElementFacade element, 691 final ClassifierFacade type) 692 { 693 final Collection<String> validatorTypesList = new ArrayList<String>(); 694 if (element != null && type != null) 695 { 696 final String format = JSFUtils.getInputFormat(element); 697 final boolean isRangeFormat = format != null && isRangeFormat(format); 698 if (element instanceof AttributeFacade) 699 { 700 if (((AttributeFacade)element).isRequired()) 701 { 702 validatorTypesList.add(VT_REQUIRED); 703 } 704 } 705 else if (element instanceof JSFParameter) 706 { 707 if (((JSFParameter)element).isRequired()) 708 { 709 validatorTypesList.add(VT_REQUIRED); 710 } 711 } 712 if (JSFUtils.isByte(type)) 713 { 714 validatorTypesList.add("byte"); 715 } 716 else if (JSFUtils.isShort(type)) 717 { 718 validatorTypesList.add("short"); 719 } 720 else if (JSFUtils.isInteger(type)) 721 { 722 validatorTypesList.add("integer"); 723 } 724 else if (JSFUtils.isLong(type)) 725 { 726 validatorTypesList.add("long"); 727 } 728 else if (JSFUtils.isFloat(type)) 729 { 730 validatorTypesList.add("float"); 731 } 732 else if (JSFUtils.isDouble(type)) 733 { 734 validatorTypesList.add("double"); 735 } 736 else if (JSFUtils.isDate(type)) 737 { 738 validatorTypesList.add("date"); 739 } 740 else if (JSFUtils.isTime(type)) 741 { 742 validatorTypesList.add("time"); 743 } 744 else if (JSFUtils.isUrl(type)) 745 { 746 validatorTypesList.add(VT_URL); 747 } 748 749 if (isRangeFormat) 750 { 751 if (JSFUtils.isInteger(type) || JSFUtils.isShort(type) || JSFUtils.isLong(type)) 752 { 753 validatorTypesList.add(VT_INT_RANGE); 754 } 755 if (JSFUtils.isFloat(type)) 756 { 757 validatorTypesList.add(VT_FLOAT_RANGE); 758 } 759 if (JSFUtils.isDouble(type)) 760 { 761 validatorTypesList.add(VT_DOUBLE_RANGE); 762 } 763 } 764 765 if (format != null) 766 { 767 if (JSFUtils.isString(type) && JSFUtils.isEmailFormat(format)) 768 { 769 validatorTypesList.add(VT_EMAIL); 770 } 771 else if (JSFUtils.isString(type) && JSFUtils.isCreditCardFormat(format)) 772 { 773 validatorTypesList.add(VT_CREDIT_CARD); 774 } 775 else 776 { 777 Collection formats = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT); 778 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();) 779 { 780 String additionalFormat = String.valueOf(formatIterator.next()); 781 if (JSFUtils.isMinLengthFormat(additionalFormat)) 782 { 783 validatorTypesList.add(VT_MIN_LENGTH); 784 } 785 else if (JSFUtils.isMaxLengthFormat(additionalFormat)) 786 { 787 validatorTypesList.add(VT_MAX_LENGTH); 788 } 789 else if (JSFUtils.isPatternFormat(additionalFormat)) 790 { 791 validatorTypesList.add(VT_MASK); 792 } 793 } 794 } 795 } 796 if (JSFUtils.getValidWhen(element) != null) 797 { 798 validatorTypesList.add(VT_VALID_WHEN); 799 } 800 if (JSFUtils.getEqual(element) != null) 801 { 802 validatorTypesList.add(VT_EQUAL); 803 } 804 805 // - custom (paramterized) validators are allowed here 806 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS); 807 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();) 808 { 809 String validator = String.valueOf(iterator.next()); 810 validatorTypesList.add(JSFUtils.parseValidatorName(validator)); 811 } 812 } 813 return validatorTypesList; 814 } 815 816 /** 817 * Gets the validator variables for the given <code>element</code> (if they can 818 * be retrieved). 819 * 820 * @param element the element from which to retrieve the variables 821 * @param type the type of the element. 822 * @param ownerParameter the optional owner parameter (if the element is an attribute for example). 823 * @return the collection of validator variables. 824 */ 825 public static Collection<List<String>> getValidatorVars( 826 final ModelElementFacade element, 827 final ClassifierFacade type, 828 final ParameterFacade ownerParameter) 829 { 830 final Map<String, List<String>> vars = new LinkedHashMap<String, List<String>>(); 831 if (element != null && type != null) 832 { 833 final String format = JSFUtils.getInputFormat(element); 834 if (format != null) 835 { 836 final boolean isRangeFormat = JSFUtils.isRangeFormat(format); 837 838 if (isRangeFormat) 839 { 840 final String min = "min"; 841 final String max = "max"; 842 vars.put( 843 min, 844 Arrays.asList(min, JSFUtils.getRangeStart(format))); 845 vars.put( 846 max, 847 Arrays.asList(max, JSFUtils.getRangeEnd(format))); 848 } 849 else 850 { 851 final Collection formats = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT); 852 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();) 853 { 854 final String additionalFormat = String.valueOf(formatIterator.next()); 855 final String minlength = "minlength"; 856 final String maxlength = "maxlength"; 857 final String mask = "mask"; 858 if (JSFUtils.isMinLengthFormat(additionalFormat)) 859 { 860 vars.put( 861 minlength, 862 Arrays.asList(minlength, JSFUtils.getMinLengthValue(additionalFormat))); 863 } 864 else if (JSFUtils.isMaxLengthFormat(additionalFormat)) 865 { 866 vars.put( 867 maxlength, 868 Arrays.asList(maxlength, JSFUtils.getMaxLengthValue(additionalFormat))); 869 } 870 else if (JSFUtils.isPatternFormat(additionalFormat)) 871 { 872 vars.put( 873 mask, 874 Arrays.asList(mask, JSFUtils.getPatternValue(additionalFormat))); 875 } 876 } 877 } 878 } 879 String inputFormat; 880 if (element instanceof JSFAttribute) 881 { 882 inputFormat = ((JSFAttribute)element).getFormat(); 883 } 884 else if (element instanceof JSFParameter) 885 { 886 inputFormat = ((JSFParameter)element).getFormat(); 887 } 888 else if (element instanceof JSFManageableEntityAttribute) 889 { 890 inputFormat = ((JSFManageableEntityAttribute)element).getFormat(); 891 } 892 else 893 { 894 throw new RuntimeException("'element' is an invalid type, it must be either an instance of '" + 895 JSFAttribute.class.getName() + "' or '" + JSFParameter.class.getName() + "'"); 896 } 897 if (JSFUtils.isDate(type)) 898 { 899 final String datePatternStrict = "datePatternStrict"; 900 if (format != null && JSFUtils.isStrictDateFormat(format)) 901 { 902 vars.put( 903 datePatternStrict, 904 Arrays.asList(datePatternStrict, inputFormat)); 905 } 906 else 907 { 908 final String datePattern = "datePattern"; 909 vars.put( 910 datePattern, 911 Arrays.asList(datePattern, inputFormat)); 912 } 913 } 914 if (JSFUtils.isTime(type)) 915 { 916 final String timePattern = "timePattern"; 917 vars.put( 918 timePattern, 919 Arrays.asList(timePattern, inputFormat)); 920 } 921 922 final String validWhen = JSFUtils.getValidWhen(element); 923 if (validWhen != null) 924 { 925 final String test = "test"; 926 vars.put( 927 test, 928 Arrays.asList(test, validWhen)); 929 } 930 931 final String equal = JSFUtils.getEqual(element, ownerParameter); 932 if (equal != null) 933 { 934 final String fieldName = "fieldName"; 935 vars.put( 936 fieldName, 937 Arrays.asList(fieldName, equal)); 938 } 939 940 // - custom (parameterized) validators are allowed here 941 // in this case we will reuse the validator arg values 942 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS); 943 for (final Object value : taggedValues) 944 { 945 final String validator = String.valueOf(value); 946 947 // - guaranteed to be of the same length 948 final List<String> validatorVars = JSFUtils.parseValidatorVars(validator); 949 final List<String> validatorArgs = JSFUtils.parseValidatorArgs(validator); 950 951 for (int ctr = 0; ctr < validatorVars.size(); ctr++) 952 { 953 vars.put(validatorVars.get(ctr), 954 Arrays.asList(validatorVars.get(ctr), validatorArgs.get(ctr))); 955 } 956 } 957 } 958 return vars.values(); 959 } 960 961 /** 962 * Gets the validator args for the <code>element</code> and the given <code>validatorType</code>. 963 * 964 * @param element the element for which to retrieve the arguments. 965 * @param validatorType the validator type name. 966 * @return the validator args as a collection. 967 */ 968 public static java.util.Collection getValidatorArgs( 969 final ModelElementFacade element, 970 final String validatorType) 971 { 972 final Collection<Object> args = new ArrayList<Object>(); 973 if ("intRange".equals(validatorType) || "floatRange".equals(validatorType) || 974 "doubleRange".equals(validatorType)) 975 { 976 args.add("${var:min}"); 977 args.add("${var:max}"); 978 } 979 else if ("minlength".equals(validatorType)) 980 { 981 args.add("${var:minlength}"); 982 } 983 else if ("maxlength".equals(validatorType)) 984 { 985 args.add("${var:maxlength}"); 986 } 987 else if ("date".equals(validatorType)) 988 { 989 final String validatorFormat = JSFUtils.getInputFormat(element); 990 if (JSFUtils.isStrictDateFormat(validatorFormat)) 991 { 992 args.add("${var:datePatternStrict}"); 993 } 994 else 995 { 996 args.add("${var:datePattern}"); 997 } 998 } 999 else if ("time".equals(validatorType)) 1000 { 1001 args.add("${var:timePattern}"); 1002 } 1003 else if ("equal".equals(validatorType)) 1004 { 1005 ModelElementFacade equalParameter = null; 1006 final String equal = JSFUtils.getEqual(element); 1007 if (element instanceof ParameterFacade) 1008 { 1009 final FrontEndParameter parameter = (FrontEndParameter)element; 1010 final OperationFacade operation = parameter.getOperation(); 1011 if (operation != null) 1012 { 1013 equalParameter = operation.findParameter(equal); 1014 } 1015 if (equalParameter == null) 1016 { 1017 final FrontEndAction action = parameter.getAction(); 1018 if (action != null) 1019 { 1020 equalParameter = action.findParameter(equal); 1021 } 1022 } 1023 } 1024 else if (element instanceof AttributeFacade) 1025 { 1026 final AttributeFacade attribute = (AttributeFacade)element; 1027 final ClassifierFacade owner = attribute.getOwner(); 1028 if (owner != null) 1029 { 1030 equalParameter = owner.findAttribute(equal); 1031 } 1032 } 1033 args.add(equalParameter); 1034 args.add("${var:fieldName}"); 1035 } 1036 1037 // custom (paramterized) validators are allowed here 1038 final Collection taggedValues = element.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_VALIDATORS); 1039 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();) 1040 { 1041 final String validator = String.valueOf(iterator.next()); 1042 if (validatorType.equals(JSFUtils.parseValidatorName(validator))) 1043 { 1044 args.addAll(JSFUtils.parseValidatorArgs(validator)); 1045 } 1046 } 1047 return args; 1048 } 1049 1050 /** 1051 * Whether or not date patterns should be treated as strict. 1052 */ 1053 private static boolean strictDateTimeFormat; 1054 1055 /** 1056 * Sets whether or not the date patterns should be treated as strict. 1057 * 1058 * @param strictDateTimeFormat 1059 */ 1060 public void setStrictDateTimeFormat(final boolean strictDateTimeFormat) 1061 { 1062 JSFUtils.strictDateTimeFormat = strictDateTimeFormat; 1063 } 1064 1065 /** 1066 * Indicates whether or not the format for this element is a strict date 1067 * format. 1068 * @param element 1069 * @return true/false 1070 */ 1071 public static boolean isStrictDateFormat(final ModelElementFacade element) 1072 { 1073 final String format = JSFUtils.getInputFormat(element); 1074 return JSFUtils.isStrictDateFormat(format); 1075 } 1076 1077 /** 1078 * Gets the format string for the given <code>element</code>. 1079 * 1080 * @param element the element for which to retrieve the format. 1081 * @param type the type of the element. 1082 * @param defaultDateFormat 1083 * @param defaultTimeFormat 1084 * @return the format string (if one is present otherwise null). 1085 */ 1086 public static String getFormat( 1087 final ModelElementFacade element, 1088 final ClassifierFacade type, 1089 final String defaultDateFormat, 1090 final String defaultTimeFormat) 1091 { 1092 String format = null; 1093 if (element != null && type != null) 1094 { 1095 format = JSFUtils.getInputFormat(element); 1096 if (format == null) 1097 { 1098 if(type.isDateType() && type.isTimeType()) 1099 { 1100 format = defaultDateFormat+" "+defaultTimeFormat; 1101 } 1102 else if (type.isTimeType()) 1103 { 1104 format = defaultTimeFormat; 1105 } 1106 else if (type.isDateType()) 1107 { 1108 format = defaultDateFormat; 1109 } 1110 } 1111 else if (type.isDateType()) 1112 { 1113 format = JSFUtils.getDateFormat(format); 1114 } 1115 } 1116 return format; 1117 } 1118 1119 /** 1120 * The XHTML extension. 1121 */ 1122 private static final String EXTENSION_XHTML = "xhtml"; 1123 1124 /** 1125 * Gets the extension for the view type. 1126 * 1127 * @return the view type extension. 1128 */ 1129 public String getViewExtension() 1130 { 1131 return EXTENSION_XHTML; 1132 } 1133 1134 //TODO remover 1135 private boolean isPortlet() 1136 { 1137 return false; 1138 } 1139 1140 /** 1141 * @return className 1142 */ 1143 public String getRequestClassName() 1144 { 1145 final String className; 1146 if (this.isPortlet()) 1147 { 1148 className = "javax.portlet.PortletRequest"; 1149 } 1150 else 1151 { 1152 className = "javax.servlet.http.HttpServletRequest"; 1153 } 1154 return className; 1155 } 1156 1157 /** 1158 * @return className 1159 */ 1160 public String getResponseClassName() 1161 { 1162 final String className; 1163 if (this.isPortlet()) 1164 { 1165 className = "javax.portlet.PortletResponse"; 1166 } 1167 else 1168 { 1169 className = "javax.servlet.http.HttpServletResponse"; 1170 } 1171 return className; 1172 } 1173 1174 /** 1175 * @return className 1176 */ 1177 public String getSessionClassName() 1178 { 1179 final String className; 1180 if (this.isPortlet()) 1181 { 1182 className = "javax.portlet.PortletSession"; 1183 } 1184 else 1185 { 1186 className = "javax.servlet.http.HttpSession"; 1187 } 1188 return className; 1189 } 1190 1191 /** 1192 * @param buffer 1193 * @return the calculated SerialVersionUID 1194 */ 1195 public static String calcSerialVersionUID(StringBuilder buffer) 1196 { 1197 final String signature = buffer.toString(); 1198 String serialVersionUID = String.valueOf(0L); 1199 try 1200 { 1201 MessageDigest md = MessageDigest.getInstance("SHA"); 1202 byte[] hashBytes = md.digest(signature.getBytes()); 1203 1204 long hash = 0; 1205 for (int ctr = Math.min( 1206 hashBytes.length, 1207 8) - 1; ctr >= 0; ctr--) 1208 { 1209 hash = (hash << 8) | (hashBytes[ctr] & 0xFF); 1210 } 1211 serialVersionUID = String.valueOf(hash); 1212 } 1213 catch (final NoSuchAlgorithmException exception) 1214 { 1215 throw new RuntimeException("Error performing JSFAction.getFormSerialVersionUID",exception); 1216 } 1217 1218 return serialVersionUID; 1219 } 1220 1221 /** 1222 * @param string 1223 * @return Integer.valueOf(string) * 6000 1224 */ 1225 public int calculateIcefacesTimeout(String string) 1226 { 1227 return string != null ? Integer.valueOf(string) * 6000 : 0; 1228 } 1229}