fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationGroup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fuml Show documentation
Show all versions of fuml Show documentation
This open source software is a reference implementation, consisting of software and related files, for the OMG specification called the Semantics of a Foundational Subset for Executable UML Models (fUML). The reference implementation is intended to implement the execution semantics of UML activity models, accepting an XMI file from a conformant UML model as its input and providing an execution trace of the selected activity model(s) as its output. The core execution engine, which is directly generated from the normative syntactic and semantic models for fUML, may also be used as a library implementation of fUML in other software.
/*
* 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