blob: 214e792091a4983c6e5c456e797d1bf1a1cce4fc [file] [log] [blame]
/*****************************************************************************
*
* Copyright (c) 2017 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* CEA LIST Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.moka.externalcontrol.semantics;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.papyrus.moka.externalcontrol.advice.IControllerAdvice;
import org.eclipse.papyrus.moka.externalcontrol.controller.ExternalController;
import org.eclipse.papyrus.moka.fuml.actions.CallActionActivation;
import org.eclipse.papyrus.moka.fuml.actions.ICallActionActivation;
import org.eclipse.papyrus.moka.fuml.activities.IToken;
import org.eclipse.papyrus.moka.fuml.commonbehavior.IExecution;
import org.eclipse.papyrus.moka.fuml.commonbehavior.IParameterValue;
import org.eclipse.papyrus.moka.fuml.commonbehavior.ParameterValue;
import org.eclipse.uml2.uml.CallAction;
import org.eclipse.uml2.uml.InputPin;
import org.eclipse.uml2.uml.OutputPin;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
public class ExternallyControlledCallActionActivation extends AbstractExternallyControlledActionActivation<CallActionActivation> implements ICallActionActivation {
public ExternallyControlledCallActionActivation(CallActionActivation visitor, ExternalController controller, List<IControllerAdvice> advices) {
super(visitor, controller, advices);
}
/*
* The set of execution object for currently ongoing calls made through this
* call action activation.
*/
public List<IExecution> callExecutions = new ArrayList<IExecution>();
private IExecution suspendedExecution;
@Override
protected void doSemanticAction() {
doAction();
}
@Override
public void doAction() {
// Get the call execution object, set its input parameters from the
// argument pins and execute it.
// Once execution completes, copy the values of the output parameters of
// the call execution to the result pins of the call action execution,
// then destroy the execution.
IExecution callExecution = this.getCallExecution();
if (callExecution != null) {
this.callExecutions.add(callExecution);
CallAction callAction = (CallAction) (this.getNode());
List<InputPin> argumentPins = callAction.getArguments();
List<Parameter> parameters = callExecution.getBehavior().getOwnedParameters();
int pinNumber = 1;
int i = 1;
while (i <= parameters.size()) {
Parameter parameter = parameters.get(i - 1);
if (parameter.getDirection() == ParameterDirectionKind.IN_LITERAL | parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL) {
ParameterValue parameterValue = new ParameterValue();
parameterValue.parameter = parameter;
parameterValue.values = this.takeTokens(argumentPins.get(pinNumber - 1));
callExecution.setParameterValue(parameterValue);
pinNumber = pinNumber + 1;
}
i = i + 1;
}
callExecution.execute();
suspendedExecution = callExecution;
}
}
@Override
public void doResumeExecution() {
CallAction callAction = (CallAction) (this.getNode());
List<OutputPin> resultPins = callAction.getResults();
List<Parameter> parameters = suspendedExecution.getBehavior().getOwnedParameters();
List<IParameterValue> outputParameterValues = suspendedExecution.getOutputParameterValues();
int pinNumber = 1;
int i = 1;
while (i <= parameters.size()) {
Parameter parameter = parameters.get(i - 1);
if ((parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL)) {
for (int j = 0; j < outputParameterValues.size(); j++) {
IParameterValue outputParameterValue = outputParameterValues.get(j);
if (outputParameterValue.getParameter() == parameter) {
OutputPin resultPin = resultPins.get(pinNumber - 1);
this.putTokens(resultPin, outputParameterValue.getValues());
}
}
pinNumber = pinNumber + 1;
}
i = i + 1;
}
suspendedExecution.destroy();
this.removeCallExecution(suspendedExecution);
suspendedExecution = null;
// FIXME completeAction should probably move to IActionActivation
List<IToken> incomingTokens = delegatedVisitor.completeAction();
if (incomingTokens.size() > 0) {
this.fire(incomingTokens);
}
// TODO clarify if resume should be called before or after complete action...
this.resume();
}
@Override
public IExecution getCallExecution() {
IExecution execution = delegatedVisitor.getCallExecution();
callExecutions.add(execution);
if (execution instanceof ExternallyControlledActivityExecution){
((ExternallyControlledActivityExecution)execution).setStackParent(this);
}
return execution;
}
@Override
public void removeCallExecution(IExecution execution) {
delegatedVisitor.removeCallExecution(execution);
callExecutions.remove(execution);
}
}