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.Iterator;
7   import java.util.LinkedHashMap;
8   import java.util.LinkedHashSet;
9   import java.util.List;
10  import java.util.Map;
11  import org.andromda.metafacades.uml.ActivityGraphFacade;
12  import org.andromda.metafacades.uml.ActorFacade;
13  import org.andromda.metafacades.uml.AssociationEndFacade;
14  import org.andromda.metafacades.uml.ClassifierFacade;
15  import org.andromda.metafacades.uml.FrontEndAction;
16  import org.andromda.metafacades.uml.FrontEndActivityGraph;
17  import org.andromda.metafacades.uml.FrontEndController;
18  import org.andromda.metafacades.uml.FrontEndFinalState;
19  import org.andromda.metafacades.uml.FrontEndForward;
20  import org.andromda.metafacades.uml.FrontEndParameter;
21  import org.andromda.metafacades.uml.FrontEndUseCase;
22  import org.andromda.metafacades.uml.FrontEndView;
23  import org.andromda.metafacades.uml.ModelElementFacade;
24  import org.andromda.metafacades.uml.Role;
25  import org.andromda.metafacades.uml.StateVertexFacade;
26  import org.andromda.metafacades.uml.UMLProfile;
27  import org.apache.commons.lang.StringUtils;
28  
29  /**
30   * MetafacadeLogic implementation for org.andromda.metafacades.uml.FrontEndUseCase.
31   *
32   * @see org.andromda.metafacades.uml.FrontEndUseCase
33   * @author Bob Fields
34   */
35  public class FrontEndUseCaseLogicImpl
36      extends FrontEndUseCaseLogic
37  {
38      private static final long serialVersionUID = -2917211873092559876L;
39  
40      /**
41       * @param metaObject
42       * @param context
43       */
44      public FrontEndUseCaseLogicImpl(
45          Object metaObject,
46          String context)
47      {
48          super(metaObject, context);
49      }
50  
51      /**
52       * @see org.andromda.metafacades.uml.FrontEndUseCase#isEntryUseCase()
53       */
54      @Override
55      protected boolean handleIsEntryUseCase()
56      {
57          return hasStereotype(UMLProfile.STEREOTYPE_FRONT_END_APPLICATION);
58      }
59  
60      /**
61       * @see org.andromda.metafacades.uml.FrontEndUseCase#getController()
62       */
63      @Override
64      protected FrontEndController handleGetController()
65      {
66          final FrontEndActivityGraph graph = this.getActivityGraph();
67          return graph == null ? null : graph.getController();
68      }
69  
70      /**
71       * @see org.andromda.metafacades.uml.FrontEndUseCase#getActivityGraph()
72       */
73      @Override
74      protected ActivityGraphFacade handleGetActivityGraph()
75      {
76          ActivityGraphFacade activityGraph = null;
77  
78          // - in case there is a tagged value pointing to an activity graph, and this graph is found,
79          //   return it.
80          final Object activity = this.findTaggedValue(UMLProfile.TAGGEDVALUE_PRESENTATION_USECASE_ACTIVITY);
81          if (activity != null)
82          {
83              final String activityName = String.valueOf(activity.toString());
84              activityGraph = this.getModel().findActivityGraphByName(activityName);
85          }
86  
87          // - otherwise just take the first one in this use-case's namespace.
88          if (activityGraph == null)
89          {
90              final Collection<ModelElementFacade> ownedElements = this.getOwnedElements();
91              for (final Iterator<ModelElementFacade> iterator = ownedElements.iterator(); iterator.hasNext();)
92              {
93                  final Object object = iterator.next();
94                  if (object instanceof FrontEndActivityGraph)
95                  {
96                      return (ActivityGraphFacade)object;
97                  }
98              }
99          }
100         return activityGraph;
101     }
102 
103     /**
104      * @see org.andromda.metafacades.uml.FrontEndUseCase#getReferencingFinalStates()
105      */
106     @Override
107     protected List handleGetReferencingFinalStates()
108     {
109         return new ArrayList(this.getModel().findFinalStatesWithNameOrHyperlink(this));
110     }
111 
112     /**
113      * @see org.andromda.metafacades.uml.FrontEndUseCase#getAllUseCases()
114      */
115     @Override
116     protected List handleGetAllUseCases()
117     {
118         final List useCases = new ArrayList();
119         for (final Iterator useCaseIterator = getModel().getAllUseCases().iterator(); useCaseIterator.hasNext();)
120         {
121             final Object object = useCaseIterator.next();
122             if (object instanceof FrontEndUseCase)
123             {
124                 useCases.add(object);
125             }
126         }
127         return useCases;
128     }
129 
130     /**
131      * Gets those roles directly associated to this use-case.
132      */
133     private Collection<Role> getAssociatedRoles()
134     {
135         final Collection<Role> usersList = new ArrayList<Role>();
136         final Collection<AssociationEndFacade> associationEnds = getAssociationEnds();
137         for (final Iterator<AssociationEndFacade> iterator = associationEnds.iterator(); iterator.hasNext();)
138         {
139             final AssociationEndFacade associationEnd = iterator.next();
140             final ClassifierFacade classifier = associationEnd.getOtherEnd().getType();
141             if (classifier instanceof Role)
142             {
143                 usersList.add((Role)classifier);
144             }
145         }
146         return usersList;
147     }
148 
149     /**
150      * Recursively collects all roles generalizing the argument user, in the specified collection.
151      */
152     private void collectRoles(
153         final Role role,
154         final Collection<Role> roles)
155     {
156         if (!roles.contains(role))
157         {
158             roles.add(role);
159             final Collection<ActorFacade> childUsers = role.getGeneralizedByActors();
160             for (final Iterator<ActorFacade> iterator = childUsers.iterator(); iterator.hasNext();)
161             {
162                 final Role childUser = (Role)iterator.next();
163                 this.collectRoles(
164                     childUser,
165                     roles);
166             }
167         }
168     }
169 
170     /**
171      * @see org.andromda.metafacades.uml.FrontEndUseCase#getRoles()
172      */
173     @Override
174     protected List<Role> handleGetRoles()
175     {
176         final Collection<Role> allRoles = new LinkedHashSet<Role>();
177         final Collection<Role> associatedUsers = this.getAssociatedRoles();
178         for (final Iterator iterator = associatedUsers.iterator(); iterator.hasNext();)
179         {
180             final Role user = (Role)iterator.next();
181             this.collectRoles(
182                 user,
183                 allRoles);
184         }
185         return new ArrayList<Role>(allRoles);
186     }
187 
188     /**
189      * @see org.andromda.metafacades.uml.FrontEndUseCase#getAllRoles()
190      */
191     @Override
192     protected List<Role> handleGetAllRoles()
193     {
194         final Collection<Role> allRoles = new LinkedHashSet<Role>();
195         for (final Iterator iterator = this.getAllUseCases().iterator(); iterator.hasNext();)
196         {
197             allRoles.addAll(((FrontEndUseCase)iterator.next()).getRoles());
198         }
199         return new ArrayList(allRoles);
200     }
201 
202     /**
203      * @see org.andromda.metafacades.uml.FrontEndUseCase#isSecured()
204      */
205     @Override
206     protected boolean handleIsSecured()
207     {
208         return !this.getRoles().isEmpty();
209     }
210 
211     /**
212      * @see org.andromda.metafacades.uml.FrontEndUseCase#getViews()
213      */
214     @Override
215     protected List handleGetViews()
216     {
217         List views;
218         final ActivityGraphFacade graph = this.getActivityGraph();
219         if (graph == null)
220         {
221             views = Collections.emptyList();
222         }
223         else
224         {
225             views =
226                 new ArrayList(getModel().getAllActionStatesWithStereotype(
227                         graph,
228                         UMLProfile.STEREOTYPE_FRONT_END_VIEW));
229         }
230         return views;
231     }
232 
233     /**
234      * @see org.andromda.metafacades.uml.FrontEndUseCase#getViews()
235      */
236     @Override
237     protected List<FrontEndAction> handleGetActions()
238     {
239         final Collection<FrontEndAction> actions = new LinkedHashSet<FrontEndAction> ();
240         final Collection<FrontEndView> pages = this.getViews();
241         for (final Iterator<FrontEndView> pageIterator = pages.iterator(); pageIterator.hasNext();)
242         {
243             final FrontEndView view = pageIterator.next();
244             actions.addAll(view.getActions());
245         }
246 
247         final FrontEndActivityGraph graph = this.getActivityGraph();
248         if (graph != null)
249         {
250             final FrontEndAction action = graph.getInitialAction();
251             if (action != null)
252             {
253                 actions.add(action);
254             }
255         }
256         return new ArrayList<FrontEndAction>(actions);
257     }
258 
259     /**
260      * @see org.andromda.metafacades.uml.FrontEndUseCase#getInitialView()
261      */
262     @Override
263     protected FrontEndView handleGetInitialView()
264     {
265         FrontEndView view = null;
266         final FrontEndActivityGraph graph = this.getActivityGraph();
267         final FrontEndAction action = graph != null ? this.getActivityGraph().getInitialAction() : null;
268         final Collection<FrontEndForward> forwards = action != null ? action.getActionForwards() : null;
269         if (forwards != null)
270         {
271             for (final Iterator<FrontEndForward> iterator = forwards.iterator(); iterator.hasNext();)
272             {
273                 final FrontEndForward forward = iterator.next();
274                 final StateVertexFacade target = forward.getTarget();
275                 if (target instanceof FrontEndView)
276                 {
277                     view = (FrontEndView)target;
278                 }
279                 else if (target instanceof FrontEndFinalState)
280                 {
281                     final FrontEndFinalState finalState = (FrontEndFinalState)target;
282                     final FrontEndUseCase targetUseCase = finalState.getTargetUseCase();
283                     if (targetUseCase != null && !targetUseCase.equals(this.THIS()))
284                     {
285                         view = targetUseCase.getInitialView();
286                     }
287                 }
288             }
289         }
290         return view;
291     }
292 
293     /**
294      * @see org.andromda.metafacades.uml.FrontEndUseCase#getViewVariables()
295      */
296     @Override
297     protected List<FrontEndParameter> handleGetViewVariables()
298     {
299         final Map<String, FrontEndParameter> pageVariableMap = new LinkedHashMap<String, FrontEndParameter>();
300 
301         // - page variables can occur twice or more in the usecase if their
302         //   names are the same for different forms, storing them in a map
303         //   solves this issue because those names do not have the action-name prefix
304         final Collection<FrontEndView> views = this.getViews();
305         for (final Iterator pageIterator = views.iterator(); pageIterator.hasNext();)
306         {
307             final FrontEndView view = (FrontEndView)pageIterator.next();
308             final Collection<FrontEndParameter> variables = view.getVariables();
309             for (final Iterator<FrontEndParameter> variableIterator = variables.iterator(); variableIterator.hasNext();)
310             {
311                 FrontEndParameter variable = variableIterator.next();
312                 final String name = variable.getName();
313                 if (StringUtils.isNotBlank(name))
314                 {
315                     final FrontEndParameter existingVariable = pageVariableMap.get(name);
316                     if (existingVariable != null)
317                     {
318                         if (existingVariable.isTable())
319                         {
320                             variable = existingVariable;
321                         }
322                     }
323                     pageVariableMap.put(
324                         name,
325                         variable);
326                 }
327             }
328         }
329         return new ArrayList<FrontEndParameter>(pageVariableMap.values());
330     }
331 }