blob: a9f16caa101c32a5a683fdc87d36bb27a7c4cc44 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2015 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Jeremie Tatibouet (CEA LIST) - Based on Ed Seidewitz remarks
*
*****************************************************************************/
package org.eclipse.papyrus.moka.fuml.statemachines.Semantics.StateMachines;
import java.util.List;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IFeatureValue;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IObject_;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.BasicBehaviors.IParameterValue;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.BasicBehaviors.IExecution;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.Communications.IEventAccepter;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.Communications.IEventOccurrence;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.Communications.IObjectActivation;
import org.eclipse.papyrus.moka.fuml.Semantics.impl.Classes.Kernel.Object_;
import org.eclipse.papyrus.moka.fuml.statemachines.interfaces.Semantics.CommonBehavior.ISM_ObjectActivation;
import org.eclipse.papyrus.moka.fuml.statemachines.interfaces.Semantics.StateMachines.IDeferredEventOccurrence;
import org.eclipse.papyrus.moka.fuml.statemachines.interfaces.Semantics.StateMachines.IDoActivityContextObject;
import org.eclipse.papyrus.moka.fuml.statemachines.interfaces.Semantics.StateMachines.IStateActivation;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.StructuralFeature;
public class DoActivityContextObject extends Object_ implements IDoActivityContextObject{
// The state activation that initiated the execution of the
// do activity behavior
public IStateActivation owner;
// The context of the state-machine that lead to the invocation of the
// doActivity behavior.
public IObject_ context;
public IObject_ getContext(){
return this.context;
}
public void initialize(IObject_ context){
// Context object of this DoActivityContextObject is the context
// of the state machine which has invoked the doActivity.
if(context!=null){
this.context = context;
}
}
@Override
public void startBehavior(Class classifier, List<IParameterValue> inputs) {
// Starts the behavior of a DoActivityContextObject. It behaves the
// same than in fUML except that for object is associated to a specific
// type of object activation: DoActivityContextObjectActivation
if(this.objectActivation == null){
this.objectActivation = new DoActivityContextObjectActivation();
this.objectActivation.setObject(this);
}
this.objectActivation.startBehavior(classifier, inputs);
}
@Override
public void register(IEventAccepter accepter) {
// When the executing doActivity registers an accepter it searches through the deferred event
// pool of the object activation associated to the state-machine context.
// 1. If the accepter being registered matches one of the deferred events then this event is
// transferred into the event pool of the doActivity object activation. This implies the
// event will be dispatched in a RTC step performed by the doActivity object activation.
// 2. If the accepter being registered does not match one of the deferred events then this latter
// is wrapped in another accepter which is registered by the state machine context object activation.
// This is realized in order to guarantee that the doActivity will have a chance to match an event
// received by the state-machine context object.
super.register(accepter);
ISM_ObjectActivation contextObjectActivation = (ISM_ObjectActivation) this.context.getObjectActivation();
int i = 1;
IDeferredEventOccurrence matchedDeferredEvent = null;
while(matchedDeferredEvent == null && i <= contextObjectActivation.getDeferredEvents().size()){
IDeferredEventOccurrence eventOccurrence = contextObjectActivation.getDeferredEvents().get(i-1);
if(this.owner == eventOccurrence.getConstrainingStateActivation() && accepter.match(eventOccurrence.getDeferredEventOccurrence())){
matchedDeferredEvent = eventOccurrence;
}
i++;
}
if(matchedDeferredEvent == null){
DoActivityExecutionEventAccepter encapsulatingAccepter = new DoActivityExecutionEventAccepter();
encapsulatingAccepter.encapsulatedAccepter = accepter;
encapsulatingAccepter.context = this;
this.context.register(encapsulatingAccepter);
}else{
contextObjectActivation.getDeferredEvents().remove(matchedDeferredEvent);
this.objectActivation.getEvents().add(matchedDeferredEvent.getDeferredEventOccurrence());
this.objectActivation.notifyEventArrival();
}
}
@Override
public IFeatureValue getFeatureValue(StructuralFeature feature) {
// Delegate read of a particular feature to the state-machine context
IFeatureValue featureValue = null;
if(this.context!=null){
featureValue = this.context.getFeatureValue(feature);
}
return featureValue;
}
@Override
public void setFeatureValue(StructuralFeature feature, List<IValue> values, Integer position) {
// Delegate write of particular feature to the state-machine context
if(this.context!=null){
this.context.setFeatureValue(feature, values, position);
}
}
@Override
public IExecution dispatch(Operation operation) {
// Delegate operation call to the state-machine context
IExecution execution = null;
if(this.context!=null){
execution = this.context.dispatch(operation);
}
return execution;
}
@Override
public void send(IEventOccurrence eventOccurrence) {
// Delegate the reception of a signal to the state-machine context
if(this.context!=null){
this.context.send(eventOccurrence);
}
}
@Override
public void destroy() {
// When destroyed in addition to the usual behavior, the do activity context object
// has to remove the encapsulating accepters it may have registered.
for(int i=0; i < this.objectActivation.getWaitingEventAccepters().size(); i++){
this.unregisterFromContext(this.objectActivation.getWaitingEventAccepters().get(i));
}
super.destroy();
}
protected void unregisterFromContext(IEventAccepter encapsulatedAccepter){
// Unregister in the context of this do activity context the encapsulating
// event accepter.
IObjectActivation contextObjectActivation = this.context.getObjectActivation();
if(contextObjectActivation!=null){
DoActivityExecutionEventAccepter encapsulatingAccepter = null;
int i = 0;
while(encapsulatingAccepter==null && i < contextObjectActivation.getWaitingEventAccepters().size()){
IEventAccepter currentAccepter = contextObjectActivation.getWaitingEventAccepters().get(i);
if(currentAccepter instanceof DoActivityExecutionEventAccepter
&& ((DoActivityExecutionEventAccepter)currentAccepter).encapsulatedAccepter==encapsulatedAccepter){
encapsulatingAccepter = (DoActivityExecutionEventAccepter) currentAccepter;
}
i++;
}
if(encapsulatingAccepter!=null){
contextObjectActivation.unregister(encapsulatingAccepter);
}
}
}
}