001package org.andromda.cartridges.ejb.metafacades; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Collections; 006import java.util.Iterator; 007import java.util.List; 008import org.andromda.cartridges.ejb.EJBGlobals; 009import org.andromda.cartridges.ejb.EJBProfile; 010import org.andromda.core.common.ExceptionRecorder; 011import org.andromda.metafacades.uml.AttributeFacade; 012import org.andromda.metafacades.uml.ClassifierFacade; 013import org.andromda.metafacades.uml.DependencyFacade; 014import org.andromda.metafacades.uml.MetafacadeUtils; 015import org.andromda.metafacades.uml.ModelElementFacade; 016import org.andromda.metafacades.uml.OperationFacade; 017import org.andromda.metafacades.uml.TypeMappings; 018import org.andromda.metafacades.uml.UMLMetafacadeProperties; 019import org.apache.commons.collections.CollectionUtils; 020import org.apache.commons.collections.Predicate; 021import org.apache.commons.lang.StringUtils; 022import org.apache.log4j.Logger; 023 024/** 025 * <p> 026 * Represents an entity EJB. </p> Metaclass facade implementation. 027 * @author Bob Fields 028 */ 029public class EJBEntityFacadeLogicImpl 030 extends EJBEntityFacadeLogic 031{ 032 private static final long serialVersionUID = 34L; 033 // ---------------- constructor ------------------------------- 034 /** 035 * @param metaObject 036 * @param context 037 */ 038 public EJBEntityFacadeLogicImpl( 039 Object metaObject, 040 String context) 041 { 042 super(metaObject, context); 043 } 044 045 /** 046 * The logger instance. 047 */ 048 private static final Logger logger = Logger.getLogger(EJBEntityFacadeLogicImpl.class); 049 050 /** 051 * @return identifiers 052 */ 053 public Collection handleGetIdentifiers() 054 { 055 Collection identifiers = new ArrayList(); 056 Iterator iter = this.getSourceDependencies().iterator(); 057 while (iter.hasNext()) 058 { 059 DependencyFacade dep = (DependencyFacade)iter.next(); 060 if (dep.hasStereotype(EJBProfile.STEREOTYPE_IDENTIFIER)) 061 { 062 identifiers = ((ClassifierFacade)dep.getTargetElement()).getInstanceAttributes(); 063 MetafacadeUtils.filterByStereotype( 064 identifiers, 065 EJBProfile.STEREOTYPE_IDENTIFIER); 066 return identifiers; 067 } 068 } 069 070 // No PK dependency found - try a PK attribute 071 if (super.getIdentifiers() != null && !super.getIdentifiers().isEmpty()) 072 { 073 AttributeFacade attr = (AttributeFacade)super.getIdentifiers().iterator().next(); 074 identifiers.add(attr); 075 return identifiers; 076 } 077 078 // Still nothing found - recurse up the inheritance tree 079 EJBEntityFacade decorator = (EJBEntityFacade)this.getGeneralization(); 080 return decorator.getIdentifiers(); 081 } 082 083 /** 084 * @return getEntityRelations() 085 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getAllEntityRelations() 086 */ 087 protected Collection handleGetAllEntityRelations() 088 { 089 // Only concrete entities may have EJB relations. Return 090 // an empty collection for everything else 091 if (this.isAbstract()) 092 { 093 return Collections.emptyList(); 094 } 095 Collection result = new ArrayList(); 096 result.addAll(getEntityRelations()); 097 ClassifierFacade classifier = (ClassifierFacade)this.getGeneralization(); 098 while (classifier != null && classifier instanceof EJBEntityFacade && classifier.isAbstract()) 099 { 100 EJBEntityFacade entity = (EJBEntityFacade)classifier; 101 result.addAll(entity.getEntityRelations()); 102 classifier = (ClassifierFacade)classifier.getGeneralization(); 103 } 104 return result; 105 } 106 107 /** 108 * @return EJBMetafacadeUtils.getViewType(this) 109 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getViewType() 110 */ 111 protected String handleGetViewType() 112 { 113 return EJBMetafacadeUtils.getViewType(this); 114 } 115 116 /** 117 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetEntityRelations() 118 */ 119 protected Collection handleGetEntityRelations() 120 { 121 Collection result = new ArrayList(); 122 for (final Iterator iterator = this.getAssociationEnds().iterator(); iterator.hasNext();) 123 { 124 EJBAssociationEndFacade associationEnd = (EJBAssociationEndFacade)iterator.next(); 125 ClassifierFacade target = associationEnd.getOtherEnd().getType(); 126 if (target instanceof EJBEntityFacade && associationEnd.getOtherEnd().isNavigable()) 127 { 128 // Check the integrity constraint 129 Object value = 130 associationEnd.getOtherEnd().getAssociation().findTaggedValue(EJBProfile.TAGGEDVALUE_GENERATE_CMR); 131 String generateCmr = value == null ? null : value.toString(); 132 if (target.isAbstract() && !"false".equalsIgnoreCase(generateCmr)) 133 { 134 throw new IllegalStateException("Relation '" + associationEnd.getAssociation().getName() + 135 "' has the abstract target '" + target.getName() + 136 "'. Abstract targets are not allowed in EJB."); 137 } 138 result.add(associationEnd); 139 } 140 } 141 142 return result; 143 } 144 145 /** 146 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetAllInstanceAttributes() 147 */ 148 protected List handleGetAllInstanceAttributes() 149 { 150 return EJBMetafacadeUtils.getAllInstanceAttributes(this); 151 } 152 153 /** 154 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetInheritedInstanceAttributes() 155 */ 156 protected List handleGetInheritedInstanceAttributes() 157 { 158 return EJBMetafacadeUtils.getInheritedInstanceAttributes(this); 159 } 160 161 /** 162 * @param follow 163 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetCreateMethods(boolean) 164 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getCreateMethods(boolean) 165 */ 166 protected Collection handleGetCreateMethods(boolean follow) 167 { 168 return EJBMetafacadeUtils.getCreateMethods( 169 this, 170 follow); 171 } 172 173 /** 174 * @param follow 175 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetSelectMethods(boolean) 176 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getSelectMethods(boolean) 177 */ 178 protected Collection handleGetSelectMethods(boolean follow) 179 { 180 Collection retval = new ArrayList(); 181 EJBEntityFacade entity = null; 182 do 183 { 184 Collection ops = this.getOperations(); 185 for (final Iterator i = ops.iterator(); i.hasNext();) 186 { 187 OperationFacade op = (OperationFacade)i.next(); 188 if (op.hasStereotype(EJBProfile.STEREOTYPE_SELECT_METHOD)) 189 { 190 retval.add(op); 191 } 192 } 193 if (follow) 194 { 195 entity = (EJBEntityFacade)this.getGeneralization(); 196 } 197 else 198 { 199 break; 200 } 201 } 202 while (entity != null); 203 return retval; 204 } 205 206 /** 207 * @return getHomeInterfaceName 208 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getHomeInterfaceName() 209 */ 210 protected String handleGetHomeInterfaceName() 211 { 212 return EJBMetafacadeUtils.getHomeInterfaceName(this); 213 } 214 215 /** 216 * @param follow 217 * @return getEnvironmentEntries 218 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getEnvironmentEntries(boolean) 219 */ 220 protected Collection handleGetEnvironmentEntries(boolean follow) 221 { 222 return EJBMetafacadeUtils.getEnvironmentEntries( 223 this, 224 follow); 225 } 226 227 /** 228 * @param follow 229 * @return getConstants 230 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getConstants(boolean) 231 */ 232 protected Collection handleGetConstants(boolean follow) 233 { 234 return EJBMetafacadeUtils.getConstants( 235 this, 236 follow); 237 } 238 239 /** 240 * @return jndiName 241 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getJndiName() 242 */ 243 protected String handleGetJndiName() 244 { 245 StringBuilder jndiName = new StringBuilder(); 246 String jndiNamePrefix = StringUtils.trimToEmpty(this.getJndiNamePrefix()); 247 if (StringUtils.isNotBlank(jndiNamePrefix)) 248 { 249 jndiName.append(jndiNamePrefix); 250 jndiName.append('/'); 251 } 252 jndiName.append("ejb/"); 253 jndiName.append(this.getFullyQualifiedName()); 254 return jndiName.toString(); 255 } 256 257 /** 258 * Gets the <code>jndiNamePrefix</code> for this EJB. 259 * 260 * @return the EJB Jndi name prefix. 261 */ 262 protected String getJndiNamePrefix() 263 { 264 String prefix = null; 265 if (this.isConfiguredProperty(EJBGlobals.JNDI_NAME_PREFIX)) 266 { 267 prefix = (String)this.getConfiguredProperty(EJBGlobals.JNDI_NAME_PREFIX); 268 } 269 return prefix; 270 } 271 272 /** 273 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsSyntheticCreateMethodAllowed() 274 */ 275 protected boolean handleIsSyntheticCreateMethodAllowed() 276 { 277 return EJBMetafacadeUtils.allowSyntheticCreateMethod(this); 278 } 279 280 /** 281 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#getBusinessOperations() 282 */ 283 // TODO: Change return type to Collection<EJBOperationFacade> (metamodel change) 284 public Collection<OperationFacade> getBusinessOperations() 285 { 286 Collection<OperationFacade> businessOperations = new ArrayList<OperationFacade>(); 287 for (OperationFacade operation : super.getBusinessOperations()) 288 { 289 if (EJBOperationFacade.class.isAssignableFrom(operation.getClass())) 290 { 291 EJBOperationFacade businessOperation = (EJBOperationFacade)operation; 292 if (businessOperation.isBusinessOperation()) 293 { 294 businessOperations.add(businessOperation); 295 } 296 } 297 } 298 return businessOperations; 299 } 300 301 /** 302 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetValueDependencies() 303 */ 304 protected Collection handleGetValueDependencies() 305 { 306 Collection dependencies = super.getSourceDependencies(); 307 CollectionUtils.filter( 308 dependencies, 309 new Predicate() 310 { 311 public boolean evaluate(Object object) 312 { 313 boolean isValueRef = false; 314 if (object instanceof DependencyFacade) 315 { 316 DependencyFacade dep = (DependencyFacade)object; 317 isValueRef = 318 dep.getStereotypeNames().contains(EJBProfile.STEREOTYPE_VALUE_REF) && 319 dep.getTargetElement().hasExactStereotype(EJBProfile.STEREOTYPE_VALUE_OBJECT); 320 } 321 return isValueRef; 322 } 323 }); 324 return dependencies; 325 } 326 327 /** 328 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsIdentifierPresent(String) 329 */ 330 protected boolean handleIsIdentifierPresent(String identifier) 331 { 332 for (ModelElementFacade attr : this.getIdentifiers(true)) 333 { 334 if (attr.getName().equalsIgnoreCase(identifier)) 335 { 336 return true; 337 } 338 } 339 return false; 340 } 341 342 /** 343 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsAttributePresent(String) 344 */ 345 protected boolean handleIsAttributePresent(String strAttr) 346 { 347 Collection<AttributeFacade> collAttrib = this.getAttributes(true); 348 for (AttributeFacade attr : collAttrib) 349 { 350 if (attr.getName().equalsIgnoreCase(strAttr)) 351 { 352 return true; 353 } 354 } 355 return false; 356 } 357 358 /** 359 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsOperationPresent(String) 360 */ 361 protected boolean handleIsOperationPresent(String op) 362 { 363 Collection<OperationFacade> collOps = this.getOperations(); 364 for (OperationFacade operation : collOps) 365 { 366 if (operation.getName().equalsIgnoreCase(op)) 367 { 368 return true; 369 } 370 } 371 return false; 372 } 373 374 /** 375 * Gets a Mappings instance from a property registered under the given <code>propertyName</code>. 376 * 377 * @param propertyName the property name to register under. 378 * @return the Mappings instance. 379 */ 380 private TypeMappings getMappingsProperty(final String propertyName) 381 { 382 Object property = this.getConfiguredProperty(propertyName); 383 TypeMappings mappings = null; 384 String uri = null; 385 if (property instanceof String) 386 { 387 uri = (String)property; 388 try 389 { 390 mappings = TypeMappings.getInstance(uri); 391 this.setProperty( 392 propertyName, 393 mappings); 394 } 395 catch (Throwable th) 396 { 397 String errMsg = "Error getting '" + propertyName + "' --> '" + uri + '\''; 398 logger.error(errMsg); 399 // don't throw the exception 400 ExceptionRecorder.instance().record( 401 errMsg, 402 th); 403 } 404 } 405 else 406 { 407 mappings = (TypeMappings)property; 408 } 409 return mappings; 410 } 411 412 /** 413 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetSqlType() 414 */ 415 protected String handleGetSqlType() 416 { 417 String mpSql = this.getMappingsProperty(UMLMetafacadeProperties.SQL_MAPPINGS_URI).getMappings().getName(); 418 if (mpSql.startsWith("Oracle")) 419 { 420 mpSql = "ORACLE"; 421 } 422 return mpSql; 423 } 424 425 /** 426 * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetTransactionType() 427 */ 428 protected String handleGetTransactionType() 429 { 430 String transactionType = (String)this.findTaggedValue(EJBProfile.TAGGEDVALUE_EJB_TRANSACTION_TYPE); 431 if (StringUtils.isBlank(transactionType)) 432 { 433 transactionType = String.valueOf(this.getConfiguredProperty(EJBGlobals.TRANSACTION_TYPE)); 434 } 435 return transactionType; 436 } 437}