001package org.andromda.cartridges.spring.metafacades; 002 003import java.text.MessageFormat; 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.Iterator; 007import org.andromda.cartridges.spring.SpringHibernateUtils; 008import org.andromda.cartridges.spring.SpringProfile; 009import org.andromda.metafacades.uml.AttributeFacade; 010import org.andromda.metafacades.uml.ClassifierFacade; 011import org.andromda.metafacades.uml.DependencyFacade; 012import org.andromda.metafacades.uml.EntityQueryOperation; 013import org.andromda.metafacades.uml.EnumerationFacade; 014import org.andromda.metafacades.uml.FilteredCollection; 015import org.andromda.metafacades.uml.GeneralizableElementFacade; 016import org.andromda.metafacades.uml.OperationFacade; 017import org.andromda.metafacades.uml.ValueObject; 018import org.apache.commons.collections.CollectionUtils; 019import org.apache.commons.lang.StringUtils; 020 021 022/** 023 * MetafacadeLogic implementation for org.andromda.cartridges.spring.metafacades.SpringEntity. 024 * 025 * @see org.andromda.cartridges.spring.metafacades.SpringEntity 026 */ 027public class SpringEntityLogicImpl 028 extends SpringEntityLogic 029{ 030 private static final long serialVersionUID = 34L; 031 /** 032 * Public constructor for SpringEntityLogicImpl 033 * @param metaObject 034 * @param context 035 * @see org.andromda.cartridges.spring.metafacades.SpringEntity 036 */ 037 public SpringEntityLogicImpl( 038 Object metaObject, 039 String context) 040 { 041 super(metaObject, context); 042 } 043 044 /** 045 * Value for one Table per root class 046 */ 047 private static final String INHERITANCE_STRATEGY_CLASS = "class"; 048 049 /** 050 * Value for joined-subclass 051 */ 052 private static final String INHERITANCE_STRATEGY_SUBCLASS = "subclass"; 053 054 /** 055 * Value for one Table per concrete class 056 */ 057 private static final String INHERITANCE_STRATEGY_CONCRETE = "concrete"; 058 059 /** 060 * Value make Entity an interface, delegate attributes to subclasses. 061 */ 062 private static final String INHERITANCE_STRATEGY_INTERFACE = "interface"; 063 064 /** 065 * Stores the valid inheritance strategies. 066 */ 067 private static final Collection<String> INHERITANCE_STRATEGIES = new ArrayList<String>(); 068 069 static 070 { 071 INHERITANCE_STRATEGIES.add(INHERITANCE_STRATEGY_CLASS); 072 INHERITANCE_STRATEGIES.add(INHERITANCE_STRATEGY_SUBCLASS); 073 INHERITANCE_STRATEGIES.add(INHERITANCE_STRATEGY_CONCRETE); 074 INHERITANCE_STRATEGIES.add(INHERITANCE_STRATEGY_INTERFACE); 075 } 076 077 /** 078 * @return getDaoNamePattern().replaceAll("\\{0\\}", getName()) 079 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoName() 080 */ 081 protected String handleGetDaoName() 082 { 083 return this.getDaoNamePattern().replaceAll( 084 "\\{0\\}", 085 this.getName()); 086 } 087 088 /** 089 * Gets the value of the {@link SpringGlobals#DAO_PATTERN} 090 * 091 * @return the DAO name pattern. 092 */ 093 private String getDaoNamePattern() 094 { 095 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_PATTERN)); 096 } 097 098 /** 099 * @return fullyQualifiedName 100 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoName() 101 */ 102 protected String handleGetFullyQualifiedDaoName() 103 { 104 return SpringMetafacadeUtils.getFullyQualifiedName( 105 this.getPackageName(), 106 this.getDaoName()); 107 } 108 109 /** 110 * @return daoImplementationName 111 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoImplementationName() 112 */ 113 protected String handleGetDaoImplementationName() 114 { 115 return this.getDaoImplementationNamePattern().replaceAll( 116 "\\{0\\}", 117 this.getName()); 118 } 119 120 /** 121 * Gets the value of the {@link SpringGlobals#DAO_IMPLEMENTATION_PATTERN} 122 * 123 * @return the DAO implementation name pattern. 124 */ 125 private String getDaoImplementationNamePattern() 126 { 127 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_IMPLEMENTATION_PATTERN)); 128 } 129 130 /** 131 * @return fullyQualifiedDaoImplementationName 132 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoImplementationName() 133 */ 134 protected String handleGetFullyQualifiedDaoImplementationName() 135 { 136 return SpringMetafacadeUtils.getFullyQualifiedName( 137 this.getPackageName(), 138 this.getDaoImplementationName()); 139 } 140 141 /** 142 * @return DaoBaseName 143 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoBaseName() 144 */ 145 protected String handleGetDaoBaseName() 146 { 147 return this.getDaoBaseNamePattern().replaceAll( 148 "\\{0\\}", 149 this.getName()); 150 } 151 152 /** 153 * Gets the value of the {@link SpringGlobals#DAO_BASE_PATTERN} 154 * 155 * @return the DAO base name pattern. 156 */ 157 private String getDaoBaseNamePattern() 158 { 159 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_BASE_PATTERN)); 160 } 161 162 /** 163 * @return FullyQualifiedDaoBaseName 164 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoBaseName() 165 */ 166 protected String handleGetFullyQualifiedDaoBaseName() 167 { 168 return SpringMetafacadeUtils.getFullyQualifiedName( 169 this.getPackageName(), 170 this.getDaoBaseName()); 171 } 172 173 /** 174 * @return EntityImplementationName 175 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getEntityImplementationName() 176 */ 177 protected String handleGetEntityImplementationName() 178 { 179 return this.getEntityName() + SpringGlobals.IMPLEMENTATION_SUFFIX; 180 } 181 182 /** 183 * @return FullyQualifiedEntityImplementationName 184 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedEntityImplementationName() 185 */ 186 protected String handleGetFullyQualifiedEntityImplementationName() 187 { 188 return SpringMetafacadeUtils.getFullyQualifiedName( 189 this.getPackageName(), 190 this.getEntityName(), 191 SpringGlobals.IMPLEMENTATION_SUFFIX); 192 } 193 194 /** 195 * @param targetSuffix 196 * @return BeanName 197 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getBeanName(boolean) 198 */ 199 protected String handleGetBeanName(boolean targetSuffix) 200 { 201 final String beanName = StringUtils.uncapitalize(StringUtils.trimToEmpty(this.getName())); 202 StringBuilder beanNameBuffer = new StringBuilder(String.valueOf(this.getConfiguredProperty(SpringGlobals.BEAN_NAME_PREFIX))); 203 beanNameBuffer.append(this.getDaoNamePattern().replaceAll("\\{0\\}", beanName)); 204 if (targetSuffix) 205 { 206 beanNameBuffer.append(SpringGlobals.BEAN_NAME_TARGET_SUFFIX); 207 } 208 return beanNameBuffer.toString(); 209 } 210 211 /** 212 * @return EntityName 213 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getEntityName() 214 */ 215 protected String handleGetEntityName() 216 { 217 final String entityNamePattern = (String)this.getConfiguredProperty("entityNamePattern"); 218 return MessageFormat.format( 219 entityNamePattern, 220 StringUtils.trimToEmpty(this.getName())); 221 } 222 223 /** 224 * @return FullyQualifiedEntityName 225 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedEntityName() 226 */ 227 protected String handleGetFullyQualifiedEntityName() 228 { 229 return SpringMetafacadeUtils.getFullyQualifiedName( 230 this.getPackageName(), 231 this.getEntityName(), 232 null); 233 } 234 235 /** 236 * @return Object Root 237 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getRoot() 238 */ 239 protected Object handleGetRoot() 240 { 241 GeneralizableElementFacade generalization = this; 242 while(generalization.getGeneralization() != null && generalization instanceof SpringEntity) 243 { 244 generalization = generalization.getGeneralization(); 245 } 246 return generalization; 247 } 248 249 /** 250 * @return IsDaoBusinessOperationsPresent 251 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isDaoBusinessOperationsPresent() 252 */ 253 protected boolean handleIsDaoBusinessOperationsPresent() 254 { 255 return this.getDaoBusinessOperations() != null && !this.getDaoBusinessOperations().isEmpty(); 256 } 257 258 /** 259 * @return DaoBusinessOperations 260 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoBusinessOperations() 261 */ 262 protected Collection<OperationFacade> handleGetDaoBusinessOperations() 263 { 264 // operations that are not finders and static 265 Collection<EntityQueryOperation> finders = this.getQueryOperations(); 266 Collection<OperationFacade> operations = this.getOperations(); 267 268 Collection<OperationFacade> nonFinders = CollectionUtils.subtract(operations, finders); 269 return new FilteredCollection(nonFinders) 270 { 271 private static final long serialVersionUID = 34L; 272 public boolean evaluate(Object object) 273 { 274 return ((OperationFacade)object).isStatic(); 275 } 276 }; 277 } 278 279 /** 280 * @return getValueObjectReferences(false) 281 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getValueObjectReferences() 282 */ 283 protected Collection<DependencyFacade> handleGetValueObjectReferences() 284 { 285 return this.getValueObjectReferences(false); 286 } 287 288 /** 289 * Retrieves the values object references for this entity. If 290 * <code>follow</code> is true, then all value object references 291 * (including those that were inherited) will be retrieved. 292 * @param follow 293 * @return ValueObject references 294 */ 295 protected Collection<DependencyFacade> getValueObjectReferences(boolean follow) 296 { 297 final Collection<DependencyFacade> sourceDependencies = new ArrayList<DependencyFacade>(this.getSourceDependencies()); 298 if (follow) 299 { 300 for ( 301 GeneralizableElementFacade entity = this.getGeneralization(); entity != null; 302 entity = entity.getGeneralization()) 303 { 304 sourceDependencies.addAll(entity.getSourceDependencies()); 305 } 306 } 307 return new FilteredCollection(sourceDependencies) 308 { 309 private static final long serialVersionUID = 34L; 310 public boolean evaluate(Object object) 311 { 312 boolean valid = false; 313 Object targetElement = ((DependencyFacade)object).getTargetElement(); 314 if (targetElement instanceof ClassifierFacade) 315 { 316 ClassifierFacade element = (ClassifierFacade)targetElement; 317 valid = element.isDataType() || element instanceof ValueObject || element instanceof EnumerationFacade; 318 } 319 return valid; 320 } 321 }; 322 } 323 324 /** 325 * @return getValueObjectReferences(true) 326 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getAllValueObjectReferences() 327 */ 328 protected Collection<DependencyFacade> handleGetAllValueObjectReferences() 329 { 330 return this.getValueObjectReferences(true); 331 } 332 333 /** 334 * @return IsDaoImplementationRequired 335 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isDaoImplementationRequired() 336 */ 337 protected boolean handleIsDaoImplementationRequired() 338 { 339 return !this.getValueObjectReferences().isEmpty() || !this.getDaoBusinessOperations().isEmpty() || 340 !this.getQueryOperations(true).isEmpty(); 341 } 342 343 /** 344 * The suffix given to the no transformation constant. "NONE" 345 */ 346 private static final String NO_TRANSFORMATION_CONSTANT_SUFFIX = "NONE"; 347 348 /** 349 * @return TRANSFORMATION_CONSTANT_PREFIX + NO_TRANSFORMATION_CONSTANT_SUFFIX 350 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoNoTransformationConstantName() 351 */ 352 protected String handleGetDaoNoTransformationConstantName() 353 { 354 return SpringGlobals.TRANSFORMATION_CONSTANT_PREFIX + NO_TRANSFORMATION_CONSTANT_SUFFIX; 355 } 356 357 /** 358 * Common routine to check inheritance. 359 * @param inheritance 360 * @return inheritance.equals(getHibernateInheritanceStrategy()) 361 */ 362 protected boolean checkHibInheritance(String inheritance) 363 { 364 return inheritance.equals(getHibernateInheritanceStrategy()); 365 } 366 367 /** 368 * @return checkHibInheritance(INHERITANCE_STRATEGY_CLASS) 369 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceClass() 370 */ 371 protected boolean handleIsHibernateInheritanceClass() 372 { 373 return checkHibInheritance(INHERITANCE_STRATEGY_CLASS); 374 } 375 376 /** 377 * @return checkHibInheritance(INHERITANCE_STRATEGY_INTERFACE) 378 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceInterface() 379 */ 380 protected boolean handleIsHibernateInheritanceInterface() 381 { 382 return checkHibInheritance(INHERITANCE_STRATEGY_INTERFACE); 383 } 384 385 /** 386 * @return checkHibInheritance(INHERITANCE_STRATEGY_SUBCLASS) 387 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceSubclass() 388 */ 389 protected boolean handleIsHibernateInheritanceSubclass() 390 { 391 return checkHibInheritance(INHERITANCE_STRATEGY_SUBCLASS); 392 } 393 394 /** 395 * @return checkHibInheritance(INHERITANCE_STRATEGY_CONCRETE) 396 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceConcrete() 397 */ 398 protected boolean handleIsHibernateInheritanceConcrete() 399 { 400 return checkHibInheritance(INHERITANCE_STRATEGY_CONCRETE); 401 } 402 403 /** 404 * Stores the default hibernate inheritance strategy. 405 */ 406 private static final String INHERITANCE_STRATEGY = "hibernateInheritanceStrategy"; 407 408 /** 409 * @return superEntity.getHibernateInheritanceStrategy() 410 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getHibernateInheritanceStrategy() 411 */ 412 protected String handleGetHibernateInheritanceStrategy() 413 { 414 String inheritance = this.getInheritance(this); 415 for (SpringEntity superEntity = this.getSpringSuperEntity(); superEntity != null && StringUtils.isBlank(inheritance);) 416 { 417 inheritance = superEntity.getHibernateInheritanceStrategy(); 418 } 419 inheritance = inheritance != null ? inheritance.toLowerCase() : null; 420 if (StringUtils.isBlank(inheritance) || !INHERITANCE_STRATEGIES.contains(inheritance)) 421 { 422 inheritance = this.getDefaultInheritanceStrategy(); 423 } 424 return inheritance; 425 } 426 427 /** 428 * Gets the default hibernate inheritance strategy. 429 * 430 * @return the default hibernate inheritance strategy. 431 */ 432 private String getDefaultInheritanceStrategy() 433 { 434 return String.valueOf(this.getConfiguredProperty(INHERITANCE_STRATEGY)); 435 } 436 437 /** 438 * Return the inheritance tagged value for for given <code>entity</code>. 439 * 440 * @param the SpringEntity from which to retrieve the inheritance tagged value. 441 * @return String inheritance tagged value. 442 */ 443 @SuppressWarnings("static-method") 444 private String getInheritance(SpringEntity entity) 445 { 446 String inheritance = null; 447 if (entity != null) 448 { 449 Object value = entity.findTaggedValue(SpringProfile.TAGGEDVALUE_HIBERNATE_INHERITANCE); 450 if (value != null) 451 { 452 inheritance = String.valueOf(value); 453 } 454 } 455 return inheritance; 456 } 457 458 /** 459 * @return IsRequiresHibernateMapping 460 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isRequiresHibernateMapping() 461 */ 462 protected boolean handleIsRequiresHibernateMapping() 463 { 464 final SpringEntity superEntity = this.getSpringSuperEntity(); 465 return 466 SpringHibernateUtils.mapSubclassesInSeparateFile( 467 (String)this.getConfiguredProperty(SpringGlobals.HIBERNATE_MAPPING_STRATEGY)) || 468 this.isRoot() && 469 ( 470 !this.isHibernateInheritanceInterface() || this.getSpecializations().isEmpty() || 471 (superEntity != null && superEntity.isHibernateInheritanceInterface()) 472 ); 473 } 474 475 /** 476 * Indicates if this entity as a <code>root</code> entity (meaning it doesn't specialize anything). 477 */ 478 private boolean isRoot() 479 { 480 final SpringEntity superEntity = this.getSpringSuperEntity(); 481 boolean abstractConcreteEntity = 482 (this.isHibernateInheritanceConcrete() || this.isHibernateInheritanceInterface()) && this.isAbstract(); 483 return ( 484 this.getSpringSuperEntity() == null || 485 (superEntity.isHibernateInheritanceInterface() || superEntity.isHibernateInheritanceConcrete()) 486 ) && !abstractConcreteEntity; 487 } 488 489 /** 490 * Gets the super entity for this entity (if one exists). If a generalization does not exist OR if it's not an 491 * instance of SpringEntity then return null. 492 * 493 * @return the super entity or null if one doesn't exist. 494 */ 495 private SpringEntity getSpringSuperEntity() 496 { 497 SpringEntity superEntity = null; 498 if (this.getGeneralization() != null && this.getGeneralization() instanceof SpringEntity) 499 { 500 superEntity = (SpringEntity)this.getGeneralization(); 501 } 502 return superEntity; 503 } 504 505 /** 506 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getAttributeEmbeddedValueList() 507 */ 508 @Override 509 protected String handleGetAttributeEmbeddedValueList() 510 { 511 final StringBuilder buffer = new StringBuilder(); 512 for (final Iterator<AttributeFacade> iterator = this.getEmbeddedValues().iterator(); iterator.hasNext();) 513 { 514 final AttributeFacade attribute = iterator.next(); 515 final String name = attribute.getName(); 516 if (StringUtils.isNotBlank(name)) 517 { 518 buffer.append('\"').append(name).append('\"'); 519 if (iterator.hasNext()) 520 { 521 buffer.append(", "); 522 } 523 } 524 } 525 return buffer.toString(); 526 } 527 528 /** 529 * @return StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty("richClient"))).equalsIgnoreCase("true") 530 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isRichClient() 531 */ 532 protected boolean handleIsRichClient() 533 { 534 String richClient = 535 StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty("richClient"))); 536 537 return "true".equalsIgnoreCase(richClient); 538 } 539 540 /** 541 * Helper function "searchUnique" + capitalize(attributeName) 542 * @param attributeName 543 * @return searchUnique function name 544 */ 545 public String getSearchUniqueFunctionName(String attributeName) 546 { 547 return "searchUnique"+StringUtils.capitalize(attributeName); 548 } 549 550}