View Javadoc

1   package org.andromda.core.simpleuml;
2   
3   import java.io.IOException;
4   import java.util.Collection;
5   import java.util.Iterator;
6   import java.util.Vector;
7   
8   import org.andromda.core.common.HTMLAnalyzer;
9   import org.andromda.core.common.StringUtilsHelper;
10  import org.andromda.core.uml14.UMLStaticHelper;
11  import org.omg.uml.foundation.core.AssociationEnd;
12  import org.omg.uml.foundation.core.Attribute;
13  import org.omg.uml.foundation.core.Classifier;
14  import org.omg.uml.foundation.core.Operation;
15  import org.omg.uml.foundation.core.Parameter;
16  import org.omg.uml.foundation.datatypes.ParameterDirectionKindEnum;
17  
18  /***
19   * This script helper simulates the old-style UML2EJB SimpleOO based
20   * script helper, and is provided mostly for backward compatability
21   * with the UML2EJB code generation scripts - it would be nice to 
22   * deprecate it at some point, but at present there is no plan to do so.
23   *
24   * @author <A HREF="http://www.amowers.com">Anthony Mowers</A>
25   */
26  public class SimpleOOHelper extends UMLStaticHelper
27  {
28      private final static String PRIMARY_KEY = "PrimaryKey";
29      private final static String ENTITY_BEAN = "Entity";
30  
31      public Object getModel()
32      {
33          return PModel.newInstance(this, this.model);
34      }
35  
36      public Collection getModelElements()
37      {
38          Collection elements = new Vector();
39          for (Iterator i = super.getModelElements().iterator();
40              i.hasNext();
41              )
42          {
43              Object o = i.next();
44              if (o instanceof Classifier)
45              {
46                  o = PClassifier.newInstance(this, (Classifier) o);
47              }
48              elements.add(o);
49          }
50  
51          return elements;
52      }
53  
54      public org
55          .andromda
56          .core
57          .uml14
58          .DirectionalAssociationEnd getAssociationData(
59          Object object)
60      {
61          if ((object == null) || !(object instanceof AssociationEnd))
62          {
63              return null;
64          }
65  
66          AssociationEnd ae = (AssociationEnd) object;
67  
68          return new DirectionalAssociationEnd(this, ae);
69      }
70  
71      /***
72       * <p>Formats an HTML String as a collection of paragraphs.
73       * Each paragraph has a getLines() method that returns a collection
74       * of Strings.</p>
75       * 
76       * @param string the String to be formatted
77       * @return Collection the collection of paragraphs found.
78       */
79      public Collection formatHTMLStringAsParagraphs(String string)
80      {
81          try
82          {
83              return new HTMLAnalyzer().htmlToParagraphs(string);
84          }
85          catch (IOException e)
86          {
87              e.printStackTrace();
88              return null;
89          }
90      }
91  
92      /***
93       *  Gets the primaryKeyAttribute attribute of the UMLScriptHelper object
94       *
95       *@param  object  Description of the Parameter
96       *@return         The primaryKeyAttribute value
97       */
98      public Attribute getPrimaryKeyAttribute(Object object)
99      {
100         Collection attributes = getAttributes(object);
101         for (Iterator i = attributes.iterator(); i.hasNext();)
102         {
103             Object attribute = i.next();
104             if (getStereotypeNames(attribute).contains(PRIMARY_KEY))
105             {
106                 return (Attribute) attribute;
107             }
108         }
109 
110         return null;
111     }
112 
113     /***
114      * Returns a string indicating whether the Bean is
115      * a local or remotely accessable bean.
116      * 
117      * @param object Bean class
118      * @return String 'local' or 'remote'
119      */
120     public String getEjbRefViewType(Object object)
121     {
122         if (ENTITY_BEAN.equals(getStereotype(object)))
123         {
124             return "local";
125         }
126 
127         return "remote";
128     }
129 
130     /***
131      * Returns a string representing the name of the
132      * home interface for the Bean.
133      *
134      *@param  object bean class
135      *@return string homeInterfaceName 
136      */
137     public String getHomeInterfaceName(Object object)
138     {
139         if (getStereotypeNames(object).contains(ENTITY_BEAN))
140         {
141             return getName(object) + "LocalHome";
142         }
143 
144         return getName(object) + "Home";
145     }
146 
147     /***
148      * Returns a string representing the component name
149      * for the Bean. It does not append the 'local' suffix 
150      * any more (deprecated).
151      *
152      * @param object
153      * @return String
154      */
155     public String getComponentInterfaceName(Object object)
156     {
157         return getName(object);
158     }
159 
160     /***
161      * Returns a list of attributes for a class. The list is
162      * useful for generating method signatures for constructors and/or
163      * generating code for calling such a constructor
164      * 
165      * @param object class object
166      * @param withTypeNames should attribute types appear in the list
167      * @param includePK should primary key be included in the list
168      * @return String representation of attribute list
169      */
170     public String getAttributesAsList(
171         Object object,
172         boolean withTypeNames,
173         boolean includePK)
174     {
175         StringBuffer sb = new StringBuffer();
176         String separator = "";
177         sb.append("(");
178 
179         for (Iterator it = getAttributes(object).iterator(); it.hasNext();)
180         {
181             Attribute a = (Attribute) it.next();
182 
183             // check if attribute is the PK of this class
184             // and include it only if includePK is true.
185             if (includePK || !getStereotypeNames(a).contains(PRIMARY_KEY))
186             {
187                 sb.append(separator);
188                 if (withTypeNames)
189                 {
190                     String typeName = findFullyQualifiedName(a.getType());
191                     sb.append(typeName);
192                     sb.append(" ");
193                     sb.append(a.getName());
194                 }
195                 else
196                 {
197                     sb.append("get");
198                     sb.append(
199                         StringUtilsHelper.upperCaseFirstLetter(
200                             a.getName()));
201                     sb.append("()");
202                 }
203                 separator = ", ";
204             }
205         }
206         sb.append(")");
207         return sb.toString();
208     }
209 
210     /***
211      * <p>Builds a call to the operation with a list of parameters.
212      * that can easily be used from the Velocity script.</p>
213      * 
214      * <p>This is good to generate business delegates.
215      * See feature request #638931.</p>
216      *
217      * @param o the operation
218      * @return String the complete call to the operation
219      */
220     public String getOperationCall(Object object)
221     {
222         if ((object == null) || !(object instanceof Operation))
223         {
224             return null;
225         }
226         Operation o = (Operation) object;
227 
228         StringBuffer sb = new StringBuffer();
229         sb.append(o.getName());
230         sb.append("(");
231         sb.append(getOperationParameterNames(o));
232         sb.append(")");
233 
234         return sb.toString();
235     }
236 
237     /***
238      * Builds a comma-separated list of parameter names of an operation.
239      * 
240      * @param o the operation
241      * @return String the list of parameter names
242      */
243     public String getOperationParameterNames(Operation o)
244     {
245         StringBuffer sb = new StringBuffer();
246         
247         Iterator it = o.getParameter().iterator();
248         
249         boolean commaNeeded = false;
250         while (it.hasNext())
251         {
252             Parameter p = (Parameter) it.next();
253         
254             if (!ParameterDirectionKindEnum.PDK_RETURN.equals(p.getKind()))
255             {
256                 if (commaNeeded)
257                 {
258                     sb.append(", ");
259                 }
260                 sb.append(p.getName());
261                 commaNeeded = true;
262             }
263         }
264         return sb.toString();
265     }
266 
267     /***
268      * returns a string representation for the Java signature for
269      * a given operation. Note: The return type is not included (any more)!
270      * 
271      * @param model element representing the operation
272      * @return String representation of the operation signature
273      */
274     public String getOperationSignature(Object object)
275     {
276         if ((object == null) || !(object instanceof Operation))
277         {
278             return null;
279         }
280 
281         Operation o = (Operation) object;
282         Iterator it = o.getParameter().iterator();
283         if (!it.hasNext())
284         {
285             return o.getName() + "()";
286         }
287 
288         StringBuffer sb = new StringBuffer(); 
289         sb.append(o.getName());
290         sb.append("(");
291         sb.append(getOperationTypedParameterList(o));
292         sb.append(")");
293 
294         return sb.toString();
295     }
296 
297 
298     /***
299      * Builds a comma-separated parameter list 
300      * (type and name of each parameter) of an operation.
301      *
302      * @param o the operation
303      * @return String the parameter list
304      */
305     public String getOperationTypedParameterList(Operation o)
306     {
307         StringBuffer sb = new StringBuffer(); 
308         Iterator it = o.getParameter().iterator();
309         
310         boolean commaNeeded = false;
311         while (it.hasNext())
312         {
313             Parameter p = (Parameter) it.next();
314         
315             if (!ParameterDirectionKindEnum.PDK_RETURN.equals(p.getKind()))
316             {
317                 String type;
318                 if (p.getType() == null)
319                 {
320                     type = "int";
321                 }
322                 else
323                 {
324                     type = getFullyQualifiedName(p.getType());
325                 }
326         
327                 if (commaNeeded)
328                 {
329                     sb.append(", ");
330                 }
331                 sb.append(type);
332                 sb.append(" ");
333                 sb.append(p.getName());
334                 commaNeeded = true;
335             }
336         }
337         return sb.toString();
338     }
339 
340     /***
341      * Provided only for backward compatability with old velocity scripts.
342      * In truth all model elements can be assigned more than one stereotype.
343      * 
344      * @param object
345      * @return String
346      */
347     public String getStereotype(Object object)
348     {
349         Iterator i = getStereotypeNames(object).iterator();
350 
351         if (i.hasNext())
352         {
353             String stereotype = (String) i.next();
354 
355             return stereotype;
356         }
357 
358         return "";
359 
360     }
361 
362     /***
363      * Returns the fully qualified name of the given
364      * model element.  The fully qualified name includes
365      * complete package qualified name of the model element.
366      * 
367      * @param object model element
368      * @return String fully qualified name
369      */
370     public String findFullyQualifiedName(Object object)
371     {
372         return getFullyQualifiedName(object);
373     }
374 
375     /***
376      * <p>Returns the JDBC type for an attribute.  It gets the type
377      * from the tag <code>andromda.persistence.JDBCType</code> for this.
378      * </p>
379      *
380      * @param attribute the attribute
381      * @return String the string to be used with JDBC
382      */
383     public String findAttributeJDBCType(Attribute attribute)
384     {
385         if (attribute == null)
386             return null;
387 
388         String value = findTagValue(attribute, "andromda.persistence.JDBCType", true);
389 
390         if (null == value)
391         {
392             Object type = attribute.getType();
393             value = findFullyQualifiedName(type);
394             if (typeMappings != null)
395             {
396                 value = typeMappings.getJDBCType(value);
397             }
398         }
399 
400         return value;
401     }
402 
403     /***
404     * <p>Returns the length for the SQL type of an attribute.  It
405     * gets the length from the tag
406     * <code>andromda.persistence.SQLFieldLength</code>.  This might return "50"
407     * for a VARCHAR field or "12,2" for a DECIMAL field.</p>
408     *
409     * @param attribute the attribute
410     * @return String the length of the underlying SQL field
411     */
412     public String findAttributeSQLFieldLength(Attribute attribute)
413     {
414         String value = findTagValue(attribute, "andromda.persistence.SQLFieldLength", true);
415         return value;
416     }
417 
418     /***
419      * <p>Returns the SQL type for an attribute.  Normally it gets the
420      * type from the tag <code>andromda.persistence.SQLType</code>.  If this tag
421      * doesn't exist, it uses {@link #findAttributeSQLFieldLength(Attribute)
422      * findAttributeSQLFieldLength()} and combines it's result with the standard
423      * SQL type for the attributes type from the type mapping configuration
424      * file.</p>
425      *
426      * @param attribute the attribute
427      * @return String the string to be used as SQL type
428      */
429     public String findAttributeSQLType(Attribute attribute)
430     {
431         String value = findTagValue(attribute, "andromda.persistence.SQLType", true);
432 
433         if (null == value)
434         {
435             Object type = attribute.getType();
436             String typeName = findFullyQualifiedName(type);
437             value = this.typeMappings.getSQLType(typeName, findAttributeSQLFieldLength(attribute));
438         }
439         return value;
440     }
441 
442     /***
443     * Returns the name of the package that contains the
444     * given model element.
445     *
446     *@param  object  model element
447     *@return  fully qualified name of the package
448     */
449     public String findPackageName(Object object)
450     {
451         return getPackageName(object);
452     }
453 
454     /***
455      * Provided only for backward compatability with 
456      * UML2EJB code generation scripts.  It does nothing
457      * in this implementation except return the object that is passed
458      * into it.
459      * 
460      * @param object
461      * @return Object
462      */
463     public Object findClassById(Object object)
464     {
465         if (object instanceof Classifier)
466         {
467             return object;
468         }
469 
470         return null;
471     }
472 
473     /***
474      * Provided only for backward compatability with UML2EJB
475      * code generation scripts.   It does not except
476      * return the object that it was passed in.
477      * 
478      * @param object a model element
479      * @return the model element that was passed
480      */
481     public Object convertToType(Object object)
482     {
483         return object;
484     }
485 
486 }