001package org.andromda.metafacades.emf.uml22; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Iterator; 006import java.util.LinkedHashSet; 007import org.andromda.metafacades.uml.ClassifierFacade; 008import org.andromda.metafacades.uml.ConstraintFacade; 009import org.andromda.metafacades.uml.DependencyFacade; 010import org.andromda.metafacades.uml.MetafacadeUtils; 011import org.andromda.metafacades.uml.ModelElementFacade; 012import org.andromda.metafacades.uml.NameMasker; 013import org.andromda.metafacades.uml.OperationFacade; 014import org.andromda.metafacades.uml.ParameterFacade; 015import org.andromda.metafacades.uml.TypeMappings; 016import org.andromda.metafacades.uml.UMLMetafacadeProperties; 017import org.andromda.metafacades.uml.UMLProfile; 018import org.andromda.translation.ocl.ExpressionKinds; 019import org.apache.commons.collections.CollectionUtils; 020import org.apache.commons.collections.Predicate; 021import org.apache.commons.collections.Transformer; 022import org.apache.commons.lang.BooleanUtils; 023import org.apache.commons.lang.ObjectUtils; 024import org.apache.commons.lang.StringUtils; 025import org.apache.log4j.Logger; 026import org.eclipse.uml2.uml.CallConcurrencyKind; 027import org.eclipse.uml2.uml.LiteralUnlimitedNatural; 028import org.eclipse.uml2.uml.Operation; 029import org.eclipse.uml2.uml.Parameter; 030import org.eclipse.uml2.uml.ParameterDirectionKind; 031import org.eclipse.uml2.uml.Type; 032 033/** 034 * MetafacadeLogic implementation for 035 * org.andromda.metafacades.uml.OperationFacade. 036 * 037 * @see org.andromda.metafacades.uml.OperationFacade 038 * @author Bob Fields 039 */ 040public class OperationFacadeLogicImpl 041 extends OperationFacadeLogic 042{ 043 private static final long serialVersionUID = 34L; 044 /** 045 * The logger instance. 046 */ 047 private static final Logger LOGGER = Logger.getLogger(OperationFacadeLogicImpl.class); 048 049 /** 050 * @param metaObject 051 * @param context 052 */ 053 public OperationFacadeLogicImpl( 054 final Operation metaObject, 055 final String context) 056 { 057 super(metaObject, context); 058 } 059 060 /** 061 * Not yet implemented, always returns null. To implement: walk through the 062 * related elements from the Sequence Diagram or OCL Body in the UML model to produce compilable code. 063 * @return null 064 * @see org.andromda.metafacades.uml.OperationFacade#getMethodBody() 065 */ 066 @Override 067 protected String handleGetMethodBody() 068 { 069 return null; 070 } 071 072 /** 073 * Overridden to provide name masking. 074 * 075 * @see org.andromda.metafacades.uml.ModelElementFacade#getName() 076 */ 077 @Override 078 protected String handleGetName() 079 { 080 final String nameMask = String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.OPERATION_NAME_MASK)); 081 return NameMasker.mask( 082 super.handleGetName(), 083 nameMask); 084 } 085 086 /** 087 * @see org.andromda.metafacades.uml.OperationFacade#getSignature() 088 */ 089 @Override 090 protected String handleGetSignature() 091 { 092 return this.getSignature(true); 093 } 094 095 /** 096 * @see org.andromda.metafacades.uml.OperationFacade#getCall() 097 */ 098 @Override 099 protected String handleGetCall() 100 { 101 return this.getCall(this.handleGetName()); 102 } 103 104 /** 105 * Constructs the operation call with the given <code>name</code> 106 * 107 * @param name 108 * the name form which to construct the operation call. 109 * @return the operation call. 110 */ 111 private String getCall(final String name) 112 { 113 final StringBuilder buffer = new StringBuilder(name); 114 buffer.append('('); 115 buffer.append(this.getArgumentNames()); 116 buffer.append(')'); 117 return buffer.toString(); 118 } 119 120 /** 121 * @see org.andromda.metafacades.uml.OperationFacade#getTypedArgumentList() 122 */ 123 @Override 124 protected String handleGetTypedArgumentList() 125 { 126 return this.getTypedArgumentList(true); 127 } 128 129 private String getTypedArgumentList(final boolean withArgumentNames) 130 { 131 // TODO: Possible covariant of the method 'getTypedArgumentList' defined in the class 'OperationFacadeLogic' 132 return MetafacadeUtils.getTypedArgumentList( 133 this.getArguments(), 134 withArgumentNames, 135 null); 136 } 137 138 /** 139 * @see org.andromda.metafacades.uml.OperationFacade#isStatic() 140 */ 141 @Override 142 protected boolean handleIsStatic() 143 { 144 return this.metaObject.isStatic(); 145 } 146 147 /** 148 * @see org.andromda.metafacades.uml.OperationFacade#isAbstract() 149 */ 150 @Override 151 protected boolean handleIsAbstract() 152 { 153 return this.metaObject.isAbstract(); 154 } 155 156 /** 157 * @see org.andromda.metafacades.uml.OperationFacade#getExceptionList() 158 */ 159 @Override 160 protected String handleGetExceptionList() 161 { 162 return this.getExceptionList(null); 163 } 164 165 /** 166 * Finds both exceptions and exception dependency references 167 * @see org.andromda.metafacades.uml.OperationFacade#getExceptions() 168 */ 169 @Override 170 protected Collection handleGetExceptions() 171 { 172 final Collection<DependencyFacade> exceptions = new LinkedHashSet<DependencyFacade>(); 173 174 // finds both exceptions and exception references 175 final class ExceptionFilter 176 implements Predicate 177 { 178 public boolean evaluate(final Object object) 179 { 180 boolean hasException = object instanceof DependencyFacade; 181 if (hasException) 182 { 183 final DependencyFacade dependency = (DependencyFacade)object; 184 // first check for exception references 185 hasException = dependency.hasStereotype(UMLProfile.STEREOTYPE_EXCEPTION_REF); 186 187 // if there wasn't any exception reference 188 // now check for actual exceptions 189 if (!hasException) 190 { 191 final ModelElementFacade targetElement = dependency.getTargetElement(); 192 hasException = targetElement != null && targetElement.hasStereotype( 193 UMLProfile.STEREOTYPE_EXCEPTION); 194 } 195 } 196 return hasException; 197 } 198 } 199 200 // first get any dependencies on this operation's 201 // owner (because these will represent the default exception(s)) 202 final Collection<DependencyFacade> ownerDependencies = new ArrayList<DependencyFacade>(this.getOwner().getSourceDependencies()); 203 if (!ownerDependencies.isEmpty()) 204 { 205 CollectionUtils.filter(ownerDependencies, new ExceptionFilter()); 206 exceptions.addAll(ownerDependencies); 207 } 208 209 final Collection<DependencyFacade> operationDependencies = new ArrayList<DependencyFacade>(this.getSourceDependencies()); 210 // now get any exceptions directly on the operation 211 if (!operationDependencies.isEmpty()) 212 { 213 CollectionUtils.filter(operationDependencies, new ExceptionFilter()); 214 exceptions.addAll(operationDependencies); 215 } 216 217 // now transform the dependency(s) to the actual exception(s) 218 CollectionUtils.transform(exceptions, new Transformer() 219 { 220 public Object transform(final Object object) 221 { 222 if (object == null) return null; 223 return ((DependencyFacade)object).getTargetElement(); 224 } 225 }); 226 227 // finally add in any members of the UML2 RaisedException list 228 // (the 'proper' UML2 way of doing exceptions .. or at least one way). 229 final Collection<Type> raisedExceptions = this.metaObject.getRaisedExceptions(); 230 exceptions.addAll(this.shieldedElements(raisedExceptions)); 231 232 return exceptions; 233 } 234 235 236 /** 237 * @see org.andromda.metafacades.uml.OperationFacade#isReturnTypePresent() 238 */ 239 @Override 240 protected boolean handleIsReturnTypePresent() 241 { 242 boolean hasReturnType = false; 243 if (this.getReturnType() != null) 244 { 245 hasReturnType = !("void".equalsIgnoreCase(StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName())) 246 || StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName(true)).equals(UMLProfile.VOID_TYPE_NAME)); 247 } 248 if (LOGGER.isDebugEnabled()) 249 { 250 final String rtnFQN = this.getReturnType().getFullyQualifiedName(true); 251 final boolean voidType = "void".equalsIgnoreCase(StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName())); 252 final String voidRtn = this.getReturnType().getFullyQualifiedName(); 253 LOGGER.debug("OperationFacadeLogicImpl.handleIsReturnTypePresent rtnFQN=" + rtnFQN + " voidType=" + voidType + " voidRtn=" + voidRtn + " hasReturnType=" + hasReturnType); 254 } 255 return hasReturnType; 256 } 257 258 /** 259 * @see org.andromda.metafacades.uml.OperationFacade#isExceptionsPresent() 260 */ 261 @Override 262 protected boolean handleIsExceptionsPresent() 263 { 264 return !this.getExceptions().isEmpty(); 265 } 266 267 /** 268 * @see org.andromda.metafacades.uml.OperationFacade#getArgumentNames() 269 */ 270 @Override 271 protected String handleGetArgumentNames() 272 { 273 final StringBuilder buffer = new StringBuilder(); 274 275 final Iterator<Parameter> iterator = this.metaObject.getOwnedParameters().iterator(); 276 277 boolean commaNeeded = false; 278 final String comma = ", "; 279 while (iterator.hasNext()) 280 { 281 final Parameter parameter = iterator.next(); 282 if (!parameter.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL)) 283 { 284 if (commaNeeded) 285 { 286 buffer.append(comma); 287 } 288 final ParameterFacade facade = (ParameterFacade)this.shieldedElement(parameter); 289 buffer.append(facade.getName()); 290 commaNeeded = true; 291 } 292 } 293 return buffer.toString(); 294 } 295 296 /** 297 * @see org.andromda.metafacades.uml.OperationFacade#getArgumentTypeNames() 298 */ 299 @Override 300 protected String handleGetArgumentTypeNames() 301 { 302 final StringBuilder buffer = new StringBuilder(); 303 304 final Iterator<Parameter> iterator = this.metaObject.getOwnedParameters().iterator(); 305 306 boolean commaNeeded = false; 307 while (iterator.hasNext()) 308 { 309 final Parameter parameter = iterator.next(); 310 311 if (!parameter.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL)) 312 { 313 if (commaNeeded) 314 { 315 buffer.append(", "); 316 } 317 final ParameterFacade facade = (ParameterFacade)this.shieldedElement(parameter); 318 buffer.append(facade.getType().getFullyQualifiedName()); 319 commaNeeded = true; 320 } 321 } 322 return buffer.toString(); 323 } 324 325 /** 326 * @see org.andromda.metafacades.uml.OperationFacade#isQuery() 327 */ 328 @Override 329 protected boolean handleIsQuery() 330 { 331 return this.metaObject.isQuery(); 332 } 333 334 /** 335 * @see org.andromda.metafacades.uml.OperationFacade#getConcurrency() 336 */ 337 @Override 338 protected String handleGetConcurrency() 339 { 340 String concurrency = null; 341 342 final CallConcurrencyKind concurrencyKind = this.metaObject.getConcurrency(); 343 if (concurrencyKind == null || concurrencyKind.equals(CallConcurrencyKind.CONCURRENT_LITERAL)) 344 { 345 concurrency = "concurrent"; 346 } 347 else if (concurrencyKind.equals(CallConcurrencyKind.GUARDED_LITERAL)) 348 { 349 concurrency = "guarded"; 350 } 351 else// CallConcurrencyKindEnum.CCK_SEQUENTIAL 352 { 353 concurrency = "sequential"; 354 } 355 356 final TypeMappings languageMappings = this.getLanguageMappings(); 357 if (languageMappings != null) 358 { 359 concurrency = languageMappings.getTo(concurrency); 360 } 361 362 return concurrency; 363 } 364 365 /** 366 * Gets the pattern for constructing the precondition name. 367 * 368 * @return the precondition pattern. 369 */ 370 private String getPreconditionPattern() 371 { 372 return String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.PRECONDITION_NAME_PATTERN)); 373 } 374 375 /** 376 * Gets the pattern for constructing the postcondition name. 377 * 378 * @return the postcondition pattern. 379 */ 380 private String getPostconditionPattern() 381 { 382 return String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.POSTCONDITION_NAME_PATTERN)); 383 } 384 385 /** 386 * @see org.andromda.metafacades.uml.OperationFacade#getPreconditionName() 387 */ 388 @Override 389 protected String handleGetPreconditionName() 390 { 391 return this.getPreconditionPattern().replaceAll( 392 "\\{0\\}", 393 this.handleGetName()); 394 } 395 396 /** 397 * @see org.andromda.metafacades.uml.OperationFacade#getPostconditionName() 398 */ 399 @Override 400 protected String handleGetPostconditionName() 401 { 402 return this.getPostconditionPattern().replaceAll( 403 "\\{0\\}", 404 this.handleGetName()); 405 } 406 407 /** 408 * @see org.andromda.metafacades.uml.OperationFacade#getPreconditionSignature() 409 */ 410 @Override 411 protected String handleGetPreconditionSignature() 412 { 413 return MetafacadeUtils.getSignature( 414 this.getPreconditionName(), 415 this.getArguments(), 416 true, 417 null); 418 } 419 420 /** 421 * @see org.andromda.metafacades.uml.OperationFacade#getPreconditionCall() 422 */ 423 @Override 424 protected String handleGetPreconditionCall() 425 { 426 return this.getCall(this.getPreconditionName()); 427 } 428 429 /** 430 * @see org.andromda.metafacades.uml.OperationFacade#isPreconditionsPresent() 431 */ 432 @Override 433 protected boolean handleIsPreconditionsPresent() 434 { 435 final Collection<ConstraintFacade> preconditions = this.getPreconditions(); 436 return preconditions != null && !preconditions.isEmpty(); 437 } 438 439 /** 440 * @see org.andromda.metafacades.uml.OperationFacade#isPostconditionsPresent() 441 */ 442 @Override 443 protected boolean handleIsPostconditionsPresent() 444 { 445 final Collection<ConstraintFacade> postconditions = this.getPostconditions(); 446 return postconditions != null && !postconditions.isEmpty(); 447 } 448 449 /** 450 * @see org.andromda.metafacades.uml.OperationFacade#findTaggedValue(String, 451 * boolean) 452 */ 453 @Override 454 protected Object handleFindTaggedValue( 455 final String name, 456 final boolean follow) 457 { 458 final String trimName = StringUtils.trimToEmpty(name); 459 Object value = this.findTaggedValue(trimName); 460 if (follow) 461 { 462 ClassifierFacade type = this.getReturnType(); 463 while (value == null && type != null) 464 { 465 value = type.findTaggedValue(trimName); 466 type = (ClassifierFacade)type.getGeneralization(); 467 } 468 } 469 return value; 470 } 471 472 /** 473 * @see org.andromda.metafacades.uml.OperationFacade#getExceptionList(String) 474 */ 475 @Override 476 protected String handleGetExceptionList(String initialExceptions) 477 { 478 initialExceptions = StringUtils.trimToEmpty(initialExceptions); 479 final StringBuilder exceptionList = new StringBuilder(initialExceptions); 480 // TODO getExceptions = Collection<ClassifierFacade> or <ModelElementFacade>? 481 final Collection exceptions = this.getExceptions(); 482 if (exceptions != null && !exceptions.isEmpty()) 483 { 484 if (StringUtils.isNotBlank(initialExceptions)) 485 { 486 exceptionList.append(", "); 487 } 488 final Iterator exceptionIt = exceptions.iterator(); 489 while (exceptionIt.hasNext()) 490 { 491 final ModelElementFacade exception = (ModelElementFacade)exceptionIt.next(); 492 exceptionList.append(exception.getFullyQualifiedName()); 493 if (exceptionIt.hasNext()) 494 { 495 exceptionList.append(", "); 496 } 497 } 498 } 499 500 return exceptionList.toString(); 501 } 502 503 /** 504 * @see org.andromda.metafacades.uml.OperationFacade#getSignature(boolean) 505 */ 506 @Override 507 protected String handleGetSignature(final boolean withArgumentNames) 508 { 509 return MetafacadeUtils.getSignature( 510 this.handleGetName(), 511 this.getArguments(), 512 withArgumentNames, 513 null); 514 } 515 516 /** 517 * @see org.andromda.metafacades.uml.OperationFacade#getTypedArgumentList(String) 518 */ 519 @Override 520 protected String handleGetTypedArgumentList(final String modifier) 521 { 522 return MetafacadeUtils.getTypedArgumentList( 523 this.getArguments(), 524 true, 525 modifier); 526 } 527 528 /** 529 * @see org.andromda.metafacades.uml.OperationFacade#getSignature(String) 530 */ 531 @Override 532 protected String handleGetSignature(final String argumentModifier) 533 { 534 return MetafacadeUtils.getSignature( 535 this.handleGetName(), 536 this.getArguments(), 537 true, 538 argumentModifier); 539 } 540 541 /** 542 * @see org.andromda.metafacades.uml.OperationFacade#getOwner() 543 */ 544 @Override 545 protected Object handleGetOwner() 546 { 547 Object obj = null; 548 // Fix from UML2, no longer calls getOwner to get the owning Class 549 if (this.metaObject.getInterface()!=null) 550 { 551 obj = this.metaObject.getInterface(); 552 } 553 else if (this.metaObject.getDatatype()!=null) 554 { 555 obj = this.metaObject.getDatatype(); 556 } 557 else 558 { 559 obj = this.metaObject.getClass_(); 560 } 561 return obj; 562 } 563 564 /** 565 * @see org.andromda.metafacades.uml.OperationFacade#getParameters() 566 */ 567 @Override 568 protected Collection<Parameter> handleGetParameters() 569 { 570 final Collection<Parameter> params = new ArrayList<Parameter>(this.metaObject.getOwnedParameters()); 571 params.add(this.metaObject.getReturnResult()); 572 CollectionUtils.filter( 573 params, 574 new Predicate() 575 { 576 public boolean evaluate(final Object object) 577 { 578 return object != null && !((Parameter)object).isException(); 579 } 580 }); 581 return params; 582 } 583 584 /** 585 * @see org.andromda.metafacades.uml.OperationFacade#getReturnType() 586 */ 587 @Override 588 protected Type handleGetReturnType() 589 { 590 return this.metaObject.getType(); 591 } 592 593 /** 594 * @return this.getReturnType().getFullyQualifiedName() 595 * @see org.andromda.metafacades.uml.OperationFacade#getGetterSetterReturnTypeName() 596 */ 597 protected String handleGetGetterSetterReturnTypeName() 598 { 599 String name = null; 600 final ClassifierFacade returnType = this.getReturnType(); 601 602 if (returnType!=null && (this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED)) 603 { 604 final TypeMappings mappings = this.getLanguageMappings(); 605 name = 606 this.handleIsOrdered() ? mappings.getTo(UMLProfile.LIST_TYPE_NAME) 607 : mappings.getTo(UMLProfile.COLLECTION_TYPE_NAME); 608 609 // set this attribute's type as a template parameter if required 610 if (BooleanUtils.toBoolean( 611 ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING)))) 612 { 613 String type = returnType.getFullyQualifiedName(); 614 if (returnType.isPrimitive()) 615 { 616 // Can't template primitive values, Objects only. Convert to wrapped. 617 type = this.getReturnType().getWrapperName(); 618 } 619 // Allow List<Type[]> implementations. 620 /*// Don't apply templating to modeled array types 621 if (returnType.isArrayType()) 622 { 623 type = type.substring(0, type.length()-2); 624 }*/ 625 /*Collection<GeneralizableElementFacade> specializations = returnType.getAllSpecializations(); 626 if ((specializations != null && !specializations.isEmpty())) 627 { 628 name += "<? extends " + type + '>'; 629 } 630 else 631 {*/ 632 name += '<' + type + '>'; 633 //} 634 } 635 } 636 if (name == null && returnType != null) 637 { 638 name = returnType.getFullyQualifiedName(); 639 // Special case: lower bound overrides primitive/wrapped type declaration 640 // TODO Apply to all primitive types, not just booleans. This is a special case because of is/get Getters. 641 if (this.getReturnType().isBooleanType()) 642 { 643 if (this.getReturnType().isPrimitive() && (this.getLower() < 1)) 644 { 645 // Type is optional, should not be primitive 646 name = StringUtils.capitalize(name); 647 } 648 else if (!this.getReturnType().isPrimitive() && this.getLower() > 0) 649 { 650 // Type is required, should not be wrapped 651 name = StringUtils.uncapitalize(name); 652 } 653 } 654 } 655 return name; 656 } 657 658 /** 659 * @return this.metaObject.isOrdered() 660 * @see org.andromda.metafacades.uml.OperationFacade#isOrdered() 661 */ 662 protected boolean handleIsOrdered() 663 { 664 return this.metaObject.isOrdered(); 665 } 666 667 /** 668 * @return this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED 669 * @see org.andromda.metafacades.uml.OperationFacade#isMany() 670 */ 671 protected boolean handleIsMany() 672 { 673 // Because of MD11.5 (their multiplicity are String), we cannot use 674 // isMultiValued() 675 // RJF3 True if either the operation is many or the return parameter is many 676 final ParameterFacade returnParameter = this.getReturnParameter(); 677 // Parameter or parameter type may be null during model validation 678 final boolean returnMany = returnParameter!=null && returnParameter.getType()!=null && 679 (returnParameter.getUpper() > 1 || 680 returnParameter.getUpper() == LiteralUnlimitedNatural.UNLIMITED 681 || returnParameter.getType().isArrayType() 682 || returnParameter.getType().isCollectionType()); 683 return returnMany || this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED; 684 } 685 686 /** 687 * @see org.andromda.metafacades.uml.OperationFacade#getArguments() 688 */ 689 @Override 690 protected Collection<Parameter> handleGetArguments() 691 { 692 final Collection<Parameter> arguments = new ArrayList<Parameter>(this.metaObject.getOwnedParameters()); 693 CollectionUtils.filter( 694 arguments, 695 new Predicate() 696 { 697 public boolean evaluate(final Object object) 698 { 699 final Parameter param = (Parameter)object; 700 return !param.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL) && !param.isException(); 701 } 702 }); 703 return arguments; 704 } 705 706 /** 707 * @see org.andromda.metafacades.uml.OperationFacade#getPreconditions() 708 */ 709 @Override 710 protected Collection<ConstraintFacade> handleGetPreconditions() 711 { 712 return this.handleGetConstraints(ExpressionKinds.PRE); 713 } 714 715 /** 716 * @see org.andromda.metafacades.uml.OperationFacade#getPostconditions() 717 */ 718 @Override 719 protected Collection<ConstraintFacade> handleGetPostconditions() 720 { 721 return this.handleGetConstraints(ExpressionKinds.POST); 722 } 723 724 /** 725 * @see org.andromda.core.metafacade.MetafacadeBase#getValidationOwner() 726 */ 727 @Override 728 public Object getValidationOwner() 729 { 730 return this.getOwner(); 731 } 732 733 /** 734 * @see org.andromda.metafacades.uml.OperationFacade#findParameter(String) 735 */ 736 @Override 737 protected ParameterFacade handleFindParameter(final String name) 738 { 739 return (ParameterFacade)this.shieldedElement(this.metaObject.getOwnedParameter(name, null)); 740 } 741 742 /** 743 * Get the UML upper multiplicity Not implemented for UML1.4 744 * @return multiplicity upperBound 745 */ 746 @Override 747 protected int handleGetUpper() 748 { 749 // MD11.5 Exports multiplicity as String 750 return this.metaObject.getUpper(); 751 //return UmlUtilities.parseMultiplicity(this.metaObject.getUpper(), 1); 752 } 753 754 /** 755 * Get the UML lower multiplicity Not implemented for UML1.4 756 * @return multiplicity lowerBound 757 */ 758 @Override 759 protected int handleGetLower() 760 { 761 // MD11.5 Exports multiplicity as String 762 return this.metaObject.getLower(); 763 //return UmlUtilities.parseLowerMultiplicity(this.metaObject.getLower(), 764 // (ClassifierFacade) this.getReturnType(), "0"); 765 // ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_MULTIPLICITY))); 766 } 767 768 /** 769 * Get the first UML2 ReturnResult parameter. Not implemented for UML1.4 770 * @return ReturnResult parameter 771 */ 772 @Override 773 public ParameterFacade handleGetReturnParameter() 774 { 775 return (ParameterFacade)this.shieldedElement(this.metaObject.getReturnResult()); 776 } 777 778 /* 779 * Override to change private to public, since it makes no sense to have private operations in generated code 780 * Allows for protected, package level visibility of operations in the model 781 * @return String visibility 782 @Override 783 protected String handleGetVisibility() 784 { 785 String visibility = super.handleGetVisibility(); 786 if (visibility==null || visibility.equals("private")) 787 { 788 visibility = "public"; 789 } 790 return visibility; 791 } 792 */ 793 794 /** 795 * @see org.andromda.metafacades.uml.OperationFacade#isOverriding() 796 */ 797 @Override 798 protected boolean handleIsOverriding() 799 { 800 return this.getOverriddenOperation() != null; 801 } 802 803 /** 804 * @see org.andromda.metafacades.uml.OperationFacade#getOverriddenOperation() 805 */ 806 @Override 807 protected OperationFacade handleGetOverriddenOperation() 808 { 809 OperationFacade overriddenOperation = null; 810 811 final String signature = this.getSignature(false); 812 813 ClassifierFacade ancestor = this.getOwner().getSuperClass(); 814 while (overriddenOperation == null && ancestor != null) 815 { 816 for (final Iterator<OperationFacade> operationIterator = ancestor.getOperations().iterator(); 817 overriddenOperation == null && operationIterator.hasNext();) 818 { 819 final OperationFacade ancestorOperation = operationIterator.next(); 820 if (signature.equals(ancestorOperation.getSignature(false))) 821 { 822 overriddenOperation = ancestorOperation; 823 } 824 } 825 826 ancestor = ancestor.getSuperClass(); 827 } 828 829 return overriddenOperation; 830 } 831 832 /** 833 * @return this.metaObject.isLeaf() 834 * @see org.andromda.metafacades.uml.OperationFacade#isLeaf() 835 */ 836 protected boolean handleIsLeaf() 837 { 838 return this.metaObject.isLeaf(); 839 } 840 841 /** 842 * @return this.metaObject.isUnique() 843 * @see org.andromda.metafacades.uml.OperationFacade#isUnique() 844 */ 845 protected boolean handleIsUnique() 846 { 847 return this.metaObject.isUnique(); 848 } 849}