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