001package org.andromda.cartridges.jsf.metafacades; 002 003import java.util.Collection; 004import java.util.Iterator; 005import org.andromda.cartridges.jsf.JSFGlobals; 006import org.andromda.cartridges.jsf.JSFProfile; 007import org.andromda.cartridges.jsf.JSFUtils; 008import org.andromda.metafacades.uml.ClassifierFacade; 009import org.andromda.metafacades.uml.ModelElementFacade; 010import org.andromda.metafacades.uml.ParameterFacade; 011import org.andromda.utils.StringUtilsHelper; 012import org.apache.commons.lang.ObjectUtils; 013import org.apache.commons.lang.StringUtils; 014 015/** 016 * MetafacadeLogic implementation for org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute. 017 * 018 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute 019 */ 020public class JSFManageableEntityAttributeLogicImpl 021 extends JSFManageableEntityAttributeLogic 022{ 023 private static final long serialVersionUID = 34L; 024 /** 025 * @param metaObject 026 * @param context 027 */ 028 public JSFManageableEntityAttributeLogicImpl(Object metaObject, String context) 029 { 030 super(metaObject, context); 031 } 032 033 /** 034 * @return messageKey 035 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getMessageKey() 036 */ 037 protected String handleGetMessageKey() 038 { 039 String titleKey = ""; 040 041 final ClassifierFacade owner = getOwner(); 042 if (owner != null) 043 { 044 titleKey += owner.getName() + '.'; 045 } 046 047 return StringUtilsHelper.toResourceMessageKey(titleKey + getName()); 048 } 049 050 /** 051 * @return StringUtilsHelper.toPhrase(getName()) 052 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getMessageValue() 053 */ 054 protected String handleGetMessageValue() 055 { 056 return StringUtilsHelper.toPhrase(getName()); 057 } 058 059 /** 060 * @return dateFormat 061 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getDateFormat() 062 */ 063 protected String handleGetDateFormat() 064 { 065 String dateFormat = this.internalGetDateFormat(); 066 067 if (dateFormat != null) 068 { 069 final String[] tokens = dateFormat.split("[\\s]+"); 070 int tokenIndex = 0; 071 if (tokenIndex < tokens.length && "strict".equals(tokens[tokenIndex].trim())) 072 { 073 tokenIndex++; 074 } 075 if (tokenIndex < tokens.length) 076 { 077 dateFormat = tokens[tokenIndex].trim(); 078 } 079 } 080 081 return dateFormat; 082 } 083 084 /** 085 * @return getType().isBlobType() 086 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isNeedsFileUpload() 087 */ 088 protected boolean handleIsNeedsFileUpload() 089 { 090 return this.getType() != null && this.getType().isBlobType(); 091 } 092 093 /** 094 * @return isHidden 095 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isHidden() 096 */ 097 protected boolean handleIsHidden() 098 { 099 return !this.isDisplay() || JSFProfile.TAGGEDVALUE_INPUT_TYPE_HIDDEN.equals(this.getWidgetType()); 100 } 101 102 /** 103 * @return widgetType 104 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getWidgetType() 105 */ 106 protected String handleGetWidgetType() 107 { 108 final Object widgetTag = findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TYPE); 109 return (widgetTag == null) ? JSFProfile.TAGGEDVALUE_INPUT_TYPE_TEXT : widgetTag.toString(); 110 } 111 112 /** 113 * @return isStrictDateFormat 114 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isStrictDateFormat() 115 */ 116 protected boolean handleIsStrictDateFormat() 117 { 118 final String dateFormat = this.internalGetDateFormat(); 119 return (dateFormat != null && dateFormat.trim().startsWith("strict")); 120 } 121 122 /** 123 * @return getMessageKey() + ".online.help" 124 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getOnlineHelpKey() 125 */ 126 protected String handleGetOnlineHelpKey() 127 { 128 return this.getMessageKey() + ".online.help"; 129 } 130 131 /** 132 * @return getDocumentation 133 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getOnlineHelpValue() 134 */ 135 protected String handleGetOnlineHelpValue() 136 { 137 final String value = StringUtilsHelper.toResourceMessage(this.getDocumentation("", 64, false)); 138 return (value == null) ? "No field documentation has been specified" : value; 139 } 140 141 /** 142 * @return format 143 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getFormat() 144 */ 145 protected String handleGetFormat() 146 { 147 return JSFUtils.getFormat( 148 (ModelElementFacade)this.THIS(), 149 this.getType(), 150 this.getDefaultDateFormat(), 151 this.getDefaultTimeFormat()); 152 } 153 154 /** 155 * @return getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_DATEFORMAT) 156 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getDefaultDateFormat() 157 */ 158 protected String handleGetDefaultDateFormat() 159 { 160 return (String)this.getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_DATEFORMAT); 161 } 162 163 /** 164 * @return getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_TIMEFORMAT) 165 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getDefaultTimeFormat() 166 */ 167 protected String handleGetDefaultTimeFormat() 168 { 169 return (String)this.getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_TIMEFORMAT); 170 } 171 172 /** 173 * @return dateFormatter 174 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getDateFormatter() 175 */ 176 protected String handleGetDateFormatter() 177 { 178 final ClassifierFacade type = this.getType(); 179 return type != null && type.isDateType() ? this.getName() + "DateFormatter" : null; 180 } 181 182 /** 183 * @return timeFormatter 184 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getTimeFormatter() 185 */ 186 protected String handleGetTimeFormatter() 187 { 188 final ClassifierFacade type = this.getType(); 189 return type != null && type.isTimeType() ? this.getName() + "TimeFormatter" : null; 190 } 191 192 /** 193 * @return backingListName 194 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getBackingListName() 195 */ 196 protected String handleGetBackingListName() 197 { 198 final String backingListName = 199 StringUtils.replace( 200 ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.BACKING_LIST_PATTERN)), 201 "{0}", 202 this.getName()); 203 return org.andromda.utils.StringUtilsHelper.lowerCamelCaseName(backingListName); 204 } 205 206 /** 207 * @return valueListName 208 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValueListName() 209 */ 210 protected String handleGetValueListName() 211 { 212 return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.VALUE_LIST_PATTERN)).replaceAll( 213 "\\{0\\}", 214 this.getName()); 215 } 216 217 /** 218 * @return labelListName 219 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getLabelListName() 220 */ 221 protected String handleGetLabelListName() 222 { 223 return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.LABEL_LIST_PATTERN)).replaceAll( 224 "\\{0\\}", 225 this.getName()); 226 } 227 228 /** 229 * @return validatorTypes 230 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValidatorTypes() 231 */ 232 protected Collection handleGetValidatorTypes() 233 { 234 return JSFUtils.getValidatorTypes( 235 (ModelElementFacade)this.THIS(), 236 this.getType()); 237 } 238 239 /** 240 * @return !getValidatorTypes().isEmpty() 241 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isValidationRequired() 242 */ 243 protected boolean handleIsValidationRequired() 244 { 245 return !this.getValidatorTypes().isEmpty(); 246 } 247 248 /** 249 * @return validatorVars 250 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValidatorVars() 251 */ 252 protected Collection handleGetValidatorVars() 253 { 254 return JSFUtils.getValidatorVars( 255 (ModelElementFacade)this.THIS(), 256 this.getType(), 257 null); 258 } 259 260 /** 261 * @return JSFUtils.getValidWhen(this) 262 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValidWhen() 263 */ 264 protected String handleGetValidWhen() 265 { 266 return JSFUtils.getValidWhen(this); 267 } 268 269 /** 270 * @return checkbox 271 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputCheckbox() 272 */ 273 protected boolean handleIsInputCheckbox() 274 { 275 boolean checkbox = this.isInputType(JSFGlobals.INPUT_CHECKBOX); 276 if (!checkbox && this.getInputType().length() == 0) 277 { 278 final ClassifierFacade type = this.getType(); 279 checkbox = type != null ? type.isBooleanType() : false; 280 } 281 return checkbox; 282 } 283 284 /** 285 * @return file 286 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputFile() 287 */ 288 protected boolean handleIsInputFile() 289 { 290 boolean file = false; 291 ClassifierFacade type = getType(); 292 if (type != null) 293 { 294 file = type.isFileType() || type.isBlobType(); 295 } 296 return file; 297 } 298 299 /** 300 * @return isInputType(JSFGlobals.INPUT_HIDDEN) 301 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputHidden() 302 */ 303 protected boolean handleIsInputHidden() 304 { 305 return this.isInputType(JSFGlobals.INPUT_HIDDEN); 306 } 307 308 /** 309 * @return isInputType(JSFGlobals.INPUT_MULTIBOX) 310 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputMultibox() 311 */ 312 protected boolean handleIsInputMultibox() 313 { 314 return this.isInputType(JSFGlobals.INPUT_MULTIBOX); 315 } 316 317 /** 318 * @return isInputType(JSFGlobals.INPUT_RADIO) 319 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputRadio() 320 */ 321 protected boolean handleIsInputRadio() 322 { 323 return this.isInputType(JSFGlobals.INPUT_RADIO); 324 } 325 326 /** 327 * @return isInputType(JSFGlobals.INPUT_PASSWORD) 328 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputSecret() 329 */ 330 protected boolean handleIsInputSecret() 331 { 332 return this.isInputType(JSFGlobals.INPUT_PASSWORD); 333 } 334 335 /** 336 * @return isInputType(JSFGlobals.INPUT_SELECT) 337 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputSelect() 338 */ 339 protected boolean handleIsInputSelect() 340 { 341 return this.isInputType(JSFGlobals.INPUT_SELECT); 342 } 343 344 /** 345 * @return isInputTable 346 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputTable() 347 */ 348 protected boolean handleIsInputTable() 349 { 350 return this.getInputTableIdentifierColumns().length() > 0 || this.isInputType(JSFGlobals.INPUT_TABLE); 351 } 352 353 /** 354 * @return inputTableIdentifierColumns 355 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getInputTableIdentifierColumns() 356 */ 357 protected String handleGetInputTableIdentifierColumns() 358 { 359 return ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TABLE_IDENTIFIER_COLUMNS)).trim(); 360 } 361 362 /** 363 * @return isInputText 364 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputText() 365 */ 366 protected boolean handleIsInputText() 367 { 368 return this.isInputType(JSFGlobals.INPUT_TEXT); 369 } 370 371 /** 372 * @return isInputTextarea 373 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputTextarea() 374 */ 375 protected boolean handleIsInputTextarea() 376 { 377 return this.isInputType(JSFGlobals.INPUT_TEXTAREA); 378 } 379 380 /** 381 * @return isInputTypePresent 382 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isInputTypePresent() 383 */ 384 protected boolean handleIsInputTypePresent() 385 { 386 boolean present = false; 387 final ClassifierFacade type = this.getType(); 388 if (type != null) 389 { 390 present = 391 (StringUtils.isNotBlank(this.getInputType()) || type.isDateType() || type.isBooleanType()) && 392 !this.isPlaintext(); 393 } 394 return present; 395 } 396 397 /** 398 * @return dummyValue 399 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getDummyValue() 400 */ 401 protected String handleGetDummyValue() 402 { 403 final ClassifierFacade type = this.getType(); 404 if (type != null) 405 { 406 final String typeName = type.getFullyQualifiedName(); 407 final String name = this.getName(); 408 if ("String".equals(typeName)) 409 { 410 return "\"" + name + "-test" + "\""; 411 } 412 if ("java.util.Date".equals(typeName)) 413 { 414 return "new java.util.Date()"; 415 } 416 if ("java.sql.Date".equals(typeName)) 417 { 418 return "new java.sql.Date(new java.util.Date().getTime())"; 419 } 420 if ("java.sql.Timestamp".equals(typeName)) 421 { 422 return "new java.sql.Timestamp(new Date().getTime())"; 423 } 424 if ("java.util.Calendar".equals(typeName)) 425 { 426 return "java.util.Calendar.getInstance()"; 427 } 428 if ("int".equals(typeName)) 429 { 430 return "(int)" + name.hashCode(); 431 } 432 if ("boolean".equals(typeName)) 433 { 434 return "false"; 435 } 436 if ("long".equals(typeName)) 437 { 438 return "(long)" + name.hashCode(); 439 } 440 if ("char".equals(typeName)) 441 { 442 return "(char)" + name.hashCode(); 443 } 444 if ("float".equals(typeName)) 445 { 446 return "(float)" + name.hashCode() / hashCode(); 447 } 448 if ("double".equals(typeName)) 449 { 450 return "(double)" + name.hashCode() / hashCode(); 451 } 452 if ("short".equals(typeName)) 453 { 454 return "(short)" + name.hashCode(); 455 } 456 if ("byte".equals(typeName)) 457 { 458 return "(byte)" + name.hashCode(); 459 } 460 if ("java.lang.Integer".equals(typeName) || "Integer".equals(typeName)) 461 { 462 return "new Integer((int)" + name.hashCode() + ")"; 463 } 464 if ("java.lang.Boolean".equals(typeName) || "Boolean".equals(typeName)) 465 { 466 return "Boolean.FALSE"; 467 } 468 if ("java.lang.Long".equals(typeName) || "Long".equals(typeName)) 469 { 470 return "new Long((long)" + name.hashCode() + ")"; 471 } 472 if ("java.lang.Character".equals(typeName) || "Character".equals(typeName)) 473 { 474 return "new Character(char)" + name.hashCode() + ")"; 475 } 476 if ("java.lang.Float".equals(typeName) || "Float".equals(typeName)) 477 { 478 return "new Float((float)" + name.hashCode() / hashCode() + ")"; 479 } 480 if ("java.lang.Double".equals(typeName) || "Double".equals(typeName)) 481 { 482 return "new Double((double)" + name.hashCode() / hashCode() + ")"; 483 } 484 if ("java.lang.Short".equals(typeName) || "Short".equals(typeName)) 485 { 486 return "new Short((short)" + name.hashCode() + ")"; 487 } 488 if ("java.lang.Byte".equals(typeName) || "Byte".equals(typeName)) 489 { 490 return "new Byte((byte)" + name.hashCode() + ")"; 491 } 492 493 //if (type.isArrayType()) return constructDummyArray(); 494 if (type.isSetType()) 495 { 496 return "new java.util.HashSet(java.util.Arrays.asList(" + constructDummyArray() + "))"; 497 } 498 if (type.isCollectionType()) 499 { 500 return "java.util.Arrays.asList(" + constructDummyArray() + ")"; 501 } 502 503 // maps and others types will simply not be treated 504 } 505 return "null"; 506 } 507 508 /** 509 * @return isEqualValidator 510 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isEqualValidator() 511 */ 512 protected boolean handleIsEqualValidator() 513 { 514 final String equal = JSFUtils.getEqual((ModelElementFacade)this.THIS()); 515 return equal != null && equal.trim().length() > 0; 516 } 517 518 /** 519 * @return isInputType(JSFGlobals.PLAIN_TEXT) 520 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#isPlaintext() 521 */ 522 protected boolean handleIsPlaintext() 523 { 524 return this.isInputType(JSFGlobals.PLAIN_TEXT); 525 } 526 527 /** 528 * @return constructDummyArray() 529 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValueListDummyValue() 530 */ 531 protected String handleGetValueListDummyValue() 532 { 533 return this.constructDummyArray(); 534 } 535 536 /** 537 * @param validatorType 538 * @return getValidatorArgs 539 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getValidatorArgs(String) 540 */ 541 protected Collection handleGetValidatorArgs(String validatorType) 542 { 543 return JSFUtils.getValidatorArgs( 544 (ModelElementFacade)this.THIS(), 545 validatorType); 546 } 547 548 /** 549 * Gets the current value of the specified input type (or an empty string 550 * if one isn't specified). 551 * 552 * @return the input type name. 553 */ 554 private String getInputType() 555 { 556 return ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TYPE)).trim(); 557 } 558 559 /** 560 * Indicates whether or not this parameter is of the given input type. 561 * 562 * @param inputType the name of the input type to check for. 563 * @return true/false 564 */ 565 private boolean isInputType(final String inputType) 566 { 567 return inputType.equalsIgnoreCase(this.getInputType()); 568 } 569 570 /** 571 * Overridden to provide consistent behavior with {@link JSFParameter#isReadOnly()}. 572 * 573 * @see org.andromda.metafacades.uml.AttributeFacade#isReadOnly() 574 */ 575 public boolean isReadOnly() 576 { 577 return JSFUtils.isReadOnly(this); 578 } 579 580 /** 581 * Constructs a string representing an array initialization in Java. 582 * 583 * @return A String representing Java code for the initialization of an array. 584 */ 585 private String constructDummyArray() 586 { 587 return JSFUtils.constructDummyArrayDeclaration( 588 this.getName(), 589 JSFGlobals.DUMMY_ARRAY_COUNT); 590 } 591 592 private String internalGetDateFormat() 593 { 594 String dateFormat = null; 595 596 if (this.getType() != null && this.getType().isDateType()) 597 { 598 final Object taggedValueObject = this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_FORMAT); 599 if (taggedValueObject == null) 600 { 601 dateFormat = (String)this.getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_DATEFORMAT); 602 } 603 else 604 { 605 dateFormat = taggedValueObject.toString(); 606 } 607 } 608 609 return dateFormat; 610 } 611 612 /** 613 * @param ownerParameter 614 * @return propertyName 615 * @see JSFAttribute#getFormPropertyName(org.andromda.metafacades.uml.ParameterFacade) 616 */ 617 protected String handleGetFormPropertyName(final ParameterFacade ownerParameter) 618 { 619 final StringBuilder propertyName = new StringBuilder(); 620 if (ownerParameter != null) 621 { 622 propertyName.append(ownerParameter.getName()); 623 propertyName.append('.'); 624 } 625 final String name = this.getName(); 626 if (name != null && name.trim().length() > 0) 627 { 628 propertyName.append(name); 629 } 630 return propertyName.toString(); 631 } 632 633 /** 634 * @param ownerParameter 635 * @return StringUtilsHelper.lowerCamelCaseName(this.getFormPropertyName(ownerParameter)) 636 * @see JSFAttribute#getFormPropertyId(ParameterFacade) 637 */ 638 protected String handleGetFormPropertyId(final ParameterFacade ownerParameter) 639 { 640 return StringUtilsHelper.lowerCamelCaseName(this.getFormPropertyName(ownerParameter)); 641 } 642 643 //TODO remove after 3.4 release 644 /** 645 * Hack to keep the compatibility with Andromda 3.4 646 * @return defaultValue 647 */ 648 public String getDefaultValue() 649 { 650 String defaultValue = super.getDefaultValue(); 651 // Put single or double quotes around default in case modeler forgot to do it. Most templates 652 // declare Type attribute = $attribute.defaultValue, requiring quotes around the value 653 if (defaultValue!=null && defaultValue.length()>0 && !super.isMany()) 654 { 655 String typeName = getType().getName(); 656 if ("String".equals(typeName) && defaultValue.indexOf('"')<0) 657 { 658 defaultValue = '"' + defaultValue + '"'; 659 } 660 else if (("char".equals(typeName) || "Character".equals(typeName)) 661 && !defaultValue.contains("'")) 662 { 663 defaultValue = "'" + defaultValue.charAt(0) + "'"; 664 } 665 } 666 if (defaultValue==null) 667 { 668 defaultValue=""; 669 } 670 return defaultValue; 671 } 672 673 /** 674 * @return getColumnLength() 675 * @see org.andromda.cartridges.jsf.metafacades.JSFManageableEntityAttribute#getMaxLength() 676 */ 677 protected String handleGetMaxLength() 678 { 679 final Collection vars=getValidatorVars(); 680 if(vars == null) 681 { 682 return getColumnLength(); 683 } 684 for(Iterator<Collection> it=vars.iterator(); it.hasNext(); ) 685 { 686 final Object[] values=(it.next()).toArray(); 687 if("maxlength".equals(values[0])) 688 { 689 return values[1].toString(); 690 } 691 } 692 return getColumnLength(); 693 } 694}