View Javadoc
1   package org.andromda.metafacades.uml14;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.LinkedHashSet;
7   import java.util.List;
8   import java.util.Set;
9   import org.andromda.metafacades.uml.EventFacade;
10  import org.andromda.metafacades.uml.FrontEndAction;
11  import org.andromda.metafacades.uml.FrontEndActionState;
12  import org.andromda.metafacades.uml.FrontEndActivityGraph;
13  import org.andromda.metafacades.uml.FrontEndControllerOperation;
14  import org.andromda.metafacades.uml.FrontEndEvent;
15  import org.andromda.metafacades.uml.FrontEndForward;
16  import org.andromda.metafacades.uml.FrontEndUseCase;
17  import org.andromda.metafacades.uml.FrontEndView;
18  import org.andromda.metafacades.uml.ParameterFacade;
19  import org.andromda.metafacades.uml.PseudostateFacade;
20  import org.andromda.metafacades.uml.StateVertexFacade;
21  import org.andromda.metafacades.uml.TransitionFacade;
22  import org.andromda.metafacades.uml.UseCaseFacade;
23  import org.andromda.utils.StringUtilsHelper;
24  
25  /**
26   * MetafacadeLogic implementation for org.andromda.metafacades.uml.FrontEndForward.
27   *
28   * @see org.andromda.metafacades.uml.FrontEndForward
29   * @author Bob Fields
30   */
31  public class FrontEndForwardLogicImpl
32      extends FrontEndForwardLogic
33  {
34      private static final long serialVersionUID = 34L;
35      /**
36       * @param metaObject
37       * @param context
38       */
39      public FrontEndForwardLogicImpl(
40          Object metaObject,
41          String context)
42      {
43          super(metaObject, context);
44      }
45  
46      /**
47       * @see org.andromda.metafacades.uml.FrontEndForward#isContainedInFrontEndUseCase()
48       */
49      @Override
50      protected boolean handleIsContainedInFrontEndUseCase()
51      {
52          return this.getFrontEndActivityGraph() != null;
53      }
54  
55      /**
56       * @see org.andromda.metafacades.uml.FrontEndForward#getFrontEndActivityGraph()
57       */
58      @Override
59      protected FrontEndActivityGraph handleGetFrontEndActivityGraph()
60      {
61          final Object graph = this.getSource().getStateMachine();
62          return (FrontEndActivityGraph)(graph instanceof FrontEndActivityGraph ? graph : null);
63      }
64  
65      /**
66       * If this forward has a trigger this method returns that trigger's name, otherwise if this forward
67       * has a name this method returns that name, otherwise if this forward's target has a name this
68       * method returns that name, otherwise simply returns <code>"unknown"</code>
69       *
70       * @see org.andromda.metafacades.uml14.ModelElementFacadeLogic#handleGetName()
71       */
72      protected final String handleGetName()
73      {
74          String forwardName = null;
75  
76          // - trigger
77          final EventFacade trigger = getTrigger();
78          if (trigger != null)
79          {
80              forwardName = trigger.getName();
81          }
82  
83          // - name
84          if (forwardName == null)
85          {
86              forwardName = super.handleGetName();
87          }
88  
89          // - target
90          if (forwardName == null)
91          {
92              forwardName = this.getTarget().getName();
93          }
94  
95          // - else
96          if (forwardName == null)
97          {
98              forwardName = "unknown";
99          }
100         return forwardName;
101     }
102 
103     /**
104      * @see org.andromda.metafacades.uml.FrontEndForward#getActionMethodName()
105      */
106     @Override
107     protected String handleGetActionMethodName()
108     {
109         return StringUtilsHelper.lowerCamelCaseName(this.getName());
110     }
111 
112     /**
113      * @see org.andromda.metafacades.uml.FrontEndForward#isEnteringView()
114      */
115     @Override
116     protected boolean handleIsEnteringView()
117     {
118         return this.getTarget() instanceof FrontEndView;
119     }
120 
121     /**
122      * @see org.andromda.metafacades.uml.FrontEndForward#isExitingView()
123      */
124     @Override
125     protected boolean handleIsExitingView()
126     {
127         return this.getSource() instanceof FrontEndView;
128     }
129 
130     /**
131      * @see org.andromda.metafacades.uml.FrontEndForward#getUseCase()
132      */
133     @Override
134     protected FrontEndUseCase handleGetUseCase()
135     {
136         FrontEndUseCase useCase = null;
137         final FrontEndActivityGraph graph = this.getFrontEndActivityGraph();
138         if (graph != null)
139         {
140             final UseCaseFacade graphUseCase = graph.getUseCase();
141             if (graphUseCase instanceof FrontEndUseCase)
142             {
143                 useCase = (FrontEndUseCase)graphUseCase;
144             }
145         }
146         return useCase;
147     }
148 
149     /**
150      * All action states that make up this action, this includes all possible action states traversed
151      * after a decision point too.
152      */
153     private Collection<FrontEndActionState> actionStates = null;
154 
155     /**
156      * @return new ArrayList(actionStates)
157      * @see org.andromda.metafacades.uml.FrontEndAction#getActionStates()
158      */
159     //@Override
160     protected List<FrontEndActionState> handleGetActionStates()
161     {
162         if (actionStates == null)
163         {
164             this.initializeCollections();
165         }
166         return new ArrayList<FrontEndActionState>(actionStates);
167     }
168 
169     /**
170      * Initializes all action states, action forwards, decision transitions and transitions in one shot, so that they
171      * can be queried more efficiently later on.
172      */
173     private void initializeCollections()
174     {
175         this.actionStates = new LinkedHashSet<FrontEndActionState>();
176         this.collectTransitions(
177             this,
178             new LinkedHashSet<TransitionFacade>());
179     }
180 
181     /**
182      * Recursively collects all action states, action forwards, decision transitions and transitions.
183      *
184      * @param transition the current transition that is being processed
185      * @param processedTransitions the set of transitions already processed
186      */
187     private void collectTransitions(
188         final TransitionFacade transition,
189         final Collection<TransitionFacade> processedTransitions)
190     {
191         if (processedTransitions.contains(transition))
192         {
193             return;
194         }
195         processedTransitions.add(transition);
196 
197         final StateVertexFacade target = transition.getTarget();
198         if (target instanceof FrontEndActionState)
199         {
200             this.actionStates.add((FrontEndActionState)target);
201             final FrontEndForward forward = ((FrontEndActionState)target).getForward();
202             if (forward != null)
203             {
204                 collectTransitions(
205                     forward,
206                     processedTransitions);
207             }
208         }
209     }
210 
211     /**
212      * @see org.andromda.metafacades.uml.FrontEndAction#getDecisionTrigger()
213      */
214     @Override
215     protected EventFacade handleGetDecisionTrigger()
216     {
217         return (this.isEnteringDecisionPoint() ? getTrigger() : null);
218     }
219 
220     /**
221      * @see org.andromda.metafacades.uml.FrontEndAction#getActions()
222      */
223     @Override
224     protected List<FrontEndAction> handleGetActions()
225     {
226         final Set<FrontEndAction> actions = new LinkedHashSet<FrontEndAction>();
227         this.findActions(
228             actions,
229             new LinkedHashSet<FrontEndForward>());
230         return new ArrayList<FrontEndAction>(actions);
231     }
232 
233     /**
234      * Recursively finds all actions for this forward, what this means depends on the context in which
235      * this forward is used: if the source is a page action state it will collect all actions going out
236      * of this page, if the source is a regular action state it will collect all actions that might traverse
237      * this action state, if the source is the initial state it will collect all actions forwarding to this
238      * forward's use-case (please not that those actions most likely are defined in other use-cases).
239      *
240      * @param actions the default set of actions, duplicates will not be recorded
241      * @param handledForwards the forwards already processed
242      */
243     private void findActions(
244         final Set<FrontEndAction> actions,
245         final Set<FrontEndForward> handledForwards)
246     {
247         if (!handledForwards.contains(this.THIS()))
248         {
249             handledForwards.add(this);
250 
251             if (this instanceof FrontEndAction) // TODO this is not so nice because FrontEndAction extends FrontEndForward, solution would be to override in FrontEndAction
252             {
253                 actions.add((FrontEndAction)this.THIS());
254             }
255             else
256             {
257                 final StateVertexFacade vertex = getSource();
258                 if (vertex instanceof FrontEndView)
259                 {
260                     final FrontEndView view = (FrontEndView)vertex;
261                     actions.addAll(view.getActions());
262                 }
263                 else if (vertex instanceof FrontEndActionState)
264                 {
265                     final FrontEndActionState actionState = (FrontEndActionState)vertex;
266                     actions.addAll(actionState.getContainerActions());
267                 }
268                 else if (vertex instanceof PseudostateFacade)
269                 {
270                     final PseudostateFacade pseudostate = (PseudostateFacade)vertex;
271                     if (!pseudostate.isInitialState())
272                     {
273                         final Collection<TransitionFacade> incomingForwards = pseudostate.getIncomings();
274                         for (TransitionFacade incomingForward : incomingForwards)
275                         {
276                             final FrontEndForward forward = (FrontEndForward) incomingForward;
277                             actions.addAll(forward.getActions());
278                         }
279                     }
280                 }
281             }
282         }
283     }
284 
285     /**
286      * Overridden since a transition doesn't exist in a package.
287      *
288      * @see org.andromda.metafacades.uml14.ModelElementFacadeLogic#handleGetPackageName()
289      */
290     protected String handleGetPackageName()
291     {
292         String packageName = null;
293 
294         final UseCaseFacade useCase = this.getUseCase();
295         if (useCase != null)
296         {
297             packageName = useCase.getPackageName();
298         }
299         return packageName;
300     }
301 
302     /**
303      * @see org.andromda.metafacades.uml.FrontEndAction#getForwardParameters()
304      */
305     @Override
306     protected List<ParameterFacade> handleGetForwardParameters()
307     {
308         final EventFacade trigger = this.getTrigger();
309         return trigger == null ? Collections.EMPTY_LIST : new ArrayList<ParameterFacade>(trigger.getParameters());
310     }
311 
312     /**
313      * @see org.andromda.metafacades.uml.FrontEndAction#getOperationCall()
314      */
315     @Override
316    protected Object handleGetOperationCall()
317     {
318         FrontEndControllerOperation operation = null;
319         final EventFacade triggerEvent = this.getTrigger();
320         if (triggerEvent instanceof FrontEndEvent)
321         {
322             final FrontEndEvent trigger = (FrontEndEvent)triggerEvent;
323             operation = trigger.getControllerCall();
324         }
325         return operation;
326     }
327 }