001package org.andromda.cartridges.ejb.metafacades;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006import org.andromda.cartridges.ejb.EJBProfile;
007import org.andromda.core.common.ExceptionUtils;
008import org.andromda.metafacades.uml.AttributeFacade;
009import org.andromda.metafacades.uml.ClassifierFacade;
010import org.andromda.metafacades.uml.ModelElementFacade;
011import org.andromda.metafacades.uml.OperationFacade;
012import org.andromda.metafacades.uml.UMLProfile;
013import org.apache.commons.collections.CollectionUtils;
014import org.apache.commons.collections.Predicate;
015import org.apache.commons.lang.StringUtils;
016
017/**
018 * Contains utilities for use with EJB metafacades.
019 *
020 * @author Chad Brandon
021 */
022class EJBMetafacadeUtils
023{
024    /**
025     * Gets all create methods for the given <code>classifier</code>.
026     * @param classifier
027     * @param follow if true, all super type create methods are also retrieved
028     * @return Collection of create methods found.
029     */
030    static Collection<OperationFacade> getCreateMethods(ClassifierFacade classifier, boolean follow)
031    {
032        ExceptionUtils.checkNull("classifer", classifier);
033        Collection<OperationFacade> retval = new ArrayList<OperationFacade>();
034        ClassifierFacade entity = classifier;
035        do
036        {
037            for (final OperationFacade op : entity.getOperations())
038            {
039                if (op.hasStereotype(EJBProfile.STEREOTYPE_CREATE_METHOD))
040                {
041                    retval.add(op);
042                }
043            }
044            if (follow)
045            {
046                entity = (ClassifierFacade)entity.getGeneralization();
047            }
048        }
049        while (follow && entity != null);
050        return retval;
051    }
052
053    /**
054     * Gets the interface name for the passed in <code>classifier</code>. Returns 'LocalHome' if the mode element has
055     * the entity stereotype, returns 'Home' otherwise.
056     * @param classifier
057     * @return the interface name.
058     */
059    static String getHomeInterfaceName(ClassifierFacade classifier)
060    {
061        ExceptionUtils.checkNull("classifer", classifier);
062        String homeInterfaceName;
063        if (classifier.hasStereotype(UMLProfile.STEREOTYPE_ENTITY))
064        {
065            homeInterfaceName = classifier.getName() + "LocalHome";
066        }
067        else
068        {
069            homeInterfaceName = classifier.getName() + "Home";
070        }
071        return homeInterfaceName;
072    }
073
074    /**
075     * Gets the view type for the passed in <code>classifier</code>. Returns 'local' if the model element has the entity
076     * stereotype, also checks the ejb tagged value and if there is no value defined, returns 'remote'.
077     * @param classifier
078     * @return String the view type name.
079     */
080    static String getViewType(ClassifierFacade classifier)
081    {
082        ExceptionUtils.checkNull("classifer", classifier);
083        String viewType = "local";
084        if (classifier.hasStereotype(EJBProfile.STEREOTYPE_SERVICE) || classifier.hasStereotype(EJBProfile.STEREOTYPE_SERVICE_ELEMENT))
085        {
086            String viewTypeValue = (String)classifier.findTaggedValue(EJBProfile.TAGGEDVALUE_EJB_VIEWTYPE);
087            // if the view type wasn't found, search all super classes
088            if (StringUtils.isEmpty(viewTypeValue))
089            {
090                viewType = (String)CollectionUtils.find(classifier.getAllGeneralizations(), new Predicate()
091                {
092                    public boolean evaluate(Object object)
093                    {
094                        return ((ModelElementFacade)object).findTaggedValue(EJBProfile.TAGGEDVALUE_EJB_VIEWTYPE) !=
095                                null;
096                    }
097                });
098            }
099            if (StringUtils.isNotBlank(viewTypeValue))
100            {
101                viewType = viewTypeValue;
102            }
103            else
104            {
105                viewType = "remote";
106            }
107        }
108        return viewType.toLowerCase();
109    }
110
111    /**
112     * Gets all the inherited instance attributes, excluding the instance attributes directory from this
113     * <code>classifier</code>.
114     * @param classifier the ClassifierFacade from which to retrieve the inherited attributes.
115     * @return a list of ordered attributes.
116     */
117    static List getInheritedInstanceAttributes(ClassifierFacade classifier)
118    {
119        ExceptionUtils.checkNull("classifer", classifier);
120        ClassifierFacade current = (ClassifierFacade)classifier.getGeneralization();
121        if (current == null)
122        {
123            return new ArrayList();
124        }
125        List retval = getInheritedInstanceAttributes(current);
126
127        if (current.getInstanceAttributes() != null)
128        {
129            retval.addAll(current.getInstanceAttributes());
130        }
131        return retval;
132    }
133
134    /**
135     * Gets all instance attributes including those instance attributes belonging to the <code>classifier</code> and any
136     * inherited ones.
137     *
138     * @param classifier the ClassifierFacade from which to retrieve the instance attributes.
139     * @return the list of all instance attributes.
140     */
141    static List getAllInstanceAttributes(ClassifierFacade classifier)
142    {
143        ExceptionUtils.checkNull("classifer", classifier);
144        List retval = getInheritedInstanceAttributes(classifier);
145        retval.addAll(classifier.getInstanceAttributes());
146        return retval;
147    }
148
149    /**
150     * Gets all environment entries for the specified <code>classifier</code>. If <code>follow</code> is true, then a
151     * search up the inheritance hierarchy will be performed and all super type environment entries will also be
152     * retrieved.
153     *
154     * @param classifier the classifier from which to retrieve the env-entries
155     * @param follow     true/false on whether or not to 'follow' the inheritance hierarchy when retrieving the
156     *                   env-entries.
157     * @return the collection of environment entries
158     */
159    static Collection getEnvironmentEntries(ClassifierFacade classifier, boolean follow)
160    {
161        ExceptionUtils.checkNull("classifer", classifier);
162
163        Collection attributes = classifier.getStaticAttributes();
164
165        if (follow)
166        {
167            for (classifier = (ClassifierFacade)classifier.getGeneralization();
168                 classifier != null; classifier = (ClassifierFacade)classifier.getGeneralization())
169            {
170                attributes.addAll(classifier.getStaticAttributes());
171            }
172        }
173
174        CollectionUtils.filter(attributes, new Predicate()
175        {
176            public boolean evaluate(Object object)
177            {
178                return ((AttributeFacade)object).hasStereotype(EJBProfile.STEREOTYPE_ENV_ENTRY);
179            }
180        });
181
182        return attributes;
183    }
184
185    /**
186     * Gets all constants for the specified <code>classifier</code>. If <code>follow</code> is true, then a search up
187     * the inheritance hierarchy will be performed and all super type constants will also be retrieved.
188     *
189     * @param classifier the classifier from which to retrieve the constants
190     * @param follow     true/false on whether or not to 'follow' the inheritance hierarchy when retrieving the
191     *                   constants.
192     * @return the collection of environment entries
193     */
194    static Collection getConstants(ClassifierFacade classifier, boolean follow)
195    {
196        ExceptionUtils.checkNull("classifer", classifier);
197
198        Collection attributes = classifier.getStaticAttributes();
199
200        if (follow)
201        {
202            for (classifier = (ClassifierFacade)classifier.getGeneralization();
203                 classifier != null; classifier = (ClassifierFacade)classifier.getGeneralization())
204            {
205                attributes.addAll(classifier.getStaticAttributes());
206            }
207        }
208
209        CollectionUtils.filter(attributes, new Predicate()
210        {
211            public boolean evaluate(Object object)
212            {
213                return !((AttributeFacade)object).hasStereotype(EJBProfile.STEREOTYPE_ENV_ENTRY);
214            }
215        });
216
217        return attributes;
218    }
219
220    /**
221     * Returns true/false based on whether or not synthetic or auto generated create methods should be allowed.
222     *
223     * @param classifier the entity or session EJB.
224     * @return true/false
225     */
226    static boolean allowSyntheticCreateMethod(ClassifierFacade classifier)
227    {
228        ExceptionUtils.checkNull("classifer", classifier);
229        return !classifier.isAbstract() && classifier.findTaggedValue(
230                EJBProfile.TAGGEDVALUE_EJB_NO_SYNTHETIC_CREATE_METHOD) == null;
231    }
232
233}