001package org.andromda.metafacades.uml14; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Collections; 006import java.util.Iterator; 007import java.util.LinkedHashMap; 008import java.util.LinkedHashSet; 009import java.util.List; 010import java.util.Map; 011import org.andromda.metafacades.uml.ActivityGraphFacade; 012import org.andromda.metafacades.uml.ActorFacade; 013import org.andromda.metafacades.uml.AssociationEndFacade; 014import org.andromda.metafacades.uml.ClassifierFacade; 015import org.andromda.metafacades.uml.FrontEndAction; 016import org.andromda.metafacades.uml.FrontEndActivityGraph; 017import org.andromda.metafacades.uml.FrontEndController; 018import org.andromda.metafacades.uml.FrontEndFinalState; 019import org.andromda.metafacades.uml.FrontEndForward; 020import org.andromda.metafacades.uml.FrontEndParameter; 021import org.andromda.metafacades.uml.FrontEndUseCase; 022import org.andromda.metafacades.uml.FrontEndView; 023import org.andromda.metafacades.uml.ModelElementFacade; 024import org.andromda.metafacades.uml.Role; 025import org.andromda.metafacades.uml.StateVertexFacade; 026import org.andromda.metafacades.uml.UMLProfile; 027import org.apache.commons.lang.StringUtils; 028 029/** 030 * MetafacadeLogic implementation for org.andromda.metafacades.uml.FrontEndUseCase. 031 * 032 * @see org.andromda.metafacades.uml.FrontEndUseCase 033 * @author Bob Fields 034 */ 035public class FrontEndUseCaseLogicImpl 036 extends FrontEndUseCaseLogic 037{ 038 private static final long serialVersionUID = -2917211873092559876L; 039 040 /** 041 * @param metaObject 042 * @param context 043 */ 044 public FrontEndUseCaseLogicImpl( 045 Object metaObject, 046 String context) 047 { 048 super(metaObject, context); 049 } 050 051 /** 052 * @see org.andromda.metafacades.uml.FrontEndUseCase#isEntryUseCase() 053 */ 054 @Override 055 protected boolean handleIsEntryUseCase() 056 { 057 return hasStereotype(UMLProfile.STEREOTYPE_FRONT_END_APPLICATION); 058 } 059 060 /** 061 * @see org.andromda.metafacades.uml.FrontEndUseCase#getController() 062 */ 063 @Override 064 protected FrontEndController handleGetController() 065 { 066 final FrontEndActivityGraph graph = this.getActivityGraph(); 067 return graph == null ? null : graph.getController(); 068 } 069 070 /** 071 * @see org.andromda.metafacades.uml.FrontEndUseCase#getActivityGraph() 072 */ 073 @Override 074 protected ActivityGraphFacade handleGetActivityGraph() 075 { 076 ActivityGraphFacade activityGraph = null; 077 078 // - in case there is a tagged value pointing to an activity graph, and this graph is found, 079 // return it. 080 final Object activity = this.findTaggedValue(UMLProfile.TAGGEDVALUE_PRESENTATION_USECASE_ACTIVITY); 081 if (activity != null) 082 { 083 final String activityName = String.valueOf(activity.toString()); 084 activityGraph = this.getModel().findActivityGraphByName(activityName); 085 } 086 087 // - otherwise just take the first one in this use-case's namespace. 088 if (activityGraph == null) 089 { 090 final Collection<ModelElementFacade> ownedElements = this.getOwnedElements(); 091 for (final Iterator<ModelElementFacade> iterator = ownedElements.iterator(); iterator.hasNext();) 092 { 093 final Object object = iterator.next(); 094 if (object instanceof FrontEndActivityGraph) 095 { 096 return (ActivityGraphFacade)object; 097 } 098 } 099 } 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}