001package org.andromda.cartridges.ejb3;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.StringTokenizer;
006import org.andromda.cartridges.ejb3.metafacades.EJB3AssociationEndFacade;
007import org.andromda.cartridges.ejb3.metafacades.EJB3EntityAttributeFacade;
008import org.andromda.metafacades.uml.ModelElementFacade;
009import org.apache.commons.collections.CollectionUtils;
010import org.apache.commons.collections.Predicate;
011import org.apache.commons.lang.StringUtils;
012
013/**
014 * Transform class for the EJB3 cartridge.
015 *
016 * @author Richard Kunze
017 * @author Chad Brandon
018 * @author Vance Karimi
019 * @author Michail Plushnikov
020 */
021public class EJB3ScriptHelper
022{
023    /**
024     * Create a collection of String objects representing the argument names.
025     *
026     * @param args A comma separated list of arguments
027     * @return Collection A collection of of Strings representing the arguments
028     */
029    public Collection<String> getArgumentsAsList(final String args)
030    {
031        StringTokenizer st = new StringTokenizer(args, ",");
032        Collection<String> retval = new ArrayList<String>(st.countTokens());
033        while (st.hasMoreTokens())
034        {
035            retval.add(st.nextToken().trim());
036        }
037        return retval;
038    }
039
040    /**
041     * Filter a list of model elements by visibility.
042     *
043     * @param list       the original list
044     * @param visibility the visibility - "public" "protected", "private" or the empty string (for package visibility)
045     * @return a list with all elements from the original list that have a matching visibility.
046     */
047    public Collection<ModelElementFacade> filterByVisibility(final Collection<ModelElementFacade> list, final String visibility)
048    {
049        return CollectionUtils.select(list, new Predicate()
050        {
051            public boolean evaluate(final Object pObj)
052            {
053                ModelElementFacade elem = (ModelElementFacade )pObj;
054                return visibility.equals(elem.getVisibility());
055            }
056        });
057    }
058
059    /**
060     * Filter a list of EntityAttributes by removing all non-updatable attributes.
061     * This filter currently removes all attributes that are of stereotype Version
062     * It also removes identifier attributes for an entity with a composite primary key class
063     * or if the identifier attribute has a specified generator.
064     *
065     * @param list The original list
066     * @param isCompositePKPresent True if entity has a composite primary key
067     * @return Collection A list of EntityAttributes from the original list that are updatable
068     */
069    public Collection<EJB3EntityAttributeFacade> filterUpdatableAttributes(final Collection<EJB3EntityAttributeFacade> list, final boolean isCompositePKPresent)
070    {
071        return CollectionUtils.select(list, new Predicate()
072        {
073            public boolean evaluate(final Object pObj)
074            {
075                if (pObj instanceof EJB3EntityAttributeFacade)
076                {
077                    EJB3EntityAttributeFacade attr = (EJB3EntityAttributeFacade)pObj;
078                    return !attr.isVersion() &&
079                        ((isCompositePKPresent && !attr.isIdentifier()) ||
080                        (!isCompositePKPresent && (attr.isIdentifier() && attr.isGeneratorTypeNone()) ||
081                         !attr.isIdentifier()));
082                }
083                else
084                {
085                    System.out.println("NOT EJB3EntityAttributeFacade: " + pObj);
086                    return false;
087                }
088            }
089        });
090    }
091
092    /**
093     * Filter a list of EntityAttributes by removing all audit attributes.
094     * This filter currently removes all attributes that are of stereotype Version
095     * It also removes identifier attributes for an entity with a composite primary key class
096     * or if the identifier attribute have a specified generator.
097     *
098     * @param list The original list
099     * @param jpaFramework If using a JPA auditing framework. Filter none if not using it.
100     * @return Collection A list of EntityAttributes from the original list that are updatable
101     */
102    public Collection<EJB3EntityAttributeFacade> filterAuditAttributes(final Collection<EJB3EntityAttributeFacade> list, final boolean jpaFramework)
103    {
104        return CollectionUtils.select(list, new Predicate()
105        {
106            public boolean evaluate(final Object pObj)
107            {
108                // returns true if attribute should not be filtered out
109                if (pObj instanceof EJB3EntityAttributeFacade)
110                {
111                    EJB3EntityAttributeFacade attr = (EJB3EntityAttributeFacade)pObj;
112                    /*System.out.println(attr.getOwner().getName() + " jpa=" + jpaFramework + " attr=" + attr.getName()
113                        + " return=" + (!jpaFramework || !(attr.getName().equals("createDate")
114                                || attr.getName().equals("createdBy") || attr.getName().equals("updateDate")
115                                || attr.getName().equals("updatedBy"))));*/
116                    return (!jpaFramework || !(attr.getName().equals("createDate")
117                        || attr.getName().equals("createdBy") || attr.getName().equals("updateDate")
118                        || attr.getName().equals("updatedBy")));
119                }
120                else
121                {
122                    //System.out.println("NOT EJB3EntityAttributeFacade: " + pObj);
123                    return false;
124                }
125            }
126        });
127    }
128
129    /**
130     * Filter a list of EntityAttributes by removing all non-required attributes.
131     * This filter currently removes all attributes that are of stereotype Version
132     * It also removes identifier attributes for an entity with a composite primary key class
133     * or if the identifier attribute have a specified generator.
134     *
135     * @param list The original list
136     * @param isCompositePKPresent True if entity has a composite primary key
137     * @return Collection A list of EntityAttributes from the original list that are updatable
138     */
139    public Collection<EJB3EntityAttributeFacade> filterRequiredAttributes(final Collection<EJB3EntityAttributeFacade> list, final boolean isCompositePKPresent)
140    {
141        return CollectionUtils.select(list, new Predicate()
142        {
143            public boolean evaluate(final Object pObj)
144            {
145                if (pObj instanceof EJB3EntityAttributeFacade)
146                {
147                    // Wrapped primitive may be set to column nullable = false to override nullable datatype
148                    EJB3EntityAttributeFacade attr = (EJB3EntityAttributeFacade)pObj;
149                    return !attr.isVersion() && !attr.isColumnNullable() &&
150                        (!attr.isIdentifier() || (!isCompositePKPresent &&
151                           attr.isGeneratorTypeNone())
152                        /*((isCompositePKPresent && !attr.isIdentifier()) ||
153                        (!isCompositePKPresent && (!attr.isIdentifier() ||
154                            (attr.isGeneratorTypeNone()))*/
155                        );
156                }
157                else
158                {
159                    System.out.println("NOT EJB3EntityAttributeFacade: " + pObj);
160                    return false;
161                }
162            }
163        });
164    }
165
166    /**
167     * Filter a list of EntityAssociationEnds by removing all non-required AssociationEnds.
168     * It also removes identifier AssociationEnds for an entity with a composite primary key class
169     *
170     * @param list The original list
171     * @param isCompositePKPresent True if entity has a composite primary key
172     * @return Collection A list of EntityAssociationEnds from the original list that are updatable
173     */
174    public Collection<EJB3AssociationEndFacade> filterRequiredAssociations(final Collection<EJB3AssociationEndFacade> list, final boolean isCompositePKPresent)
175    {
176        return CollectionUtils.select(list, new Predicate()
177        {
178            public boolean evaluate(final Object pObj)
179            {
180                if (pObj instanceof EJB3AssociationEndFacade)
181                {
182                    EJB3AssociationEndFacade assoc = (EJB3AssociationEndFacade)pObj;
183                    return assoc.getOtherEnd().isRequired() || assoc.isIdentifier();
184                    /*return attr.isRequired() &&
185                        ((isCompositePKPresent && !attr.isIdentifier()) ||
186                        (!isCompositePKPresent && (!attr.isIdentifier() ||
187                            (attr.isIdentifier()))
188                        ));*/
189                }
190                else
191                {
192                    System.out.println("NOT EJB3AssociationEndFacade: " + pObj);
193                    return false;
194                }
195            }
196        });
197    }
198
199    /**
200     * Replaces all instances of the dot (.) in the name argument with an underscore (_)
201     * and returns the string response.
202     *
203     * @param name The name, typically a fully qualified name with dot notation
204     * @return The string with all dots replaced with underscore.
205     */
206    public String toUnderscoreName(final String name)
207    {
208        return StringUtils.replaceChars(name, '.', '_');
209    }
210
211    private static final String BACKSLASH = "\"";
212    private static final String QUOTE = "'";
213    /**
214     * Removes instances of the quotation marks (" and ') at the beginning and end of the value argument
215     *
216     * @param pValue The value, which can contains leading and trailing quotation marks
217     * @return The string without quotation marks
218     */
219    public String removeQuotationmarks(final String pValue)
220    {
221        String result = StringUtils.removeStart(pValue, BACKSLASH);
222        result = StringUtils.removeEnd(result, BACKSLASH);
223        result = StringUtils.removeStart(result, QUOTE);
224        return StringUtils.removeEnd(result, QUOTE);
225    }
226
227    private static final String COMMA = ", ";
228    /**
229     * Returns the comma separated list of interceptor classes.
230     *
231     * @param interceptors The collection ModelElementFacade elements representing the interceptors
232     * @param prepend Prefix any interceptors to the comma separated list
233     * @return String containing the comma separated fully qualified class names
234     */
235    public String getInterceptorsAsList(final Collection<ModelElementFacade> interceptors, final String prepend)
236    {
237        StringBuilder sb = new StringBuilder();
238        String separator = "";
239
240        if (StringUtils.isNotBlank(prepend))
241        {
242            sb.append(prepend);
243            separator = COMMA;
244        }
245
246        for (ModelElementFacade interceptor : interceptors)
247        {
248            sb.append(separator);
249            separator = COMMA;
250            sb.append(interceptor.getFullyQualifiedName()).append(".class");
251        }
252        return sb.toString();
253    }
254
255    /**
256     * Reverses the <code>packageName</code>.
257     *
258     * @param packageName the package name to reverse.
259     * @return the reversed package name.
260     */
261    public static String reversePackage(final String packageName)
262    {
263        return StringUtils.reverseDelimited(packageName, EJB3Globals.NAMESPACE_DELIMITER);
264    }
265}