/* * 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 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.Actions.BasicActions.*; import fUML.Semantics.*; import fUML.Semantics.Classes.Kernel.*; import fUML.Semantics.CommonBehaviors.BasicBehaviors.*; import fUML.Semantics.Actions.BasicActions.*; import fUML.Semantics.Loci.*; public abstract class ActivityNodeActivation extends fUML.Semantics.Loci.LociL1.SemanticVisitor { public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationGroup group = null; public fUML.Syntax.Activities.IntermediateActivities.ActivityNode node = null; public fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList incomingEdges = new fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList(); public fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList outgoingEdges = new fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstanceList(); public boolean running = false; public fUML.Semantics.Activities.IntermediateActivities.TokenList heldTokens = new fUML.Semantics.Activities.IntermediateActivities.TokenList(); public void initialize(ActivityNode node, ActivityNodeActivationGroup group) { // Initialize this node activation. this.node = node; this.group = group; this.running = false; } public void run() { // Run the activation of this node. Debug.println(this.node == null? "[run] Anonymous activation of type " + this.getClass().getName(): "[run] node = " + this.node.name); this.running = true; } // run public void receiveOffer() { // Receive an offer from an incoming edge. // Check if all prerequisites have been satisfied. If so, fire. Debug.println("[receiveOffer] " + (this.node == null ? "..." : "node = " + this.node.name)); _beginIsolation(); boolean ready = this.isReady(); TokenList tokens = new TokenList(); if (ready) { Debug.println("[receiveOffer] Firing."); tokens = this.takeOfferedTokens(); } _endIsolation(); if (ready) { this.fire(tokens); } } // receiveOffer public fUML.Semantics.Activities.IntermediateActivities.TokenList takeOfferedTokens() { // Get tokens from all incoming edges. TokenList allTokens = new TokenList(); ActivityEdgeInstanceList incomingEdges = this.incomingEdges; for (int i = 0; i < incomingEdges.size(); i++) { ActivityEdgeInstance incomingEdge = incomingEdges.getValue(i); TokenList tokens = incomingEdge.takeOfferedTokens(); for (int j = 0; j < tokens.size(); j++) { Token token = tokens.getValue(j); allTokens.addValue(token); } } return allTokens; } // takeOfferedTokens public abstract void fire( fUML.Semantics.Activities.IntermediateActivities.TokenList incomingTokens); public void sendOffers( fUML.Semantics.Activities.IntermediateActivities.TokenList tokens) { // Send offers for the given set of tokens over all outgoing edges (if // there are any tokens actually being offered). if (tokens.size() > 0) { // *** Send all outgoing offers concurrently. *** ActivityEdgeInstanceList outgoingEdges = this.outgoingEdges; for (Iterator i = outgoingEdges.iterator(); i.hasNext();) { ActivityEdgeInstance outgoingEdge = (ActivityEdgeInstance) i .next(); // Debug.println("[sendOffers] Sending offer to " + // outgoingEdge.target.node.name + "."); outgoingEdge.sendOffer(tokens); } } } // sendOffers public void terminate() { // Terminate the activation of this node. Debug.println(this.running, this.node == null? "[terminate] Anonymous activation of type " + this.getClass().getName(): "[terminate] node = " + this.node.name); this.running = false; } // terminate public boolean isReady() { // Check if all the prerequisites for this node have been satisfied. // By default, check that this node is running. return this.isRunning(); } // isReady public boolean isRunning() { // Test whether this node activation is running. return this.running; } // isRunning public void addOutgoingEdge( fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance edge) { // Add an activity edge instance as an outgoing edge of this activity // node activation. edge.source = this; this.outgoingEdges.addValue(edge); } // addOutgoingEdge public void addIncomingEdge( fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance edge) { // Add an activity edge instance as an incoming edge of this activity // node activation. edge.target = this; this.incomingEdges.addValue(edge); } // addIncomingEdge public void createNodeActivations() { // Create node activations for any subnodes of the node for this // activation. // For most kinds of nodes, this does nothing. return; } // createNodeActivations public void createEdgeInstances() { // Create edge instances for any edge instances owned by the node for // this activation. // For most kinds of nodes, this does nothing. return; } // createEdgeInstances public boolean isSourceFor( fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance edgeInstance) { // Check if this node activation is the effective source for the given // edge instance. return edgeInstance.source == this; } // isSourceFor public fUML.Semantics.Activities.IntermediateActivities.ActivityExecution getActivityExecution() { // Return the activity execution that contains this activity node // activation, directly or indirectly. return this.group.getActivityExecution(); } // getActivityExecution public fUML.Semantics.Classes.Kernel.Object_ getExecutionContext() { // Get the context object for the containing activity execution. return this.getActivityExecution().context; } // getExecutionContext public fUML.Semantics.Loci.LociL1.Locus getExecutionLocus() { // Get the locus of the containing activity execution. return this.getActivityExecution().locus; } // getExecutionLocus public fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation getNodeActivation( fUML.Syntax.Activities.IntermediateActivities.ActivityNode node) { // Get the activity node activation corresponding to the given activity // node, in the context of this activity node activation. // By default, return this activity node activation, if it is for the // given node, otherwise return nothing. ActivityNodeActivation activation = null; if (node == this.node) { activation = this; } return activation; } // getNodeActivation public void addToken( fUML.Semantics.Activities.IntermediateActivities.Token token) { // Transfer the given token to be held by this node. Debug.println("[addToken] " + (this.node == null? "...": "node = " + this.node.name)); Token transferredToken = token.transfer(this); // Debug.println("[addToken] Adding token with value = " + // transferredToken.getValue()); this.heldTokens.addValue(transferredToken); } // addToken public int removeToken( fUML.Semantics.Activities.IntermediateActivities.Token token) { // Remove the given token, if it is held by this node activation. // Return the position (counting from 1) of the removed token (0 if // there is none removed). boolean notFound = true; int i = 1; while (notFound & i <= this.heldTokens.size()) { if (this.heldTokens.getValue(i - 1) == token) { Debug.println("[removeToken] " + (this.node == null? "...": "node = " + this.node.name)); this.heldTokens.remove(i - 1); notFound = false; } i = i + 1; } if (notFound) { i = 0; } else { i = i - 1; } return i; } // removeToken public void addTokens( fUML.Semantics.Activities.IntermediateActivities.TokenList tokens) { // Transfer the given tokens to be the held tokens for this node. // if (this.node == null) { // Debug.println("[addTokens] ..."); // } else { // Debug.println("[addTokens] node = " + this.node.name); // } for (int i = 0; i < tokens.size(); i++) { Token token = tokens.getValue(i); this.addToken(token); } } // addTokens public fUML.Semantics.Activities.IntermediateActivities.TokenList takeTokens() { // Take the tokens held by this node activation. TokenList tokens = this.getTokens(); this.clearTokens(); return tokens; } // takeTokens public void clearTokens() { // Remove all held tokens. while (this.heldTokens.size() > 0) { this.heldTokens.getValue(0).withdraw(); } } // clearTokens public fUML.Semantics.Activities.IntermediateActivities.TokenList getTokens() { // Get the tokens held by this node activation. // Debug.println("[getTokens] node = " + this.node.name); TokenList tokens = new TokenList(); TokenList heldTokens = this.heldTokens; for (int i = 0; i < heldTokens.size(); i++) { Token heldToken = heldTokens.getValue(i); // Debug.println("[getTokens] token value = " + // heldTokens.getValue()); tokens.addValue(heldToken); } return tokens; } // getTokens public void suspend() { // Suspend this activation within the activation group that contains it. this.group.suspend(this); } // suspend public void resume() { // Resume this activation within the activation group that contains it. this.group.resume(this); } // resume } // ActivityNodeActivation