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

fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionRegionActivation 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-2012 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.ExtraStructuredActivities;

import fUML.Debug;
import UMLPrimitiveTypes.*;

import java.util.Iterator;

import fUML.Syntax.*;
import fUML.Syntax.Classes.Kernel.*;
import fUML.Syntax.CommonBehaviors.BasicBehaviors.*;
import fUML.Syntax.CommonBehaviors.Communications.*;
import fUML.Syntax.Activities.IntermediateActivities.*;
import fUML.Syntax.Activities.CompleteStructuredActivities.*;
import fUML.Syntax.Activities.ExtraStructuredActivities.*;
import fUML.Syntax.Actions.BasicActions.*;

import fUML.Semantics.*;
import fUML.Semantics.Classes.Kernel.*;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.*;
import fUML.Semantics.CommonBehaviors.Communications.*;
import fUML.Semantics.Activities.IntermediateActivities.*;
import fUML.Semantics.Activities.CompleteStructuredActivities.*;
import fUML.Semantics.Actions.BasicActions.*;
import fUML.Semantics.Loci.*;

public class ExpansionRegionActivation extends
		fUML.Semantics.Actions.BasicActions.ActionActivation {

	public fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroupList activationGroups = new fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroupList();
	public fUML.Semantics.Activities.ExtraStructuredActivities.TokenSetList inputTokens = new fUML.Semantics.Activities.ExtraStructuredActivities.TokenSetList();
	public fUML.Semantics.Activities.ExtraStructuredActivities.TokenSetList inputExpansionTokens = new fUML.Semantics.Activities.ExtraStructuredActivities.TokenSetList();
	public int next = 0;

	public fUML.Semantics.Activities.IntermediateActivities.TokenList takeOfferedTokens() {
		// Take the tokens from the input pin and input expansion node
		// activations and save them.

		super.takeOfferedTokens();

		ExpansionRegion region = (ExpansionRegion) (this.node);
		InputPinList inputPins = region.input;
		ExpansionNodeList inputElements = region.inputElement;

		this.inputTokens.clear();
		this.inputExpansionTokens.clear();

		for (int i = 0; i < inputPins.size(); i++) {
			InputPin inputPin = inputPins.getValue(i);
			TokenSet tokenSet = new TokenSet();
			tokenSet.tokens = this.getPinActivation(inputPin).takeTokens();
			this.inputTokens.addValue(tokenSet);
		}

		int n = this.numberOfValues();

		for (int i = 0; i < inputElements.size(); i++) {
			ExpansionNode inputElement = inputElements.getValue(i);
			ExpansionNodeActivation expansionNodeActivation = this
					.getExpansionNodeActivation(inputElement);
			expansionNodeActivation.fire(expansionNodeActivation
					.takeOfferedTokens());
			TokenList tokens = expansionNodeActivation.takeTokens();
			TokenSet tokenSet = new TokenSet();
			int j = 1;
			while (j <= n) {
				tokenSet.tokens.add(tokens.getValue(j - 1));
				j = j + 1;
			}
			this.inputExpansionTokens.addValue(tokenSet);
		}

		return new TokenList();
	} // takeOfferedTokens

	public void doAction() {
		// If the expansion region has mustIsolate=true, then carry out its
		// behavior with isolation.
		// Otherwise just activate it normally.

		if (((StructuredActivityNode) (this.node)).mustIsolate) {
			_beginIsolation();
			this.doStructuredActivity();
			_endIsolation();
		} else {
			this.doStructuredActivity();
		}

	} // doAction

	public void doStructuredActivity() {
		// Create a number of expansion region activation groups equal to the
		// number of values expanded in the region,
		// setting the region inputs and group inputs for each group.
		// Run the body of the region in each group, either iteratively or in
		// parallel.
		// Add the outputs of each activation group to the corresonding output
		// expansion node activations.

		ExpansionRegion region = (ExpansionRegion) this.node;
		InputPinList inputPins = region.input;
		ExpansionNodeList inputElements = region.inputElement;
		ExpansionNodeList outputElements = region.outputElement;

		this.activationGroups.clear();
		int n = this.inputExpansionTokens.getValue(0).tokens.size();
		int k = 1;
		while (k <= n) {
			ExpansionActivationGroup activationGroup = new ExpansionActivationGroup();
			activationGroup.regionActivation = this;
			activationGroup.index = k;

			int j = 1;
			while (j <= inputPins.size()) {
				OutputPinActivation regionInput = new OutputPinActivation();
				regionInput.run();
				activationGroup.regionInputs.addValue(regionInput);
				j = j + 1;
			}

			j = 1;
			while (j <= inputElements.size()) {
				OutputPinActivation groupInput = new OutputPinActivation();
				groupInput.run();
				activationGroup.groupInputs.addValue(groupInput);
				j = j + 1;
			}

			j = 1;
			while (j <= outputElements.size()) {
				OutputPinActivation groupOutput = new OutputPinActivation();
				groupOutput.run();
				activationGroup.groupOutputs.addValue(groupOutput);
				j = j + 1;
			}

			activationGroup.createNodeActivations(region.node);
			activationGroup.createEdgeInstances(region.edge);
			this.activationGroups.addValue(activationGroup);

			k = k + 1;
		}

		// ExpansionActivationGroupList activationGroups = this.activationGroups;

		if (region.mode == ExpansionKind.iterative) {
			Debug.println("[doStructuredActivity] Expansion mode = iterative");
			this.next = 1;
			this.runIterative();
		} else if (region.mode == ExpansionKind.parallel) {
			Debug.println("[doStructuredActivity] Expansion mode = parallel");
			this.runParallel();
		}

		this.doOutput();

	} // doStructuredActivity

	public void runIterative() {
		// Run the body of the region iteratively, either until all activation
		// groups have run or until the region is suspended.

		ExpansionActivationGroupList activationGroups = this.activationGroups;

		while (this.next <= activationGroups.size() & !this.isSuspended()) {
			ExpansionActivationGroup activationGroup = activationGroups
					.getValue(this.next - 1);
			this.runGroup(activationGroup);
			this.next = this.next + 1;
		}
	} // runIterative

	public void runParallel() {
		// Run the body of the region concurrently.

		ExpansionActivationGroupList activationGroups = this.activationGroups;

		// *** Activate all groups concurrently. ***
		for (Iterator i = activationGroups.iterator(); i.hasNext();) {
			ExpansionActivationGroup activationGroup = (ExpansionActivationGroup) i
					.next();
			this.runGroup(activationGroup);
		}
	} // runParallel

	public void doOutput() {
		// Place tokens on the output expansion nodes.

		ExpansionRegion region = (ExpansionRegion) this.node;
		ExpansionNodeList outputElements = region.outputElement;

		Debug.println("[doOutput] Expansion region " + region.name + " is "
				+ (this.isSuspended() ? "suspended." : "completed."));

		if (!this.isSuspended()) {
			for (int i = 0; i < activationGroups.size(); i++) {
				ExpansionActivationGroup activationGroup = activationGroups
						.getValue(i);
				OutputPinActivationList groupOutputs = activationGroup.groupOutputs;
				for (int j = 0; j < groupOutputs.size(); j++) {
					OutputPinActivation groupOutput = groupOutputs.getValue(j);
					ExpansionNode outputElement = outputElements.getValue(j);
					this.getExpansionNodeActivation(outputElement).addTokens(
							groupOutput.takeTokens());
				}
			}
		}
	} // doOutput

	public void terminate() {
		// Terminate the execution of all contained node activations (which
		// completes the performance of the expansion region activation).

		ExpansionActivationGroupList activationGroups = this.activationGroups;
		for (int i = 0; i < activationGroups.size(); i++) {
			ExpansionActivationGroup activationGroup = this.activationGroups
					.getValue(i);

			OutputPinActivationList groupOutputs = activationGroup.groupOutputs;

			_beginIsolation();
			for (int j = 0; j < groupOutputs.size(); j++) {
				OutputPinActivation groupOutput = groupOutputs.getValue(j);
				groupOutput.fire(groupOutput.takeOfferedTokens());
			}
			activationGroup.terminateAll();
			_endIsolation();
		}

		super.terminate();
	} // terminate

	public void sendOffers() {
		// Fire all output expansion nodes and send offers on all outgoing
		// control flows.

		ExpansionRegion region = (ExpansionRegion) (this.node);

		// *** Send offers from all output expansion nodes concurrently. ***
		ExpansionNodeList outputElements = region.outputElement;
		for (Iterator i = outputElements.iterator(); i.hasNext();) {
			ExpansionNode outputElement = (ExpansionNode) i.next();
			this.getExpansionNodeActivation(outputElement)
					.sendUnofferedTokens();
		}

		// Send offers on all outgoing control flows.
		super.sendOffers();

	} // sendOffers

	public void runGroup(
			fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup activationGroup) {
		// Set up the inputs for the group with the given index, run the group
		// and then fire the group outputs.

		if (this.isRunning()) {
			Debug.println("[runGroup] groupInput[0] = "
					+ this.inputExpansionTokens.getValue(0).tokens.getValue(activationGroup.index - 1).getValue());

			TokenSetList inputTokens = this.inputTokens;
			for (int j = 0; j < inputTokens.size(); j++) {
				TokenSet tokenSet = inputTokens.getValue(j);
				OutputPinActivation regionInput = activationGroup.regionInputs
						.getValue(j);
				regionInput.clearTokens();
				regionInput.addTokens(tokenSet.tokens);
				regionInput.sendUnofferedTokens();
			}

			TokenSetList inputExpansionTokens = this.inputExpansionTokens;
			for (int j = 0; j < inputExpansionTokens.size(); j++) {
				TokenSet tokenSet = inputExpansionTokens.getValue(j);
				OutputPinActivation groupInput = activationGroup.groupInputs
						.getValue(j);
				groupInput.clearTokens();
				if (tokenSet.tokens.size() >= activationGroup.index) {
					groupInput.addToken(tokenSet.tokens
							.getValue(activationGroup.index - 1));
				}
				groupInput.sendUnofferedTokens();
			}

			activationGroup.run(activationGroup.nodeActivations);

			this.terminateGroup(activationGroup);
		}
	} // runGroup

	public void terminateGroup(
			fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup activationGroup) {
		// Terminate the given activation group, after preserving any group
		// outputs.
		if (this.isRunning() & !this.isSuspended()) {
			OutputPinActivationList groupOutputs = activationGroup.groupOutputs;
			for (int i = 0; i < groupOutputs.size(); i++) {
				OutputPinActivation groupOutput = groupOutputs.getValue(i);
				groupOutput.fire(groupOutput.takeOfferedTokens());
			}

			activationGroup.terminateAll();
		}
	} // terminateGroup

	public fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionNodeActivation getExpansionNodeActivation(
			fUML.Syntax.Activities.ExtraStructuredActivities.ExpansionNode node) {
		// Return the expansion node activation corresponding to the given
		// expansion node, in the context of the activity node activation group
		// this expansion region activation is in.
		// [Note: Expansion regions do not own their expansion nodes. Instead,
		// they are own as object nodes by the enclosing activity or group.
		// Therefore, they will already be activated along with their expansion
		// region.]

		return (ExpansionNodeActivation) (this.group.getNodeActivation(node));

	} // getExpansionNodeActivation

	public int numberOfValues() {
		// Return the number of values to be acted on by the expansion region of
		// this activation, which is the minimum of the number of values offered
		// to each of the input expansion nodes of the activation.

		ExpansionRegion region = (ExpansionRegion) (this.node);
		ExpansionNodeList inputElements = region.inputElement;

		int n = this.getExpansionNodeActivation(inputElements.getValue(0))
				.countOfferedValues();
		int i = 2;
		while (i <= inputElements.size()) {
			int count = this.getExpansionNodeActivation(
					inputElements.getValue(i - 1)).countOfferedValues();
			if (count < n) {
				n = count;
			}
			i = i + 1;
		}

		return n;
	} // numberOfValues

	public boolean isSuspended() {
		// Check if the activation group for this node is suspended.

		boolean suspended = false;
		int i = 1;
		while (i <= this.activationGroups.size() & !suspended) {
			ActivityNodeActivationGroup group = this.activationGroups
					.get(i - 1);
			suspended = group.isSuspended();
			i = i + 1;
		}

		return suspended;
	} // isSuspended

	public void resume(
			fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup activationGroup) {
		// Resume an expansion region after the suspension of the given
		// activation group. If the region is iterative, then continue with the
		// iteration. If the region is parallel, and there are no more suspended
		// activation groups, then generate the expansion node output.

		ExpansionRegion region = (ExpansionRegion) this.node;

		this.resume();
		this.terminateGroup(activationGroup);
		if (region.mode == ExpansionKind.iterative) {
			this.runIterative();
		}

		this.doOutput();
	} // resume

} // ExpansionRegionActivation




© 2015 - 2024 Weber Informatics LLC | Privacy Policy