001package org.andromda.cartridges.ejb3.metafacades;
002
003import java.text.MessageFormat;
004import java.util.ArrayList;
005import java.util.Collection;
006import java.util.Iterator;
007import java.util.LinkedHashSet;
008import java.util.List;
009import org.andromda.cartridges.ejb3.EJB3Globals;
010import org.andromda.cartridges.ejb3.EJB3Profile;
011import org.andromda.core.common.ExceptionRecorder;
012import org.andromda.metafacades.uml.AssociationEndFacade;
013import org.andromda.metafacades.uml.AttributeFacade;
014import org.andromda.metafacades.uml.ClassifierFacade;
015import org.andromda.metafacades.uml.DependencyFacade;
016import org.andromda.metafacades.uml.Entity;
017import org.andromda.metafacades.uml.EntityAssociationEnd;
018import org.andromda.metafacades.uml.EntityAttribute;
019import org.andromda.metafacades.uml.EntityMetafacadeUtils;
020import org.andromda.metafacades.uml.EnumerationFacade;
021import org.andromda.metafacades.uml.GeneralizableElementFacade;
022import org.andromda.metafacades.uml.MetafacadeUtils;
023import org.andromda.metafacades.uml.ModelElementFacade;
024import org.andromda.metafacades.uml.OperationFacade;
025import org.andromda.metafacades.uml.Role;
026import org.andromda.metafacades.uml.TypeMappings;
027import org.andromda.metafacades.uml.UMLMetafacadeProperties;
028import org.andromda.metafacades.uml.UMLProfile;
029import org.andromda.metafacades.uml.ValueObject;
030import org.apache.commons.collections.Closure;
031import org.apache.commons.collections.CollectionUtils;
032import org.apache.commons.collections.Predicate;
033import org.apache.commons.collections.Transformer;
034import org.apache.commons.lang.BooleanUtils;
035import org.apache.commons.lang.ObjectUtils;
036import org.apache.commons.lang.StringUtils;
037import org.apache.commons.lang.math.NumberUtils;
038
039/**
040 * MetafacadeLogic implementation for org.andromda.cartridges.ejb3.metafacades.EJB3EntityFacade.
041 *
042 * @see EJB3EntityFacade
043 */
044public class EJB3EntityFacadeLogicImpl
045    extends EJB3EntityFacadeLogic
046{
047    private static final long serialVersionUID = 34L;
048    /**
049     * The default entity association cascade property
050     */
051    public static final String ENTITY_DEFAULT_CASCADE = "entityDefaultCascade";
052
053    /**
054     * Stores the default entity inheritance strategy
055     */
056    private static final String ENTITY_INHERITANCE_STRATEGY = "entityInheritanceStrategy";
057
058    /**
059     * Stores the default entity discriminator type used in the
060     * inheritance annotation
061     */
062    private static final String ENTITY_DISCRIMINATOR_TYPE = "entityDiscriminatorType";
063
064    /**
065     * Stores the default entity discriminator column name used in
066     * the DiscriminatorColumn annotation
067     */
068    private static final String ENTITY_DISCRIMINATOR_COLUMN_NAME = "entityDiscriminatorColumnName";
069
070    /**
071     * The default view type accessibility for an entity POJO bean
072     */
073    public static final String ENTITY_DEFAULT_VIEW_TYPE = "entityViewType";
074
075    /**
076     * Value for one table per root class
077     */
078    private static final String INHERITANCE_STRATEGY_TABLE_PER_CLASS = "TABLE_PER_CLASS";
079
080    /**
081     * Value for a single table for the hierarchy
082     */
083    private static final String INHERITANCE_STRATEGY_SINGLE_TABLE = "SINGLE_TABLE";
084
085    /**
086     * Value for joined subclass
087     */
088    private static final String INHERITANCE_STRATEGY_JOINED_SUBLCASS = "JOINED";
089
090    /**
091     * Stores the valid inheritance strategies
092     */
093    private static final Collection<String> inheritanceStrategies = new ArrayList<String>();
094
095    static
096    {
097        inheritanceStrategies.add(INHERITANCE_STRATEGY_TABLE_PER_CLASS);
098        inheritanceStrategies.add(INHERITANCE_STRATEGY_SINGLE_TABLE);
099        inheritanceStrategies.add(INHERITANCE_STRATEGY_JOINED_SUBLCASS);
100    }
101
102    /**
103     * Value for string based discriminator type
104     */
105    public static final String DISCRIMINATORTYPE_STRING = "STRING";
106
107    /**
108     * Value for char based discriminator type
109     */
110    public static final String DISCRIMINATORTYPE_CHAR = "CHAR";
111
112    /**
113     * Value for integer based discriminator type
114     */
115    public static final String DISCRIMINATORTYPE_INTEGER = "INTEGER";
116
117    /**
118     * Stores the valid discriminator types
119     */
120    private static final Collection<String> discriminatorTypes = new ArrayList<String>();
121
122    static
123    {
124        discriminatorTypes.add(DISCRIMINATORTYPE_STRING);
125        discriminatorTypes.add(DISCRIMINATORTYPE_CHAR);
126        discriminatorTypes.add(DISCRIMINATORTYPE_INTEGER);
127    }
128
129    /**
130     * The property which stores the pattern defining the entity name.
131     */
132    public static final String ENTITY_NAME_PATTERN = "entityNamePattern";
133
134    /**
135     * The property which stores the pattern defining the entity
136     * implementation name.
137     */
138    public static final String ENTITY_IMPLEMENTATION_NAME_PATTERN = "entityImplementationNamePattern";
139
140    /**
141     * The property that stores the pattern defining the entity
142     * listener class name.
143     */
144    public static final String ENTITY_LISTENER_NAME_PATTERN = "entityListenerNamePattern";
145
146    /**
147     * The property that stores the pattern defining the entity
148     * embeddable super class name.
149     */
150    public static final String ENTITY_EMBEDDABLE_NAME_PATTERN = "entityEmbeddableNamePattern";
151
152    /**
153     * The property that stores the pattern defining the entity
154     * composite primary key class name.
155     */
156    private static final String ENTITY_COMPOSITE_PRIMARY_KEY_NAME_PATTERN = "entityCompositePrimaryKeyNamePattern";
157
158    /**
159     * The property that stores the generic finders option
160     */
161    private static final String ENTITY_GENERIC_FINDERS = "entityGenericFinders";
162
163    /**
164     * The property that stores whether caching is enabled.
165     */
166    private static final String HIBERNATE_ENABLE_CACHE = "hibernateEnableCache";
167
168    /**
169     * The property that stores the hibernate entity cache value.
170     */
171    private static final String HIBERNATE_ENTITY_CACHE = "hibernateEntityCache";
172
173    /**
174     * The property that determines whether to use the default cache region for
175     * entities and queries.
176     */
177    private static final String USE_DEFAULT_CACHE_REGION = "useDefaultCacheRegion";
178
179    /**
180     * The pattern used to construct the DAO implementation name.
181     */
182    private static final String DAO_IMPLEMENTATION_PATTERN = "daoImplementationNamePattern";
183
184    /**
185     * The pattern used to construct the DAO base name.
186     */
187    private static final String DAO_BASE_PATTERN = "daoBaseNamePattern";
188
189    /**
190     * The property which stores the pattern defining the DAO default exception name.
191     */
192    private static final String DAO_DEFAULT_EXCEPTION_NAME_PATTERN = "daoDefaultExceptionNamePattern";
193
194    // ---------------- constructor -------------------------------
195
196    /**
197     * @param metaObject
198     * @param context
199     */
200    public EJB3EntityFacadeLogicImpl(final Object metaObject, final String context)
201    {
202        super (metaObject, context);
203    }
204
205    // --------------- methods ---------------------
206
207    /**
208     * This was meant to overrides the default implementation in EntityLogicImpl.java.
209     * TODO: check - is it really required?
210     * @return identifiers
211     * @see EJB3EntityFacade#getIdentifiers()
212     */
213    public Collection handleGetIdentifiers()
214    {
215        Collection identifiers = new ArrayList();
216        // This looks at dependencies only, not attributes or association identifiers
217        for (final DependencyFacade dep : this.getSourceDependencies())
218        {
219            if (dep.hasStereotype(EJB3Profile.STEREOTYPE_IDENTIFIER))
220            {
221                identifiers = ((ClassifierFacade)dep.getTargetElement()).getInstanceAttributes();
222                MetafacadeUtils.filterByStereotype(identifiers, EJB3Profile.STEREOTYPE_IDENTIFIER);
223                return identifiers;
224            }
225        }
226
227        // No PK dependency found - use PK attribute/association identifiers
228        Collection<ModelElementFacade> entityIdentifiers = this.getIdentifiers(true);
229        if (entityIdentifiers != null && !entityIdentifiers.isEmpty())
230        {
231            identifiers.addAll(entityIdentifiers);
232        }
233
234        // Still nothing found - recurse up the inheritance tree
235        GeneralizableElementFacade general = this.getGeneralization();
236        if (identifiers.isEmpty() && general instanceof EJB3EntityFacade)
237        {
238            identifiers = ((EJB3EntityFacade)general).getIdentifiers();
239        }
240        return identifiers;
241    }
242
243    /**
244     * This overrides the default implementation in EntityLogicImpl.java.
245     *
246     * This provides the means to check super classes, even those modeled
247     * as mapped superclasses, as well as entities.
248     *
249     * Gets all identifiers for this entity. If 'follow' is true, and if
250     * no identifiers can be found on the entity, a search up the
251     * inheritance chain will be performed, and the identifiers from
252     * the first super class having them will be used.
253     *
254     * @param follow a flag indicating whether or not the inheritance hierarchy
255     *        should be followed
256     * @return the collection of identifiers.
257     */
258    public Collection<ModelElementFacade> getIdentifiers(boolean follow)
259    {
260        final List<AttributeFacade> attributes = this.getAttributes();
261        MetafacadeUtils.filterByStereotype(
262            attributes,
263            UMLProfile.STEREOTYPE_IDENTIFIER);
264
265        final List<AssociationEndFacade> associations = this.getAssociationEnds();
266        MetafacadeUtils.filterByStereotype(
267            associations,
268            UMLProfile.STEREOTYPE_IDENTIFIER);
269
270        if (attributes.isEmpty() && associations.isEmpty() && follow)
271        {
272            if (this.getGeneralization() instanceof EJB3EntityFacade)
273            {
274                return ((EJB3EntityFacade)this.getGeneralization()).getIdentifiers(follow);
275            }
276            else if (this.getGeneralization() instanceof EJB3MappedSuperclassFacade)
277            {
278                return ((EJB3MappedSuperclassFacade)this.getGeneralization()).getIdentifiers(follow);
279            }
280        }
281        Collection<ModelElementFacade> identifiers = new ArrayList<ModelElementFacade>();
282        for (AttributeFacade attribute : attributes)
283        {
284            identifiers.add((EntityAttribute)attribute);
285        }
286        for (AssociationEndFacade association :associations)
287        {
288            identifiers.add((EntityAssociationEnd)association);
289        }
290        return identifiers;
291    }
292
293    /**
294     * @see EJB3EntityFacade#isSyntheticCreateMethodAllowed()
295     */
296    @Override
297    protected boolean handleIsSyntheticCreateMethodAllowed()
298    {
299        return EJB3MetafacadeUtils.allowSyntheticCreateMethod(this);
300    }
301
302    /**
303     * @return getEntityRelations()
304     * @see EJB3EntityFacade#getAllEntityRelations()
305     */
306    protected Collection handleGetAllEntityRelations()
307    {
308        return this.getEntityRelations();
309    }
310
311    /**
312     * @see EJB3EntityFacade#getJndiName()
313     */
314    @Override
315    protected String handleGetJndiName()
316    {
317        StringBuilder jndiName = new StringBuilder();
318        String jndiNamePrefix = StringUtils.trimToEmpty(this.getJndiNamePrefix());
319        if (StringUtils.isNotBlank(jndiNamePrefix))
320        {
321            jndiName.append(jndiNamePrefix);
322            jndiName.append("/");
323        }
324        jndiName.append("ejb/");
325        jndiName.append(this.getFullyQualifiedName());
326        return jndiName.toString();
327    }
328
329    /**
330     * Gets the <code>jndiNamePrefix</code> for this EJB.
331     *
332     * @return the EJB Jndi name prefix.
333     */
334    protected String getJndiNamePrefix()
335    {
336        String prefix = null;
337        if (this.isConfiguredProperty(EJB3Globals.JNDI_NAME_PREFIX))
338        {
339            prefix = (String)this.getConfiguredProperty(EJB3Globals.JNDI_NAME_PREFIX);
340        }
341        return prefix;
342    }
343
344    /**
345     * @see EJB3EntityFacade#getViewType()
346     */
347    @Override
348    protected String handleGetViewType()
349    {
350        return EJB3MetafacadeUtils.getViewType(this,
351                String.valueOf(this.getConfiguredProperty(ENTITY_DEFAULT_VIEW_TYPE)));
352    }
353
354    /**
355     * @return EJB3MetafacadeUtils.getAllInstanceAttributes(this)
356     * @see EJB3EntityFacade#getAllInstanceAttributes()
357     */
358    protected List handleGetAllInstanceAttributes()
359    {
360        return EJB3MetafacadeUtils.getAllInstanceAttributes(this);
361    }
362
363    /**
364     * @return EJB3MetafacadeUtils.getInheritedInstanceAttributes(this)
365     * @see EJB3EntityFacade#getInheritedInstanceAttributes()
366     */
367    protected List handleGetInheritedInstanceAttributes()
368    {
369        return EJB3MetafacadeUtils.getInheritedInstanceAttributes(this);
370    }
371
372    /**
373     * @see EJB3EntityFacade#getHomeInterfaceName()
374     */
375    @Override
376    protected String handleGetHomeInterfaceName()
377    {
378        return EJB3MetafacadeUtils.getHomeInterfaceName(this);
379    }
380
381    /**
382     * @return dependencies
383     * @see EJB3EntityFacade#getValueDependencies()
384     *
385     * NOTE: This is not required since ValueObject no longer exist and replaced with POJOs
386     */
387    protected Collection handleGetValueDependencies()
388    {
389        Collection dependencies = super.getSourceDependencies();
390        CollectionUtils.filter(
391                dependencies,
392                new Predicate()
393                {
394                    public boolean evaluate(Object object)
395                    {
396                        boolean isValueRef = false;
397                        if (object instanceof DependencyFacade)
398                        {
399                            DependencyFacade dep = (DependencyFacade)object;
400                            isValueRef = dep.getStereotypeNames().contains(EJB3Profile.STEREOTYPE_VALUE_REF)
401                                && dep.getTargetElement().hasExactStereotype(EJB3Profile.STEREOTYPE_VALUE_OBJECT);
402                        }
403                        return isValueRef;
404                    }
405                });
406        return dependencies;
407    }
408
409    /**
410     * @return entityRelations
411     * @see EJB3EntityFacade#getEntityRelations()
412     */
413    protected Collection handleGetEntityRelations()
414    {
415        Collection<AssociationEndFacade> result = new ArrayList<AssociationEndFacade>();
416        for (final AssociationEndFacade associationEnd : this.getAssociationEnds())
417        {
418            ClassifierFacade target = associationEnd.getOtherEnd().getType();
419            if (target instanceof EJB3EntityFacade && associationEnd.getOtherEnd().isNavigable())
420            {
421                result.add(associationEnd);
422            }
423        }
424
425        return result;
426    }
427
428    /**
429     * @param follow
430     * @return EJB3MetafacadeUtils.getCreateMethods(this, follow)
431     * @see EJB3EntityFacade#getCreateMethods(boolean)
432     */
433    protected Collection handleGetCreateMethods(boolean follow)
434    {
435        return EJB3MetafacadeUtils.getCreateMethods(this, follow);
436    }
437
438    /**
439     * @param follow
440     * @return selectMethods
441     * @see EJB3EntityFacade#getSelectMethods(boolean)
442     */
443    protected Collection<OperationFacade> handleGetSelectMethods(boolean follow)
444    {
445        Collection<OperationFacade> retval = new ArrayList<OperationFacade>();
446        EJB3EntityFacade entity = null;
447        do
448        {
449            for (final OperationFacade op : this.getOperations())
450            {
451                if (op.hasStereotype(EJB3Profile.STEREOTYPE_SELECT_METHOD))
452                {
453                    retval.add(op);
454                }
455            }
456            if (follow)
457            {
458                entity = (EJB3EntityFacade)this.getGeneralization();
459            }
460            else
461            {
462                break;
463            }
464        }
465        while (entity != null);
466        return retval;
467    }
468
469    /**
470     * @param follow
471     * @return EJB3MetafacadeUtils.getEnvironmentEntries(this, follow)
472     * @see EJB3EntityFacade#getEnvironmentEntries(boolean)
473     */
474    protected Collection handleGetEnvironmentEntries(boolean follow)
475    {
476        return EJB3MetafacadeUtils.getEnvironmentEntries(this, follow);
477    }
478
479    /**
480     * @param follow
481     * @return EJB3MetafacadeUtils.getConstants(this, follow)
482     * @see EJB3EntityFacade#getConstants(boolean)
483     */
484    protected Collection handleGetConstants(boolean follow)
485    {
486        return EJB3MetafacadeUtils.getConstants(this, follow);
487    }
488
489    /**
490     * @see EJB3EntityFacade#isOperationPresent(String)
491     */
492    @Override
493    protected boolean handleIsOperationPresent(String op)
494    {
495        Collection collOps = this.getOperations();
496        for (final Iterator it = collOps.iterator(); it.hasNext();)
497        {
498            final OperationFacade operation = (OperationFacade)it.next();
499            if (operation.getName().equalsIgnoreCase(op))
500            {
501                return true;
502            }
503        }
504        return false;
505    }
506
507    /**
508     * @see EJB3EntityFacade#isAttributePresent(String)
509     */
510    @Override
511    protected boolean handleIsAttributePresent(String att)
512    {
513        Collection collAttrib = this.getAttributes(true);
514        for (final Iterator it = collAttrib.iterator(); it.hasNext();)
515        {
516            final AttributeFacade attr = (AttributeFacade)it.next();
517            if (attr.getName().equalsIgnoreCase(att))
518            {
519                return true;
520            }
521        }
522        return false;
523    }
524
525    /**
526     * @see EJB3EntityFacade#isIdentifierPresent(String)
527     */
528    @Override
529    protected boolean handleIsIdentifierPresent(String id)
530    {
531        Collection collIdentifier = this.getIdentifiers(true);
532        for (final Iterator it = collIdentifier.iterator(); it.hasNext();)
533        {
534            final AttributeFacade attr = (AttributeFacade)it.next();
535            if (attr.getName().equalsIgnoreCase(id))
536            {
537                return true;
538            }
539        }
540        return false;
541    }
542
543    /**
544     * @see EJB3EntityFacade#getSqlType()
545     */
546    @Override
547    protected String handleGetSqlType()
548    {
549        String mpSql = this.getMappingsProperty(UMLMetafacadeProperties.SQL_MAPPINGS_URI).getMappings().getName();
550        if (mpSql.startsWith("Oracle"))
551        {
552            mpSql = "ORACLE";
553        }
554        return mpSql;
555    }
556
557    /**
558     * Gets a Mappings instance from a property registered under the given <code>propertyName</code>.
559     *
560     * @param propertyName the property name to register under.
561     * @return the Mappings instance.
562     */
563    private TypeMappings getMappingsProperty(final String propertyName)
564    {
565        Object property = this.getConfiguredProperty(propertyName);
566        TypeMappings mappings = null;
567        String uri = null;
568        if (property instanceof String)
569        {
570            uri = (String)property;
571            try
572            {
573                mappings = TypeMappings.getInstance(uri);
574                this.setProperty(propertyName, mappings);
575            }
576            catch (Throwable th)
577            {
578                String errMsg = "Error getting '" + propertyName + "' --> '" + uri + "'";
579                // don't throw the exception
580                ExceptionRecorder.instance().record(errMsg, th);
581            }
582        }
583        else
584        {
585            mappings = (TypeMappings)property;
586        }
587        return mappings;
588    }
589
590    /**
591     * @see org.andromda.metafacades.uml.Entity#getBusinessOperations()
592     */
593    public Collection<OperationFacade> getBusinessOperations()
594    {
595        Collection<OperationFacade> operations = super.getBusinessOperations();
596        CollectionUtils.filter(operations, new Predicate()
597        {
598            public boolean evaluate(Object object)
599            {
600                boolean businessOperation = false;
601                if (EJB3OperationFacade.class.isAssignableFrom(object.getClass()))
602                {
603                    businessOperation = ((EJB3OperationFacade)object).isBusinessOperation();
604                }
605                return businessOperation;
606            }
607        });
608        return operations;
609    }
610
611    /**
612     * @see EJB3EntityFacadeLogic#handleGetEntityCompositePrimaryKeyName()
613     */
614    @Override
615    protected String handleGetEntityCompositePrimaryKeyName()
616    {
617        String compPKPattern =
618            String.valueOf(this.getConfiguredProperty(ENTITY_COMPOSITE_PRIMARY_KEY_NAME_PATTERN));
619
620        return MessageFormat.format(
621            compPKPattern,
622                StringUtils.trimToEmpty(this.getName()));
623    }
624
625    /**
626     * @see EJB3EntityFacadeLogic#handleGetEntityListenerName()
627     */
628    @Override
629    protected String handleGetEntityListenerName()
630    {
631        String entityListenerPattern = (String)this.getConfiguredProperty(ENTITY_LISTENER_NAME_PATTERN);
632
633        return MessageFormat.format(
634            entityListenerPattern,
635                StringUtils.trimToEmpty(this.getName()));
636    }
637
638    /**
639     * @see EJB3EntityFacadeLogic#handleGetEntityEmbeddableName()
640     */
641    @Override
642    protected String handleGetEntityEmbeddableName()
643    {
644        String embeddableSuperclassName =
645            (String)this.getConfiguredProperty(ENTITY_EMBEDDABLE_NAME_PATTERN);
646
647        return MessageFormat.format(
648            embeddableSuperclassName,
649                StringUtils.trimToEmpty(this.getName()));
650    }
651
652    /**
653     * @see EJB3EntityFacadeLogic#handleGetEntityName()
654     */
655    @Override
656    protected String handleGetEntityName()
657    {
658        String entityNamePattern = (String)this.getConfiguredProperty(ENTITY_NAME_PATTERN);
659
660        return MessageFormat.format(
661            entityNamePattern,
662                StringUtils.trimToEmpty(this.getName()));
663    }
664
665    /**
666     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedEntityCompositePrimaryKeyName()
667     */
668    @Override
669    protected String handleGetFullyQualifiedEntityCompositePrimaryKeyName()
670    {
671        return EJB3MetafacadeUtils.getFullyQualifiedName(
672                this.getPackageName(),
673                this.getEntityCompositePrimaryKeyName(),
674                null);
675    }
676
677    /**
678     * @see EJB3EntityFacadeLogic#handleGetEntityImplementationName()
679     */
680    @Override
681    protected String handleGetEntityImplementationName()
682    {
683        String implNamePattern =
684            String.valueOf(this.getConfiguredProperty(ENTITY_IMPLEMENTATION_NAME_PATTERN));
685
686        return MessageFormat.format(
687            implNamePattern,
688                StringUtils.trimToEmpty(this.getName()));
689    }
690
691    /**
692     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedEntityListenerName()
693     */
694    @Override
695    protected String handleGetFullyQualifiedEntityListenerName()
696    {
697        return EJB3MetafacadeUtils.getFullyQualifiedName(
698                this.getPackageName(),
699                this.getEntityListenerName(),
700                null);
701    }
702
703    /**
704     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedEntityEmbeddableName()
705     */
706    @Override
707    protected String handleGetFullyQualifiedEntityEmbeddableName()
708    {
709        return EJB3MetafacadeUtils.getFullyQualifiedName(
710                this.getPackageName(),
711                this.getEntityEmbeddableName(),
712                null);
713    }
714
715    /**
716     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedEntityName()
717     */
718    @Override
719    protected String handleGetFullyQualifiedEntityName()
720    {
721        return EJB3MetafacadeUtils.getFullyQualifiedName(
722                this.getPackageName(),
723                this.getEntityName(),
724                null);
725    }
726
727    /**
728     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedEntityImplementationName()
729     */
730    @Override
731    protected String handleGetFullyQualifiedEntityImplementationName()
732    {
733        return EJB3MetafacadeUtils.getFullyQualifiedName(
734                this.getPackageName(),
735                this.getEntityImplementationName(),
736                null);
737    }
738
739    /**
740     * Override the default table name definition to lookup the tagged value first.
741     * @return tableName
742     */
743    @Override
744    public String getTableName()
745    {
746        String tableName = (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_ENTITY_TABLE_NAME);
747        if (StringUtils.isBlank(tableName))
748        {
749            tableName = super.getTableName();
750        }
751        return tableName;
752    }
753
754    /**
755     * @see EJB3EntityFacadeLogic#handleGetDefaultCascadeType()
756     */
757    @Override
758    protected String handleGetDefaultCascadeType()
759    {
760        return StringUtils.trimToEmpty(String.valueOf(this.getConfiguredProperty(ENTITY_DEFAULT_CASCADE)));
761    }
762
763    /**
764     * @see EJB3EntityFacadeLogic#handleGetDiscriminatorColumn()
765     */
766    @Override
767    protected String handleGetDiscriminatorColumn()
768    {
769        String discriminatorColumnName =
770            (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_DISCRIMINATOR_COLUMN);
771        if (StringUtils.isBlank(discriminatorColumnName))
772        {
773            discriminatorColumnName = String.valueOf(this.getConfiguredProperty(ENTITY_DISCRIMINATOR_COLUMN_NAME));
774        }
775        return discriminatorColumnName;
776    }
777
778    /**
779     * @see EJB3EntityFacadeLogic#handleGetDiscriminatorColumnDefinition()
780     */
781    @Override
782    protected String handleGetDiscriminatorColumnDefinition()
783    {
784        return (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_DISCRIMINATOR_COLUMN_DEFINITION);
785    }
786
787    /**
788     * @see EJB3EntityFacadeLogic#handleGetDiscriminatorLength()
789     */
790    protected int handleGetDiscriminatorLength()
791    {
792        int length = 0;
793        String lengthAsStr =
794            (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_DISCRIMINATOR_COLUMN_LENGTH);
795        if (StringUtils.isNotBlank(lengthAsStr))
796        {
797            length = NumberUtils.toInt(lengthAsStr);
798        }
799        return length;
800    }
801
802    /**
803     * @see EJB3EntityFacadeLogic#handleGetDiscriminatorType()
804     */
805    @Override
806    protected String handleGetDiscriminatorType()
807    {
808        String discriminatorType = (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_DISCRIMINATOR_TYPE);
809        if (StringUtils.isBlank(discriminatorType))
810        {
811            discriminatorType = String.valueOf(this.getConfiguredProperty(ENTITY_DISCRIMINATOR_TYPE));
812        }
813        return discriminatorType;
814    }
815
816    /**
817     * @see EJB3EntityFacadeLogic#handleGetDiscriminatorValue()
818     */
819    @Override
820    protected String handleGetDiscriminatorValue()
821    {
822        String discriminatorValue =
823            (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_DISCRIMINATOR_VALUE);
824        if (StringUtils.isBlank(discriminatorValue))
825        {
826            discriminatorValue = StringUtils.substring(this.getEntityName(), 0, 1);
827        }
828        return discriminatorValue;
829    }
830
831    /**
832     * Gets the default entity inheritance strategy from namespace.
833     *
834     * @return the default entity inheritance strategy.
835     */
836    private String getDefaultInheritanceStrategy()
837    {
838        return String.valueOf(this.getConfiguredProperty(ENTITY_INHERITANCE_STRATEGY));
839    }
840
841    /**
842     * Return the inheritance tagged value for for given <code>entity</code>.
843     *
844     * @param entity EJB3EntityFacade from which to retrieve the inheritance tagged value.
845     * @return String inheritance tagged value.
846     */
847    private String getInheritance(EJB3EntityFacade entity)
848    {
849        String inheritance = null;
850        if (entity != null)
851        {
852            Object value = entity.findTaggedValue(EJB3Profile.TAGGEDVALUE_PERSISTENCE_INHERITANCE);
853            if (value != null)
854            {
855                inheritance = String.valueOf(value);
856            }
857        }
858        return inheritance;
859    }
860
861    /**
862     * Returns the super entity for this entity, if one exists by generalization. If a
863     * generalization does NOT exist OR if it's not an instance of EJB3EntityFacade
864     * then returns null.
865     *
866     * @return the super entity or null if one doesn't exist.
867     */
868    private EJB3EntityFacade getSuperEntity()
869    {
870        EJB3EntityFacade superEntity = null;
871        if ((this.getGeneralization() != null) && this.getGeneralization() instanceof EJB3EntityFacade
872            && !this.getGeneralization().hasStereotype(EJB3Profile.STEREOTYPE_MAPPED_SUPERCLASS))
873        {
874            superEntity = (EJB3EntityFacade)this.getGeneralization();
875        }
876        return superEntity;
877    }
878
879    /**
880     * @see EJB3EntityFacadeLogic#handleIsInheritanceSingleTable()
881     */
882    @Override
883    protected boolean handleIsInheritanceSingleTable()
884    {
885        return this.getInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_SINGLE_TABLE);
886    }
887
888    /**
889     * @see EJB3EntityFacadeLogic#handleGetInheritanceStrategy()
890     */
891    @Override
892    protected String handleGetInheritanceStrategy()
893    {
894        String inheritance = this.getInheritance(this);
895        for (EJB3EntityFacade superEntity = this.getSuperEntity();
896            (superEntity != null) && StringUtils.isBlank(inheritance); )
897        {
898            inheritance = superEntity.getInheritanceStrategy();
899        }
900
901        if (StringUtils.isBlank(inheritance) || !inheritanceStrategies.contains(inheritance))
902        {
903            inheritance = this.getDefaultInheritanceStrategy();
904        }
905        return inheritance;
906    }
907
908    /**
909     * @see EJB3EntityFacadeLogic#handleIsInheritanceTablePerClass()
910     */
911    @Override
912    protected boolean handleIsInheritanceTablePerClass()
913    {
914        return this.getInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_TABLE_PER_CLASS);
915    }
916
917    /**
918     * @see EJB3EntityFacadeLogic#handleIsInheritanceJoined()
919     */
920    @Override
921    protected boolean handleIsInheritanceJoined()
922    {
923        return this.getInheritanceStrategy().equalsIgnoreCase(INHERITANCE_STRATEGY_JOINED_SUBLCASS);
924    }
925
926    /**
927     * Returns true if this entity is a <code>root</code> entity and has no generalizations.
928     *
929     * @return
930     */
931    private boolean isRoot()
932    {
933        final EJB3EntityFacade superEntity = this.getSuperEntity();
934        return (superEntity == null && !this.isAbstract());
935    }
936
937    /**
938     * @see EJB3EntityFacadeLogic#handleIsRequiresSpecializationMapping()
939     */
940    @Override
941    protected boolean handleIsRequiresSpecializationMapping()
942    {
943        return (this.isInheritanceSingleTable() || this.isInheritanceTablePerClass() || this.isInheritanceJoined())
944                && !this.getSpecializations().isEmpty();
945    }
946
947    /**
948     * @see EJB3EntityFacadeLogic#handleIsRequiresGeneralizationMapping()
949     */
950    @Override
951    protected boolean handleIsRequiresGeneralizationMapping()
952    {
953        return (this.getSuperEntity() != null &&
954                (this.getSuperEntity().isInheritanceSingleTable() ||
955                        this.getSuperEntity().isInheritanceTablePerClass() ||
956                        this.getSuperEntity().isInheritanceJoined()));
957    }
958
959    /**
960     * @see EJB3EntityFacadeLogic#handleIsEmbeddableSuperclass()
961     */
962    @Override
963    protected boolean handleIsEmbeddableSuperclass()
964    {
965        boolean isEmbeddableSuperclass = this.hasStereotype(EJB3Profile.STEREOTYPE_MAPPED_SUPERCLASS);
966
967        /**
968         * Must the root class - Cannot have embeddable superclass in the middle of the hierarchy
969         */
970        return isEmbeddableSuperclass && isRoot();
971    }
972
973    /**
974     * @see EJB3EntityFacadeLogic#handleIsEmbeddableSuperclassGeneralizationExists()
975     */
976    @Override
977    protected boolean handleIsEmbeddableSuperclassGeneralizationExists()
978    {
979        return (this.getSuperEntity() != null && this.getSuperEntity().isEmbeddableSuperclass());
980    }
981
982    /**
983     * @see EJB3EntityFacadeLogic#handleGetAttributesAsList(Collection, boolean, boolean, boolean)
984     */
985    @Override
986    protected String handleGetAttributesAsList(
987            Collection attributes,
988            boolean includeTypes,
989            boolean includeNames,
990            boolean includeAutoIdentifiers)
991    {
992        if ((!includeNames && !includeTypes) || attributes == null)
993        {
994            return "";
995        }
996
997        StringBuilder sb = new StringBuilder();
998        String separator = "";
999
1000        boolean isCompositePKPresent = this.isCompositePrimaryKeyPresent();
1001        if (isCompositePKPresent)
1002        {
1003            if (includeTypes)
1004            {
1005                sb.append(this.getFullyQualifiedName()).append("PK");
1006            }
1007            sb.append(" pk");
1008            separator = ", ";
1009        }
1010        for (final Object obj : attributes)
1011        {
1012            if (obj instanceof EJB3EntityAttributeFacade)
1013            {
1014                EJB3EntityAttributeFacade attr = (EJB3EntityAttributeFacade)obj;
1015                // Do not include attributes that are assigned for optimistic lock value as a version
1016                if (!attr.isVersion())
1017                {
1018                    /* Do not include identifier attributes for entities with a composite primary key
1019                     or if includeAutoIdentifiers is false, do not include identifiers with auto generated values. */
1020                    if (!attr.isIdentifier() ||
1021                       (!isCompositePKPresent && (includeAutoIdentifiers || attr.isGeneratorTypeNone())))
1022                    {
1023                        sb.append(separator);
1024                        separator = ", ";
1025                        if (includeTypes)
1026                        {
1027                            /*
1028                             * If attribute is a LOB and lob type is overridden, then use
1029                             * overriding lob type.
1030                             */
1031                            if (attr.isLob() && StringUtils.isNotBlank(attr.getLobType()))
1032                            {
1033                                sb.append(attr.getLobType());
1034                            }
1035                            else
1036                            {
1037                                sb.append(attr.getGetterSetterTypeName());
1038                            }
1039                            sb.append(" ");
1040                        }
1041                        if (includeNames)
1042                        {
1043                            sb.append(attr.getName());
1044                        }
1045                    }
1046                }
1047            }
1048            if (obj instanceof EJB3AssociationEndFacade)
1049            {
1050                EJB3AssociationEndFacade assoc = (EJB3AssociationEndFacade)obj;
1051                /* Do not include identifier attributes for entities with a composite primary key
1052                 or if includeAutoIdentifiers is false, do not include identifiers with auto generated values.*/
1053                //System.out.println(this.getName() + "." + assoc.getName() + " Identifier:" + assoc.isIdentifier() + " isCompositePKPresent:" + isCompositePKPresent + " includeAutoIdentifiers:" + includeAutoIdentifiers);
1054                if (!assoc.isIdentifier() || !isCompositePKPresent)
1055                {
1056                    sb.append(separator);
1057                    separator = ", ";
1058                    if (includeTypes)
1059                    {
1060                        sb.append(assoc.getGetterSetterTypeName()).append(" ");
1061                    }
1062                    if (includeNames)
1063                    {
1064                        sb.append(assoc.getName());
1065                    }
1066                }
1067            }
1068        }
1069        return sb.toString();
1070    }
1071
1072    /**
1073     * @see EJB3EntityFacadeLogic#handleIsGenericFinders()
1074     */
1075    @Override
1076    protected boolean handleIsGenericFinders()
1077    {
1078        return BooleanUtils.toBoolean(String.valueOf(this.getConfiguredProperty(ENTITY_GENERIC_FINDERS)));
1079    }
1080
1081    /**
1082     * @see EJB3EntityFacadeLogic#handleIsCompositePrimaryKeyPresent()
1083     */
1084    @Override
1085    protected boolean handleIsCompositePrimaryKeyPresent()
1086    {
1087        boolean isCompositePK = false;
1088        if (this.getIdentifiers().size() > 1)
1089        {
1090            isCompositePK = true;
1091        }
1092        return isCompositePK;
1093    }
1094
1095    /**
1096     * @see EJB3EntityFacadeLogic#handleIsListenerEnabled()
1097     */
1098    @Override
1099    protected boolean handleIsListenerEnabled()
1100    {
1101        return this.hasStereotype(EJB3Profile.STEREOTYPE_LISTENER);
1102    }
1103
1104    /**
1105     * @see EJB3EntityFacadeLogic#handleIsFinderFindAllExists()
1106     */
1107    @Override
1108    protected boolean handleIsFinderFindAllExists()
1109    {
1110        boolean finderExists = false;
1111        for (final Iterator iter = this.getQueryOperations().iterator(); iter.hasNext();)
1112        {
1113            final OperationFacade operation = (OperationFacade)iter.next();
1114            if ("findAll".equalsIgnoreCase(StringUtils.trimToEmpty(operation.getName())))
1115            {
1116                // Check for no finder arguments
1117                if (operation.getArguments().isEmpty())
1118                {
1119                    finderExists = true;
1120                    break;
1121                }
1122            }
1123        }
1124        return finderExists;
1125    }
1126
1127    /**
1128     * @see EJB3EntityFacadeLogic#handleIsFinderFindByPrimaryKeyExists()
1129     */
1130    @Override
1131    protected boolean handleIsFinderFindByPrimaryKeyExists()
1132    {
1133        boolean finderExists = false;
1134        for (final Iterator iter = this.getQueryOperations().iterator(); iter.hasNext();)
1135        {
1136            final OperationFacade operation = (OperationFacade)iter.next();
1137            if ("findByPrimaryKey".equalsIgnoreCase(operation.getName()))
1138            {
1139                finderExists = true;
1140                break;
1141            }
1142        }
1143        return finderExists;
1144    }
1145
1146    /**
1147     * @see EJB3EntityFacadeLogic#handleIsManageable()
1148     */
1149    @Override
1150    protected boolean handleIsManageable()
1151    {
1152        return this.hasStereotype(EJB3Profile.STEREOTYPE_MANAGEABLE);
1153    }
1154
1155    /**
1156     * @see EJB3EntityFacadeLogic#handleGetManageableDisplayAttribute()
1157     */
1158    protected AttributeFacade handleGetManageableDisplayAttribute()
1159    {
1160        AttributeFacade displayAttribute = null;
1161
1162        final Object taggedValueObject = this.findTaggedValue(UMLProfile.TAGGEDVALUE_MANAGEABLE_DISPLAY_NAME);
1163        if (taggedValueObject != null)
1164        {
1165            displayAttribute = this.findAttribute(StringUtils.trimToEmpty(taggedValueObject.toString()));
1166        }
1167
1168        final Collection<AttributeFacade> attributes = this.getAttributes(true);
1169        for (final Iterator<AttributeFacade> attributeIterator = attributes.iterator();
1170            attributeIterator.hasNext() && displayAttribute == null;)
1171        {
1172            final AttributeFacade attribute = attributeIterator.next();
1173            if (attribute.isUnique())
1174            {
1175                displayAttribute = attribute;
1176            }
1177        }
1178
1179        if (displayAttribute == null)
1180        {
1181            if (!this.getIdentifiers().isEmpty())
1182            {
1183                ModelElementFacade facade = this.getIdentifiers().iterator().next();
1184                if (facade instanceof AttributeFacade)
1185                {
1186                    displayAttribute = (AttributeFacade)facade;
1187                }
1188                else if (!attributes.isEmpty())
1189                {
1190                    displayAttribute = (EntityAttribute)attributes.iterator().next();
1191                }
1192            }
1193            else if (!attributes.isEmpty())
1194            {
1195                displayAttribute = (EntityAttribute)attributes.iterator().next();
1196            }
1197        }
1198
1199        return displayAttribute;
1200    }
1201
1202    /**
1203     * @see EJB3EntityFacadeLogic#handleGetIdentifier()
1204     */
1205    protected ModelElementFacade handleGetIdentifier()
1206    {
1207        ModelElementFacade identifier = null;
1208        final Collection<ModelElementFacade> identifiers = this.getIdentifiers();
1209        if (identifiers != null && !identifiers.isEmpty())
1210        {
1211            identifier = this.getIdentifiers().iterator().next();
1212        }
1213        return identifier;
1214    }
1215
1216    /**
1217     * @see EJB3EntityFacadeLogic#handleGetCacheType()
1218     */
1219    @Override
1220    protected String handleGetCacheType()
1221    {
1222        String cacheType = (String)findTaggedValue(EJB3Profile.TAGGEDVALUE_HIBERNATE_ENTITY_CACHE);
1223        if (StringUtils.isBlank(cacheType))
1224        {
1225            cacheType = String.valueOf(this.getConfiguredProperty(HIBERNATE_ENTITY_CACHE));
1226        }
1227        return StringUtils.trimToEmpty(cacheType);
1228    }
1229
1230    /**
1231     * @see EJB3EntityFacadeLogic#handleIsCacheEnabled()
1232     */
1233    @Override
1234    protected boolean handleIsCacheEnabled()
1235    {
1236        return BooleanUtils.toBoolean(String.valueOf(this.getConfiguredProperty(HIBERNATE_ENABLE_CACHE)));
1237    }
1238
1239    /**
1240     * @see EJB3EntityFacadeLogic#handleIsUseDefaultCacheRegion()
1241     */
1242    @Override
1243    protected boolean handleIsUseDefaultCacheRegion()
1244    {
1245        return BooleanUtils.toBoolean(String.valueOf(this.getConfiguredProperty(USE_DEFAULT_CACHE_REGION)));
1246    }
1247
1248    /**
1249     * @see EJB3EntityFacadeLogic#handleGetDaoName()
1250     */
1251    @Override
1252    protected String handleGetDaoName()
1253    {
1254        return MessageFormat.format(
1255            getDaoNamePattern(),
1256                StringUtils.trimToEmpty(this.getName()));
1257    }
1258
1259    /**
1260     * Gets the value of the {@link EJB3Globals#DAO_PATTERN}
1261     *
1262     * @return the DAO name pattern.
1263     */
1264    private String getDaoNamePattern()
1265    {
1266        return String.valueOf(this.getConfiguredProperty(EJB3Globals.DAO_PATTERN));
1267    }
1268
1269    /**
1270     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedDaoName()
1271     */
1272    @Override
1273    protected String handleGetFullyQualifiedDaoName()
1274    {
1275        return EJB3MetafacadeUtils.getFullyQualifiedName(
1276                this.getPackageName(),
1277                this.getDaoName(),
1278                null);
1279    }
1280
1281    /**
1282     * @see EJB3EntityFacadeLogic#handleGetDaoImplementationName()
1283     */
1284    @Override
1285    protected String handleGetDaoImplementationName()
1286    {
1287        return MessageFormat.format(
1288                getDaoImplementationNamePattern(),
1289                StringUtils.trimToEmpty(this.getName()));
1290    }
1291
1292    /**
1293     * Gets the value of the {@link #DAO_IMPLEMENTATION_PATTERN}
1294     *
1295     * @return the DAO implementation name pattern.
1296     */
1297    private String getDaoImplementationNamePattern()
1298    {
1299        return String.valueOf(this.getConfiguredProperty(DAO_IMPLEMENTATION_PATTERN));
1300    }
1301
1302    /**
1303     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedDaoImplementationName()
1304     */
1305    @Override
1306    protected String handleGetFullyQualifiedDaoImplementationName()
1307    {
1308        return EJB3MetafacadeUtils.getFullyQualifiedName(
1309                this.getPackageName(),
1310                this.getDaoImplementationName(),
1311                null);
1312    }
1313
1314    /**
1315     * @see EJB3EntityFacadeLogic#handleGetDaoBaseName()
1316     */
1317    @Override
1318    protected String handleGetDaoBaseName()
1319    {
1320        return MessageFormat.format(
1321                getDaoBaseNamePattern(),
1322                StringUtils.trimToEmpty(this.getName()));
1323    }
1324
1325    /**
1326     * Gets the value of the {@link #DAO_BASE_PATTERN}
1327     *
1328     * @return the DAO base name pattern.
1329     */
1330    private String getDaoBaseNamePattern()
1331    {
1332        return String.valueOf(this.getConfiguredProperty(DAO_BASE_PATTERN));
1333    }
1334
1335    /**
1336     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedDaoBaseName()
1337     */
1338    @Override
1339    protected String handleGetFullyQualifiedDaoBaseName()
1340    {
1341        return EJB3MetafacadeUtils.getFullyQualifiedName(
1342                this.getPackageName(),
1343                this.getDaoBaseName(),
1344                null);
1345    }
1346
1347    /**
1348     * @see EJB3EntityFacadeLogic#handleIsDaoBusinessOperationsPresent()
1349     */
1350    @Override
1351    protected boolean handleIsDaoBusinessOperationsPresent()
1352    {
1353        return this.getDaoBusinessOperations() != null && !this.getDaoBusinessOperations().isEmpty();
1354    }
1355
1356    /**
1357     * @see EJB3EntityFacadeLogic#handleGetDaoBusinessOperations()
1358     */
1359    protected Collection<OperationFacade> handleGetDaoBusinessOperations()
1360    {
1361        // operations that are not finders and static
1362        Collection finders = this.getQueryOperations();
1363        Collection<OperationFacade> operations = this.getOperations();
1364
1365        Collection<OperationFacade> nonFinders = CollectionUtils.subtract(operations, finders);
1366        CollectionUtils.filter(
1367            nonFinders,
1368            new Predicate()
1369            {
1370                public boolean evaluate(Object object)
1371                {
1372                    return ((OperationFacade)object).isStatic();
1373                }
1374            }
1375        );
1376        return nonFinders;
1377    }
1378
1379    /**
1380     * @see EJB3EntityFacadeLogic#handleGetValueObjectReferences()
1381     */
1382    protected Collection<DependencyFacade> handleGetValueObjectReferences()
1383    {
1384        return this.getValueObjectReferences(false);
1385    }
1386
1387    /**
1388     * @see EJB3EntityFacadeLogic#handleGetAllValueObjectReferences()
1389     */
1390    protected Collection<DependencyFacade> handleGetAllValueObjectReferences()
1391    {
1392        return this.getValueObjectReferences(true);
1393    }
1394
1395    /**
1396     * @see EJB3EntityFacadeLogic#handleIsDaoImplementationRequired()
1397     */
1398    @Override
1399    protected boolean handleIsDaoImplementationRequired()
1400    {
1401        return !this.getValueObjectReferences().isEmpty() || !this.getDaoBusinessOperations().isEmpty() ||
1402            !this.getQueryOperations(true).isEmpty();
1403    }
1404
1405    /**
1406     * @see EJB3EntityFacadeLogic#handleGetDaoNoTransformationConstantName()
1407     */
1408    @Override
1409    protected String handleGetDaoNoTransformationConstantName()
1410    {
1411        return EJB3Globals.TRANSFORMATION_CONSTANT_PREFIX + EJB3Globals.NO_TRANSFORMATION_CONSTANT_SUFFIX;
1412    }
1413
1414    /**
1415     * @see EJB3EntityFacadeLogic#handleGetValueObjectReferences(boolean)
1416     */
1417    protected Collection<DependencyFacade> handleGetValueObjectReferences(boolean follow)
1418    {
1419        final Collection<DependencyFacade> sourceDependencies = new ArrayList<DependencyFacade>(this.getSourceDependencies());
1420        if (follow)
1421        {
1422            for (GeneralizableElementFacade entity = this.getGeneralization(); entity != null;
1423                entity = entity.getGeneralization())
1424            {
1425                sourceDependencies.addAll(entity.getSourceDependencies());
1426            }
1427        }
1428        Collection<DependencyFacade> valueDependencies = new ArrayList<DependencyFacade>();
1429        for (DependencyFacade dependency : sourceDependencies)
1430        {
1431            Object targetElement = dependency.getTargetElement();
1432            if (targetElement instanceof ClassifierFacade)
1433            {
1434                ClassifierFacade element = (ClassifierFacade)targetElement;
1435                if (element.isDataType() || element instanceof ValueObject ||
1436                            element instanceof EnumerationFacade)
1437                {
1438                    valueDependencies.add(dependency);
1439                }
1440            }
1441        }
1442        return valueDependencies;
1443    }
1444
1445    /**
1446     * @see EJB3EntityFacadeLogic#handleGetRoot()
1447     */
1448    protected Object handleGetRoot()
1449    {
1450        GeneralizableElementFacade generalization = this;
1451        for (
1452            ; generalization.getGeneralization() != null && generalization instanceof EJB3EntityFacade;
1453            generalization = generalization.getGeneralization())
1454            ;
1455        return generalization;
1456    }
1457
1458    /**
1459     * @see EJB3EntityFacadeLogic#handleGetDefaultPersistenceContextUnitName()
1460     */
1461    @Override
1462    protected String handleGetDefaultPersistenceContextUnitName()
1463    {
1464        return StringUtils.trimToEmpty(
1465                ObjectUtils.toString(this.getConfiguredProperty(EJB3Globals.PERSISTENCE_CONTEXT_UNIT_NAME)));
1466    }
1467
1468    /**
1469     * @see EJB3EntityFacadeLogic#handleGetDaoDefaultExceptionName()
1470     */
1471    @Override
1472    protected String handleGetDaoDefaultExceptionName()
1473    {
1474        return MessageFormat.format(
1475                getDaoDefaultExceptionNamePattern(),
1476                StringUtils.trimToEmpty(this.getName()));
1477    }
1478
1479    /**
1480     * Gets the value of the {@link #DAO_DEFAULT_EXCEPTION_NAME_PATTERN}
1481     *
1482     * @return the DAO default exception name pattern.
1483     */
1484    private String getDaoDefaultExceptionNamePattern()
1485    {
1486        return String.valueOf(this.getConfiguredProperty(DAO_DEFAULT_EXCEPTION_NAME_PATTERN));
1487    }
1488
1489    /**
1490     * @see EJB3EntityFacadeLogic#handleGetFullyQualifiedDaoDefaultExceptionName()
1491     */
1492    @Override
1493    protected String handleGetFullyQualifiedDaoDefaultExceptionName()
1494    {
1495        return EJB3MetafacadeUtils.getFullyQualifiedName(
1496                this.getPackageName(),
1497                this.getDaoDefaultExceptionName(),
1498                null);
1499    }
1500
1501    /**
1502     * @see EJB3EntityFacadeLogic#handleIsEntityImplementationRequired()
1503     */
1504    @Override
1505    protected boolean handleIsEntityImplementationRequired()
1506    {
1507        return !this.getBusinessOperations().isEmpty();
1508    }
1509
1510    /**
1511     * @see EJB3EntityFacadeLogic#handleGetInstanceAttributes(boolean, boolean)
1512     */
1513    protected Collection<AttributeFacade> handleGetInstanceAttributes(
1514            boolean follow,
1515            boolean withIdentifiers)
1516    {
1517        final Collection<AttributeFacade> attributes = this.getAttributes(follow, withIdentifiers);
1518        CollectionUtils.filter(
1519            attributes,
1520            new Predicate()
1521            {
1522                public boolean evaluate(Object object)
1523                {
1524                    boolean valid = true;
1525                    if (object instanceof EntityAttribute)
1526                    {
1527                        valid = !((EntityAttribute)object).isStatic();
1528                    }
1529                    return valid;
1530                }
1531            });
1532        // If a 1:1 owned identifier relationship, the dependent identifier attributes should be included in addition to the association
1533        // and the generator="foreign" and @PrimaryKeyJoinColumn annotations are used.
1534        final List<AssociationEndFacade> associationEnds = this.getAssociationEnds();
1535        /*MetafacadeUtils.filterByStereotype(
1536            associationEnds,
1537            UMLProfile.STEREOTYPE_IDENTIFIER);*/
1538        //System.out.println("GetInstanceAttributes " + this.getFullyQualifiedName() + " associationEnds=" + this.getAssociationEnds().size() + " identifiers=" + associationEnds.size());
1539        for(AssociationEndFacade associationEnd : associationEnds)
1540        {
1541            //System.out.println("GetInstanceAttributes " + this.getFullyQualifiedName() + " " + associationEnd.getOtherEnd().getFullyQualifiedName() + " Identifier=" + associationEnd.getOtherEnd().hasStereotype("Identifier") + " associationEnd=" + associationEnd + " One2One=" + associationEnd.getOtherEnd().isOne2One() + " Type=" + associationEnd.getOtherEnd().getType());
1542            if (associationEnd.getOtherEnd().hasStereotype("Identifier") && associationEnd.getOtherEnd().isOne2One() && !associationEnd.getOtherEnd().hasStereotype(UMLProfile.STEREOTYPE_TRANSIENT) && associationEnd.getOtherEnd() instanceof EJB3AssociationEndFacade)
1543            {
1544                EJB3AssociationEndFacade ejb3AssociationEnd = (EJB3AssociationEndFacade) associationEnd;
1545                //System.out.println("GetInstanceAttributes " + this.getFullyQualifiedName() + " " + ejb3AssociationEnd + " Owning=" + ejb3AssociationEnd.isOwning() + " Aggregation=" + ejb3AssociationEnd.isAggregation() + " Composition=" + ejb3AssociationEnd.isComposition() + " OAggregation=" + ejb3AssociationEnd.getOtherEnd().isAggregation() + " OComposition=" + ejb3AssociationEnd.getOtherEnd().isComposition());
1546                if (ejb3AssociationEnd.isOwning())
1547                {
1548                    Entity entity = (Entity)ejb3AssociationEnd.getType();
1549                    Collection<ModelElementFacade> identifierAttributes = EntityMetafacadeUtils.getIdentifierAttributes(entity, follow);
1550                    //System.out.println("GetInstanceAttributes "  + this.getFullyQualifiedName() + " entity=" + entity + " Attributes=" + identifierAttributes);
1551                    for(ModelElementFacade identifier : identifierAttributes)
1552                    {
1553                        //System.out.println(identifier);
1554                        if (identifier instanceof AttributeFacade)
1555                        {
1556                            attributes.add((AttributeFacade)identifier);
1557                            //System.out.println("Added "  + identifier + " to entity=" + entity);
1558                        }
1559                    }
1560                }
1561            }
1562        }
1563        return attributes;
1564    }
1565
1566    /**
1567     * @see EJB3EntityFacadeLogic#handleGetInstanceAttributeNameList(boolean, boolean)
1568     */
1569    @Override
1570    protected String handleGetInstanceAttributeNameList(boolean follow, boolean withIdentifiers)
1571    {
1572        return this.getNameList(this.getInstanceAttributes(follow, withIdentifiers));
1573    }
1574
1575    /**
1576     * @see EJB3EntityFacadeLogic#handleGetInstanceAttributeTypeList(boolean, boolean)
1577     */
1578    @Override
1579    protected String handleGetInstanceAttributeTypeList(boolean follow, boolean withIdentifiers)
1580    {
1581        return this.getTypeList(this.getInstanceAttributes(follow, withIdentifiers));
1582    }
1583
1584    /**
1585     * Constructs a comma separated list of attribute type names from the passed in collection of
1586     * <code>attributes</code>.
1587     *
1588     * @param attributes the attributes to construct the list from.
1589     * @return the comma separated list of attribute types.
1590     */
1591    private String getTypeList(final Collection attributes)
1592    {
1593        final StringBuilder list = new StringBuilder();
1594        final String comma = ", ";
1595        CollectionUtils.forAllDo(
1596            attributes,
1597            new Closure()
1598            {
1599                public void execute(final Object object)
1600                {
1601                    if (object instanceof AttributeFacade)
1602                    {
1603                        final AttributeFacade attribute = (AttributeFacade)object;
1604                        if (attribute.getType() != null)
1605                        {
1606                            list.append(attribute.getGetterSetterTypeName());
1607                            list.append(comma);
1608                        }
1609                    }
1610                    if (object instanceof AssociationEndFacade)
1611                    {
1612                        final AssociationEndFacade associationEnd = (AssociationEndFacade)object;
1613                        if (associationEnd.getType() != null)
1614                        {
1615                            list.append(associationEnd.getGetterSetterTypeName());
1616                            list.append(comma);
1617                        }
1618                    }
1619                }
1620            });
1621        if (list.toString().endsWith(comma))
1622        {
1623            list.delete(list.lastIndexOf(comma), list.length());
1624        }
1625        return list.toString();
1626    }
1627
1628    /**
1629     * Constructs a comma separated list of attribute names from the passed in collection of <code>attributes</code>.
1630     *
1631     * @param properties the properties to construct the list from.
1632     * @return the comma separated list of attribute names.
1633     */
1634    private String getNameList(final Collection properties)
1635    {
1636        final StringBuilder list = new StringBuilder();
1637        final String comma = ", ";
1638        CollectionUtils.forAllDo(
1639            properties,
1640            new Closure()
1641            {
1642                public void execute(Object object)
1643                {
1644                    if (object instanceof EntityAttribute)
1645                    {
1646                        list.append(((AttributeFacade)object).getName());
1647                        list.append(comma);
1648                    }
1649                    if (object instanceof EntityAssociationEnd)
1650                    {
1651                        list.append(((AssociationEndFacade)object).getName());
1652                        list.append(comma);
1653                    }
1654                }
1655            });
1656        if (list.toString().endsWith(comma))
1657        {
1658            list.delete(list.lastIndexOf(comma), list.length());
1659        }
1660        return list.toString();
1661    }
1662
1663    /**
1664     * @see EJB3EntityFacadeLogic#handleIsSecurityEnabled()
1665     */
1666    @Override
1667    protected boolean handleIsSecurityEnabled()
1668    {
1669        return StringUtils.isNotBlank(this.getSecurityRealm());
1670    }
1671
1672    /**
1673     * @see EJB3EntityFacadeLogic#handleGetRolesAllowed()
1674     */
1675    @Override
1676    protected String handleGetRolesAllowed()
1677    {
1678        StringBuilder rolesAllowed = null;
1679        String separator = "";
1680
1681        for (final Iterator iter = this.getNonRunAsRoles().iterator(); iter.hasNext(); )
1682        {
1683            if (rolesAllowed == null)
1684            {
1685                rolesAllowed = new StringBuilder();
1686            }
1687            rolesAllowed.append(separator);
1688            Role role = (Role)iter.next();
1689            rolesAllowed.append('"');
1690            rolesAllowed.append(role.getName());
1691            rolesAllowed.append('"');
1692            separator = ", ";
1693        }
1694        return rolesAllowed != null ? rolesAllowed.toString() : null;
1695    }
1696
1697    /**
1698     * @see EJB3EntityFacadeLogic#handleGetSecurityRealm()
1699     */
1700    @Override
1701    protected String handleGetSecurityRealm()
1702    {
1703        String securityRealm = (String)this.findTaggedValue(EJB3Profile.TAGGEDVALUE_EJB_SECURITY_REALM);
1704        if (StringUtils.isBlank(securityRealm))
1705        {
1706            securityRealm = StringUtils.trimToEmpty(
1707                    ObjectUtils.toString(this.getConfiguredProperty(EJB3Globals.SECURITY_REALM)));
1708        }
1709        return securityRealm;
1710    }
1711
1712    /**
1713     * @see EJB3EntityFacadeLogic#handleGetNonRunAsRoles()
1714     */
1715    protected Collection handleGetNonRunAsRoles()
1716    {
1717        Collection<DependencyFacade> roles = this.getTargetDependencies();
1718        CollectionUtils.filter(
1719            roles,
1720            new Predicate()
1721            {
1722                public boolean evaluate(final Object object)
1723                {
1724                    DependencyFacade dependency = (DependencyFacade)object;
1725                    return dependency != null
1726                            && dependency.getSourceElement() != null
1727                            && dependency.getSourceElement() instanceof Role
1728                            && !dependency.hasStereotype(EJB3Profile.STEREOTYPE_SECURITY_RUNAS);
1729                }
1730            });
1731        CollectionUtils.transform(
1732            roles,
1733            new Transformer()
1734            {
1735                public Object transform(final Object object)
1736                {
1737                    return ((DependencyFacade)object).getSourceElement();
1738                }
1739            });
1740        final Collection allRoles = new LinkedHashSet(roles);
1741        // add all roles which are generalizations of this one
1742        CollectionUtils.forAllDo(
1743            roles,
1744            new Closure()
1745            {
1746                public void execute(final Object object)
1747                {
1748                    allRoles.addAll(((Role)object).getAllSpecializations());
1749                }
1750            });
1751        return allRoles;
1752    }
1753
1754    /**
1755     * @see EJB3EntityFacadeLogic#handleIsUseQueryCache()
1756     */
1757    @Override
1758    protected boolean handleIsUseQueryCache()
1759    {
1760        return BooleanUtils.toBoolean(
1761                String.valueOf(this.getConfiguredProperty(EJB3Globals.HIBERNATE_USER_QUERY_CACHE)));
1762    }
1763
1764    /**
1765     * @see EJB3EntityFacadeLogic#handleIsSeamComponent()
1766     */
1767    @Override
1768    protected boolean handleIsSeamComponent()
1769    {
1770        return EJB3MetafacadeUtils.isSeamComponent(this);
1771    }
1772
1773    /**
1774     * @see EJB3EntityFacadeLogic#handleGetSeamComponentScopeType()
1775     */
1776    @Override
1777    protected String handleGetSeamComponentScopeType()
1778    {
1779        return EJB3MetafacadeUtils.getSeamComponentScopeType(this, false);
1780    }
1781
1782    /**
1783     * @see EJB3EntityFacadeLogic#handleGetSeamComponentName()
1784     */
1785    @Override
1786    protected String handleGetSeamComponentName()
1787    {
1788        return EJB3MetafacadeUtils.getSeamComponentName(this);
1789    }
1790}