View Javadoc
1   package org.andromda.cartridges.hibernate.metafacades;
2   
3   import java.text.MessageFormat;
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.List;
7   import org.andromda.cartridges.hibernate.HibernateProfile;
8   import org.andromda.cartridges.hibernate.HibernateUtils;
9   import org.andromda.metafacades.uml.AssociationEndFacade;
10  import org.andromda.metafacades.uml.Entity;
11  import org.andromda.metafacades.uml.EntityAttribute;
12  import org.andromda.metafacades.uml.EntityMetafacadeUtils;
13  import org.andromda.metafacades.uml.GeneralizableElementFacade;
14  import org.andromda.metafacades.uml.ModelElementFacade;
15  import org.andromda.metafacades.uml.OperationFacade;
16  import org.andromda.metafacades.uml.UMLMetafacadeProperties;
17  import org.apache.commons.lang.ObjectUtils;
18  import org.apache.commons.lang.StringUtils;
19  
20  /**
21   * <p> Provides support for the hibernate inheritance strategies of class
22   * (table per hierarchy), subclass (table per subclass in hierarchy) and
23   * concrete (table per class). With concrete the strategy can be changed lower
24   * down. Also provides for the root class being defined as an interface and the
25   * attributes remapped to the subclasses. This is useful in the concrete case
26   * because it has limitations in the associations.
27   * </p>
28   * <p> Also provides support for not generating the entity factory which is
29   * useful when using subclass mode.
30   * </p>
31   *
32   * @author Chad Brandon
33   * @author Martin West
34   * @author Carlos Cuenca
35   * @author Peter Friese
36   * @author Wouter Zoons
37   * @author Bob Fields
38   */
39  public class HibernateEntityLogicImpl
40      extends HibernateEntityLogic
41  {
42      private static final long serialVersionUID = 34L;
43      /**
44       * @param metaObject
45       * @param context
46       */
47      public HibernateEntityLogicImpl(
48          Object metaObject,
49          String context)
50      {
51          super(metaObject, context);
52      }
53  
54      /**
55       * Value for one table per root class
56       */
57      private static final String INHERITANCE_STRATEGY_CLASS = "class";
58  
59      /**
60       * Value for joined-subclass
61       */
62      private static final String INHERITANCE_STRATEGY_SUBCLASS = "subclass";
63  
64      /**
65       * Value for one table per concrete class
66       */
67      private static final String INHERITANCE_STRATEGY_CONCRETE = "concrete";
68  
69      /**
70       * Value make entity an interface, delegate attributes to subclasses.
71       */
72      private static final String INHERITANCE_STRATEGY_INTERFACE = "interface";
73  
74      /**
75       * Value for one table per concrete class, (with union-subclass)
76       */
77      private static final String INHERITANCE_STRATEGY_UNION_SUBCLASS = "union-subclass";
78  
79      /**
80       * Stores the valid inheritance strategies.
81       */
82      private static final Collection<String> inheritanceStrategies = new ArrayList<String>();
83  
84      static
85      {
86          inheritanceStrategies.add(INHERITANCE_STRATEGY_CLASS);
87          inheritanceStrategies.add(INHERITANCE_STRATEGY_SUBCLASS);
88          inheritanceStrategies.add(INHERITANCE_STRATEGY_CONCRETE);
89          inheritanceStrategies.add(INHERITANCE_STRATEGY_INTERFACE);
90          inheritanceStrategies.add(INHERITANCE_STRATEGY_UNION_SUBCLASS);
91      }
92  
93      /**
94       * Stores the default hibernate inheritance strategy.
95       */
96      private static final String INHERITANCE_STRATEGY = "hibernateInheritanceStrategy";
97  
98      /**
99       * Stores the hibernate entity cache value.
100      */
101     private static final String HIBERNATE_ENTITY_CACHE = "hibernateEntityCache";
102 
103     /**
104      * The namespace property storing the hibernate default-cascade value for an
105      * entity.
106      */
107     private static final String HIBERNATE_DEFAULT_CASCADE = "hibernateDefaultCascade";
108 
109     /**
110      * Namespace property storing the default hibernate generator class.
111      */
112     private static final String DEFAULT_HIBERNATE_GENERATOR_CLASS = "defaultHibernateGeneratorClass";
113 
114     /**
115      * Represents a <em>foreign</em> Hibernate generator class.
116      */
117     private static final String HIBERNATE_GENERATOR_CLASS_FOREIGN = "foreign";
118 
119     /**
120      * Represents an <em>assigned</em> Hibernate generator class.
121      */
122     private static final String HIBERNATE_GENERATOR_CLASS_ASSIGNED = "assigned";
123     private static final String HIBERNATE_GENERATOR_CLASS_SEQUENCE = "sequence";
124 
125     /**
126      * The namespace property for specifying a hibernate proxy for this entity.
127      */
128     private static final String HIBERNATE_PROXY = "hibernateProxy";
129 
130     /**
131      * The "class" mapping name.
132      */
133     private static final String CLASS_MAPPING_NAME = "class";
134 
135     /**
136      * The "joined-subclass" mapping name.
137      */
138     private static final String JOINED_SUBCLASS_MAPPING_NAME = "joined-subclass";
139 
140     /**
141      * The "subclass" mapping name.
142      */
143     private static final String SUBCLASS_MAPPING_NAME = "subclass";
144 
145     /**
146      * The "union-subclass" mapping name.
147      */
148     private static final String UNION_SUBCLASS_MAPPING_NAME = "union-subclass";
149 
150     /**
151      * Return all the business operations (ones that are inherited as well as
152      * directly on the entity).
153      *
154      * @return all business operations
155      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getAllBusinessOperations()
156      */
157     protected Collection<OperationFacade> handleGetAllBusinessOperations()
158     {
159         Collection<OperationFacade> result = this.getBusinessOperations();
160         GeneralizableElementFacade general = this.getGeneralization();
161         // Allow for Entities that inherit from a non-Entity ancestor
162         if (general != null && general instanceof Entity)
163         {
164             Entity superElement = (Entity)general;
165             result.addAll(superElement.getBusinessOperations());
166             general = this.getGeneralization();
167         }
168 
169         return result;
170     }
171 
172     /**
173      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateInheritanceStrategy()
174      */
175     @Override
176     protected String handleGetHibernateInheritanceStrategy()
177     {
178         String inheritance = HibernateEntityLogicImpl.getInheritance(this);
179 
180         for (HibernateEntity superEntity = this.getSuperEntity();
181             (superEntity != null) && StringUtils.isBlank(inheritance);)
182         {
183             inheritance = superEntity.getHibernateInheritanceStrategy();
184         }
185 
186         inheritance = inheritance != null ? inheritance.toLowerCase() : null;
187 
188         if (StringUtils.isBlank(inheritance) || !inheritanceStrategies.contains(inheritance))
189         {
190             inheritance = this.getDefaultInheritanceStrategy();
191         }
192 
193         return inheritance;
194     }
195 
196     /**
197      * Gets the default hibernate inheritance strategy.
198      *
199      * @return the default hibernate inheritance strategy.
200      */
201     private String getDefaultInheritanceStrategy()
202     {
203         return String.valueOf(this.getConfiguredProperty(INHERITANCE_STRATEGY));
204     }
205 
206     /**
207      * Return the inheritance tagged value for for given <code>entity</code>.
208      *
209      * @param entity the HibernateEntity from which to retrieve the inheritance tagged
210      *        value.
211      * @return String inheritance tagged value.
212      */
213     private static String getInheritance(HibernateEntity entity)
214     {
215         String inheritance = null;
216 
217         if (entity != null)
218         {
219             final Object value = entity.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_INHERITANCE);
220             if (value != null)
221             {
222                 inheritance = String.valueOf(value);
223             }
224         }
225         return inheritance;
226     }
227 
228     /**
229      * @see org.andromda.metafacades.uml.ClassifierFacade#getProperties()
230      */
231     public List<ModelElementFacade> getProperties()
232     {
233         List<ModelElementFacade> properties = new ArrayList<ModelElementFacade>();
234         properties.addAll(this.getAttributes());
235         for (final AssociationEndFacade end : this.getAssociationEnds())
236         {
237             final AssociationEndFacade otherEnd = end.getOtherEnd();
238             if (otherEnd.isNavigable() ||
239                 (end.isChild() && isForeignHibernateGeneratorClass()))
240             {
241                 properties.add(otherEnd);
242             }
243         }
244         return properties;
245     }
246 
247     /**
248      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateInheritanceClass()
249      */
250     @Override
251     protected boolean handleIsHibernateInheritanceClass()
252     {
253         return this.getHibernateInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_CLASS);
254     }
255 
256     /**
257      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateInheritanceInterface()
258      */
259     @Override
260     protected boolean handleIsHibernateInheritanceInterface()
261     {
262         return this.getHibernateInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_INTERFACE);
263     }
264 
265     /**
266      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateInheritanceSubclass()
267      */
268     @Override
269     protected boolean handleIsHibernateInheritanceSubclass()
270     {
271         return this.getHibernateInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_SUBCLASS);
272     }
273 
274     /**
275      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateInheritanceConcrete()
276      */
277     @Override
278     protected boolean handleIsHibernateInheritanceConcrete()
279     {
280         return this.getHibernateInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_CONCRETE);
281     }
282 
283     /**
284      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateInheritanceUnionSubClass()
285      */
286     @Override
287     protected boolean handleIsHibernateInheritanceUnionSubClass()
288     {
289         String version = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION);
290         return (version.startsWith(HibernateGlobals.HIBERNATE_VERSION_3) || version.startsWith(HibernateGlobals.HIBERNATE_VERSION_4))
291             && this.getHibernateInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_UNION_SUBCLASS);
292     }
293 
294     /**
295      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isLazy()
296      */
297     @Override
298     protected boolean handleIsLazy()
299     {
300         String value = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_LAZY);
301         if (StringUtils.isBlank(value))
302         {
303             String version = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION);
304             value = version.startsWith(HibernateGlobals.HIBERNATE_VERSION_2) ? "false" : "true";
305         }
306         return Boolean.valueOf(value).booleanValue();
307     }
308 
309     /**
310      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateCacheType()
311      */
312     @Override
313     protected String handleGetHibernateCacheType()
314     {
315         String cacheType = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ENTITY_CACHE);
316         if (StringUtils.isBlank(cacheType))
317         {
318             cacheType = String.valueOf(this.getConfiguredProperty(HIBERNATE_ENTITY_CACHE));
319         }
320         return cacheType;
321     }
322 
323     /**
324      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getFullyQualifiedEntityName()
325      */
326     @Override
327     protected String handleGetFullyQualifiedEntityName()
328     {
329         return HibernateMetafacadeUtils.getFullyQualifiedName(
330             this.getPackageName(),
331             this.getEntityName(),
332             null);
333     }
334 
335     /**
336      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getFullyQualifiedEntityImplementationName()
337      */
338     @Override
339     protected String handleGetFullyQualifiedEntityImplementationName()
340     {
341         return HibernateMetafacadeUtils.getFullyQualifiedName(
342             this.getPackageName(),
343             this.getEntityImplementationName(),
344             null);
345     }
346 
347     /**
348      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateDefaultCascade()
349      */
350     @Override
351     protected String handleGetHibernateDefaultCascade()
352     {
353         return StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty(HIBERNATE_DEFAULT_CASCADE)));
354     }
355 
356     /**
357      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateGeneratorClass()
358      */
359     @Override
360     protected String handleGetHibernateGeneratorClass()
361     {
362         String hibernateGeneratorClass;
363 
364         // if the entity is using a foreign identifier, then
365         // we automatically set the identifier generator
366         // class to be foreign
367         if (this.isUsingForeignIdentifier())
368         {
369             hibernateGeneratorClass = HIBERNATE_GENERATOR_CLASS_FOREIGN;
370         }
371         else if (this.isUsingAssignedIdentifier())
372         {
373             hibernateGeneratorClass = HIBERNATE_GENERATOR_CLASS_ASSIGNED;
374         }
375         else
376         {
377             hibernateGeneratorClass =
378                 (String)this.findTaggedValue(
379                     HibernateProfile.TAGGEDVALUE_HIBERNATE_GENERATOR_CLASS,
380                     false);
381 
382             if (StringUtils.isBlank(hibernateGeneratorClass))
383             {
384                 hibernateGeneratorClass = (String)this.getConfiguredProperty(DEFAULT_HIBERNATE_GENERATOR_CLASS);
385             }
386         }
387         return StringUtils.trimToEmpty(hibernateGeneratorClass);
388     }
389 
390     /**
391      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isForeignHibernateGeneratorClass()
392      */
393     @Override
394     protected boolean handleIsForeignHibernateGeneratorClass()
395     {
396         // check to see if the entity is using a foreign identifier
397         // OR if the actual hibernate generator class is set to foreign
398         return this.isUsingForeignIdentifier() ||
399         this.getHibernateGeneratorClass().equalsIgnoreCase(HIBERNATE_GENERATOR_CLASS_FOREIGN);
400     }
401 
402     /**
403      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isSequenceHibernateGeneratorClass()
404      */
405     @Override
406     protected boolean handleIsSequenceHibernateGeneratorClass()
407     {
408         return this.getHibernateGeneratorClass().equalsIgnoreCase(HIBERNATE_GENERATOR_CLASS_SEQUENCE);
409     }
410 
411     /**
412      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getEntityName()
413      */
414     @Override
415     protected String handleGetEntityName()
416     {
417         String entityNamePattern = (String)this.getConfiguredProperty(HibernateGlobals.ENTITY_NAME_PATTERN);
418 
419         return MessageFormat.format(
420             entityNamePattern,
421                 StringUtils.trimToEmpty(this.getName()));
422     }
423 
424     /**
425      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getEntityImplementationName()
426      */
427     @Override
428     protected String handleGetEntityImplementationName()
429     {
430         String implNamePattern =
431             String.valueOf(this.getConfiguredProperty(HibernateGlobals.ENTITY_IMPLEMENTATION_NAME_PATTERN));
432 
433         return MessageFormat.format(
434             implNamePattern,
435                 StringUtils.trimToEmpty(this.getName()));
436     }
437 
438     /**
439      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateDiscriminatorColumn()
440      */
441     @Override
442     protected String handleGetHibernateDiscriminatorColumn()
443     {
444         String column = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_ENTITY_DISCRIMINATOR_COLUMN);
445 
446         if (StringUtils.isBlank(column))
447         {
448             column = String.valueOf(this.getConfiguredProperty(HibernateGlobals.ENTITY_DISCRIMINATOR_COLUMN));
449         }
450 
451         return column;
452     }
453 
454     /**
455      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateDiscriminatorType()
456      */
457     @Override
458     protected String handleGetHibernateDiscriminatorType()
459     {
460         String type = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_ENTITY_DISCRIMINATOR_TYPE);
461 
462         if (StringUtils.isBlank(type))
463         {
464             type = String.valueOf(this.getConfiguredProperty(HibernateGlobals.ENTITY_DISCRIMINATOR_TYPE));
465         }
466 
467         return type;
468     }
469 
470     /**
471      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateDiscriminatorLength()
472      */
473     @Override
474     protected int handleGetHibernateDiscriminatorLength()
475     {
476         return 1;
477     }
478 
479     /**
480      * Override so that we retrieve only the operations that are classifier
481      * scope (i.e. static).
482      *
483      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntityLogic#getBusinessOperations()
484      */
485     @Override
486     public Collection<OperationFacade> getBusinessOperations()
487     {
488         return HibernateMetafacadeUtils.filterBusinessOperations(super.getBusinessOperations());
489     }
490 
491     /**
492      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isBusinessOperationsPresent()
493      */
494     @Override
495     protected boolean handleIsBusinessOperationsPresent()
496     {
497         final Collection<OperationFacade> allBusinessOperations = this.getAllBusinessOperations();
498 
499         return (allBusinessOperations != null) && !allBusinessOperations.isEmpty();
500     }
501 
502     /**
503      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateProxy()
504      */
505     @Override
506     protected boolean handleIsHibernateProxy()
507     {
508         String hibernateProxy = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_PROXY);
509         if (StringUtils.isBlank(hibernateProxy))
510         {
511             hibernateProxy = (String)this.getConfiguredProperty(HIBERNATE_PROXY);
512         }
513         return Boolean.valueOf(hibernateProxy).booleanValue();
514     }
515 
516     /**
517      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getEhCacheMaxElementsInMemory()
518      */
519     @Override
520     protected int handleGetEhCacheMaxElementsInMemory()
521     {
522         String maxElements = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_EHCACHE_MAX_ELEMENTS);
523         if (StringUtils.isBlank(maxElements))
524         {
525             maxElements = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_EHCACHE_MAX_ELEMENTS);
526         }
527         return Integer.parseInt(StringUtils.trimToEmpty(maxElements));
528     }
529 
530     /**
531      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isEhCacheEternal()
532      */
533     @Override
534     protected boolean handleIsEhCacheEternal()
535     {
536         String eternal = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_EHCACHE_ETERNAL);
537         if (StringUtils.isBlank(eternal))
538         {
539             eternal = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_EHCACHE_ETERNAL);
540         }
541         return Boolean.valueOf(StringUtils.trimToEmpty(eternal)).booleanValue();
542     }
543 
544     /**
545      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getEhCacheTimeToIdleSeconds()
546      */
547     @Override
548     protected int handleGetEhCacheTimeToIdleSeconds()
549     {
550         String timeToIdle =
551            (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_EHCACHE_TIME_TO_IDLE);
552         if (StringUtils.isBlank(timeToIdle))
553         {
554             timeToIdle = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_EHCACHE_TIME_TO_IDLE);
555         }
556         return Integer.parseInt(StringUtils.trimToEmpty(timeToIdle));
557     }
558 
559     /**
560      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getEhCacheTimeToLiveSeconds()
561      */
562     @Override
563     protected int handleGetEhCacheTimeToLiveSeconds()
564     {
565         String timeToLive =
566            (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_EHCACHE_TIME_TO_LIVE);
567         if (StringUtils.isBlank(timeToLive))
568         {
569             timeToLive = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_EHCACHE_TIME_TO_LIVE);
570         }
571         return Integer.parseInt(StringUtils.trimToEmpty(timeToLive));
572     }
573 
574     /**
575      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isEhCacheOverflowToDisk()
576      */
577     @Override
578     protected boolean handleIsEhCacheOverflowToDisk()
579     {
580         String eternal = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_EHCACHE_OVERFLOW_TO_DISK);
581         if (StringUtils.isBlank(eternal))
582         {
583             eternal = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_EHCACHE_OVERFLOW_TO_DISK);
584         }
585         return Boolean.valueOf(StringUtils.trimToEmpty(eternal)).booleanValue();
586     }
587 
588     /**
589      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isHibernateCacheDistributed()
590      */
591     @Override
592     protected boolean handleIsHibernateCacheDistributed()
593     {
594         String distributed = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_ENTITYCACHE_DISTRIBUTED);
595         boolean distributedCachingEnabled = Boolean.valueOf(StringUtils.trimToEmpty(distributed)).booleanValue();
596 
597         if (distributedCachingEnabled)
598         {
599             String entityCacheDistributed =
600                 (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ENTITYCACHE_DISTRIBUTED);
601             return Boolean.valueOf(StringUtils.trimToEmpty(entityCacheDistributed)).booleanValue();
602         }
603         return false;
604     }
605 
606     /**
607      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isTableRequired()
608      */
609     @Override
610     protected boolean handleIsTableRequired()
611     {
612         return !this.isHibernateInheritanceClass() ||
613         (this.isHibernateInheritanceClass() && (this.getGeneralization() == null));
614     }
615 
616     /**
617      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getMappingClassName()
618      */
619     @Override
620     protected String handleGetMappingClassName()
621     {
622         String mappingClassName = CLASS_MAPPING_NAME;
623         final HibernateEntity superEntity = this.getSuperEntity();
624 
625         if ((superEntity != null) && !superEntity.isHibernateInheritanceInterface() &&
626             !superEntity.isHibernateInheritanceConcrete())
627         {
628             mappingClassName = JOINED_SUBCLASS_MAPPING_NAME;
629 
630             if (this.isHibernateInheritanceClass())
631             {
632                 mappingClassName = SUBCLASS_MAPPING_NAME;
633             }
634             else if (this.isHibernateInheritanceUnionSubClass())
635             {
636                 mappingClassName = UNION_SUBCLASS_MAPPING_NAME;
637             }
638         }
639 
640         return mappingClassName;
641     }
642 
643     /**
644      * Gets the super entity for this entity (if one exists). If a
645      * generalization does not exist OR if it's not an instance of
646      * HibernateEntity then return null.
647      *
648      * @return the super entity or null if one doesn't exist.
649      */
650     private HibernateEntity getSuperEntity()
651     {
652         HibernateEntity superEntity = null;
653 
654         if ((this.getGeneralization() != null) && this.getGeneralization() instanceof HibernateEntity)
655         {
656             superEntity = (HibernateEntity)this.getGeneralization();
657         }
658 
659         return superEntity;
660     }
661 
662     /**
663      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getSubclassKeyColumn()
664      */
665     @Override
666     protected String handleGetSubclassKeyColumn()
667     {
668         String column = null;
669         final HibernateEntity superEntity = this.getSuperEntity();
670 
671         if ((superEntity != null) && superEntity.isHibernateInheritanceSubclass())
672         {
673             ModelElementFacade facade = this.getIdentifiers().iterator().next();
674             if (facade instanceof EntityAttribute)
675             {
676                 column = ((EntityAttribute)facade).getColumnName();
677             }
678         }
679 
680         return column;
681     }
682 
683     /**
684      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isRequiresMapping()
685      */
686     @Override
687     protected boolean handleIsRequiresMapping()
688     {
689         final HibernateEntity superEntity = this.getSuperEntity();
690         return HibernateUtils.mapSubclassesInSeparateFile(
691             (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_MAPPING_STRATEGY)) ||
692             this.isRoot() &&
693             (
694                 !this.isHibernateInheritanceInterface() || this.getSpecializations().isEmpty() ||
695                 (superEntity != null && superEntity.isHibernateInheritanceInterface())
696             );
697     }
698 
699     /**
700      * Indicates if this entity is a <code>root</code> entity (meaning it
701      * doesn't specialize anything).
702      */
703     private boolean isRoot()
704     {
705         final HibernateEntity superEntity = this.getSuperEntity();
706         boolean abstractConcreteEntity =
707             (this.isHibernateInheritanceConcrete() || this.isHibernateInheritanceInterface()) && this.isAbstract();
708 
709         return (
710             this.getSuperEntity() == null ||
711             (superEntity.isHibernateInheritanceInterface() || superEntity.isHibernateInheritanceConcrete())
712         ) && !abstractConcreteEntity;
713     }
714 
715     /**
716      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isRequiresSpecializationMapping()
717      */
718     @Override
719     protected boolean handleIsRequiresSpecializationMapping()
720     {
721         return !HibernateUtils.mapSubclassesInSeparateFile(
722             (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_MAPPING_STRATEGY)) && this.isRoot() &&
723         (
724             this.isHibernateInheritanceSubclass() || this.isHibernateInheritanceClass() ||
725             this.isHibernateInheritanceUnionSubClass()
726         );
727     }
728 
729     /**
730      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isDynamicInsert()
731      */
732     @Override
733     protected boolean handleIsDynamicInsert()
734     {
735         String dynamicInsert =
736             (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ENTITY_DYNAMIC_INSERT);
737         if (StringUtils.isBlank(dynamicInsert))
738         {
739             dynamicInsert = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_ENTITY_DYNAMIC_INSERT);
740         }
741         return Boolean.valueOf(dynamicInsert).booleanValue();
742     }
743 
744     /**
745      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isDynamicUpdate()
746      */
747     @Override
748     protected boolean handleIsDynamicUpdate()
749     {
750         String dynamicUpdate =
751             (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ENTITY_DYNAMIC_UPDATE);
752         if (StringUtils.isBlank(dynamicUpdate))
753         {
754             dynamicUpdate = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_ENTITY_DYNAMIC_UPDATE);
755         }
756         return Boolean.valueOf(dynamicUpdate).booleanValue();
757     }
758 
759     /**
760      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#isMappingRequiresSuperProperties()
761      */
762     @Override
763     protected boolean handleIsMappingRequiresSuperProperties()
764     {
765         return this.isHibernateInheritanceInterface() || (this.isHibernateInheritanceConcrete() && this.isAbstract());
766     }
767 
768     /**
769      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateVersionProperty()
770      */
771     @Override
772     protected String handleGetHibernateVersionProperty()
773     {
774         String version = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_VERSION_PROPERTY);
775         if (StringUtils.isBlank(version))
776         {
777             version = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION_PROPERTY);
778         }
779         return version;
780     }
781 
782     /**
783      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateVersionPropertySqlName()
784      */
785     @Override
786     protected String handleGetHibernateVersionPropertySqlName()
787     {
788         return EntityMetafacadeUtils.toSqlName(this.getHibernateVersionProperty(), this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR));
789     }
790 
791     /**
792      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getVersion()
793      */
794     @Override
795     protected int handleGetVersion()
796     {
797         String version = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION);
798         if (version==null)
799         {
800             version = HibernateGlobals.HIBERNATE_VERSION_3;
801         }
802         else
803         {
804             version = version.substring(0, 1);
805         }
806         return Integer.parseInt(version);
807     }
808 
809     private boolean isXmlPersistenceActive()
810     {
811         return HibernateUtils.isXmlPersistenceActive(
812             (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION),
813             (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_XML_PERSISTENCE));
814     }
815 
816     /**
817      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntityLogic#handleGetXmlTagName()
818      */
819     protected String handleGetXmlTagName()
820     {
821         String tagName = null;
822         if (isXmlPersistenceActive())
823         {
824             tagName = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_XML_TAG_NAME);
825 
826             if (StringUtils.isBlank(tagName))
827             {
828                 tagName = this.getName();
829             }
830         }
831         return (StringUtils.isBlank(tagName)) ? null : tagName;
832     }
833 
834     /**
835      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getHibernateDiscriminatorValue()
836      */
837     @Override
838     protected String handleGetHibernateDiscriminatorValue()
839     {
840         String value = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_ENTITY_DISCRIMINATOR_VALUE);
841         if (StringUtils.isBlank(value))
842         {
843             value = getEntityImplementationName();
844         }
845         return value;
846     }
847 
848     /**
849      * @see org.andromda.cartridges.hibernate.metafacades.HibernateEntity#getSequenceName()
850      */
851     @Override
852     protected String handleGetSequenceName()
853     {
854         String sequenceName = this.getTableName();
855         final String sequenceSuffix = this.getSequenceSuffix();
856         // Implicit conversion from short to int
857         final int maxLength = this.getMaxSqlNameLength() - this.getSequenceSuffix().length();
858         if (maxLength > 0)
859         {
860             final Object method = this.getConfiguredProperty(UMLMetafacadeProperties.SHORTEN_SQL_NAMES_METHOD);
861             sequenceName = EntityMetafacadeUtils.ensureMaximumNameLength(sequenceName, Integer.valueOf(maxLength).shortValue(), (String)method) + sequenceSuffix;
862         }
863         return sequenceName;
864     }
865 
866     private static final String SEQUENCE_IDENTIFIER_SUFFIX = "sequenceIdentifierSuffix";
867 
868     private String getSequenceSuffix()
869     {
870         return ObjectUtils.toString(this.getConfiguredProperty(SEQUENCE_IDENTIFIER_SUFFIX));
871     }
872 }