| /***************************************************************************** |
| * Copyright (c) 2012 CEA LIST. |
| * |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * CEA LIST - Initial API and implementation |
| * |
| *****************************************************************************/ |
| package org.eclipse.papyrus.moka.fuml.actions; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.papyrus.moka.fuml.actions.IPinActivation; |
| import org.eclipse.papyrus.moka.fuml.activities.ActivityNodeActivationGroup; |
| import org.eclipse.papyrus.moka.fuml.activities.IActivityEdgeInstance; |
| import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivation; |
| import org.eclipse.papyrus.moka.fuml.activities.IObjectToken; |
| import org.eclipse.papyrus.moka.fuml.activities.IToken; |
| import org.eclipse.papyrus.moka.fuml.activities.ObjectToken; |
| import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue; |
| import org.eclipse.uml2.uml.Action; |
| import org.eclipse.uml2.uml.ActivityNode; |
| import org.eclipse.uml2.uml.ExecutableNode; |
| import org.eclipse.uml2.uml.InputPin; |
| import org.eclipse.uml2.uml.OutputPin; |
| import org.eclipse.uml2.uml.StructuredActivityNode; |
| |
| public class StructuredActivityNodeActivation extends ActionActivation implements IStructuredActivityNodeActivation { |
| |
| /* |
| * The group of activations of the activity nodes contained in the |
| * structured activity node. |
| */ |
| public ActivityNodeActivationGroup activationGroup; |
| |
| @Override |
| public void doAction() { |
| // If the structured activity node has mustIsolate=true, then carry out |
| // its behavior with isolation. |
| // Otherwise just activate it normally. |
| if (((StructuredActivityNode) (this.node)).isMustIsolate()) { |
| _beginIsolation(); |
| this.doStructuredActivity(); |
| _endIsolation(); |
| } else { |
| this.doStructuredActivity(); |
| } |
| } |
| |
| public void doStructuredActivity() { |
| // Run all activations of contained nodes. When this is complete, |
| // return. |
| // (This is the default behavior for a structured activity node used |
| // simply as a group. It is overridden for the execution of conditional |
| // and loop nodes.) |
| Action action = (Action) (this.node); |
| // *** Concurrently send offers from all input pins. *** |
| List<InputPin> inputPins = getInputs(action); // CHANGED from: action.getInputs(); |
| for (Iterator<InputPin> i = inputPins.iterator(); i.hasNext();) { |
| InputPin inputPin = i.next(); |
| IPinActivation pinActivation = this.getPinActivation(inputPin); |
| pinActivation.sendUnofferedTokens(); |
| } |
| this.activationGroup.run(this.activationGroup.nodeActivations); |
| } |
| |
| @Override |
| public void terminate() { |
| // Terminate the execution of all contained node activations (which |
| // completes the performance of the structured activity node |
| // activation), and then terminate this node itself. |
| this.terminateAll(); |
| super.terminate(); |
| } |
| |
| @Override |
| public IActivityNodeActivation getNodeActivation(ActivityNode node) { |
| // If this structured activity node activation is not for the given |
| // node, then check if there is an activation for the node in the |
| // activation group. |
| IActivityNodeActivation thisActivation = super.getNodeActivation(node); |
| IActivityNodeActivation activation = null; |
| if (thisActivation != null) { |
| activation = thisActivation; |
| } else if (this.activationGroup != null) { |
| activation = this.activationGroup.getNodeActivation(node); |
| } |
| return activation; |
| } |
| |
| public List<ActivityNode> makeActivityNodeList(List<ExecutableNode> nodes) { |
| // Return an activity node list containing the given list of executable |
| // nodes |
| // and any pins that they own. |
| List<ActivityNode> activityNodes = new ArrayList<ActivityNode>(); |
| for (int i = 0; i < nodes.size(); i++) { |
| ActivityNode node = nodes.get(i); |
| activityNodes.add(node); |
| if (node instanceof Action) { |
| Action action = (Action) node; |
| List<InputPin> inputPins = getInputs(action); // CHANGED from: action.getInputs(); |
| for (int j = 0; j < inputPins.size(); j++) { |
| InputPin inputPin = inputPins.get(j); |
| activityNodes.add(inputPin); |
| } |
| List<OutputPin> outputPins = getOutputs(action); // CHANGED from: action.getOutputs(); |
| for (int j = 0; j < outputPins.size(); j++) { |
| OutputPin outputPin = outputPins.get(j); |
| activityNodes.add(outputPin); |
| } |
| } |
| } |
| return activityNodes; |
| } |
| |
| public List<IValue> getPinValues(OutputPin pin) { |
| // Return the values of the tokens on the pin activation corresponding |
| // to the given pin in the internal activation group for this node |
| // activation. |
| PinActivation pinActivation = (PinActivation) (this.activationGroup.getNodeActivation(pin)); |
| List<IToken> tokens = pinActivation.getTokens(); |
| List<IValue> values = new ArrayList<IValue>(); |
| for (int i = 0; i < tokens.size(); i++) { |
| IToken token = tokens.get(i); |
| IValue value = ((ObjectToken) token).value; |
| if (value != null) { |
| values.add(value); |
| } |
| } |
| return values; |
| } |
| |
| public void putPinValues(OutputPin pin, List<IValue> values) { |
| // Place tokens for the given values on the pin activation corresponding |
| // to the given output pin on the internal activation group for this |
| // node activation. |
| PinActivation pinActivation = (PinActivation) (this.activationGroup.getNodeActivation(pin)); |
| for (int i = 0; i < values.size(); i++) { |
| IValue value = values.get(i); |
| IObjectToken token = new ObjectToken(); |
| token.setValue(value); |
| pinActivation.addToken(token); |
| } |
| } |
| |
| @Override |
| public void createNodeActivations() { |
| // Create an activation group and create node activations for all the |
| // nodes within the structured activity node. |
| super.createNodeActivations(); |
| |
| this.activationGroup = new ActivityNodeActivationGroup(); |
| this.activationGroup.containingNodeActivation = this; |
| this.activationGroup.createNodeActivations(((StructuredActivityNode) (this.node)).getNodes()); |
| } |
| |
| @Override |
| public void createEdgeInstances() { |
| // Create instances for all edges owned by this node. |
| this.activationGroup.createEdgeInstances(((StructuredActivityNode) (this.node)).getEdges()); |
| } |
| |
| @Override |
| public Boolean isSourceFor(IActivityEdgeInstance edgeInstance) { |
| // Returns true if this node is either the source for the given |
| // edgeInstance itself or if it contains the source in its |
| // activation group. |
| boolean isSource = super.isSourceFor(edgeInstance); |
| if (!isSource) { |
| isSource = this.activationGroup.hasSourceFor(edgeInstance); |
| } |
| return isSource; |
| } |
| |
| public void terminateAll() { |
| // Terminate the execution of all contained node activations (which |
| // completes the performance of the structured activity node |
| // activation). |
| this.activationGroup.terminateAll(); |
| } |
| |
| public Boolean isSuspended() { |
| // Check if the activation group for this node is suspended. |
| return this.activationGroup.isSuspended(); |
| } |
| |
| @Override |
| public List<IToken> completeAction() { |
| // Only actually complete this structured activity node if it is not |
| // suspended. |
| List<IToken> incomingTokens = new ArrayList<IToken>(); |
| if (!this.isSuspended()) { |
| incomingTokens = super.completeAction(); |
| } |
| return incomingTokens; |
| } |
| |
| @Override |
| public void resume() { |
| // When this structured activity node is resumed after being suspended, |
| // then complete its prior firing and, if there are more incoming |
| // tokens, fire it again. If, after that, the node is not suspended, |
| // then finish its resumption. |
| List<IToken> incomingTokens = super.completeAction(); |
| if (incomingTokens.size() > 0) { |
| this.fire(incomingTokens); |
| } |
| if (!this.isSuspended()) { |
| super.resume(); |
| } |
| } |
| } |