/*
* 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.CommonBehaviors.Communications;
import fUML.Debug;
import UMLPrimitiveTypes.*;
import java.util.Iterator;
import fUML.Syntax.Classes.Kernel.*;
import fUML.Syntax.CommonBehaviors.BasicBehaviors.*;
import fUML.Semantics.CommonBehaviors.BasicBehaviors.*;
import fUML.Semantics.Loci.LociL1.*;
public class ObjectActivation extends org.modeldriven.fuml.FumlObject {
public fUML.Semantics.CommonBehaviors.Communications.ClassifierBehaviorInvocationEventAccepterList classifierBehaviorInvocations = new fUML.Semantics.CommonBehaviors.Communications.ClassifierBehaviorInvocationEventAccepterList();
public fUML.Semantics.CommonBehaviors.Communications.EventAccepterList waitingEventAccepters = new fUML.Semantics.CommonBehaviors.Communications.EventAccepterList();
public fUML.Semantics.CommonBehaviors.Communications.EventOccurrenceList eventPool = new fUML.Semantics.CommonBehaviors.Communications.EventOccurrenceList();
public fUML.Semantics.Classes.Kernel.Object_ object = null;
public void stop() {
// Stop this object activation by terminating all classifier behavior
// executions.
ClassifierBehaviorInvocationEventAccepterList classifierBehaviorInvocations = this.classifierBehaviorInvocations;
for (int i = 0; i < classifierBehaviorInvocations.size(); i++) {
ClassifierBehaviorInvocationEventAccepter classifierBehaviorInvocation = classifierBehaviorInvocations
.getValue(i);
classifierBehaviorInvocation.terminate();
}
} // stop
public void register(
fUML.Semantics.CommonBehaviors.Communications.EventAccepter accepter) {
// Register the given event accepter to wait for a dispatched signal
// event.
Debug.println("[register] object = " + this.object);
Debug.println("[register] accepter = " + accepter);
this.waitingEventAccepters.addValue(accepter);
} // register
public void unregister(
fUML.Semantics.CommonBehaviors.Communications.EventAccepter accepter) {
// Remove the given event accepter for the list of waiting event
// accepters.
Debug.println("[unregister] object = " + this.object);
Debug.println("[unregister] accepter = " + accepter);
boolean notFound = true;
int i = 1;
while (notFound & i <= this.waitingEventAccepters.size()) {
if (this.waitingEventAccepters.getValue(i - 1) == accepter) {
this.waitingEventAccepters.remove(i - 1);
notFound = false;
}
i = i + 1;
}
} // unregister
public void dispatchNextEvent() {
// Get the next event occurrence out of the event pool.
// If there are one or more waiting event accepters with triggers that
// match the event occurrence, then dispatch it to exactly one of those
// waiting accepters.
if (this.eventPool.size() > 0) {
EventOccurrence eventOccurrence = this.getNextEvent();
Debug.println("[dispatchNextEvent] eventOccurrence = " + eventOccurrence);
intList matchingEventAccepterIndexes = new intList();
EventAccepterList waitingEventAccepters = this.waitingEventAccepters;
for (int i = 0; i < waitingEventAccepters.size(); i++) {
EventAccepter eventAccepter = waitingEventAccepters.getValue(i);
if (eventAccepter.match(eventOccurrence)) {
matchingEventAccepterIndexes.addValue(i);
}
}
if (matchingEventAccepterIndexes.size() > 0) {
// *** Choose one matching event accepter non-deterministically. ***
int j = ((ChoiceStrategy) this.object.locus.factory
.getStrategy("choice"))
.choose(matchingEventAccepterIndexes.size());
int k = matchingEventAccepterIndexes.getValue(j - 1);
EventAccepter selectedEventAccepter = this.waitingEventAccepters
.getValue(k);
this.waitingEventAccepters.removeValue(k);
selectedEventAccepter.accept(eventOccurrence);
}
}
} // dispatchNextEvent
public fUML.Semantics.CommonBehaviors.Communications.EventOccurrence getNextEvent() {
// Get the next event from the event pool, using a get next event
// strategy.
return ((GetNextEventStrategy) this.object.locus.factory
.getStrategy("getNextEvent")).getNextEvent(this);
} // getNextEvent
public void send(
fUML.Semantics.CommonBehaviors.Communications.EventOccurrence eventOccurrence) {
// Add an event occurrence to the event pool and signal that a
// new event occurrence has arrived.
this.eventPool.addValue(eventOccurrence);
_send(new ArrivalSignal());
} // send
public void startBehavior(
fUML.Syntax.Classes.Kernel.Class_ classifier,
fUML.Semantics.CommonBehaviors.BasicBehaviors.ParameterValueList inputs) {
// Start the event dispatch loop for this object activation (if it has
// not already been started).
// If a classifier is given that is a type of the object of this object
// activation and there is not already a classifier behavior invocation
// for it,
// then create a classifier behavior invocation for it and add an invocation
// event occurrence to the event pool.
// Otherwise, create a classifier behavior invocation for each of the
// types of the object of this object activation which has a classifier
// behavior or which is a behavior itself
// and for which there is not currently a classifier behavior invocation.
// Start EventDispatchLoop
_startObjectBehavior();
if (classifier == null) {
Debug.println("[startBehavior] Starting behavior for all classifiers...");
// *** Start all classifier behaviors concurrently. ***
Class_List types = this.object.types;
for (Iterator i = types.iterator(); i.hasNext();) {
Class_ type = (Class_) i.next();
if (type instanceof Behavior | type.classifierBehavior != null) {
this.startBehavior(type, new ParameterValueList());
}
}
} else {
Debug.println("[startBehavior] Starting behavior for " + classifier.name + "...");
_beginIsolation();
boolean notYetStarted = true;
int i = 1;
while (notYetStarted
& i <= this.classifierBehaviorInvocations.size()) {
notYetStarted = (this.classifierBehaviorInvocations
.getValue(i - 1).classifier != classifier);
i = i + 1;
}
if (notYetStarted) {
ClassifierBehaviorInvocationEventAccepter newInvocation = new ClassifierBehaviorInvocationEventAccepter();
newInvocation.objectActivation = this;
this.classifierBehaviorInvocations.addValue(newInvocation);
newInvocation.invokeBehavior(classifier, inputs);
InvocationEventOccurrence eventOccurrence = new InvocationEventOccurrence();
eventOccurrence.execution = newInvocation.execution;
this.eventPool.addValue(eventOccurrence);
_send(new ArrivalSignal());
}
_endIsolation();
}
} // startBehavior
private ObjectActivation_EventDispatchLoopExecution behavior =
new ObjectActivation_EventDispatchLoopExecution(this);
public void _send(ArrivalSignal signal) {
this.behavior._send(signal);
}
public void _startObjectBehavior() {
this.behavior._startObjectBehavior();
}
public static void _endIsolation() {
Debug.println("[_endIsolation] End isolation.");
}
public static void _beginIsolation() {
Debug.println("[_beginIsolation] Begin isolation.");
}
} // ObjectActivation