1 package org.andromda.cartridges.spring.metafacades;
2
3 import java.text.MessageFormat;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Iterator;
7
8 import org.andromda.cartridges.spring.SpringProfile;
9 import org.andromda.cartridges.spring.SpringHibernateUtils;
10 import org.andromda.metafacades.uml.AttributeFacade;
11 import org.andromda.metafacades.uml.ClassifierFacade;
12 import org.andromda.metafacades.uml.DependencyFacade;
13 import org.andromda.metafacades.uml.EnumerationFacade;
14 import org.andromda.metafacades.uml.FilteredCollection;
15 import org.andromda.metafacades.uml.GeneralizableElementFacade;
16 import org.andromda.metafacades.uml.OperationFacade;
17 import org.andromda.metafacades.uml.UMLProfile;
18 import org.andromda.metafacades.uml.ValueObject;
19 import org.apache.commons.collections.CollectionUtils;
20 import org.apache.commons.lang.StringUtils;
21
22
23 /***
24 * MetafacadeLogic implementation for org.andromda.cartridges.spring.metafacades.SpringEntity.
25 *
26 * @see org.andromda.cartridges.spring.metafacades.SpringEntity
27 */
28 public class SpringEntityLogicImpl
29 extends SpringEntityLogic
30 {
31 public SpringEntityLogicImpl(
32 Object metaObject,
33 String context)
34 {
35 super(metaObject, context);
36 }
37
38 /***
39 * Value for one Table per root class
40 */
41 private static final String INHERITANCE_STRATEGY_CLASS = "class";
42
43 /***
44 * Value for joined-subclass
45 */
46 private static final String INHERITANCE_STRATEGY_SUBCLASS = "subclass";
47
48 /***
49 * Value for one Table per concrete class
50 */
51 private static final String INHERITANCE_STRATEGY_CONCRETE = "concrete";
52
53 /***
54 * Value make Entity an interface, delegate attributes to subclasses.
55 */
56 private static final String INHERITANCE_STRATEGY_INTERFACE = "interface";
57
58 /***
59 * Stores the valid inheritance strategies.
60 */
61 private static final Collection inheritanceStrategies = new ArrayList();
62
63 static
64 {
65 inheritanceStrategies.add(INHERITANCE_STRATEGY_CLASS);
66 inheritanceStrategies.add(INHERITANCE_STRATEGY_SUBCLASS);
67 inheritanceStrategies.add(INHERITANCE_STRATEGY_CONCRETE);
68 inheritanceStrategies.add(INHERITANCE_STRATEGY_INTERFACE);
69 }
70
71 /***
72 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoName()
73 */
74 protected java.lang.String handleGetDaoName()
75 {
76 return this.getDaoNamePattern().replaceAll(
77 "//{0//}",
78 this.getName());
79 }
80
81 /***
82 * Gets the value of the {@link SpringGlobals#DAO_PATTERN}
83 *
84 * @return the DAO name pattern.
85 */
86 private String getDaoNamePattern()
87 {
88 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_PATTERN));
89 }
90
91 /***
92 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoName()
93 */
94 protected java.lang.String handleGetFullyQualifiedDaoName()
95 {
96 return SpringMetafacadeUtils.getFullyQualifiedName(
97 this.getPackageName(),
98 this.getDaoName());
99 }
100
101 /***
102 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoImplementationName()
103 */
104 protected java.lang.String handleGetDaoImplementationName()
105 {
106 return this.getDaoImplementationNamePattern().replaceAll(
107 "//{0//}",
108 this.getName());
109 }
110
111 /***
112 * Gets the value of the {@link SpringGlobals#DAO_IMPLEMENTATION_PATTERN}
113 *
114 * @return the DAO implementation name pattern.
115 */
116 private String getDaoImplementationNamePattern()
117 {
118 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_IMPLEMENTATION_PATTERN));
119 }
120
121 /***
122 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoImplementationName()
123 */
124 protected java.lang.String handleGetFullyQualifiedDaoImplementationName()
125 {
126 return SpringMetafacadeUtils.getFullyQualifiedName(
127 this.getPackageName(),
128 this.getDaoImplementationName());
129 }
130
131 /***
132 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoBaseName()
133 */
134 protected java.lang.String handleGetDaoBaseName()
135 {
136 return this.getDaoBaseNamePattern().replaceAll(
137 "//{0//}",
138 this.getName());
139 }
140
141 /***
142 * Gets the value of the {@link SpringGlobals#DAO_BASE_PATTERN}
143 *
144 * @return the DAO base name pattern.
145 */
146 private String getDaoBaseNamePattern()
147 {
148 return String.valueOf(this.getConfiguredProperty(SpringGlobals.DAO_BASE_PATTERN));
149 }
150
151 /***
152 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedDaoBaseName()
153 */
154 protected java.lang.String handleGetFullyQualifiedDaoBaseName()
155 {
156 return SpringMetafacadeUtils.getFullyQualifiedName(
157 this.getPackageName(),
158 this.getDaoBaseName());
159 }
160
161 /***
162 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getImplementationName()
163 */
164 protected java.lang.String handleGetEntityImplementationName()
165 {
166 return this.getEntityName() + SpringGlobals.IMPLEMENTATION_SUFFIX;
167 }
168
169 /***
170 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedEntityImplementationName()
171 */
172 protected java.lang.String handleGetFullyQualifiedEntityImplementationName()
173 {
174 return SpringMetafacadeUtils.getFullyQualifiedName(
175 this.getPackageName(),
176 this.getEntityName(),
177 SpringGlobals.IMPLEMENTATION_SUFFIX);
178 }
179
180 /***
181 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getBeanName(boolean)
182 */
183 protected java.lang.String handleGetBeanName(boolean targetSuffix)
184 {
185 final String beanName = StringUtils.uncapitalize(StringUtils.trimToEmpty(this.getName()));
186 final StringBuffer beanNameBuffer = new StringBuffer(this.getDaoNamePattern().replaceAll("//{0//}", beanName));
187 if (targetSuffix)
188 {
189 beanNameBuffer.append(SpringGlobals.BEAN_NAME_TARGET_SUFFIX);
190 }
191 return beanNameBuffer.toString();
192 }
193
194 /***
195 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getEntityName()
196 */
197 protected String handleGetEntityName()
198 {
199 final String entityNamePattern = (String)this.getConfiguredProperty("entityNamePattern");
200 return MessageFormat.format(
201 entityNamePattern,
202 new Object[] {StringUtils.trimToEmpty(this.getName())});
203 }
204
205 /***
206 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getFullyQualifiedEntityName()
207 */
208 protected String handleGetFullyQualifiedEntityName()
209 {
210 return SpringMetafacadeUtils.getFullyQualifiedName(
211 this.getPackageName(),
212 this.getEntityName(),
213 null);
214 }
215
216 /***
217 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getRoot()
218 */
219 protected Object handleGetRoot()
220 {
221 GeneralizableElementFacade generalization = this;
222 for (
223 ; generalization.getGeneralization() != null && generalization instanceof SpringEntity;
224 generalization = generalization.getGeneralization())
225 ;
226 return generalization;
227 }
228
229 /***
230 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isDaoBusinessOperationsPresent()
231 */
232 protected boolean handleIsDaoBusinessOperationsPresent()
233 {
234 return this.getDaoBusinessOperations() != null && !this.getDaoBusinessOperations().isEmpty();
235 }
236
237 /***
238 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoBusinessOperations()
239 */
240 protected Collection handleGetDaoBusinessOperations()
241 {
242
243 Collection finders = this.getQueryOperations();
244 Collection operations = this.getOperations();
245
246 Collection nonFinders = CollectionUtils.subtract(operations, finders);
247 return new FilteredCollection(nonFinders)
248 {
249 public boolean evaluate(Object object)
250 {
251 return ((OperationFacade)object).isStatic();
252 }
253 };
254 }
255
256 /***
257 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getValueObjectReferences()
258 */
259 protected Collection handleGetValueObjectReferences()
260 {
261 return this.getValueObjectReferences(false);
262 }
263
264 /***
265 * Retrieves the values object references for this entity. If
266 * <code>follow</code> is true, then all value object references
267 * (including those that were inherited) will be retrieved.
268 */
269 protected Collection getValueObjectReferences(boolean follow)
270 {
271 final Collection sourceDependencies = new ArrayList(this.getSourceDependencies());
272 if (follow)
273 {
274 for (
275 GeneralizableElementFacade entity = this.getGeneralization(); entity != null;
276 entity = entity.getGeneralization())
277 {
278 sourceDependencies.addAll(entity.getSourceDependencies());
279 }
280 }
281 return new FilteredCollection(sourceDependencies)
282 {
283 public boolean evaluate(Object object)
284 {
285 boolean valid = false;
286 Object targetElement = ((DependencyFacade)object).getTargetElement();
287 if (targetElement instanceof ClassifierFacade)
288 {
289 ClassifierFacade element = (ClassifierFacade)targetElement;
290 valid = element.isDataType() || element instanceof ValueObject || element instanceof EnumerationFacade;
291 }
292 return valid;
293 }
294 };
295 }
296
297 /***
298 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getAllValueObjectReferences()
299 */
300 protected Collection handleGetAllValueObjectReferences()
301 {
302 return this.getValueObjectReferences(true);
303 }
304
305 /***
306 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isDaoImplementationRequired()
307 */
308 protected boolean handleIsDaoImplementationRequired()
309 {
310 return !this.getValueObjectReferences().isEmpty() || !this.getDaoBusinessOperations().isEmpty() ||
311 !this.getQueryOperations(true).isEmpty();
312 }
313
314 /***
315 * The suffix given to the no transformation constant.
316 */
317 private static final String NO_TRANSFORMATION_CONSTANT_SUFFIX = "NONE";
318
319 /***
320 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getDaoNoTransformationConstantName()
321 */
322 protected String handleGetDaoNoTransformationConstantName()
323 {
324 return SpringGlobals.TRANSFORMATION_CONSTANT_PREFIX + NO_TRANSFORMATION_CONSTANT_SUFFIX;
325 }
326
327 /***
328 * Common routine to check inheritance.
329 */
330 protected boolean checkHibInheritance(String inheritance)
331 {
332 return inheritance.equals(getHibernateInheritanceStrategy());
333 }
334
335 /***
336 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceClass()
337 */
338 protected boolean handleIsHibernateInheritanceClass()
339 {
340 return checkHibInheritance(INHERITANCE_STRATEGY_CLASS);
341 }
342
343 /***
344 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceInterface()
345 */
346 protected boolean handleIsHibernateInheritanceInterface()
347 {
348 return checkHibInheritance(INHERITANCE_STRATEGY_INTERFACE);
349 }
350
351 /***
352 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceSubclass()
353 */
354 protected boolean handleIsHibernateInheritanceSubclass()
355 {
356 return checkHibInheritance(INHERITANCE_STRATEGY_SUBCLASS);
357 }
358
359 /***
360 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isHibernateInheritanceConcrete()
361 */
362 protected boolean handleIsHibernateInheritanceConcrete()
363 {
364 return checkHibInheritance(INHERITANCE_STRATEGY_CONCRETE);
365 }
366
367 /***
368 * Stores the default hibernate inheritance strategy.
369 */
370 private static final String INHERITANCE_STRATEGY = "hibernateInheritanceStrategy";
371
372 /***
373 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getHibernateInheritanceStrategy()
374 */
375 protected String handleGetHibernateInheritanceStrategy()
376 {
377 String inheritance = this.getInheritance(this);
378 for (SpringEntity superEntity = this.getSuperEntity(); superEntity != null && StringUtils.isBlank(inheritance);)
379 {
380 inheritance = superEntity.getHibernateInheritanceStrategy();
381 }
382 inheritance = inheritance != null ? inheritance.toLowerCase() : null;
383 if (StringUtils.isBlank(inheritance) || !inheritanceStrategies.contains(inheritance))
384 {
385 inheritance = this.getDefaultInheritanceStrategy();
386 }
387 return inheritance;
388 }
389
390 /***
391 * Gets the default hibernate inhertance strategy.
392 *
393 * @return the default hibernate inheritance strategy.
394 */
395 private String getDefaultInheritanceStrategy()
396 {
397 return String.valueOf(this.getConfiguredProperty(INHERITANCE_STRATEGY));
398 }
399
400 /***
401 * Return the inheritance tagged value for for given <code>entity</code>.
402 *
403 * @param the SpringEntity from which to retrieve the inheritance tagged value.
404 * @return String inheritance tagged value.
405 */
406 private String getInheritance(SpringEntity entity)
407 {
408 String inheritance = null;
409 if (entity != null)
410 {
411 Object value = entity.findTaggedValue(SpringProfile.TAGGEDVALUE_HIBERNATE_INHERITANCE);
412 if (value != null)
413 {
414 inheritance = String.valueOf(value);
415 }
416 }
417 return inheritance;
418 }
419
420 /***
421 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isRequiresHibernateMapping()
422 */
423 protected boolean handleIsRequiresHibernateMapping()
424 {
425 final SpringEntity superEntity = this.getSuperEntity();
426 return
427 SpringHibernateUtils.mapSubclassesInSeparateFile(
428 (String)this.getConfiguredProperty(SpringGlobals.HIBERNATE_MAPPING_STRATEGY)) ||
429 this.isRoot() &&
430 (
431 !this.isHibernateInheritanceInterface() || this.getSpecializations().isEmpty() ||
432 (superEntity != null && superEntity.isHibernateInheritanceInterface())
433 );
434 }
435
436 /***
437 * Indicates if this entity as a <code>root</code> entity (meaning it doesn't specialize anything).
438 */
439 private boolean isRoot()
440 {
441 final SpringEntity superEntity = this.getSuperEntity();
442 boolean abstractConcreteEntity =
443 (this.isHibernateInheritanceConcrete() || this.isHibernateInheritanceInterface()) && this.isAbstract();
444 return (
445 this.getSuperEntity() == null ||
446 (superEntity.isHibernateInheritanceInterface() || superEntity.isHibernateInheritanceConcrete())
447 ) && !abstractConcreteEntity;
448 }
449
450 /***
451 * Gets the super entity for this entity (if one exists). If a generalization does not exist OR if it's not an
452 * instance of SpringEntity then return null.
453 *
454 * @return the super entity or null if one doesn't exist.
455 */
456 private SpringEntity getSuperEntity()
457 {
458 SpringEntity superEntity = null;
459 if (this.getGeneralization() != null && this.getGeneralization() instanceof SpringEntity)
460 {
461 superEntity = (SpringEntity)this.getGeneralization();
462 }
463 return superEntity;
464 }
465
466 /***
467 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#getAttributeEmbeddedValueList()
468 */
469 protected String handleGetAttributeEmbeddedValueList()
470 {
471 final Collection embeddedValues = new ArrayList();
472 for (final Iterator iterator = this.getAttributes(true).iterator(); iterator.hasNext();)
473 {
474 final AttributeFacade attribute = (AttributeFacade)iterator.next();
475 final ClassifierFacade type = attribute.getType();
476 if (type != null && type.hasStereotype(UMLProfile.STEREOTYPE_EMBEDDED_VALUE))
477 {
478 embeddedValues.add(attribute.getName());
479 }
480 }
481 final StringBuffer buffer = new StringBuffer();
482 for (final Iterator iterator = embeddedValues.iterator(); iterator.hasNext();)
483 {
484 final String name = (String)iterator.next();
485 if (StringUtils.isNotBlank(name))
486 {
487 buffer.append('\"' + name + '\"');
488 if (iterator.hasNext())
489 {
490 buffer.append(", ");
491 }
492 }
493 }
494 return buffer.toString();
495 }
496
497 /***
498 * @see org.andromda.cartridges.spring.metafacades.SpringEntity#isRichClient()
499 */
500 protected boolean handleIsRichClient()
501 {
502 String richClient =
503 StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty("richClient")));
504
505 return richClient.equalsIgnoreCase("true");
506 }
507
508 }