001package org.andromda.metafacades.uml14; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Iterator; 006import java.util.LinkedHashSet; 007import java.util.List; 008import java.util.Set; 009import org.andromda.core.metafacade.MetafacadeConstants; 010import org.andromda.metafacades.uml.AssociationEndFacade; 011import org.andromda.metafacades.uml.AttributeFacade; 012import org.andromda.metafacades.uml.ClassifierFacade; 013import org.andromda.metafacades.uml.DependencyFacade; 014import org.andromda.metafacades.uml.Entity; 015import org.andromda.metafacades.uml.EntityAssociationEnd; 016import org.andromda.metafacades.uml.EntityAttribute; 017import org.andromda.metafacades.uml.EntityMetafacadeUtils; 018import org.andromda.metafacades.uml.EntityQueryOperation; 019import org.andromda.metafacades.uml.FilteredCollection; 020import org.andromda.metafacades.uml.MetafacadeUtils; 021import org.andromda.metafacades.uml.ModelElementFacade; 022import org.andromda.metafacades.uml.NameMasker; 023import org.andromda.metafacades.uml.OperationFacade; 024import org.andromda.metafacades.uml.UMLMetafacadeProperties; 025import org.andromda.metafacades.uml.UMLProfile; 026import org.andromda.utils.StringUtilsHelper; 027import org.apache.commons.collections.Closure; 028import org.apache.commons.collections.CollectionUtils; 029import org.apache.commons.collections.Predicate; 030import org.apache.commons.collections.Transformer; 031import org.apache.commons.lang.ObjectUtils; 032import org.apache.commons.lang.StringUtils; 033import org.omg.uml.foundation.core.Attribute; 034import org.omg.uml.foundation.core.Classifier; 035 036 037/** 038 * Metaclass facade implementation. 039 * @author Bob Fields 040 */ 041public class EntityLogicImpl 042 extends EntityLogic 043{ 044 private static final long serialVersionUID = 8742467678618468728L; 045 046 /** 047 * @param metaObject 048 * @param context 049 */ 050 public EntityLogicImpl( 051 final Object metaObject, 052 final String context) 053 { 054 super(metaObject, context); 055 } 056 057 /** 058 * A collection of MOF ids for entities that have dynamic 059 * identifiers present. 060 */ 061 private static final Collection dynamicIdentifiersPresent = new ArrayList(); 062 063 /** 064 * @see org.andromda.core.metafacade.MetafacadeBase#initialize() 065 */ 066 public void initialize() 067 { 068 super.initialize(); 069 070 // if there are no identifiers on this entity, create and add one. 071 // enumeration don't have identifiers since they are not entities 072 if (!this.isIdentifiersPresent() && this.isAllowDefaultIdentifiers()) 073 { 074 this.createIdentifier(); 075 dynamicIdentifiersPresent.add(this.getId()); 076 } 077 } 078 079 /** 080 * Overridden to provide name masking. 081 * 082 * @see org.andromda.metafacades.uml.ModelElementFacade#getName() 083 */ 084 @Override 085 protected String handleGetName() 086 { 087 final String nameMask = String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.ENTITY_NAME_MASK)); 088 return NameMasker.mask( 089 super.handleGetName(), 090 nameMask); 091 } 092 093 /** 094 * @see org.andromda.metafacades.uml.Entity#getQueryOperations() 095 */ 096 @Override 097 protected Collection<OperationFacade> handleGetQueryOperations() 098 { 099 return this.getQueryOperations(false); 100 } 101 102 /** 103 * @see org.andromda.metafacades.uml.Entity#getQueryOperations(boolean) 104 */ 105 @Override 106 protected Collection<OperationFacade> handleGetQueryOperations(final boolean follow) 107 { 108 final Collection<OperationFacade> operations = new ArrayList<OperationFacade>(this.getOperations()); 109 final Collection<OperationFacade> queryOperations = new ArrayList<OperationFacade>(); 110 111 MetafacadeUtils.filterByType( 112 operations, 113 EntityQueryOperation.class); 114 for (OperationFacade operation : operations) 115 { 116 queryOperations.add((EntityQueryOperation)operation); 117 } 118 for (ClassifierFacade superClass = (ClassifierFacade)getGeneralization(); superClass != null && follow; 119 superClass = (ClassifierFacade)superClass.getGeneralization()) 120 { 121 if (Entity.class.isAssignableFrom(superClass.getClass())) 122 { 123 Entity entity = (Entity)superClass; 124 queryOperations.addAll(entity.getQueryOperations()); 125 } 126 } 127 return queryOperations; 128 } 129 130 /** 131 * @see org.andromda.metafacades.uml.Entity#getIdentifiers() 132 */ 133 @Override 134 protected Collection<ModelElementFacade> handleGetIdentifiers() 135 { 136 return this.getIdentifiers(true); 137 } 138 139 /** 140 * @see org.andromda.metafacades.uml.Entity#getIdentifiers(boolean) 141 */ 142 @Override 143 protected Collection<ModelElementFacade> handleGetIdentifiers(final boolean follow) 144 { 145 return EntityMetafacadeUtils.getIdentifiers( 146 this, 147 follow); 148 } 149 150 /** 151 * Creates an identifier from the default identifier properties specified within a namespace. 152 */ 153 private void createIdentifier() 154 { 155 // first check if the foreign identifier flag is set, and 156 // let those taken precedence if so 157 if (!this.checkForAndAddForeignIdentifiers()) 158 { 159 this.createIdentifier( 160 this.getDefaultIdentifier(), 161 this.getDefaultIdentifierType(), 162 this.getDefaultIdentifierVisibility()); 163 } 164 } 165 166 /** 167 * Creates a new identifier and adds it to the underlying meta model 168 * classifier instance. 169 * 170 * @param name the name to give the identifier 171 * @param type the type to give the identifier 172 * @param visibility the visibility to give the identifier 173 */ 174 private void createIdentifier( 175 final String name, 176 final String type, 177 final String visibility) 178 { 179 final Classifier classifier = (Classifier)this.metaObject; 180 181 // if we auto-create entity identifiers it will only be on hierarchy roots, 182 // problems would arise when calls to #checkForAndAddForeignIdentifiers() 183 // navigate over associated entities, effectively initializing their facade instances: 184 // this results in subclasses having an identifier generated before their ancestors 185 // ideally the method mentioned above would not make use of facades but meta-classes only, 186 // if one is to refactor it that way this comment may be removed together with the line of code under it 187 // 188 // notice how the next line of code does not make use of facades, this is done on purpose in order 189 // to avoid using uninitialized facades 190 // 191 // (Wouter, Sept. 20 2006) also see other UML implementations 192 if (!classifier.getGeneralization().isEmpty()) return; 193 194 // only create the identifier if an identifer with the name doesn't 195 // already exist 196 if (!UML14MetafacadeUtils.attributeExists( 197 classifier, 198 name)) 199 { 200 final Attribute identifier = 201 UML14MetafacadeUtils.createAttribute( 202 name, 203 type, 204 visibility, 205 MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR); 206 207 identifier.getStereotype().add( 208 UML14MetafacadeUtils.findOrCreateStereotype(UMLProfile.STEREOTYPE_IDENTIFIER)); 209 210 classifier.getFeature().add(identifier); 211 } 212 } 213 214 /** 215 * @see org.andromda.metafacades.uml.Entity#isIdentifiersPresent() 216 */ 217 @Override 218 protected boolean handleIsIdentifiersPresent() 219 { 220 final Collection<ModelElementFacade> identifiers = this.getIdentifiers(true); 221 return identifiers != null && !identifiers.isEmpty(); 222 } 223 224 /** 225 * @see org.andromda.metafacades.uml.Entity#isDynamicIdentifiersPresent() 226 */ 227 @Override 228 protected boolean handleIsDynamicIdentifiersPresent() 229 { 230 return dynamicIdentifiersPresent.contains(this.getId()); 231 } 232 233 /** 234 * @see org.andromda.metafacades.uml.Entity#getTableName() 235 */ 236 @Override 237 protected String handleGetTableName() 238 { 239 final String prefixProperty = UMLMetafacadeProperties.TABLE_NAME_PREFIX; 240 final String tableNamePrefix = 241 this.isConfiguredProperty(prefixProperty) 242 ? ObjectUtils.toString(this.getConfiguredProperty(prefixProperty)) : null; 243 return EntityMetafacadeUtils.getSqlNameFromTaggedValue( 244 tableNamePrefix, 245 this, 246 UMLProfile.TAGGEDVALUE_PERSISTENCE_TABLE, 247 this.getMaxSqlNameLength(), 248 this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR), 249 this.getConfiguredProperty(UMLMetafacadeProperties.SHORTEN_SQL_NAMES_METHOD)); 250 } 251 252 /** 253 * @see org.andromda.metafacades.uml.Entity#getOperationCallFromAttributes(boolean) 254 */ 255 @Override 256 protected String handleGetOperationCallFromAttributes(final boolean withIdentifiers) 257 { 258 return this.getOperationCallFromAttributes( 259 withIdentifiers, 260 false); 261 } 262 263 /** 264 * @see org.andromda.metafacades.uml.Entity#getOperationCallFromAttributes(boolean, boolean) 265 */ 266 @Override 267 protected String handleGetOperationCallFromAttributes( 268 final boolean withIdentifiers, 269 final boolean follow) 270 { 271 final StringBuilder buffer = new StringBuilder(); 272 String separator = ""; 273 buffer.append('('); 274 275 final Collection<AttributeFacade> attributes = new ArrayList(this.getAttributes()); 276 277 for (ClassifierFacade superClass = (ClassifierFacade)getGeneralization(); superClass != null && follow; 278 superClass = (ClassifierFacade)superClass.getGeneralization()) 279 { 280 if (superClass instanceof Entity) 281 { 282 final Entity entity = (Entity)superClass; 283 attributes.addAll(entity.getAttributes()); 284 } 285 } 286 287 if (!attributes.isEmpty()) 288 { 289 for (final Iterator iterator = attributes.iterator(); iterator.hasNext();) 290 { 291 final EntityAttribute attribute = (EntityAttribute)iterator.next(); 292 if (withIdentifiers || !attribute.isIdentifier()) 293 { 294 buffer.append(separator); 295 if (attribute.getType() != null) 296 { 297 buffer.append(attribute.getType().getFullyQualifiedName()); 298 } 299 buffer.append(' '); 300 buffer.append(attribute.getName()); 301 separator = ", "; 302 } 303 } 304 } 305 buffer.append(')'); 306 return buffer.toString(); 307 } 308 309 /** 310 * @see org.andromda.metafacades.uml.Entity#getAttributeTypeList(boolean, boolean) 311 */ 312 @Override 313 protected String handleGetAttributeTypeList( 314 final boolean follow, 315 final boolean withIdentifiers) 316 { 317 return this.getTypeList(this.getAttributes( 318 follow, 319 withIdentifiers)); 320 } 321 322 /** 323 * @see org.andromda.metafacades.uml.Entity#getAttributeNameList(boolean, boolean) 324 */ 325 @Override 326 protected String handleGetAttributeNameList( 327 final boolean follow, 328 final boolean withIdentifiers) 329 { 330 return this.getNameList(this.getAttributes( 331 follow, 332 withIdentifiers)); 333 } 334 335 /** 336 * @see org.andromda.metafacades.uml.Entity#getAttributeNameList(boolean, boolean, boolean) 337 */ 338 @Override 339 protected String handleGetAttributeNameList( 340 final boolean follow, 341 final boolean withIdentifiers, 342 final boolean withDerived) 343 { 344 return this.getNameList(this.getAttributes( 345 follow, 346 withIdentifiers, 347 withDerived)); 348 } 349 350 /** 351 * @see org.andromda.metafacades.uml.Entity#getRequiredAttributeTypeList(boolean, boolean) 352 */ 353 @Override 354 protected String handleGetRequiredAttributeTypeList( 355 final boolean follow, 356 final boolean withIdentifiers) 357 { 358 return this.getTypeList(this.getRequiredAttributes( 359 follow, 360 withIdentifiers)); 361 } 362 363 /** 364 * @see org.andromda.metafacades.uml.Entity#getRequiredAttributeNameList(boolean, boolean) 365 */ 366 @Override 367 protected String handleGetRequiredAttributeNameList( 368 final boolean follow, 369 final boolean withIdentifiers) 370 { 371 return this.getNameList(this.getRequiredAttributes( 372 follow, 373 withIdentifiers)); 374 } 375 376 /** 377 * @see org.andromda.metafacades.uml.Entity#getRequiredPropertyTypeList(boolean, boolean) 378 */ 379 @Override 380 protected String handleGetRequiredPropertyTypeList( 381 final boolean follow, 382 final boolean withIdentifiers) 383 { 384 return this.getTypeList(this.getRequiredProperties( 385 follow, 386 withIdentifiers)); 387 } 388 389 /** 390 * @see org.andromda.metafacades.uml.Entity#getRequiredPropertyNameList(boolean, boolean) 391 */ 392 @Override 393 protected String handleGetRequiredPropertyNameList( 394 final boolean follow, 395 final boolean withIdentifiers) 396 { 397 return this.getNameList(this.getRequiredProperties( 398 follow, 399 withIdentifiers)); 400 } 401 402 /** 403 * Constructs a comma separated list of attribute type names from the passed in collection of 404 * <code>attributes</code>. 405 * 406 * @param attributes the attributes to construct the list from. 407 * @return the comma separated list of attribute types. 408 */ 409 private String getTypeList(final Collection attributes) 410 { 411 final StringBuilder list = new StringBuilder(); 412 final String comma = ", "; 413 CollectionUtils.forAllDo( 414 attributes, 415 new Closure() 416 { 417 public void execute(final Object object) 418 { 419 if (object instanceof AttributeFacade) 420 { 421 final AttributeFacade attribute = (AttributeFacade)object; 422 if (attribute.getType() != null) 423 { 424 list.append(attribute.getType().getFullyQualifiedName()); 425 list.append(comma); 426 } 427 } 428 if (object instanceof AssociationEndFacade) 429 { 430 final AssociationEndFacade associationEnd = (AssociationEndFacade)object; 431 if (associationEnd.getType() != null) 432 { 433 list.append(associationEnd.getType().getFullyQualifiedName()); 434 list.append(comma); 435 } 436 } 437 } 438 }); 439 if (list.toString().endsWith(comma)) 440 { 441 list.delete( 442 list.lastIndexOf(comma), 443 list.length()); 444 } 445 return list.toString(); 446 } 447 448 /** 449 * Constructs a comma separated list of attribute names from the passed in collection of <code>attributes</code>. 450 * 451 * @param properties the properties to construct the list from. 452 * @return the comma separated list of attribute names. 453 */ 454 private String getNameList(final Collection properties) 455 { 456 final StringBuilder list = new StringBuilder(); 457 final String comma = ", "; 458 CollectionUtils.forAllDo( 459 properties, 460 new Closure() 461 { 462 public void execute(Object object) 463 { 464 if (object instanceof EntityAttribute) 465 { 466 list.append(((AttributeFacade)object).getName()); 467 list.append(comma); 468 } 469 if (object instanceof EntityAssociationEnd) 470 { 471 list.append(((AssociationEndFacade)object).getName()); 472 list.append(comma); 473 } 474 } 475 }); 476 if (list.toString().endsWith(comma)) 477 { 478 list.delete( 479 list.lastIndexOf(comma), 480 list.length()); 481 } 482 return list.toString(); 483 } 484 485 /** 486 * @see org.andromda.metafacades.uml.Entity#isChild() 487 */ 488 @Override 489 protected boolean handleIsChild() 490 { 491 return CollectionUtils.find( 492 this.getAssociationEnds(), 493 new Predicate() 494 { 495 public boolean evaluate(Object object) 496 { 497 return ((AssociationEndFacade)object).getOtherEnd().isComposition(); 498 } 499 }) != null; 500 } 501 502 /** 503 * @see org.andromda.metafacades.uml.Entity#getParentEnd() 504 */ 505 @Override 506 protected AssociationEndFacade handleGetParentEnd() 507 { 508 AssociationEndFacade parentEnd = null; 509 final AssociationEndFacade end = 510 (AssociationEndFacade)CollectionUtils.find( 511 this.getAssociationEnds(), 512 new Predicate() 513 { 514 public boolean evaluate(Object object) 515 { 516 return ((AssociationEndFacade)object).getOtherEnd().isComposition(); 517 } 518 }); 519 if (end != null) 520 { 521 parentEnd = end.getOtherEnd(); 522 } 523 return parentEnd; 524 } 525 526 /** 527 * @see org.andromda.metafacades.uml.Entity#getChildEnds() 528 */ 529 @Override 530 protected Collection<AssociationEndFacade> handleGetChildEnds() 531 { 532 final Collection<AssociationEndFacade> childEnds = 533 new FilteredCollection(this.getAssociationEnds()) 534 { 535 private static final long serialVersionUID = -4602337379703645043L; 536 537 public boolean evaluate(Object object) 538 { 539 return ((AssociationEndFacade)object).isComposition(); 540 } 541 }; 542 CollectionUtils.transform( 543 childEnds, 544 new Transformer() 545 { 546 public Object transform(Object object) 547 { 548 return ((AssociationEndFacade)object).getOtherEnd(); 549 } 550 }); 551 return childEnds; 552 } 553 554 /** 555 * @see org.andromda.metafacades.uml.Entity#getBusinessOperations() 556 */ 557 @Override 558 protected Collection<OperationFacade> handleGetBusinessOperations() 559 { 560 final Collection<OperationFacade> businessOperations = new ArrayList(this.getImplementationOperations()); 561 MetafacadeUtils.filterByNotType( 562 businessOperations, 563 EntityQueryOperation.class); 564 return businessOperations; 565 } 566 567 /** 568 * @see org.andromda.metafacades.uml.Entity#getEntityReferences() 569 */ 570 @Override 571 protected Collection<DependencyFacade> handleGetEntityReferences() 572 { 573 return new FilteredCollection(this.getSourceDependencies()) 574 { 575 private static final long serialVersionUID = -8696886289865317133L; 576 577 public boolean evaluate(Object object) 578 { 579 ModelElementFacade targetElement = ((DependencyFacade)object).getTargetElement(); 580 return targetElement instanceof Entity; 581 } 582 }; 583 } 584 585 /** 586 * @see org.andromda.metafacades.uml.Entity#getAttributes(boolean, boolean) 587 */ 588 @Override 589 protected Collection handleGetAttributes( 590 boolean follow, 591 final boolean withIdentifiers) 592 { 593 return this.getAttributes(follow, withIdentifiers, true); 594 } 595 596 /** 597 * @see org.andromda.metafacades.uml.Entity#getAttributes(boolean, boolean, boolean) 598 */ 599 @Override 600 protected Collection handleGetAttributes( 601 boolean follow, 602 final boolean withIdentifiers, 603 final boolean withDerived) 604 { 605 final Collection attributes = this.getAttributes(follow); 606 CollectionUtils.filter( 607 attributes, 608 new Predicate() 609 { 610 public boolean evaluate(Object object) 611 { 612 boolean valid = true; 613 if (!withIdentifiers && object instanceof EntityAttribute) 614 { 615 valid = !((EntityAttribute)object).isIdentifier(); 616 } 617 if (valid && !withDerived && object instanceof EntityAttribute) 618 { 619 valid = !((EntityAttribute)object).isDerived(); 620 } 621 return valid; 622 } 623 }); 624 return attributes; 625 } 626 627 /** 628 * @see org.andromda.metafacades.uml.Entity#getProperties(boolean, boolean) 629 */ 630 @Override 631 protected Collection handleGetProperties( 632 boolean follow, 633 final boolean withIdentifiers) 634 { 635 final Collection properties = this.getProperties(follow); 636 CollectionUtils.filter( 637 properties, 638 new Predicate() 639 { 640 public boolean evaluate(Object object) 641 { 642 boolean valid = true; 643 if (!withIdentifiers && object instanceof EntityAttribute) 644 { 645 valid = !((EntityAttribute)object).isIdentifier(); 646 } 647 return valid; 648 } 649 }); 650 return properties; 651 } 652 653 /** 654 * @see org.andromda.metafacades.uml.Entity#getRequiredAttributes(boolean, boolean) 655 */ 656 @Override 657 protected Collection handleGetRequiredAttributes( 658 boolean follow, 659 final boolean withIdentifiers) 660 { 661 final Collection attributes = this.getAttributes( 662 follow, 663 withIdentifiers, false); 664 CollectionUtils.filter( 665 attributes, 666 new Predicate() 667 { 668 public boolean evaluate(Object object) 669 { 670 boolean valid; 671 valid = ((AttributeFacade)object).isRequired(); 672 if (valid && !withIdentifiers && object instanceof EntityAttribute) 673 { 674 valid = !((EntityAttribute)object).isIdentifier(); 675 } 676 return valid; 677 } 678 }); 679 return attributes; 680 } 681 682 /** 683 * @see org.andromda.metafacades.uml.Entity#getRequiredProperties(boolean, boolean) 684 */ 685 @Override 686 protected Collection handleGetRequiredProperties( 687 final boolean follow, 688 final boolean withIdentifiers) 689 { 690 final Set properties = new LinkedHashSet(this.getProperties( 691 follow, 692 withIdentifiers)); 693 CollectionUtils.filter( 694 properties, 695 new Predicate() 696 { 697 public boolean evaluate(final Object object) 698 { 699 boolean valid = false; 700 if (object instanceof AttributeFacade) 701 { 702 AttributeFacade attribute = (AttributeFacade)object; 703 valid = attribute.isRequired() && !attribute.isDerived(); 704 if (valid && !withIdentifiers && object instanceof EntityAttribute) 705 { 706 valid = !((EntityAttribute)object).isIdentifier(); 707 } 708 } 709 else if (object instanceof AssociationEndFacade) 710 { 711 valid = ((AssociationEndFacade)object).isRequired(); 712 } 713 return valid; 714 } 715 }); 716 717 List sortedProperties = new ArrayList(properties); 718 MetafacadeUtils.sortByFullyQualifiedName(sortedProperties); 719 return sortedProperties; 720 } 721 722 /** 723 * Gets the maximum name length SQL names may be 724 */ 725 @Override 726 protected short handleGetMaxSqlNameLength() 727 { 728 return Short.valueOf((String)this.getConfiguredProperty(UMLMetafacadeProperties.MAX_SQL_NAME_LENGTH)); 729 } 730 731 /** 732 * Returns true/false on whether or not default identifiers are allowed 733 */ 734 private boolean isAllowDefaultIdentifiers() 735 { 736 return Boolean.valueOf((String)this.getConfiguredProperty(UMLMetafacadeProperties.ALLOW_DEFAULT_IDENTITIFIERS)) 737 .booleanValue(); 738 } 739 740 /** 741 * Gets the name of the default identifier. 742 */ 743 private String getDefaultIdentifier() 744 { 745 return ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_IDENTIFIER_PATTERN)) 746 .replaceAll( 747 "\\{0\\}", 748 StringUtilsHelper.lowerCamelCaseName(this.getName())); 749 } 750 751 /** 752 * Gets the name of the default identifier type. 753 */ 754 private String getDefaultIdentifierType() 755 { 756 return (String)this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_IDENTIFIER_TYPE); 757 } 758 759 /** 760 * Gets the default identifier visibility. 761 */ 762 private String getDefaultIdentifierVisibility() 763 { 764 return (String)this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_IDENTIFIER_VISIBILITY); 765 } 766 767 /** 768 * Checks to see if this entity has any associations where the foreign identifier flag may be set, and if so creates 769 * and adds identifiers just like the foreign entity to this entity. 770 * 771 * @return true if any identifiers were added, false otherwise 772 */ 773 private boolean checkForAndAddForeignIdentifiers() 774 { 775 boolean identifiersAdded = false; 776 final EntityAssociationEnd end = this.getForeignIdentifierEnd(); 777 if (end != null && end.getType() instanceof Entity) 778 { 779 final Entity foreignEntity = (Entity)end.getOtherEnd().getType(); 780 final Collection<ModelElementFacade> identifiers = EntityMetafacadeUtils.getIdentifiers( 781 foreignEntity, 782 true); 783 for (final ModelElementFacade facade : identifiers) 784 { 785 if (facade instanceof AttributeFacade) 786 { 787 AttributeFacade identifier = (AttributeFacade)facade; 788 this.createIdentifier( 789 identifier.getName(), 790 identifier.getType().getFullyQualifiedName(true), 791 identifier.getVisibility()); 792 } 793 else if (facade instanceof AssociationEndFacade) 794 { 795 AssociationEndFacade identifier = (AssociationEndFacade)facade; 796 this.createIdentifier( 797 identifier.getName(), 798 identifier.getType().getFullyQualifiedName(true), 799 identifier.getVisibility()); 800 } 801 identifiersAdded = true; 802 } 803 } 804 return identifiersAdded; 805 } 806 807 /** 808 * Override to filter out any association ends that point to model elements other than other entities. 809 * 810 * @see org.andromda.metafacades.uml.ClassifierFacade#getAssociationEnds() 811 */ 812 @Override 813 public List handleGetAssociationEnds() 814 { 815 final List associationEnds = (List)this.shieldedElements(super.handleGetAssociationEnds()); 816 CollectionUtils.filter( 817 associationEnds, 818 new Predicate() 819 { 820 public boolean evaluate(Object object) 821 { 822 return ((AssociationEndFacade)object).getOtherEnd().getType() instanceof Entity; 823 } 824 }); 825 return associationEnds; 826 } 827 828 /** 829 * @see org.andromda.metafacades.uml14.EntityLogic#handleIsUsingForeignIdentifier() 830 */ 831 protected boolean handleIsUsingForeignIdentifier() 832 { 833 return this.getForeignIdentifierEnd() != null; 834 } 835 836 /** 837 * Gets the association end that is flagged as having the foreign identifier set (or null if none is). 838 */ 839 private EntityAssociationEnd getForeignIdentifierEnd() 840 { 841 return (EntityAssociationEnd)CollectionUtils.find( 842 this.getAssociationEnds(), 843 new Predicate() 844 { 845 public boolean evaluate(Object object) 846 { 847 boolean valid = false; 848 if (object != null && EntityAssociationEnd.class.isAssignableFrom(object.getClass())) 849 { 850 EntityAssociationEnd end = (EntityAssociationEnd)object; 851 valid = end.isForeignIdentifier(); 852 } 853 return valid; 854 } 855 }); 856 } 857 858 /** 859 * @see org.andromda.metafacades.uml.Entity#isUsingAssignedIdentifier() 860 */ 861 @Override 862 protected boolean handleIsUsingAssignedIdentifier() 863 { 864 boolean assigned = false; 865 final Collection<ModelElementFacade> identifiers = this.getIdentifiers(); 866 if (identifiers != null && !identifiers.isEmpty()) 867 { 868 ModelElementFacade facade = identifiers.iterator().next(); 869 if (facade instanceof AttributeFacade) 870 { 871 final AttributeFacade identifier = (AttributeFacade)facade; 872 assigned = 873 Boolean.valueOf( 874 ObjectUtils.toString( 875 identifier.findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_ASSIGNED_IDENTIFIER))) 876 .booleanValue(); 877 } 878 } 879 return assigned; 880 } 881 882 /** 883 * @see org.andromda.metafacades.uml.Entity#getSchema() 884 */ 885 @Override 886 protected String handleGetSchema() 887 { 888 String schemaName = ObjectUtils.toString(this.findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_SCHEMA)); 889 if (StringUtils.isBlank(schemaName)) 890 { 891 schemaName = ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.SCHEMA_NAME)); 892 } 893 return schemaName; 894 } 895 896 /** 897 * @see org.andromda.metafacades.uml.Entity#getIdentifierAssociationEnds() 898 */ 899 @Override 900 protected Collection handleGetIdentifierAssociationEnds() 901 { 902 final Collection<AssociationEndFacade> associationEnds = new ArrayList<AssociationEndFacade>(this.getAssociationEnds()); 903 MetafacadeUtils.filterByStereotype( 904 associationEnds, 905 UMLProfile.STEREOTYPE_IDENTIFIER); 906 return associationEnds; 907 } 908 909 /** 910 * @see org.andromda.metafacades.uml.Entity#isCompositeIdentifier() 911 */ 912 @Override 913 protected boolean handleIsCompositeIdentifier() 914 { 915 int identifiers = (!this.getIdentifiers().isEmpty()) ? this.getIdentifiers().size() : 0; 916 identifiers = 917 identifiers + 918 (!this.getIdentifierAssociationEnds().isEmpty() ? this.getIdentifierAssociationEnds().size() : 0); 919 return identifiers >= 2; 920 } 921 922 /** 923 * @see org.andromda.metafacades.uml.Entity#getAllEntityReferences() 924 */ 925 @Override 926 protected Collection<DependencyFacade> handleGetAllEntityReferences() 927 { 928 final Collection<DependencyFacade> result = new LinkedHashSet<DependencyFacade> (); 929 930 // get references of the service itself 931 result.addAll(this.getEntityReferences()); 932 933 // get references of all super classes 934 CollectionUtils.forAllDo(this.getAllGeneralizations(), new Closure() 935 { 936 public void execute(Object object) 937 { 938 if (object instanceof Entity) 939 { 940 final Entity entity = (Entity)object; 941 result.addAll(entity.getEntityReferences()); 942 } 943 } 944 945 }); 946 return result; 947 } 948 949 /** 950 * @see org.andromda.metafacades.uml.Entity#getEmbeddedValues() 951 */ 952 @Override 953 protected Collection<AttributeFacade> handleGetEmbeddedValues() 954 { 955 final Collection<AttributeFacade> embeddedValues = new ArrayList<AttributeFacade>(); 956 for (final Iterator<AttributeFacade> iterator = this.getAttributes(true).iterator(); iterator.hasNext();) 957 { 958 final AttributeFacade attribute = iterator.next(); 959 final ClassifierFacade type = attribute.getType(); 960 if (type != null && type.isEmbeddedValue()) 961 { 962 embeddedValues.add(attribute); 963 } 964 } 965 return embeddedValues; 966 } 967 968 /** 969 * @see org.andromda.metafacades.uml.Entity#getFullyQualifiedIdentifierTypeName() 970 */ 971 @Override 972 public String handleGetFullyQualifiedIdentifierTypeName() { 973 if(isCompositeIdentifier()) 974 { 975 return getFullyQualifiedName()+(String)this.getConfiguredProperty(UMLMetafacadeProperties.COMPOSITE_IDENTIFIER_TYPE_NAME_SUFIX); 976 } 977 else 978 { 979 ModelElementFacade facade = getIdentifiers().iterator().next(); 980 if (facade instanceof AttributeFacade) 981 { 982 return ((AttributeFacade)facade).getType().getFullyQualifiedName(); 983 } 984 else if (facade instanceof AssociationEndFacade) 985 { 986 return ((AssociationEndFacade)facade).getType().getFullyQualifiedName(); 987 } 988 else 989 { 990 return ""; 991 } 992 } 993 } 994 995 /** 996 * @see org.andromda.metafacades.uml.Entity#getIdentifierName() 997 */ 998 @Override 999 public String handleGetIdentifierName() { 1000 if(isCompositeIdentifier()) 1001 { 1002 return StringUtils.uncapitalize(getName())+(String)this.getConfiguredProperty(UMLMetafacadeProperties.COMPOSITE_IDENTIFIER_NAME_SUFIX); 1003 } 1004 else 1005 { 1006 return getIdentifiers().iterator().next().getName(); 1007 } 1008 } 1009 1010 /** 1011 * @see org.andromda.metafacades.uml.Entity#getIdentifierTypeName() 1012 */ 1013 @Override 1014 public String handleGetIdentifierTypeName() { 1015 if(isCompositeIdentifier()) 1016 { 1017 return getName()+(String)this.getConfiguredProperty(UMLMetafacadeProperties.COMPOSITE_IDENTIFIER_TYPE_NAME_SUFIX); 1018 } 1019 else 1020 { 1021 ModelElementFacade facade = getIdentifiers().iterator().next(); 1022 if (facade instanceof AttributeFacade) 1023 { 1024 return ((AttributeFacade)facade).getType().getName(); 1025 } 1026 else if (facade instanceof AssociationEndFacade) 1027 { 1028 return ((AssociationEndFacade)facade).getType().getName(); 1029 } 1030 else 1031 { 1032 return ""; 1033 } 1034 } 1035 } 1036 1037 /** 1038 * @see org.andromda.metafacades.uml.Entity#getIdentifierGetterName() 1039 */ 1040 @Override 1041 public String handleGetIdentifierGetterName() { 1042 return "get"+StringUtils.capitalize(getIdentifierName()); 1043 } 1044 1045 /** 1046 * @see org.andromda.metafacades.uml.Entity#getIdentifierSetterName() 1047 */ 1048 @Override 1049 public String handleGetIdentifierSetterName() { 1050 return "set"+StringUtils.capitalize(getIdentifierName()); 1051 } 1052}