001package org.andromda.metafacades.uml14;
002
003import java.util.Collection;
004import org.andromda.metafacades.uml.Entity;
005import org.andromda.metafacades.uml.EntityAssociationEnd;
006import org.andromda.metafacades.uml.EntityAttribute;
007import org.andromda.metafacades.uml.EntityMetafacadeUtils;
008import org.andromda.metafacades.uml.ModelElementFacade;
009import org.andromda.metafacades.uml.NameMasker;
010import org.andromda.metafacades.uml.TypeMappings;
011import org.andromda.metafacades.uml.UMLMetafacadeProperties;
012import org.andromda.metafacades.uml.UMLProfile;
013import org.apache.commons.lang.ObjectUtils;
014import org.apache.commons.lang.StringUtils;
015import org.apache.log4j.Logger;
016
017/**
018 * Represents an association end of an entity.
019 * Metaclass facade implementation.
020 * @author Bob Fields
021 */
022public class EntityAssociationEndLogicImpl
023        extends EntityAssociationEndLogic
024{
025    private static final long serialVersionUID = 34L;
026    /**
027     * @param metaObject
028     * @param context
029     */
030    public EntityAssociationEndLogicImpl(Object metaObject, String context)
031    {
032        super(metaObject, context);
033    }
034
035    /**
036     * Overridden to provide name masking.
037     *
038     * @see org.andromda.metafacades.uml.ModelElementFacade#getName()
039     */
040    @Override
041    protected String handleGetName()
042    {
043        final String nameMask = String.valueOf(
044            this.getConfiguredProperty(UMLMetafacadeProperties.ENTITY_PROPERTY_NAME_MASK));
045        return NameMasker.mask(super.handleGetName(), nameMask);
046    }
047
048    /**
049     * The logger instance.
050     */
051    private static final Logger logger = Logger.getLogger(EntityAssociationEndLogicImpl.class);
052
053    /**
054     * @see org.andromda.metafacades.uml.EntityAssociationEnd#getColumnName()
055     */
056    @Override
057    public String handleGetColumnName()
058    {
059        String columnName = null;
060        // prevent ClassCastException if the association isn't an Entity
061        if (this.getType() instanceof Entity)
062        {
063            final String columnNamePrefix =
064                this.isConfiguredProperty(UMLMetafacadeProperties.COLUMN_NAME_PREFIX)
065                ? ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.COLUMN_NAME_PREFIX)) : null;
066            final String columnNameSuffix =
067                this.isConfiguredProperty(UMLMetafacadeProperties.COLUMN_NAME_SUFFIX)
068                ? ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.COLUMN_NAME_SUFFIX)) : "";
069            columnName =
070                EntityMetafacadeUtils.getSqlNameFromTaggedValue(
071                    columnNamePrefix,
072                    this,
073                    UMLProfile.TAGGEDVALUE_PERSISTENCE_COLUMN,
074                    ((Entity)this.getType()).getMaxSqlNameLength(),
075                    columnNameSuffix + this.getForeignKeySuffix(),
076                    this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR),
077                    this.getConfiguredProperty(UMLMetafacadeProperties.SHORTEN_SQL_NAMES_METHOD));
078        }
079        return columnName;
080    }
081
082    /**
083     * @see org.andromda.metafacades.uml.EntityAssociationEnd#getForeignKeySuffix()
084     */
085    @Override
086    public String handleGetForeignKeySuffix()
087    {
088        return (String)this.getConfiguredProperty(UMLMetafacadeProperties.FOREIGN_KEY_SUFFIX);
089    }
090
091    /**
092     * @see org.andromda.metafacades.uml.EntityAssociationEnd#isForeignIdentifier()
093     */
094    @Override
095    protected boolean handleIsForeignIdentifier()
096    {
097        final Object value = this.findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_FOREIGN_IDENTIFIER);
098        return value != null && Boolean.valueOf(String.valueOf(value));
099    }
100
101    /**
102     * @see org.andromda.metafacades.uml.EntityAssociationEnd#getForeignKeyConstraintName()
103     */
104    @Override
105    protected String handleGetForeignKeyConstraintName()
106    {
107        return EntityMetafacadeUtils.getForeignKeyConstraintName(
108            (EntityAssociationEnd)THIS(),
109            ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.CONSTRAINT_SUFFIX)).trim(),
110            ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR)).trim(),
111            ObjectUtils.toString(getConfiguredProperty(UMLMetafacadeProperties.MAX_SQL_NAME_LENGTH)).trim(),
112            ObjectUtils.toString(getConfiguredProperty(UMLMetafacadeProperties.SHORTEN_SQL_NAMES_METHOD)).trim());
113    }
114
115    /**
116     * @see org.andromda.metafacades.uml.EntityAssociationEnd#getColumnIndex()
117     */
118    @Override
119    public String handleGetColumnIndex()
120    {
121        final String index = (String)this.findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_COLUMN_INDEX);
122        return index != null ? StringUtils.trimToEmpty(index) : null;
123    }
124
125    /**
126     * @see org.andromda.metafacades.uml14.EntityAssociationEndLogic#handleGetSqlType()
127     */
128    protected String handleGetSqlType()
129    {
130        String value = null;
131        if (this.getSqlMappings() != null)
132        {
133            EntityAttribute identifier = null;
134            // we retrieve the column length from the first identifier of the primary key
135            // on the other side (since that should correspond to the foreign key).
136            if (this.getType() instanceof Entity)
137            {
138                final Entity type = (Entity)this.getType();
139                final Collection<ModelElementFacade> identifiers = type.getIdentifiers();
140                if (identifiers != null && !identifiers.isEmpty())
141                {
142                    ModelElementFacade attribute = identifiers.iterator().next();
143                    if (attribute instanceof EntityAttribute)
144                    {
145                        identifier = (EntityAttribute)attribute;
146                    }
147                }
148            }
149            if (identifier != null && identifier.getType() != null)
150            {
151                String typeName = identifier.getType().getFullyQualifiedName(true);
152                value = this.getSqlMappings().getTo(typeName);
153                final String columnLength = identifier.getColumnLength();
154                if (StringUtils.isNotBlank(columnLength))
155                {
156                    value = EntityMetafacadeUtils.constructSqlTypeName(value, columnLength);
157                }
158            }
159        }
160        return value;
161    }
162
163    /**
164     * Gets the SQL mappings that have been set for this entity attribute.
165     *
166     * @return the SQL Mappings instance.
167     */
168    public TypeMappings getSqlMappings()
169    {
170        final String propertyName = UMLMetafacadeProperties.SQL_MAPPINGS_URI;
171        final Object property = this.getConfiguredProperty(propertyName);
172        TypeMappings mappings = null;
173        String uri;
174        if (property instanceof String)
175        {
176            uri = (String)property;
177            try
178            {
179                mappings = TypeMappings.getInstance(uri);
180                this.setProperty(propertyName, mappings);
181            }
182            catch (final Throwable throwable)
183            {
184                logger.error("Error getting '" + propertyName + "' --> '" + uri + '\'', throwable);
185                // don't throw the exception
186            }
187        }
188        else
189        {
190            mappings = (TypeMappings)property;
191        }
192        return mappings;
193    }
194
195    /**
196     * @see org.andromda.metafacades.uml14.EntityAssociationEndLogic#handleIsTransient()
197     */
198    protected boolean handleIsTransient()
199    {
200        return this.hasStereotype(UMLProfile.STEREOTYPE_TRANSIENT);
201    }
202
203    /**
204     * @see org.andromda.metafacades.uml.EntityAssociationEnd#isIdentifiersPresent()
205     */
206    @Override
207    protected boolean handleIsIdentifiersPresent() {
208        return this.hasStereotype(UMLProfile.STEREOTYPE_IDENTIFIER);
209    }
210
211    /**
212     * @return findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_ASSOCIATION_END_UNIQUE_GROUP)
213     * @see org.andromda.metafacades.uml.EntityAssociationEnd#getUniqueGroup()
214     */
215    //@Override
216    protected String handleGetUniqueGroup() {
217        final String group = (String)this.findTaggedValue(UMLProfile.TAGGEDVALUE_PERSISTENCE_ASSOCIATION_END_UNIQUE_GROUP);
218        return group != null ? StringUtils.trimToEmpty(group) : null;
219    }
220
221    /**
222     * @see org.andromda.metafacades.uml.EntityAssociationEnd#isIdentifier()
223     */
224    @Override
225    protected boolean handleIsIdentifier()
226    {
227        return this.hasStereotype(UMLProfile.STEREOTYPE_IDENTIFIER);
228    }
229}