View Javadoc
1   package org.andromda.metafacades.emf.uml22;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Iterator;
6   import java.util.LinkedHashMap;
7   import java.util.LinkedHashSet;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.Set;
11  import org.andromda.metafacades.uml.ActionStateFacade;
12  import org.andromda.metafacades.uml.ClassifierFacade;
13  import org.andromda.metafacades.uml.EventFacade;
14  import org.andromda.metafacades.uml.FrontEndAction;
15  import org.andromda.metafacades.uml.FrontEndActionState;
16  import org.andromda.metafacades.uml.FrontEndActivityGraph;
17  import org.andromda.metafacades.uml.FrontEndController;
18  import org.andromda.metafacades.uml.FrontEndControllerOperation;
19  import org.andromda.metafacades.uml.FrontEndEvent;
20  import org.andromda.metafacades.uml.FrontEndForward;
21  import org.andromda.metafacades.uml.FrontEndParameter;
22  import org.andromda.metafacades.uml.FrontEndPseudostate;
23  import org.andromda.metafacades.uml.FrontEndUseCase;
24  import org.andromda.metafacades.uml.ModelElementFacade;
25  import org.andromda.metafacades.uml.OperationFacade;
26  import org.andromda.metafacades.uml.ParameterFacade;
27  import org.andromda.metafacades.uml.StateVertexFacade;
28  import org.andromda.metafacades.uml.TransitionFacade;
29  
30  /**
31   * MetafacadeLogic implementation for
32   * org.andromda.metafacades.uml.FrontEndControllerOperation.
33   *
34   * @see org.andromda.metafacades.uml.FrontEndControllerOperation
35   */
36  public class FrontEndControllerOperationLogicImpl
37      extends FrontEndControllerOperationLogic
38  {
39      private static final long serialVersionUID = 34L;
40      /**
41       * @param metaObject
42       * @param context
43       */
44      public FrontEndControllerOperationLogicImpl(
45          final Object metaObject,
46          final String context)
47      {
48          super(metaObject, context);
49      }
50  
51      /**
52       * Override to return the owner's package as the package name.
53       *
54       * @see org.andromda.metafacades.emf.uml22.ModelElementFacadeLogic#handleGetPackageName()
55       */
56      @Override
57      public String handleGetPackageName()
58      {
59          final ClassifierFacade owner = this.getOwner();
60          return owner != null ? owner.getPackageName() : "";
61      }
62  
63      /**
64       * @see org.andromda.metafacades.uml.FrontEndControllerOperation#isOwnerIsController()
65       */
66      @Override
67      protected boolean handleIsOwnerIsController()
68      {
69          return this.getOwner() instanceof FrontEndController;
70      }
71  
72      /**
73       * @see org.andromda.metafacades.uml.FrontEndControllerOperation#getFormFields()
74       */
75      @Override
76      protected List<FrontEndParameter> handleGetFormFields()
77      {
78          final Map<String, FrontEndParameter> formFieldsMap = new LinkedHashMap<String, FrontEndParameter>();
79  
80          // for quick lookup we use a hashset for the argument names, we only
81          // consider parameters with a name
82          // which is also present in this set
83          final Set<String> argumentNames = new LinkedHashSet<String>();
84          final Collection<ParameterFacade> arguments = this.getArguments();
85          for (final Iterator<ParameterFacade> argumentIterator = arguments.iterator(); argumentIterator.hasNext();)
86          {
87              final ModelElementFacade element = (ModelElementFacade)argumentIterator.next();
88              argumentNames.add(element.getName());
89          }
90  
91          // - get all actions deferring to this operation
92          final List<FrontEndAction> deferringActions = this.getDeferringActions();
93          for (final Iterator<FrontEndAction> iterator = deferringActions.iterator(); iterator.hasNext();)
94          {
95              final FrontEndAction action = iterator.next();
96  
97              // store the action parameters
98              final List<FrontEndParameter> actionFormFields = action.getFormFields();
99              for (final Iterator<FrontEndParameter> fieldIterator = actionFormFields.iterator(); fieldIterator.hasNext();)
100             {
101                 final FrontEndParameter parameter = fieldIterator.next();
102                 final String name = parameter.getName();
103 
104                 // - only add if the parameter is an action parameter and its an
105                 // argument of this operation
106                 if (parameter.getAction() != null && argumentNames.contains(name))
107                 {
108                     formFieldsMap.put(
109                         name,
110                         parameter);
111                 }
112             }
113 
114             // get all forwards and overwrite when we find a table (or add when
115             // not yet present)
116             final List<FrontEndForward> forwards = action.getActionForwards();
117             for (final Iterator<FrontEndForward> forwardIterator = forwards.iterator(); forwardIterator.hasNext();)
118             {
119                 final FrontEndForward forward = forwardIterator.next();
120 
121                 // - only consider forwards directly entering a view
122                 if (forward.isEnteringView())
123                 {
124                     final List<FrontEndParameter> viewVariables = forward.getForwardParameters();
125                     for (final Iterator<FrontEndParameter> variableIterator = viewVariables.iterator(); variableIterator.hasNext();)
126                     {
127                         final FrontEndParameter viewVariable = variableIterator.next();
128                         final String name = viewVariable.getName();
129                         if (argumentNames.contains(name))
130                         {
131                             if (!formFieldsMap.containsKey(name) || viewVariable.isTable())
132                             {
133                                 formFieldsMap.put(
134                                     name,
135                                     viewVariable);
136                             }
137                         }
138                     }
139                 }
140             }
141         }
142 
143         // since all arguments need to be present we add those that haven't yet
144         // been stored in the map
145         for (ParameterFacade parameter : arguments)
146         {
147             final FrontEndParameter argument = (FrontEndParameter)parameter;
148             final String name = argument.getName();
149             if (!formFieldsMap.containsKey(name))
150             {
151                 formFieldsMap.put(
152                     name,
153                     argument);
154             }
155         }
156         return new ArrayList<FrontEndParameter>(formFieldsMap.values());
157     }
158 
159     /**
160      * @see org.andromda.metafacades.uml.FrontEndControllerOperation#getActivityGraph()
161      */
162     @Override
163     protected FrontEndActivityGraph handleGetActivityGraph()
164     {
165         FrontEndActivityGraph graph = null;
166 
167         final ClassifierFacade owner = this.getOwner();
168         if (owner instanceof FrontEndController)
169         {
170             final FrontEndController controller = (FrontEndController)owner;
171             final FrontEndUseCase useCase = controller.getUseCase();
172             if (useCase != null)
173             {
174                 graph = useCase.getActivityGraph();
175             }
176         }
177         return graph;
178     }
179 
180     /**
181      * @see org.andromda.metafacades.uml.FrontEndControllerOperation#getDeferringActions()
182      */
183     @Override
184     protected List<FrontEndAction> handleGetDeferringActions()
185     {
186         final Collection<FrontEndAction> deferringActions = new LinkedHashSet<FrontEndAction>();
187 
188         final FrontEndActivityGraph graph = this.getActivityGraph();
189         if (graph != null)
190         {
191             final Collection<ActionStateFacade> actionStates = graph.getActionStates();
192             for (final Iterator<ActionStateFacade> actionStateIterator = actionStates.iterator(); actionStateIterator.hasNext();)
193             {
194                 final Object actionStateObject = actionStateIterator.next();
195                 if (actionStateObject instanceof FrontEndActionState)
196                 {
197                     final FrontEndActionState actionState = (FrontEndActionState)actionStateObject;
198                     final Collection<OperationFacade> controllerCalls = actionState.getControllerCalls();
199                     for (final Iterator<OperationFacade> controllerCallIterator = controllerCalls.iterator();
200                         controllerCallIterator.hasNext();)
201                     {
202                         final OperationFacade operation = controllerCallIterator.next();
203                         if (this.equals(operation))
204                         {
205                             deferringActions.addAll(actionState.getContainerActions());
206                         }
207                     }
208                 }
209             }
210 
211             final Collection<TransitionFacade> transitions = graph.getTransitions();
212             for (final Iterator<TransitionFacade> transitionIterator = transitions.iterator(); transitionIterator.hasNext();)
213             {
214                 final FrontEndForward transition = (FrontEndForward)transitionIterator.next();
215                 final EventFacade event = transition.getTrigger();
216                 if (event instanceof FrontEndEvent)
217                 {
218                     final FrontEndEvent trigger = (FrontEndEvent)event;
219                     final FrontEndControllerOperation operation = trigger.getControllerCall();
220                     if (this.equals(operation))
221                     {
222                         // we have two types of controller calls: the ones in
223                         // action states and the ones for decisions
224                         final StateVertexFacade source = transition.getSource();
225                         if (source instanceof FrontEndActionState)
226                         {
227                             final FrontEndActionState sourceActionState = (FrontEndActionState)source;
228                             deferringActions.addAll(sourceActionState.getContainerActions());
229                         }
230 
231                         // test for decision
232                         final StateVertexFacade target = transition.getTarget();
233                         if (target instanceof FrontEndPseudostate)
234                         {
235                             final FrontEndPseudostate targetPseudoState = (FrontEndPseudostate)target;
236                             if (targetPseudoState.isDecisionPoint())
237                             {
238                                 deferringActions.addAll(targetPseudoState.getContainerActions());
239                             }
240                         }
241                     }
242                 }
243             }
244         }
245         return new ArrayList<FrontEndAction>(deferringActions);
246     }
247 
248     /**
249      * @see org.andromda.metafacades.uml.FrontEndControllerOperation#isAllArgumentsHaveFormFields()
250      */
251     @Override
252     protected boolean handleIsAllArgumentsHaveFormFields()
253     {
254         final Collection<ParameterFacade> arguments = this.getArguments();
255         final Collection<FrontEndAction> deferringActions = this.getDeferringActions();
256 
257         boolean allArgumentsHaveFormFields = true;
258         for (final Iterator<ParameterFacade> iterator = arguments.iterator(); iterator.hasNext() && allArgumentsHaveFormFields;)
259         {
260             final ParameterFacade parameter = iterator.next();
261             final String parameterName = parameter.getName();
262             final ClassifierFacade parameterType = parameter.getType();
263             final String parameterTypeName = parameterType != null ? parameterType.getFullyQualifiedName() : "";
264 
265             boolean actionMissingField = false;
266             for (final Iterator<FrontEndAction> actionIterator = deferringActions.iterator();
267                 actionIterator.hasNext() && !actionMissingField;)
268             {
269                 final FrontEndAction action = actionIterator.next();
270                 final Collection<FrontEndParameter> actionFormFields = action.getFormFields();
271 
272                 boolean fieldPresent = false;
273                 for (final Iterator fieldIterator = actionFormFields.iterator();
274                     fieldIterator.hasNext() && !fieldPresent;)
275                 {
276                     final ParameterFacade field = (ParameterFacade)fieldIterator.next();
277                     final ClassifierFacade fieldType = field.getType();
278                     final String fieldTypeName = fieldType != null ? fieldType.getFullyQualifiedName() : "";
279                     if (parameterName.equals(field.getName()) && parameterTypeName.equals(fieldTypeName))
280                     {
281                         fieldPresent = true;
282                     }
283                 }
284                 actionMissingField = !fieldPresent;
285             }
286             allArgumentsHaveFormFields = !actionMissingField;
287         }
288         return allArgumentsHaveFormFields;
289     }
290 }