All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationGroup Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 1.5.0a
Show newest version
/*
 * 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy