001package org.andromda.cartridges.ejb3.metafacades;
002
003import java.util.Collection;
004import java.util.Iterator;
005import java.util.List;
006import org.andromda.metafacades.uml.AssociationEndFacade;
007import org.andromda.metafacades.uml.Entity;
008import org.andromda.metafacades.uml.MetafacadeUtils;
009import org.andromda.metafacades.uml.UMLMetafacadeProperties;
010import org.andromda.metafacades.uml.UMLProfile;
011import org.apache.commons.lang.ObjectUtils;
012import org.apache.commons.lang.StringUtils;
013
014/**
015 * MetafacadeLogic implementation for org.andromda.cartridges.ejb3.metafacades.EJB3AssociationFacade.
016 *
017 * @see EJB3AssociationFacade
018 */
019public class EJB3AssociationFacadeLogicImpl
020    extends EJB3AssociationFacadeLogic
021{
022    private static final long serialVersionUID = 34L;
023    // ---------------- constructor -------------------------------
024
025    /**
026     * @param metaObject
027     * @param context
028     */
029    public EJB3AssociationFacadeLogicImpl(final Object metaObject, final String context)
030    {
031        super(metaObject, context);
032    }
033
034    // --------------- methods ---------------------
035
036    /**
037     * Override to provide support for One-2-Many unidirectional associations as well as Many-2-Many.
038     *
039     * Returns the EJB3 cartridge specific table name for the association
040     * @return table name
041     */
042    @Override
043    public String getTableName()
044    {
045        String tableName = null;
046        final List<AssociationEndFacade> ends = this.getAssociationEnds();
047        if (ends != null && !ends.isEmpty())
048        {
049            for (AssociationEndFacade facade : ends)
050            {
051                final EJB3AssociationEndFacade end = (EJB3AssociationEndFacade)facade;
052                if ((end.isMany2Many() && end.isOwning()) ||
053                    (end.isOne2Many() && !end.isNavigable() && end.getOtherEnd().isNavigable()))
054                {
055                    // prevent ClassCastException if the association isn't an
056                    // Entity
057                    if (Entity.class.isAssignableFrom(end.getType().getClass()))
058                    {
059                        final String prefixProperty = UMLMetafacadeProperties.TABLE_NAME_PREFIX;
060                        final String tableNamePrefix =
061                            this.isConfiguredProperty(prefixProperty)
062                            ? ObjectUtils.toString(this.getConfiguredProperty(prefixProperty)) : null;
063                        tableName =
064                            EJB3MetafacadeUtils.getSqlNameFromTaggedValue(
065                                tableNamePrefix,
066                                this,
067                                UMLProfile.TAGGEDVALUE_PERSISTENCE_TABLE,
068                                ((Entity)end.getType()).getMaxSqlNameLength(),
069                                null,
070                                this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR),
071                                this.getConfiguredProperty(UMLMetafacadeProperties.SHORTEN_SQL_NAMES_METHOD));
072                    }
073                    break;
074                }
075            }
076        }
077
078//        if (StringUtils.isNotBlank(tableName) && getName().toLowerCase().startsWith(tableName.toLowerCase()))
079//        {
080//            tableName = getRelationName().replaceAll("-", "_").toUpperCase();
081//        }
082
083        return tableName;
084    }
085
086    /**
087     * Override the default implementation to use the current getRelationName implementation
088     * @return name
089     */
090    @Override
091    public String getName()
092    {
093        String name = (super.getName().equalsIgnoreCase(super.getRelationName()) ? null : super.getName());
094
095        // if the name isn't defined, use the this implementation of relation name
096        if (StringUtils.isBlank(name))
097        {
098            name = this.getRelationName();
099        }
100        return name;
101    }
102
103    /**
104     * Override the default implementation to set the owning side name first followed by inverse side.
105     * If there is no owning side defined, then adopt the default logic of using alphabetical ordering.
106     * @return relation name
107     */
108    @Override
109    public String getRelationName()
110    {
111        final Collection<AssociationEndFacade> ends = this.getAssociationEnds();
112        final Iterator endIt = ends.iterator();
113        final EJB3AssociationEndFacade firstEnd = (EJB3AssociationEndFacade)endIt.next();
114        final EJB3AssociationEndFacade secondEnd = (EJB3AssociationEndFacade)endIt.next();
115        final String separator = String.valueOf(
116                this.getConfiguredProperty(UMLMetafacadeProperties.RELATION_NAME_SEPARATOR));
117
118        if (secondEnd.isOwning())
119        {
120            return secondEnd.getName() + separator + firstEnd.getName();
121        }
122        else if (firstEnd.isOwning())
123        {
124            return firstEnd.getName() + separator + secondEnd.getName();
125        }
126        else
127        {
128            return MetafacadeUtils.toRelationName(
129                    firstEnd.getName(),
130                    secondEnd.getName(),
131                    separator);
132        }
133    }
134}