001: package org.andromda.metafacades.emf.uml2;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Collections;
006: import java.util.Iterator;
007: import java.util.LinkedHashSet;
008: import java.util.Set;
009:
010: import org.andromda.metafacades.uml.EventFacade;
011: import org.andromda.metafacades.uml.FrontEndAction;
012: import org.andromda.metafacades.uml.FrontEndActionState;
013: import org.andromda.metafacades.uml.FrontEndActivityGraph;
014: import org.andromda.metafacades.uml.FrontEndControllerOperation;
015: import org.andromda.metafacades.uml.FrontEndEvent;
016: import org.andromda.metafacades.uml.FrontEndForward;
017: import org.andromda.metafacades.uml.FrontEndUseCase;
018: import org.andromda.metafacades.uml.FrontEndView;
019: import org.andromda.metafacades.uml.PseudostateFacade;
020: import org.andromda.metafacades.uml.StateVertexFacade;
021: import org.andromda.metafacades.uml.TransitionFacade;
022: import org.andromda.metafacades.uml.UseCaseFacade;
023: import org.andromda.utils.StringUtilsHelper;
024: import org.apache.commons.lang.StringUtils;
025:
026: /**
027: * MetafacadeLogic implementation for
028: * org.andromda.metafacades.uml.FrontEndForward.
029: *
030: * @see org.andromda.metafacades.uml.FrontEndForward
031: */
032: public class FrontEndForwardLogicImpl extends FrontEndForwardLogic {
033: public FrontEndForwardLogicImpl(final Object metaObject,
034: final String context) {
035: super (metaObject, context);
036: }
037:
038: /**
039: * @see org.andromda.metafacades.uml.FrontEndForward#isContainedInFrontEndUseCase()
040: */
041: protected boolean handleIsContainedInFrontEndUseCase() {
042: return this .getFrontEndActivityGraph() != null;
043: }
044:
045: /**
046: * @see org.andromda.metafacades.uml.FrontEndForward#getFrontEndActivityGraph()
047: */
048: protected Object handleGetFrontEndActivityGraph() {
049: final Object graph = this .getSource().getStateMachine();
050: return graph instanceof FrontEndActivityGraph ? graph : null;
051: }
052:
053: /**
054: * If this forward has a trigger this method returns that trigger's name,
055: * otherwise if this forward has a name this method returns that name,
056: * otherwise if this forward's target has a name this method returns that
057: * name, otherwise simply returns <code>"unknown"</code>
058: *
059: * @see org.andromda.metafacades.emf.uml2.ModelElementFacadeLogic#handleGetName()
060: */
061: protected final String handleGetName() {
062: String forwardName = null;
063:
064: // - trigger
065: final EventFacade trigger = this .getTrigger();
066: if (trigger != null) {
067: forwardName = trigger.getName();
068: }
069:
070: // - name
071: if (StringUtils.isEmpty(forwardName)) {
072: forwardName = super .handleGetName();
073: }
074:
075: // - target
076: if (StringUtils.isEmpty(forwardName)) {
077: forwardName = this .getTarget().getName();
078: }
079:
080: // - else
081: if (StringUtils.isEmpty(forwardName)) {
082: forwardName = "unknown";
083: }
084: return forwardName;
085: }
086:
087: /**
088: * @see org.andromda.metafacades.uml.FrontEndForward#getActionMethodName()
089: */
090: protected String handleGetActionMethodName() {
091: return StringUtilsHelper.lowerCamelCaseName(this .getName());
092: }
093:
094: /**
095: * @see org.andromda.metafacades.uml.FrontEndForward#isEnteringView()
096: */
097: protected boolean handleIsEnteringView() {
098: return this .getTarget() instanceof FrontEndView;
099: }
100:
101: /**
102: * @see org.andromda.metafacades.uml.FrontEndForward#isExitingView()
103: */
104: protected boolean handleIsExitingView() {
105: return this .getSource() instanceof FrontEndView;
106: }
107:
108: /**
109: * @see org.andromda.metafacades.uml.FrontEndForward#getUseCase()
110: */
111: protected Object handleGetUseCase() {
112: FrontEndUseCase useCase = null;
113: final FrontEndActivityGraph graph = this
114: .getFrontEndActivityGraph();
115: if (graph != null) {
116: final UseCaseFacade graphUseCase = graph.getUseCase();
117: if (graphUseCase instanceof FrontEndUseCase) {
118: useCase = (FrontEndUseCase) graphUseCase;
119: }
120: }
121: return useCase;
122: }
123:
124: /**
125: * All action states that make up this action, this includes all possible
126: * action states traversed after a decision point too.
127: */
128: private Collection actionStates = null;
129:
130: /**
131: * @see org.andromda.metafacades.uml.FrontEndAction#getActionStates()
132: */
133: protected java.util.List handleGetActionStates() {
134: if (this .actionStates == null) {
135: this .initializeCollections();
136: }
137: return new ArrayList(this .actionStates);
138: }
139:
140: /**
141: * Initializes all action states, action forwards, decision transitions and
142: * transitions in one shot, so that they can be queried more effiencently
143: * later on.
144: */
145: private void initializeCollections() {
146: this .actionStates = new LinkedHashSet();
147: this .collectTransitions(this , new LinkedHashSet());
148: }
149:
150: /**
151: * Recursively collects all action states, action forwards, decision
152: * transitions and transitions.
153: *
154: * @param transition
155: * the current transition that is being processed
156: * @param processedTransitions
157: * the set of transitions already processed
158: */
159: private void collectTransitions(final TransitionFacade transition,
160: final Collection processedTransitions) {
161: if (processedTransitions.contains(transition)) {
162: return;
163: }
164: processedTransitions.add(transition);
165:
166: final StateVertexFacade target = transition.getTarget();
167: if (target instanceof FrontEndActionState) {
168: this .actionStates.add(target);
169: final FrontEndForward forward = ((FrontEndActionState) target)
170: .getForward();
171: if (forward != null) {
172: this .collectTransitions(forward, processedTransitions);
173: }
174: }
175: }
176:
177: /**
178: * @see org.andromda.metafacades.uml.FrontEndAction#getDecisionTrigger()
179: */
180: protected Object handleGetDecisionTrigger() {
181: return this .isEnteringDecisionPoint() ? this .getTrigger()
182: : null;
183: }
184:
185: /**
186: * @see org.andromda.metafacades.uml.FrontEndAction#getActions()
187: */
188: protected java.util.List handleGetActions() {
189: final Set actions = new LinkedHashSet();
190: this .findActions(actions, new LinkedHashSet());
191: return new ArrayList(actions);
192: }
193:
194: /**
195: * Recursively finds all actions for this forward, what this means depends
196: * on the context in which this forward is used: if the source is a page
197: * action state it will collect all actions going out of this page, if the
198: * source is a regular action state it will collect all actions that might
199: * traverse this action state, if the source is the initial state it will
200: * collect all actions forwarding to this forward's use-case (please not
201: * that those actions most likely are defined in other use-cases).
202: *
203: * @param actions
204: * the default set of actions, duplicates will not be recorded
205: * @param handledForwards
206: * the forwards already processed
207: */
208: private void findActions(final Set actions,
209: final Set handledForwards) {
210: if (!handledForwards.contains(this .THIS())) {
211: handledForwards.add(this );
212:
213: if (this instanceof FrontEndAction) // @todo this is not so nice
214: // because FrontEndAction // extends FrontEndForward, // solution would be to override // in FrontEndAction
215: {
216: actions.add(this .THIS());
217: } else {
218: final StateVertexFacade vertex = this .getSource();
219: if (vertex instanceof FrontEndView) {
220: final FrontEndView view = (FrontEndView) vertex;
221: actions.addAll(view.getActions());
222: } else if (vertex instanceof FrontEndActionState) {
223: final FrontEndActionState actionState = (FrontEndActionState) vertex;
224: actions.addAll(actionState.getContainerActions());
225: } else if (vertex instanceof PseudostateFacade) {
226: final PseudostateFacade pseudostate = (PseudostateFacade) vertex;
227: if (!pseudostate.isInitialState()) {
228: final Collection incomingForwards = pseudostate
229: .getIncoming();
230: for (final Iterator forwardIterator = incomingForwards
231: .iterator(); forwardIterator.hasNext();) {
232: final FrontEndForward forward = (FrontEndForward) forwardIterator
233: .next();
234: actions.addAll(forward.getActions());
235: }
236: }
237: }
238: }
239: }
240: }
241:
242: /**
243: * Overriden since a transition doesn't exist in a package.
244: *
245: * @see org.andromda.metafacades.emf.uml2.ModelElementFacadeLogic#handleGetPackageName()
246: */
247: protected String handleGetPackageName() {
248: String packageName = null;
249:
250: final UseCaseFacade useCase = this .getUseCase();
251: if (useCase != null) {
252: packageName = useCase.getPackageName();
253: }
254: return packageName;
255: }
256:
257: /**
258: * @see org.andromda.metafacades.uml.FrontEndAction#getForwardParameters()
259: */
260: protected java.util.List handleGetForwardParameters() {
261: final EventFacade trigger = this .getTrigger();
262: return trigger == null ? Collections.EMPTY_LIST
263: : new ArrayList(trigger.getParameters());
264: }
265:
266: /**
267: * @see org.andromda.metafacades.uml.FrontEndAction#getOperationCall()
268: */
269: protected Object handleGetOperationCall() {
270: FrontEndControllerOperation operation = null;
271: final EventFacade triggerEvent = this .getTrigger();
272: if (triggerEvent instanceof FrontEndEvent) {
273: final FrontEndEvent trigger = (FrontEndEvent) triggerEvent;
274: operation = trigger.getControllerCall();
275: }
276: return operation;
277: }
278: }
|