/*
* Initial version copyright 2008 Lockheed Martin Corporation, except
* as stated in the file entitled Licensing-Information.
*
* All modifications copyright 2009-2017 Data Access Technologies, Inc.
*
* Licensed under the Academic Free License version 3.0
* (http://www.opensource.org/licenses/afl-3.0.php), except as stated
* in the file entitled Licensing-Information.
*/
package fUML.Semantics.Activities.IntermediateActivities;
import fUML.Debug;
import java.util.Iterator;
import fUML.Syntax.Activities.IntermediateActivities.*;
import fUML.Syntax.Actions.BasicActions.*;
import fUML.Semantics.Actions.BasicActions.*;
import fUML.Semantics.Activities.CompleteStructuredActivities.*;
import fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionNodeActivation;
public class ActivityNodeActivationGroup extends
org.modeldriven.fuml.FumlObject {
public fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList edgeInstances = new fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList();
public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList nodeActivations = new fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList();
public fUML.Semantics.Activities.IntermediateActivities.ActivityExecution activityExecution = null;
public fUML.Semantics.Activities.CompleteStructuredActivities.StructuredActivityNodeActivation containingNodeActivation = null;
public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList suspendedActivations = new fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList();
public void run(
fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList activations) {
// Run the given node activations.
// Then concurrently send offers to all input activity parameter node activations (if any).
// Finally, concurrently send offers to all activations of other kinds of nodes that have
// no incoming edges with the given set (if any).
for (int i = 0; i < activations.size(); i++) {
ActivityNodeActivation activation = activations.getValue(i);
activation.run();
}
Debug.println("[run] Checking for enabled nodes...");
ActivityNodeActivationList enabledParameterNodeActivations = new ActivityNodeActivationList();
ActivityNodeActivationList enabledOtherActivations = new ActivityNodeActivationList();
for (int i = 0; i < activations.size(); i++) {
ActivityNodeActivation activation = activations.getValue(i);
Debug.println("[run] Checking node " + activation.node.name + "...");
if (!(activation instanceof PinActivation |
activation instanceof ExpansionNodeActivation)) {
boolean isEnabled = this.checkIncomingEdges(
activation.incomingEdges, activations);
// For an action activation, also consider incoming edges to
// input pins
if (isEnabled & activation instanceof ActionActivation) {
InputPinList inputPins = ((Action) activation.node).input;
int j = 1;
while (j <= inputPins.size() & isEnabled) {
InputPin inputPin = inputPins.getValue(j - 1);
ActivityEdgeInstanceList inputEdges = ((ActionActivation) activation)
.getPinActivation(inputPin).incomingEdges;
isEnabled = this.checkIncomingEdges(inputEdges,
activations);
j = j + 1;
}
}
if (isEnabled) {
Debug.println("[run] Node " + activation.node.name + " is enabled.");
if (activation instanceof ActivityParameterNodeActivation) {
enabledParameterNodeActivations.addValue(activation);
} else {
enabledOtherActivations.addValue(activation);
}
}
}
}
// *** Send offers to all enabled activity parameter nodes concurrently. ***
for (Iterator i = enabledParameterNodeActivations.iterator(); i.hasNext();) {
ActivityNodeActivation activation = (ActivityNodeActivation) i.next();
Debug.println("[run] Sending offer to activity parameter node " + activation.node.name + ".");
activation.receiveOffer();
}
// *** Send offers to all other enabled nodes concurrently. ***
for (Iterator i = enabledOtherActivations.iterator(); i.hasNext();) {
ActivityNodeActivation activation = (ActivityNodeActivation) i
.next();
Debug.println("[run] Sending offer to node " + activation.node.name + ".");
activation.receiveOffer();
}
} // run
public boolean checkIncomingEdges(
fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList incomingEdges,
fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationList activations) {
// Check if any incoming edges have a source in a given set of
// activations.
int j = 1;
boolean notFound = true;
while (j <= incomingEdges.size() & notFound) {
int k = 1;
while (k <= activations.size() & notFound) {
if (activations.getValue(k - 1).isSourceFor(
incomingEdges.getValue(j - 1))) {
notFound = false;
}
k = k + 1;
}
j = j + 1;
}
return notFound;
} // checkIncomingEdges
public void runNodes(
fUML.Syntax.Activities.IntermediateActivities.ActivityNodeList nodes) {
// Run the node activations associated with the given nodes in this
// activation group.
ActivityNodeActivationList nodeActivations = new ActivityNodeActivationList();
for (int i = 0; i < nodes.size(); i++) {
ActivityNode node = nodes.getValue(i);
ActivityNodeActivation nodeActivation = this
.getNodeActivation(node);
if (nodeActivation != null) {
nodeActivations.addValue(nodeActivation);
}
}
this.run(nodeActivations);
} // runNodes
public void activate(
fUML.Syntax.Activities.IntermediateActivities.ActivityNodeList nodes,
fUML.Syntax.Activities.IntermediateActivities.ActivityEdgeList edges) {
// Activate and run the given set of nodes with the given set of edges,
// within this activation group.
this.createNodeActivations(nodes);
this.createEdgeInstances(edges);
this.run(this.nodeActivations);
// Debug.println("[activate] Exiting.");
} // activate
public void terminateAll() {
// Terminate all node activations in the group.
Debug.println("[terminateAll] Terminating activation group for "
+ (this.activityExecution != null ? "activity "
+ this.activityExecution.getTypes().getValue(0).name
: this.containingNodeActivation != null ? "node "
+ this.containingNodeActivation.node.name
: "expansion region") + ".");
ActivityNodeActivationList nodeActivations = this.nodeActivations;
for (int i = 0; i < nodeActivations.size(); i++) {
ActivityNodeActivation nodeActivation = nodeActivations.getValue(i);
nodeActivation.terminate();
}
this.suspendedActivations.clear();
} // terminateAll
public void createNodeActivations(
fUML.Syntax.Activities.IntermediateActivities.ActivityNodeList nodes) {
// Add activity node activations for the given set of nodes to this
// group and create edge instances between them.
for (int i = 0; i < nodes.size(); i++) {
ActivityNode node = nodes.getValue(i);
Debug.println("[createNodeActivations] Creating a node activation for "
+ node.name + "...");
this.createNodeActivation(node);
}
} // createNodeActivations
public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation createNodeActivation(
fUML.Syntax.Activities.IntermediateActivities.ActivityNode node) {
// Create an activity node activation for a given activity node in this
// activity node activation group.
ActivityNodeActivation activation = (ActivityNodeActivation) (this
.getActivityExecution().locus.factory.instantiateVisitor(node));
activation.initialize(node, this);
this.nodeActivations.addValue(activation);
activation.createNodeActivations();
return activation;
} // createNodeActivation
public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation getNodeActivation(
fUML.Syntax.Activities.IntermediateActivities.ActivityNode node) {
// Return the node activation (if any) in this group,
// or any nested group, corresponding to the given activity node.
// If this is a group for a structured activity node activation,
// also include the pin activations for that node activation.
ActivityNodeActivation activation = null;
if (this.containingNodeActivation != null && node instanceof Pin) {
activation = this.containingNodeActivation
.getPinActivation((Pin) node);
}
if (activation == null) {
int i = 1;
while (activation == null & i <= this.nodeActivations.size()) {
activation = this.nodeActivations.getValue(i - 1)
.getNodeActivation(node);
i = i + 1;
}
}
return activation;
} // getNodeActivation
public void createEdgeInstances(
fUML.Syntax.Activities.IntermediateActivities.ActivityEdgeList edges) {
// Create instance edges for the given activity edges, as well as for
// edge instances within any nodes activated in this group.
for (int i = 0; i < edges.size(); i++) {
ActivityEdge edge = edges.getValue(i);
Debug.println("[createEdgeInstances] Creating an edge instance from "
+ edge.source.name + " to " + edge.target.name + ".");
ActivityEdgeInstance edgeInstance = new ActivityEdgeInstance();
edgeInstance.edge = edge;
edgeInstance.group = this;
this.edgeInstances.addValue(edgeInstance);
this.getNodeActivation(edge.source).addOutgoingEdge(edgeInstance);
this.getNodeActivation(edge.target).addIncomingEdge(edgeInstance);
// Debug.println("[createEdgeInstances] Edge instance created...");
}
ActivityNodeActivationList nodeActivations = this.nodeActivations;
for (int i = 0; i < nodeActivations.size(); i++) {
ActivityNodeActivation nodeActivation = nodeActivations.getValue(i);
nodeActivation.createEdgeInstances();
}
// Debug.println("[createEdgeInstances] Done creating edge instances.");
} // createEdgeInstances
public fUML.Semantics.Activities.IntermediateActivities.ActivityExecution getActivityExecution() {
// Return the activity execution to which this group belongs, directly
// or indirectly.
ActivityExecution activityExecution = this.activityExecution;
if (activityExecution == null) {
activityExecution = this.containingNodeActivation.group.getActivityExecution();
}
// Debug.println("[getActivityExecution] activityExecution = " + activityExecution);
return activityExecution;
} // getActivityExecution
public fUML.Semantics.Activities.IntermediateActivities.ActivityParameterNodeActivationList getOutputParameterNodeActivations() {
// Return the set of all activations in this group of activity parameter
// nodes for output (inout, out and return) parameters.
ActivityParameterNodeActivationList parameterNodeActivations = new ActivityParameterNodeActivationList();
ActivityNodeActivationList nodeActivations = this.nodeActivations;
for (int i = 0; i < nodeActivations.size(); i++) {
ActivityNodeActivation activation = nodeActivations.getValue(i);
if (activation instanceof ActivityParameterNodeActivation) {
if (activation.incomingEdges.size() > 0) {
parameterNodeActivations.addValue((ActivityParameterNodeActivation) activation);
}
}
}
return parameterNodeActivations;
} // getOutputParameterNodeActivations
public boolean hasSourceFor(
fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance edgeInstance) {
// Returns true if this activation group has a node activation
// corresponding to the source of the given edge instance.
boolean hasSource = false;
ActivityNodeActivationList activations = this.nodeActivations;
int i = 1;
while (!hasSource & i <= activations.size()) {
hasSource = activations.getValue(i - 1).isSourceFor(edgeInstance);
i = i + 1;
}
return hasSource;
} // hasSourceFor
public boolean isSuspended() {
// Check if this activation group has any suspended activations and
// is, therefore, itself suspended.
return this.suspendedActivations.size() > 0;
} // isSuspended
public void suspend(
fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation activation) {
// Suspend the given activation in this activation group. If this is
// the only suspended activation, and the activation group has a
// containing node activation, then suspend that containing activation.
Debug.println("[suspend] node="
+ (activation.node == null ? "null" : activation.node.name));
if (!this.isSuspended()) {
StructuredActivityNodeActivation containingNodeActivation = this.containingNodeActivation;
if (containingNodeActivation != null) {
containingNodeActivation.suspend();
}
}
this.suspendedActivations.addValue(activation);
} // suspend
public void resume(
fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation activation) {
// Resume the given activation by removing it from the suspended
// activation list for this activation group. If this is the last
// suspended activation, and the activation group has a containing
// node activation, then resume that containing activation.
Debug.println("[resume] node="
+ (activation.node == null ? "null" : activation.node.name));
boolean found = false;
int i = 1;
while (!found & i <= this.suspendedActivations.size()) {
if (this.suspendedActivations.get(i - 1) == activation) {
this.suspendedActivations.removeValue(i - 1);
found = true;
}
i = i + 1;
}
if (!this.isSuspended()) {
StructuredActivityNodeActivation containingNodeActivation = this.containingNodeActivation;
if (containingNodeActivation != null) {
containingNodeActivation.resume();
}
}
} // resume
} // ActivityNodeActivationGroup