View Javadoc
1   package org.andromda.cartridges.ejb.metafacades;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.Iterator;
7   import java.util.List;
8   import org.andromda.cartridges.ejb.EJBGlobals;
9   import org.andromda.cartridges.ejb.EJBProfile;
10  import org.andromda.core.common.ExceptionRecorder;
11  import org.andromda.metafacades.uml.AttributeFacade;
12  import org.andromda.metafacades.uml.ClassifierFacade;
13  import org.andromda.metafacades.uml.DependencyFacade;
14  import org.andromda.metafacades.uml.MetafacadeUtils;
15  import org.andromda.metafacades.uml.ModelElementFacade;
16  import org.andromda.metafacades.uml.OperationFacade;
17  import org.andromda.metafacades.uml.TypeMappings;
18  import org.andromda.metafacades.uml.UMLMetafacadeProperties;
19  import org.apache.commons.collections.CollectionUtils;
20  import org.apache.commons.collections.Predicate;
21  import org.apache.commons.lang.StringUtils;
22  import org.apache.log4j.Logger;
23  
24  /**
25   * <p>
26   * Represents an entity EJB. </p> Metaclass facade implementation.
27   * @author Bob Fields
28   */
29  public class EJBEntityFacadeLogicImpl
30      extends EJBEntityFacadeLogic
31  {
32      private static final long serialVersionUID = 34L;
33      // ---------------- constructor -------------------------------
34      /**
35       * @param metaObject
36       * @param context
37       */
38      public EJBEntityFacadeLogicImpl(
39          Object metaObject,
40          String context)
41      {
42          super(metaObject, context);
43      }
44  
45      /**
46       * The logger instance.
47       */
48      private static final Logger logger = Logger.getLogger(EJBEntityFacadeLogicImpl.class);
49  
50      /**
51       * @return identifiers
52       */
53      public Collection handleGetIdentifiers()
54      {
55          Collection identifiers = new ArrayList();
56          Iterator iter = this.getSourceDependencies().iterator();
57          while (iter.hasNext())
58          {
59              DependencyFacade dep = (DependencyFacade)iter.next();
60              if (dep.hasStereotype(EJBProfile.STEREOTYPE_IDENTIFIER))
61              {
62                  identifiers = ((ClassifierFacade)dep.getTargetElement()).getInstanceAttributes();
63                  MetafacadeUtils.filterByStereotype(
64                      identifiers,
65                      EJBProfile.STEREOTYPE_IDENTIFIER);
66                  return identifiers;
67              }
68          }
69  
70          // No PK dependency found - try a PK attribute
71          if (super.getIdentifiers() != null && !super.getIdentifiers().isEmpty())
72          {
73              AttributeFacade attr = (AttributeFacade)super.getIdentifiers().iterator().next();
74              identifiers.add(attr);
75              return identifiers;
76          }
77  
78          // Still nothing found - recurse up the inheritance tree
79          EJBEntityFacade decorator = (EJBEntityFacade)this.getGeneralization();
80          return decorator.getIdentifiers();
81      }
82  
83      /**
84       * @return getEntityRelations()
85       * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getAllEntityRelations()
86       */
87      protected Collection handleGetAllEntityRelations()
88      {
89          // Only concrete entities may have EJB relations. Return
90          // an empty collection for everything else
91          if (this.isAbstract())
92          {
93              return Collections.emptyList();
94          }
95          Collection result = new ArrayList();
96          result.addAll(getEntityRelations());
97          ClassifierFacade classifier = (ClassifierFacade)this.getGeneralization();
98          while (classifier != null && classifier instanceof EJBEntityFacade && classifier.isAbstract())
99          {
100             EJBEntityFacade entity = (EJBEntityFacade)classifier;
101             result.addAll(entity.getEntityRelations());
102             classifier = (ClassifierFacade)classifier.getGeneralization();
103         }
104         return result;
105     }
106 
107     /**
108      * @return EJBMetafacadeUtils.getViewType(this)
109      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getViewType()
110      */
111     protected String handleGetViewType()
112     {
113         return EJBMetafacadeUtils.getViewType(this);
114     }
115 
116     /**
117      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetEntityRelations()
118      */
119     protected Collection handleGetEntityRelations()
120     {
121         Collection result = new ArrayList();
122         for (final Iterator iterator = this.getAssociationEnds().iterator(); iterator.hasNext();)
123         {
124             EJBAssociationEndFacade associationEnd = (EJBAssociationEndFacade)iterator.next();
125             ClassifierFacade target = associationEnd.getOtherEnd().getType();
126             if (target instanceof EJBEntityFacade && associationEnd.getOtherEnd().isNavigable())
127             {
128                 // Check the integrity constraint
129                 Object value =
130                     associationEnd.getOtherEnd().getAssociation().findTaggedValue(EJBProfile.TAGGEDVALUE_GENERATE_CMR);
131                 String generateCmr = value == null ? null : value.toString();
132                 if (target.isAbstract() && !"false".equalsIgnoreCase(generateCmr))
133                 {
134                     throw new IllegalStateException("Relation '" + associationEnd.getAssociation().getName() +
135                         "' has the abstract target '" + target.getName() +
136                         "'. Abstract targets are not allowed in EJB.");
137                 }
138                 result.add(associationEnd);
139             }
140         }
141 
142         return result;
143     }
144 
145     /**
146      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetAllInstanceAttributes()
147      */
148     protected List handleGetAllInstanceAttributes()
149     {
150         return EJBMetafacadeUtils.getAllInstanceAttributes(this);
151     }
152 
153     /**
154      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetInheritedInstanceAttributes()
155      */
156     protected List handleGetInheritedInstanceAttributes()
157     {
158         return EJBMetafacadeUtils.getInheritedInstanceAttributes(this);
159     }
160 
161     /**
162      * @param follow
163      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetCreateMethods(boolean)
164      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getCreateMethods(boolean)
165      */
166     protected Collection handleGetCreateMethods(boolean follow)
167     {
168         return EJBMetafacadeUtils.getCreateMethods(
169             this,
170             follow);
171     }
172 
173     /**
174      * @param follow
175      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetSelectMethods(boolean)
176      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getSelectMethods(boolean)
177      */
178     protected Collection handleGetSelectMethods(boolean follow)
179     {
180         Collection retval = new ArrayList();
181         EJBEntityFacade entity = null;
182         do
183         {
184             Collection ops = this.getOperations();
185             for (final Iterator i = ops.iterator(); i.hasNext();)
186             {
187                 OperationFacade op = (OperationFacade)i.next();
188                 if (op.hasStereotype(EJBProfile.STEREOTYPE_SELECT_METHOD))
189                 {
190                     retval.add(op);
191                 }
192             }
193             if (follow)
194             {
195                 entity = (EJBEntityFacade)this.getGeneralization();
196             }
197             else
198             {
199                 break;
200             }
201         }
202         while (entity != null);
203         return retval;
204     }
205 
206     /**
207      * @return getHomeInterfaceName
208      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getHomeInterfaceName()
209      */
210     protected String handleGetHomeInterfaceName()
211     {
212         return EJBMetafacadeUtils.getHomeInterfaceName(this);
213     }
214 
215     /**
216      * @param follow
217      * @return getEnvironmentEntries
218      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getEnvironmentEntries(boolean)
219      */
220     protected Collection handleGetEnvironmentEntries(boolean follow)
221     {
222         return EJBMetafacadeUtils.getEnvironmentEntries(
223             this,
224             follow);
225     }
226 
227     /**
228      * @param follow
229      * @return getConstants
230      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getConstants(boolean)
231      */
232     protected Collection handleGetConstants(boolean follow)
233     {
234         return EJBMetafacadeUtils.getConstants(
235             this,
236             follow);
237     }
238 
239     /**
240      * @return jndiName
241      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacade#getJndiName()
242      */
243     protected String handleGetJndiName()
244     {
245         StringBuilder jndiName = new StringBuilder();
246         String jndiNamePrefix = StringUtils.trimToEmpty(this.getJndiNamePrefix());
247         if (StringUtils.isNotBlank(jndiNamePrefix))
248         {
249             jndiName.append(jndiNamePrefix);
250             jndiName.append('/');
251         }
252         jndiName.append("ejb/");
253         jndiName.append(this.getFullyQualifiedName());
254         return jndiName.toString();
255     }
256 
257     /**
258      * Gets the <code>jndiNamePrefix</code> for this EJB.
259      *
260      * @return the EJB Jndi name prefix.
261      */
262     protected String getJndiNamePrefix()
263     {
264         String prefix = null;
265         if (this.isConfiguredProperty(EJBGlobals.JNDI_NAME_PREFIX))
266         {
267             prefix = (String)this.getConfiguredProperty(EJBGlobals.JNDI_NAME_PREFIX);
268         }
269         return prefix;
270     }
271 
272     /**
273      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsSyntheticCreateMethodAllowed()
274      */
275     protected boolean handleIsSyntheticCreateMethodAllowed()
276     {
277         return EJBMetafacadeUtils.allowSyntheticCreateMethod(this);
278     }
279 
280     /**
281      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#getBusinessOperations()
282      */
283     // TODO: Change return type to Collection<EJBOperationFacade> (metamodel change)
284     public Collection<OperationFacade> getBusinessOperations()
285     {
286         Collection<OperationFacade> businessOperations = new ArrayList<OperationFacade>();
287         for (OperationFacade operation : super.getBusinessOperations())
288         {
289             if (EJBOperationFacade.class.isAssignableFrom(operation.getClass()))
290             {
291                 EJBOperationFacade businessOperation = (EJBOperationFacade)operation;
292                 if (businessOperation.isBusinessOperation())
293                 {
294                     businessOperations.add(businessOperation);
295                 }
296             }
297         }
298         return businessOperations;
299     }
300 
301     /**
302      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetValueDependencies()
303      */
304     protected Collection handleGetValueDependencies()
305     {
306         Collection dependencies = super.getSourceDependencies();
307         CollectionUtils.filter(
308             dependencies,
309             new Predicate()
310             {
311                 public boolean evaluate(Object object)
312                 {
313                     boolean isValueRef = false;
314                     if (object instanceof DependencyFacade)
315                     {
316                         DependencyFacade dep = (DependencyFacade)object;
317                         isValueRef =
318                             dep.getStereotypeNames().contains(EJBProfile.STEREOTYPE_VALUE_REF) &&
319                             dep.getTargetElement().hasExactStereotype(EJBProfile.STEREOTYPE_VALUE_OBJECT);
320                     }
321                     return isValueRef;
322                 }
323             });
324         return dependencies;
325     }
326 
327     /**
328      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsIdentifierPresent(String)
329      */
330     protected boolean handleIsIdentifierPresent(String identifier)
331     {
332         for (ModelElementFacade attr : this.getIdentifiers(true))
333         {
334             if (attr.getName().equalsIgnoreCase(identifier))
335             {
336                 return true;
337             }
338         }
339         return false;
340     }
341 
342     /**
343      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsAttributePresent(String)
344      */
345     protected boolean handleIsAttributePresent(String strAttr)
346     {
347         Collection<AttributeFacade> collAttrib = this.getAttributes(true);
348         for (AttributeFacade attr : collAttrib)
349         {
350             if (attr.getName().equalsIgnoreCase(strAttr))
351             {
352                 return true;
353             }
354         }
355         return false;
356     }
357 
358     /**
359      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleIsOperationPresent(String)
360      */
361     protected boolean handleIsOperationPresent(String op)
362     {
363         Collection<OperationFacade> collOps = this.getOperations();
364         for (OperationFacade operation : collOps)
365         {
366             if (operation.getName().equalsIgnoreCase(op))
367             {
368                 return true;
369             }
370         }
371         return false;
372     }
373 
374     /**
375      * Gets a Mappings instance from a property registered under the given <code>propertyName</code>.
376      *
377      * @param propertyName the property name to register under.
378      * @return the Mappings instance.
379      */
380     private TypeMappings getMappingsProperty(final String propertyName)
381     {
382         Object property = this.getConfiguredProperty(propertyName);
383         TypeMappings mappings = null;
384         String uri = null;
385         if (property instanceof String)
386         {
387             uri = (String)property;
388             try
389             {
390                 mappings = TypeMappings.getInstance(uri);
391                 this.setProperty(
392                     propertyName,
393                     mappings);
394             }
395             catch (Throwable th)
396             {
397                 String errMsg = "Error getting '" + propertyName + "' --> '" + uri + '\'';
398                 logger.error(errMsg);
399                 // don't throw the exception
400                 ExceptionRecorder.instance().record(
401                     errMsg,
402                     th);
403             }
404         }
405         else
406         {
407             mappings = (TypeMappings)property;
408         }
409         return mappings;
410     }
411 
412     /**
413      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetSqlType()
414      */
415     protected String handleGetSqlType()
416     {
417         String mpSql = this.getMappingsProperty(UMLMetafacadeProperties.SQL_MAPPINGS_URI).getMappings().getName();
418         if (mpSql.startsWith("Oracle"))
419         {
420             mpSql = "ORACLE";
421         }
422         return mpSql;
423     }
424 
425     /**
426      * @see org.andromda.cartridges.ejb.metafacades.EJBEntityFacadeLogic#handleGetTransactionType()
427      */
428     protected String handleGetTransactionType()
429     {
430         String transactionType = (String)this.findTaggedValue(EJBProfile.TAGGEDVALUE_EJB_TRANSACTION_TYPE);
431         if (StringUtils.isBlank(transactionType))
432         {
433             transactionType = String.valueOf(this.getConfiguredProperty(EJBGlobals.TRANSACTION_TYPE));
434         }
435         return transactionType;
436     }
437 }