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

fUML.Semantics.CommonBehaviors.Communications.CallEventExecution 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
/*
 * Copyright 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.CommonBehaviors.Communications;

import fUML.Debug;
import fUML.Semantics.Classes.Kernel.Reference;
import fUML.Semantics.Classes.Kernel.Value;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.Execution;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.ParameterValue;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.ParameterValueList;
import fUML.Syntax.Classes.Kernel.Operation;
import fUML.Syntax.Classes.Kernel.Parameter;
import fUML.Syntax.Classes.Kernel.ParameterDirectionKind;
import fUML.Syntax.Classes.Kernel.ParameterList;

public class CallEventExecution extends Execution {

	public boolean callerSuspended = false;
	
	public boolean isCallerSuspended() {
		// Check if the caller is still suspended.
		// This is done in isolation from possible concurrent updates to this flag.
		
		_beginIsolation();
		boolean isSuspended = this.callerSuspended;
		Debug.println("[isCallerSuspended] operation = " + this.getOperation().name + 
				", callerSuspended = " + isSuspended);
		_endIsolation();
		
		return isSuspended;
	}
	
	public void setCallerSuspended(boolean callerSuspended) {
		// Set the caller suspended flag to the given value.
	    // This is done in isolation from possible concurrent queries to this flag.
		
		_beginIsolation();
		this.callerSuspended = callerSuspended;
		Debug.println("[setCallerSuspended] operation = " + this.getOperation().name + 
				", callerSuspended = " + callerSuspended);
		_endIsolation();
	}
	
	public void suspendCaller() {
		// Suspend the caller until the caller is released.
		
		while(this.isCallerSuspended()) {
			this.wait_();
		}
		
	}
	
	public void releaseCaller() {
		// Release the caller, if suspended.
		
		this.setCallerSuspended(false);
	}
	
	@Override
	public void execute() {
		// Make the call on the target object (which is the context of this execution) 
		// and suspend the caller until the call is completed. 
		
		// Note: The callerSuspended flag needs to be set before the call is made,
		// in case the call is immediately handled and returned, even before the
		// suspend loop is started.
		this.setCallerSuspended(true);
		
		this.makeCall();		
		this.suspendCaller();		
	}
	
	public void makeCall() {
		// Make the call on the target object (which is the context of this execution)
		// by sending a call event occurrence. (Note that the call will never be 
		// completed if the target is not an active object, since then the object 
		// would then have no event pool in which the event occurrence could be placed.)
		
		Reference reference = new Reference();
		reference.referent = this.context;		
		this.createEventOccurrence().sendTo(reference);		
	}
	
	public EventOccurrence createEventOccurrence() {
		// Create a call event occurrence associated with this call event execution.
		// (This operation may be overridden in subclasses to alter how the event
		// occurrence is create, e.g., if it is necessary to wrap it.)
		
		CallEventOccurrence eventOccurrence = new CallEventOccurrence();
		eventOccurrence.execution = this;
		return eventOccurrence;
	}
	
	public Operation getOperation() {
		// Return the operation being called by this call event execution.

		return ((CallEventBehavior)this.getBehavior()).operation;
	}
	
	public ParameterValueList getInputParameterValues(){
		// Return input parameter values for this execution
		
		ParameterValueList parameterValues = new ParameterValueList();
		for(int i=0; i < this.parameterValues.size(); i++){
			ParameterValue parameterValue = this.parameterValues.get(i);
			if(parameterValue.parameter.direction == ParameterDirectionKind.in
					| parameterValue.parameter.direction == ParameterDirectionKind.inout){
				parameterValues.addValue(parameterValue);
			}
		}
		return parameterValues;
	}

	public void setOutputParameterValues(ParameterValueList parameterValues) {
		// Set the output parameter values for this execution.
		
		ParameterList parameters = this.getBehavior().ownedParameter;
		int i = 1;
		int j = 1;
		while (i <= parameters.size()) {
            Parameter parameter = parameters.get(i-1);
            if (parameter.direction == ParameterDirectionKind.inout | 
            		parameter.direction == ParameterDirectionKind.out | 
            		parameter.direction == ParameterDirectionKind.return_ ) {
				ParameterValue parameterValue = parameterValues.get(j-1);
				parameterValue.parameter = parameter;
				this.setParameterValue(parameterValue);
				j = j + 1;
            }
			i = i + 1;
		}
	}
	
	@Override
	public Value new_() {
		// Create a new call event execution.
		
		return new CallEventExecution();
	}
	
	@Override
	public Value copy() {
		// Create a new call event execution that is a copy of this execution, with the
		// caller initially not suspended.
		
		CallEventExecution copy = (CallEventExecution)super.copy();
		copy.callerSuspended = false;
		return copy;
	}
	
	 public void wait_() {
		 // Wait for an indeterminate amount of time to allow other concurrent
		 // executions to proceed.
		 // [There is no further formal specification for this operation.]
		 
		 Debug.println(!ExecutionQueue.step(), "[wait] Stuck!");
	 }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy