001package org.andromda.cartridges.spring.metafacades; 002 003import java.util.Collection; 004import java.util.Collections; 005import java.util.HashSet; 006import java.util.Set; 007import org.andromda.cartridges.spring.SpringProfile; 008import org.andromda.metafacades.uml.MetafacadeUtils; 009import org.andromda.metafacades.uml.ParameterFacade; 010import org.andromda.metafacades.uml.UMLProfile; 011import org.andromda.utils.StringUtilsHelper; 012import org.apache.commons.lang.BooleanUtils; 013import org.apache.commons.lang.ObjectUtils; 014import org.apache.commons.lang.StringUtils; 015 016/** 017 * MetafacadeLogic implementation for org.andromda.cartridges.spring.metafacades.SpringServiceOperation. 018 * 019 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation 020 */ 021public class SpringServiceOperationLogicImpl 022 extends SpringServiceOperationLogic 023{ 024 private static final long serialVersionUID = 34L; 025 /** 026 * Public constructor for SpringServiceOperationLogicImpl 027 * @param metaObject 028 * @param context 029 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation 030 */ 031 public SpringServiceOperationLogicImpl(Object metaObject, String context) 032 { 033 super(metaObject, context); 034 } 035 036 /** 037 * @return hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE_OPERATION) 038 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#isWebserviceExposed() 039 */ 040 protected boolean handleIsWebserviceExposed() 041 { 042 return this.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE_OPERATION); 043 } 044 045 /** 046 * @return getImplementationOperationName(StringUtils.capitalize(this.getName())) 047 * or getImplementationOperationName(StringUtils.capitalize(this.getSignature()) 048 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getImplementationName() 049 */ 050 protected String handleGetImplementationName() 051 { 052 return this.getImplementationOperationName(StringUtils.capitalize(this.getName())); 053 } 054 055 /** 056 * @return getOutgoingMessageImplementationSignature() or getOutgoingMessageImplementationSignature() 057 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getImplementationSignature() 058 */ 059 protected String handleGetImplementationSignature() 060 { 061 String signature = null; 062 if (this.isIncomingMessageOperation()) 063 { 064 signature = this.getIncomingMessageImplementationSignature(); 065 } 066 else if (this.isOutgoingMessageOperation()) 067 { 068 signature = this.getOutgoingMessageImplementationSignature(); 069 } 070 else 071 { 072 signature = this.getImplementationOperationName(StringUtils.capitalize(this.getSignature())); 073 } 074 return signature; 075 } 076 077 /** 078 * @see org.andromda.metafacades.uml.OperationFacade#getCall() 079 * 080 * Overridden to provide the message argument (when necessary) 081 */ 082 public String getCall() 083 { 084 String call = null; 085 if (this.isIncomingMessageOperation() && this.getArguments().isEmpty()) 086 { 087 call = this.getName() + "(message)"; 088 } 089 else 090 { 091 call = super.getCall(); 092 } 093 return call; 094 } 095 096 /** 097 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getSignature(String) 098 * 099 * Overridden to provide the appropriate incoming message (if needed). 100 */ 101 public String getSignature(String modifier) 102 { 103 String signature = null; 104 if (this.isIncomingMessageOperation() && this.getArguments().isEmpty()) 105 { 106 signature = this.getIncomingMessageSignature(modifier); 107 } 108 else 109 { 110 signature = super.getSignature(modifier); 111 } 112 return signature; 113 } 114 115 /** 116 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperationLogic#getSignature(boolean) 117 * 118 * Overridden to provide the appropriate incoming message (if needed). 119 */ 120 public String getSignature(final boolean withArgumentNames) 121 { 122 String signature = null; 123 if (this.isIncomingMessageOperation() && this.getArguments().isEmpty()) 124 { 125 signature = this.getIncomingMessageSignature(null); 126 } 127 else 128 { 129 signature = super.getSignature(withArgumentNames); 130 } 131 return signature; 132 } 133 134 /** 135 * 136 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperationLogic#getSignature() 137 * 138 * Overridden to provide the appropriate incoming message (if needed). 139 */ 140 public String getSignature() 141 { 142 return this.getSignature(true); 143 } 144 145 /** 146 * @return getImplementationOperationName(StringUtils.capitalize(this.getCall())) 147 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperationLogic#getImplementationCall() 148 */ 149 protected String handleGetImplementationCall() 150 { 151 return this.getImplementationOperationName(StringUtils.capitalize(this.getCall())); 152 } 153 154 /** 155 * Retrieves the implementationOperatName by replacing the <code>replacement</code> in the {@link 156 * SpringGlobals#IMPLEMENTATION_OPERATION_NAME_PATTERN} 157 * 158 * @param replacement the replacement string for the pattern. 159 * @return the operation name 160 */ 161 private String getImplementationOperationName(String replacement) 162 { 163 return StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty( 164 SpringGlobals.IMPLEMENTATION_OPERATION_NAME_PATTERN))).replaceAll("\\{0\\}", replacement); 165 } 166 167 /** 168 * The transaction type for Spring service operations. 169 */ 170 private static final String SERVICE_OPERATION_TRANSACTION_TYPE = "serviceOperationTransactionType"; 171 172 /** 173 * @return getOwner().findTaggedValue(SpringProfile.TAGGEDVALUE_TRANSACTION_TYPE) 174 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperationLogic#getTransactionType() 175 */ 176 public String handleGetTransactionType() 177 { 178 String transactionType = (String)this.findTaggedValue(SpringProfile.TAGGEDVALUE_TRANSACTION_TYPE); 179 if (StringUtils.isBlank(transactionType)) 180 { 181 transactionType = (String)this.getOwner().findTaggedValue(SpringProfile.TAGGEDVALUE_TRANSACTION_TYPE); 182 } 183 if (StringUtils.isBlank(transactionType)) 184 { 185 transactionType = String.valueOf(this.getConfiguredProperty(SERVICE_OPERATION_TRANSACTION_TYPE)); 186 } 187 return transactionType; 188 } 189 190 /** 191 * The transaction type for EJB wrapped service operations.. 192 */ 193 private static final String EJB_SERVICE_OPERATION_TRANSACTION_TYPE = "ejbServiceOperationTransactionType"; 194 195 /** 196 * @return EjbTransactionType 197 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperationLogic#getEjbTransactionType() 198 */ 199 protected String handleGetEjbTransactionType() 200 { 201 String transactionType = (String)this.findTaggedValue(SpringProfile.TAGGEDVALUE_EJB_TRANSACTION_TYPE); 202 if (StringUtils.isBlank(transactionType)) 203 { 204 transactionType = (String)this.getOwner().findTaggedValue(SpringProfile.TAGGEDVALUE_EJB_TRANSACTION_TYPE); 205 } 206 if (StringUtils.isBlank(transactionType)) 207 { 208 transactionType = String.valueOf(this.getConfiguredProperty(EJB_SERVICE_OPERATION_TRANSACTION_TYPE)); 209 } 210 return transactionType; 211 } 212 213 /** 214 * @return ThrowsClause 215 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getThrowsClause() 216 */ 217 protected String handleGetThrowsClause() 218 { 219 StringBuilder throwsClause = null; 220 if (this.isExceptionsPresent()) 221 { 222 throwsClause = new StringBuilder(this.getExceptionList()); 223 } 224 if (throwsClause != null) 225 { 226 throwsClause.insert(0, "throws "); 227 } 228 return throwsClause != null ? throwsClause.toString() : null; 229 } 230 231 /** 232 * @param initialExceptions 233 * @return ThrowsClause 234 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getThrowsClause(String) 235 */ 236 protected String handleGetThrowsClause(String initialExceptions) 237 { 238 final StringBuilder throwsClause = new StringBuilder(initialExceptions); 239 if (this.getThrowsClause() != null) 240 { 241 throwsClause.insert(0, ", "); 242 throwsClause.insert(0, this.getThrowsClause()); 243 } 244 else 245 { 246 throwsClause.insert(0, "throws "); 247 } 248 return throwsClause.toString(); 249 } 250 251 /** 252 * @return getMessageImplementationCall("session") 253 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getOutgoingMessageImplementationCall() 254 */ 255 protected String handleGetOutgoingMessageImplementationCall() 256 { 257 return this.getMessageImplementationCall("session"); 258 } 259 260 private String getMessageImplementationCall(String firstArgument) 261 { 262 final StringBuilder buffer = new StringBuilder(); 263 buffer.append(StringUtils.capitalize(this.getName())); 264 buffer.append('('); 265 final boolean outgoingMessageOperation = this.isOutgoingMessageOperation(); 266 if (outgoingMessageOperation || (this.isIncomingMessageOperation() && this.getArguments().isEmpty())) 267 { 268 buffer.append(firstArgument); 269 } 270 final String argumentNames = this.getArgumentNames(); 271 if (outgoingMessageOperation && StringUtils.isNotBlank(argumentNames)) 272 { 273 buffer.append(", "); 274 } 275 if (StringUtils.isNotBlank(argumentNames)) 276 { 277 buffer.append(argumentNames); 278 } 279 buffer.append(')'); 280 return this.getImplementationOperationName(buffer.toString()); 281 } 282 283 /** 284 * @return getMessagingImplementationSignature("javax.jms.Session session") 285 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getOutgoingMessageImplementationSignature() 286 */ 287 protected String handleGetOutgoingMessageImplementationSignature() 288 { 289 return this.getMessagingImplementationSignature("javax.jms.Session session"); 290 } 291 292 private String getMessagingImplementationSignature(final String firstArgument) 293 { 294 return this.getMessagingOperationSignature(this.getImplementationName(), firstArgument, null); 295 } 296 297 /** 298 * Gets the signature for an incoming message operation. 299 * 300 * @return the signature 301 */ 302 private String getIncomingMessageSignature(String modifier) 303 { 304 return this.getMessagingOperationSignature(this.getName(), "javax.jms.Message message", modifier); 305 } 306 307 /** 308 * Constructs the incoming or outgoing messaging operation signature given the <code>operationName</code> 309 * and the <code>firstArgument</code>. 310 * 311 * @param operationName the name of the operation. 312 * @param firstArgument the argument that will be the first argument in the operation signature. 313 * @param modifier the modifier to add to each argument (if null or empty, it isn't added). 314 * @return the signature of the operation. 315 */ 316 private String getMessagingOperationSignature(final String operationName, final String firstArgument, final String modifier) 317 { 318 final StringBuilder signature = new StringBuilder(operationName); 319 signature.append('('); 320 if (StringUtils.isNotBlank(modifier)) 321 { 322 signature.append(modifier).append(' '); 323 } 324 final Collection<ParameterFacade> arguments = this.getArguments(); 325 final boolean outgoingMessageOperation = this.isOutgoingMessageOperation(); 326 if (outgoingMessageOperation || (this.isIncomingMessageOperation() && arguments.isEmpty())) 327 { 328 signature.append(firstArgument); 329 } 330 final String argumentList = MetafacadeUtils.getTypedArgumentList( 331 this.getArguments(), 332 true, 333 modifier); 334 if (outgoingMessageOperation && StringUtils.isNotBlank(argumentList)) 335 { 336 signature.append(", "); 337 } 338 if (StringUtils.isNotBlank(argumentList)) 339 { 340 signature.append(argumentList); 341 } 342 signature.append(')'); 343 return signature.toString(); 344 } 345 346 /** 347 * @return getMessageImplementationCall("message") 348 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getIncomingMessageImplementationCall() 349 */ 350 protected String handleGetIncomingMessageImplementationCall() 351 { 352 return this.getMessageImplementationCall("message"); 353 } 354 355 /** 356 * @return getMessagingImplementationSignature("javax.jms.Message message") 357 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getIncomingMessageImplementationSignature() 358 */ 359 protected String handleGetIncomingMessageImplementationSignature() 360 { 361 return this.getMessagingImplementationSignature("javax.jms.Message message"); 362 } 363 364 /** 365 * @return "javax.jms.Message" or getGetterSetterReturnTypeName() 366 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getImplementationReturnTypeName() 367 */ 368 protected String handleGetImplementationReturnTypeName() 369 { 370 String returnTypeName = null; 371 if (this.isOutgoingMessageOperation()) 372 { 373 returnTypeName = "javax.jms.Message"; 374 } 375 else 376 { 377 returnTypeName = getGetterSetterReturnTypeName(); 378 } 379 return returnTypeName; 380 } 381 382 /** 383 * @return FullyQualifiedMessageListenerName 384 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getFullyQualifiedMessageListenerName() 385 */ 386 protected String handleGetFullyQualifiedMessageListenerName() 387 { 388 StringBuilder name = new StringBuilder(); 389 final String packageName = this.getPackageName(); 390 if (StringUtils.isNotBlank(packageName)) 391 { 392 name.append(packageName).append('.'); 393 } 394 name.append(this.getMessageListenerName()); 395 return name.toString(); 396 } 397 398 /** 399 * @return MessageListenerName 400 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getMessageListenerName() 401 */ 402 protected String handleGetMessageListenerName() 403 { 404 return this.getOwner().getName() + 405 StringUtilsHelper.upperCamelCaseName(this.getName()); 406 } 407 408 /** 409 * @return StringUtils.uncapitalize(this.getMessageListenerName()) 410 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getMessageListenerBeanName() 411 */ 412 protected String handleGetMessageListenerBeanName() 413 { 414 return StringUtils.uncapitalize(this.getMessageListenerName()); 415 } 416 417 /** 418 * @return getName() + MESSAGE_LISTENER_CONTAINER_SUFFIX 419 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getMessageListenerContainerReferenceName() 420 */ 421 protected String handleGetMessageListenerContainerReferenceName() 422 { 423 return this.getName() + MESSAGE_LISTENER_CONTAINER_SUFFIX; 424 } 425 426 /** 427 * The suffix for the listener container. "ListenerContainer" 428 */ 429 private static final String MESSAGE_LISTENER_CONTAINER_SUFFIX = "ListenerContainer"; 430 431 /** 432 * @return getMessageListenerBeanName() + MESSAGE_LISTENER_CONTAINER_SUFFIX 433 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getMessageListenerContainerBeanName() 434 */ 435 protected String handleGetMessageListenerContainerBeanName() 436 { 437 return this.getMessageListenerBeanName() + MESSAGE_LISTENER_CONTAINER_SUFFIX; 438 } 439 440 /** 441 * @return findTaggedValue(SpringProfile.TAGGEDVALUEVALUE_MESSAGING_SESSION_ACKNOWLEDGE_MODE) 442 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#getSessionAcknowledgeMode() 443 */ 444 protected String handleGetSessionAcknowledgeMode() 445 { 446 // use the attribute name by default 447 String mode = null; 448 449 // if there is a tagged value, use it instead 450 Object value = findTaggedValue(SpringProfile.TAGGEDVALUEVALUE_MESSAGING_SESSION_ACKNOWLEDGE_MODE); 451 if (value != null) 452 { 453 mode = ObjectUtils.toString(value); 454 } 455 456 return mode; 457 } 458 459 /** 460 * @return findTaggedValue(SpringProfile.TAGGEDVALUEVALUE_ACTIVEMQ_OPTIMIZE_ACKNOWLEDGE) 461 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#isOptimizeAcknowledge() 462 */ 463 protected boolean handleIsOptimizeAcknowledge() 464 { 465 return BooleanUtils.toBoolean(ObjectUtils.toString(this.findTaggedValue(SpringProfile.TAGGEDVALUEVALUE_ACTIVEMQ_OPTIMIZE_ACKNOWLEDGE))); 466 } 467 468 /** 469 * @return IsNullMessageConverterRequired 470 * @see org.andromda.cartridges.spring.metafacades.SpringServiceOperation#isNullMessageConverterRequired() 471 */ 472 protected boolean handleIsNullMessageConverterRequired() 473 { 474 boolean result = false; 475 476 Collection<ParameterFacade> arguments = getArguments(); 477 if (arguments != null && arguments.size() == 1) 478 { 479 ParameterFacade parameter = arguments.iterator().next(); 480 String parameterType = parameter.getType().getFullyQualifiedName(); 481 482 Set<String> jmsMessageTypes = new HashSet<String>(); 483 Collections.addAll(jmsMessageTypes, SpringGlobals.jmsMessageTypes); 484 485 result = jmsMessageTypes.contains(parameterType); 486 } 487 488 return result; 489 } 490 491 /** 492 * {@inheritDoc} 493 */ 494 protected boolean handleIsInitMethod() 495 { 496 return hasStereotype(SpringProfile.STEREOTYPE_POST_CONSTRUCT_METHOD); 497 } 498 499 /** 500 * {@inheritDoc} 501 */ 502 protected boolean handleIsDestroyMethod() 503 { 504 return hasStereotype(SpringProfile.STEREOTYPE_PRE_DESTROY_METHOD); 505 } 506}