View Javadoc
1   package org.andromda.cartridges.bpm4struts.metafacades;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.HashMap;
6   import java.util.Iterator;
7   import java.util.LinkedHashMap;
8   import java.util.LinkedHashSet;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Set;
12  import org.andromda.cartridges.bpm4struts.Bpm4StrutsGlobals;
13  import org.andromda.metafacades.uml.ClassifierFacade;
14  import org.andromda.metafacades.uml.DependencyFacade;
15  import org.andromda.metafacades.uml.EventFacade;
16  import org.andromda.metafacades.uml.FrontEndActivityGraph;
17  import org.andromda.metafacades.uml.FrontEndControllerOperation;
18  import org.andromda.metafacades.uml.ModelElementFacade;
19  import org.andromda.metafacades.uml.OperationFacade;
20  import org.andromda.metafacades.uml.ParameterFacade;
21  import org.andromda.metafacades.uml.ServiceOperation;
22  import org.andromda.metafacades.uml.StateVertexFacade;
23  import org.andromda.utils.StringUtilsHelper;
24  
25  /**
26   * MetafacadeLogic implementation for org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperation.
27   *
28   * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperation
29   */
30  public class StrutsControllerOperationLogicImpl
31      extends StrutsControllerOperationLogic
32  {
33      private static final long serialVersionUID = 34L;
34      /**
35       * @param metaObject
36       * @param context
37       */
38      public StrutsControllerOperationLogicImpl(
39          Object metaObject,
40          String context)
41      {
42          super(metaObject, context);
43      }
44  
45      /**
46       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetInterfaceName()
47       */
48      protected String handleGetInterfaceName()
49      {
50          return StringUtilsHelper.upperCamelCaseName(getName()) + Bpm4StrutsGlobals.FORM_SUFFIX;
51      }
52  
53      /**
54       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetInterfacePackageName()
55       */
56      protected String handleGetInterfacePackageName()
57      {
58          return getOwner().getPackageName();
59      }
60  
61      /**
62       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetInterfaceType()
63       */
64      protected String handleGetInterfaceType()
65      {
66          return getInterfacePackageName() + '.' + getInterfaceName();
67      }
68  
69      /**
70       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetInterfaceFullPath()
71       */
72      protected String handleGetInterfaceFullPath()
73      {
74          return '/' + getInterfaceType().replace('.', '/');
75      }
76  
77      /**
78       * Overridden because StrutsAction does not extend FrontEndAction.
79       *
80       * @see org.andromda.metafacades.uml.FrontEndControllerOperation#getDeferringActions()
81       */
82      public java.util.List getDeferringActions()
83      {
84          final Collection deferringActions = new LinkedHashSet();
85  
86          final FrontEndActivityGraph graph = getActivityGraph();
87          if (graph != null)
88          {
89              final Collection actionStates = graph.getActionStates();
90              for (final Iterator actionStateIterator = actionStates.iterator(); actionStateIterator.hasNext();)
91              {
92                  final Object actionStateObject = actionStateIterator.next();
93                  if (actionStateObject instanceof StrutsActionState)
94                  {
95                      final StrutsActionState actionState = (StrutsActionState)actionStateObject;
96                      final Collection controllerCalls = actionState.getControllerCalls();
97                      for (final Iterator controllerCallIterator = controllerCalls.iterator();
98                           controllerCallIterator.hasNext();)
99                      {
100                         final OperationFacade operation = (OperationFacade)controllerCallIterator.next();
101                         if (this.equals(operation))
102                         {
103                             deferringActions.addAll(actionState.getContainerActions());
104                         }
105                     }
106                 }
107             }
108 
109             final Collection transitions = graph.getTransitions();
110             for (final Iterator transitionIterator = transitions.iterator(); transitionIterator.hasNext();)
111             {
112                 final StrutsForward transition = (StrutsForward)transitionIterator.next();
113                 final EventFacade event = transition.getTrigger();
114                 if (event instanceof StrutsTrigger)
115                 {
116                     final StrutsTrigger trigger = (StrutsTrigger)event;
117                     final FrontEndControllerOperation operation = trigger.getControllerCall();
118                     if (this.equals(operation))
119                     {
120                         // we have two types of controller calls: the ones in action states and the ones for decisions
121                         final StateVertexFacade source = transition.getSource();
122                         if (source instanceof StrutsActionState)
123                         {
124                             final StrutsActionState sourceActionState = (StrutsActionState)source;
125                             deferringActions.addAll(sourceActionState.getContainerActions());
126                         }
127 
128                         // test for decision
129                         final StateVertexFacade target = transition.getTarget();
130                         if (target instanceof StrutsPseudostate)
131                         {
132                             final StrutsPseudostate targetPseudoState = (StrutsPseudostate)target;
133                             if (targetPseudoState.isDecisionPoint())
134                             {
135                                 deferringActions.addAll(targetPseudoState.getContainerActions());
136                             }
137                         }
138                     }
139                 }
140             }
141         }
142         return new ArrayList(deferringActions);
143     }
144 
145     /**
146      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetController()
147      */
148     protected Object handleGetController()
149     {
150         final Object owner = getOwner();
151         return (owner instanceof StrutsController) ? owner : null;
152     }
153 
154     /**
155      * Overridden since StrutsAction does not extend FrontEndAction.
156      *
157      * @see org.andromda.metafacades.uml.FrontEndControllerOperation#getFormFields()
158      */
159     public List getFormFields()
160     {
161         final Map formFieldsMap = new LinkedHashMap();
162 
163         // for quick lookup we use a hashset for the argument names, we only consider parameters with a name
164         // which is also present in this set
165         final Set argumentNames = new LinkedHashSet();
166         final Collection arguments = this.getArguments();
167         for (final Iterator argumentIterator = arguments.iterator(); argumentIterator.hasNext();)
168         {
169             final ModelElementFacade element = (ModelElementFacade)argumentIterator.next();
170             argumentNames.add(element.getName());
171         }
172 
173         // get all actions deferring to this operation
174         final List deferringActions = this.getDeferringActions();
175         for (int i = 0; i < deferringActions.size(); i++)
176         {
177             final StrutsAction action = (StrutsAction)deferringActions.get(i);
178             // store the action parameters
179             final List actionFormFields = action.getActionFormFields();
180             for (int j = 0; j < actionFormFields.size(); j++)
181             {
182                 final ModelElementFacade parameter = (ModelElementFacade)actionFormFields.get(j);
183                 if (argumentNames.contains(parameter.getName()))
184                 {
185                     formFieldsMap.put(parameter.getName(), parameter);
186                 }
187             }
188             // get all forwards and overwrite when we find a table (or add when not yet present)
189             final List forwards = action.getActionForwards();
190             for (int j = 0; j < forwards.size(); j++)
191             {
192                 final StrutsForward forward = (StrutsForward)forwards.get(j);
193                 // only consider forwards directly entering a page
194                 if (forward.isEnteringPage())
195                 {
196                     final List pageVariables = forward.getForwardParameters();
197                     for (int k = 0; k < pageVariables.size(); k++)
198                     {
199                         final StrutsParameter pageVariable = (StrutsParameter)pageVariables.get(k);
200                         if (argumentNames.contains(pageVariable.getName()))
201                         {
202                             if (!formFieldsMap.containsKey(pageVariable.getName()) || pageVariable.isTable())
203                             {
204                                 formFieldsMap.put(pageVariable.getName(), pageVariable);
205                             }
206                         }
207                     }
208                 }
209             }
210         }
211 
212         // since all arguments need to be present we add those that haven't yet been stored in the map
213         for (final Iterator argumentIterator = arguments.iterator(); argumentIterator.hasNext();)
214         {
215             final StrutsParameter argument = (StrutsParameter)argumentIterator.next();
216             if (!formFieldsMap.containsKey(argument.getName()))
217             {
218                 formFieldsMap.put(argument.getName(), argument);
219             }
220         }
221 
222         return new ArrayList(formFieldsMap.values());
223     }
224 
225     /**
226      * Overridden because StrutsAction does not extend FrontEndAction
227      *
228      * @see org.andromda.metafacades.uml.FrontEndControllerOperation#isAllArgumentsHaveFormFields()
229      */
230     public boolean isAllArgumentsHaveFormFields()
231     {
232         final Collection<ParameterFacade> arguments = this.getArguments();
233         final Collection deferringActions = this.getDeferringActions();
234 
235         boolean allArgumentsHaveFormFields = true;
236         for (final Iterator iterator = arguments.iterator(); iterator.hasNext() && allArgumentsHaveFormFields;)
237         {
238             final ParameterFacade parameter = (ParameterFacade)iterator.next();
239             final String parameterName = parameter.getName();
240             final ClassifierFacade parameterType = parameter.getType();
241             final String parameterTypeName = parameterType != null ? parameterType.getFullyQualifiedName() : "";
242 
243             boolean actionMissingField = false;
244             for (final Iterator actionIterator = deferringActions.iterator();
245                 actionIterator.hasNext() && !actionMissingField;)
246             {
247                 final StrutsAction action = (StrutsAction)actionIterator.next();
248                 final Collection<StrutsParameter> actionFormFields = action.getActionFormFields();
249 
250                 boolean fieldPresent = false;
251                 for (final Iterator fieldIterator = actionFormFields.iterator();
252                     fieldIterator.hasNext() && !fieldPresent;)
253                 {
254                     final ParameterFacade field = (ParameterFacade)fieldIterator.next();
255                     final ClassifierFacade fieldType = field.getType();
256                     final String fieldTypeName = fieldType != null ? fieldType.getFullyQualifiedName() : "";
257                     if (parameterName.equals(field.getName()) && parameterTypeName.equals(fieldTypeName))
258                     {
259                         fieldPresent = true;
260                     }
261                 }
262                 actionMissingField = !fieldPresent;
263             }
264             allArgumentsHaveFormFields = !actionMissingField;
265         }
266         return allArgumentsHaveFormFields;
267     }
268 
269     /**
270      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleIsBackEndServiceOperationMatchingParameters()
271      */
272     protected boolean handleIsBackEndServiceOperationMatchingParameters()
273     {
274         boolean matches = true;
275 
276         final ServiceOperation serviceOperation = getBackEndServiceOperation();
277 
278         // cache this operation's parameters for easy lookup
279         final Map parameterMap = new HashMap();
280         final Collection<ParameterFacade> controllerParameters = getParameters();
281         for (final Iterator iterator = controllerParameters.iterator(); iterator.hasNext();)
282         {
283             final ParameterFacade parameter = (ParameterFacade)iterator.next();
284             parameterMap.put(parameter.getName(), parameter.getType());
285         }
286 
287         // make sure that any service parameter exists here too
288         final Collection<ParameterFacade> serviceParameters = serviceOperation.getParameters();
289         for (final Iterator iterator = serviceParameters.iterator(); iterator.hasNext() && matches;)
290         {
291             final ParameterFacade serviceParameter = (ParameterFacade)iterator.next();
292             final ClassifierFacade controllerParameterType = (ClassifierFacade)parameterMap.get(
293                 serviceParameter.getName());
294             matches = (controllerParameterType != null) && controllerParameterType.equals(serviceParameter.getType());
295         }
296 
297         return matches;
298     }
299 
300     /**
301      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleGetBackEndServiceOperation()
302      */
303     protected Object handleGetBackEndServiceOperation()
304     {
305         Object operation = null;
306 
307         final Collection<DependencyFacade> dependencies = getSourceDependencies();
308         for (final Iterator dependencyIterator = dependencies.iterator();
309              dependencyIterator.hasNext() && operation == null;)
310         {
311             final DependencyFacade dependency = (DependencyFacade)dependencyIterator.next();
312             final Object target = dependency.getTargetElement();
313             if (target instanceof ServiceOperation)
314             {
315                 operation = target;
316             }
317         }
318 
319         return operation;
320     }
321 
322     /**
323      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsControllerOperationLogic#handleIsCallingBackEnd()
324      */
325     protected boolean handleIsCallingBackEnd()
326     {
327         return getBackEndServiceOperation() != null;
328     }
329 }