001package org.andromda.cartridges.hibernate.metafacades;
002
003import java.util.Collection;
004import java.util.Iterator;
005import org.andromda.cartridges.hibernate.HibernateProfile;
006import org.andromda.metafacades.uml.ParameterFacade;
007import org.apache.commons.lang.StringUtils;
008
009/**
010 * @author Chad Brandon
011 * @author Carlos Cuenca
012 * @see HibernateFinderMethodLogic
013 *      Metaclass facade implementation.
014 */
015public class HibernateFinderMethodLogicImpl
016    extends HibernateFinderMethodLogic
017{
018    private static final long serialVersionUID = 34L;
019    // ---------------- constructor -------------------------------
020    /**
021     * @param metaObject
022     * @param context
023     */
024    public HibernateFinderMethodLogicImpl(
025        Object metaObject,
026        String context)
027    {
028        super(metaObject, context);
029    }
030
031    /**
032     * @see org.andromda.cartridges.hibernate.metafacades.HibernateFinderMethod#getQuery()
033     */
034    @Override
035    protected String handleGetQuery()
036    {
037        // first see if we can retrieve the query from the super class as an OCL
038        // translation
039        String queryString = this.getTranslatedQuery();
040
041        // otherwise see if there is a query stored as a tagged value
042        if (StringUtils.isEmpty(queryString))
043        {
044            Object value = this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_QUERY);
045            queryString = (String)value;
046            if (queryString != null)
047            {
048                // remove any excess whitespace
049                queryString = queryString.replaceAll("[$\\s]+", " ");
050            }
051        }
052
053        // if there wasn't any stored query, create one by default.
054        if (StringUtils.isEmpty(queryString))
055        {
056            String variableName = StringUtils.uncapitalize(this.getOwner().getName()).substring(0,1);
057            queryString = "SELECT " + variableName + " FROM " + this.getOwner().getName() + " AS " + variableName;
058            Collection arguments = this.getArguments();
059            if (arguments != null && !arguments.isEmpty())
060            {
061                queryString = queryString + " WHERE";
062                Iterator argumentIt = arguments.iterator();
063                for (; argumentIt.hasNext();)
064                {
065                    ParameterFacade argument = (ParameterFacade)argumentIt.next();
066                    String parameter = "?";
067                    if (this.isUseNamedParameters())
068                    {
069                        parameter = ':' + argument.getName();
070                    }
071                    queryString = queryString + ' ' + variableName + '.' + argument.getName() + " = " + parameter;
072                    if (argumentIt.hasNext())
073                    {
074                        queryString = queryString + " AND";
075                    }
076                }
077            }
078        }
079        return queryString;
080    }
081
082    /**
083     * Stores the translated query so that its only translated once.
084     */
085    private String translatedQuery = null;
086
087    /**
088     * Retrieves the translated query.
089     */
090    private String getTranslatedQuery()
091    {
092        if (StringUtils.isBlank(this.translatedQuery))
093        {
094            this.translatedQuery = super.getQuery("query.Hibernate-QL");
095        }
096        return this.translatedQuery;
097    }
098
099    /**
100     * Stores whether or not named parameters should be used in hibernate
101     * queries.
102     */
103    private static final String USE_NAMED_PARAMETERS = "hibernateQueryUseNamedParameters";
104
105    /**
106     * @see org.andromda.cartridges.hibernate.metafacades.HibernateFinderMethod#isUseNamedParameters()
107     */
108    @Override
109    protected boolean handleIsUseNamedParameters()
110    {
111        boolean useNamedParameters = Boolean.valueOf(String.valueOf(this.getConfiguredProperty(USE_NAMED_PARAMETERS))).booleanValue()
112                || StringUtils.isNotBlank(this.getTranslatedQuery());
113        return HibernateMetafacadeUtils.getUseNamedParameters(this, useNamedParameters);
114    }
115
116    /**
117     * Stores the value indicating whether or not to use hibernate query
118     * caching.
119     */
120    private static final String HIBERNATE_USE_QUERY_CACHE = "hibernateUseQueryCache";
121
122    /**
123     * @see org.andromda.cartridges.hibernate.metafacades.HibernateFinderMethod#isUseQueryCache()
124     */
125    @Override
126    protected boolean handleIsUseQueryCache()
127    {
128        boolean useQueryCache =
129            Boolean.valueOf(String.valueOf(this.getConfiguredProperty(HIBERNATE_USE_QUERY_CACHE))).booleanValue();
130
131        if (useQueryCache)
132        {
133            useQueryCache =
134                    Boolean.valueOf(
135                    String.valueOf(findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_USE_QUERY_CACHE)))
136                       .booleanValue();
137        }
138        return useQueryCache;
139    }
140}