blob: fec1e8beceab5e904dcca9f9e08d4e538e804c8f [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2019, 2020 CEA LIST and others.
*
* 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.engine.uml;
import java.util.ArrayList;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.papyrus.moka.debug.engine.DebuggableExecutionEngine;
import org.eclipse.papyrus.moka.debug.engine.IDebuggableExecutionEngine;
import org.eclipse.papyrus.moka.debug.engine.IDebuggableExecutionEngineThread;
import org.eclipse.papyrus.moka.engine.uml.libraries.LibraryRegistry;
import org.eclipse.papyrus.moka.engine.uml.scheduling.IsTargetThreadCondition;
import org.eclipse.papyrus.moka.engine.uml.scheduling.UMLTaskExecutionFactory;
import org.eclipse.papyrus.moka.fuml.actions.DefaultCreateObjectActionStrategy;
import org.eclipse.papyrus.moka.fuml.actions.DefaultGetAssociationStrategy;
import org.eclipse.papyrus.moka.fuml.commonbehavior.FIFOGetNextEventStrategy;
import org.eclipse.papyrus.moka.fuml.commonbehavior.IParameterValue;
import org.eclipse.papyrus.moka.fuml.loci.FirstChoiceStrategy;
import org.eclipse.papyrus.moka.fuml.loci.ILocus;
import org.eclipse.papyrus.moka.fuml.loci.ISemanticVisitor;
import org.eclipse.papyrus.moka.fuml.structuredclassifiers.IObject_;
import org.eclipse.papyrus.moka.fuml.tasks.IUMLRootTaskExecution;
import org.eclipse.papyrus.moka.fuml.tasks.IUMLTaskExecutionFactory;
import org.eclipse.papyrus.moka.kernel.engine.EngineConfiguration;
import org.eclipse.papyrus.moka.kernel.engine.ExecutionEngineException;
import org.eclipse.papyrus.moka.kernel.scheduling.control.Scheduler;
import org.eclipse.papyrus.moka.pscs.actions.additions.CS_NotNormativeDefaultConstructStrategy;
import org.eclipse.papyrus.moka.pscs.loci.CS_Executor;
import org.eclipse.papyrus.moka.pscs.structuredclassifiers.CS_DefaultRequestPropagationStrategy;
import org.eclipse.papyrus.moka.pscs.structuredclassifiers.CS_DispatchOperationOfInterfaceStrategy;
import org.eclipse.papyrus.moka.pscs.structuredclassifiers.CS_NameBased_StructuralFeatureOfInterfaceAccessStrategy;
import org.eclipse.papyrus.moka.pssm.loci.SM_ExecutionFactory;
import org.eclipse.papyrus.moka.pssm.loci.SM_Locus;
import org.eclipse.papyrus.moka.utils.UMLPrimitiveTypesUtils;
import org.eclipse.uml2.uml.Element;
public class UMLExecutionEngine extends DebuggableExecutionEngine<IObject_, ISemanticVisitor>
implements IUMLExecutionEngine {
/**
* Virtual machine on which the execution takes place
*/
protected ILocus locus;
/**
* Factory enabling the creation of the appropriate root task for this engine
*/
protected IUMLTaskExecutionFactory rootTaskFactory;
/**
* Behave as the super class. In addition, instantiate the locus and
* parameterize it with the appropriate execution factory and executor. Finally,
* built in types, libraries and semantic strategies are installed at the locus
*/
@Override
public void init(EngineConfiguration<?> configuration, SubMonitor monitor) {
super.init(configuration, monitor);
locus = createLocus();
rootTaskFactory = createUMLTaskFactory();
locus.getFactory().setTaskFactory(rootTaskFactory);
installBuiltInTypes();
installLibraries();
installSemanticStrategies();
}
/**
* Create the UML task factory used by this engine
*
* @return the task factory
*/
protected IUMLTaskExecutionFactory createUMLTaskFactory() {
return new UMLTaskExecutionFactory(controller.getExecutionLoop());
}
/**
* Create and parameterize the locus
*/
@Override
public ILocus createLocus() {
ILocus locus = new SM_Locus();
locus.setExecutor(new CS_Executor());
locus.setFactory(new SM_ExecutionFactory());
return locus;
}
/**
* Start the execution. This is technically realized by adding the the root
* execution to the execution queue controlled by the execution controller
*/
@Override
public void start(SubMonitor monitor) throws ExecutionEngineException {
Element source = (Element) configuration.getExecutionSource();
if (locus != null && source != null) {
IUMLRootTaskExecution<?> rootExecution = rootTaskFactory.createRootExecution(source);
if(rootExecution != null) {
rootExecution.setLocus(locus);
rootExecution.setInputParameterValues(new ArrayList<IParameterValue>());
if(rootExecution.canExecute()) {
controller.getExecutionLoop().init(rootExecution, new Scheduler());
SubMonitor progress = monitor.split(1);
progress.subTask("Run model"); //$NON-NLS-1$
controller.start();
progress.worked(1);
} else {
throw new ExecutionEngineException(identifier, status, "Could not start the execution from the specified model element"); //$NON-NLS-1$
}
} else {
throw new ExecutionEngineException(identifier, status, "Could not instantiate an execution from the specified element"); //$NON-NLS-1$
}
}
}
/**
* Register UML primitive types
*/
@Override
public void installBuiltInTypes() {
Element source = (Element) configuration.getExecutionSource();
if (locus != null && source != null) {
locus.getFactory().addBuiltInType(UMLPrimitiveTypesUtils.getReal(source));
locus.getFactory().addBuiltInType(UMLPrimitiveTypesUtils.getInteger(source));
locus.getFactory().addBuiltInType(UMLPrimitiveTypesUtils.getBoolean(source));
locus.getFactory().addBuiltInType(UMLPrimitiveTypesUtils.getString(source));
}
}
/**
* Install all registered libraries (e.g., the FUML Library)
*/
@Override
public void installLibraries() {
Element source = (Element) configuration.getExecutionSource();
if (locus != null && source.eResource() != null && source.eResource().getResourceSet() != null) {
LibraryRegistry.getInstance().loadLibraryFactories(source.eResource().getResourceSet());
LibraryRegistry.getInstance().installLibraries(locus);
}
}
/**
* Install semantic strategies used to realized the execution
*/
@Override
public void installSemanticStrategies() {
if (locus != null) {
locus.getFactory().setStrategy(new FirstChoiceStrategy());
locus.getFactory().setStrategy(new FIFOGetNextEventStrategy());
locus.getFactory().setStrategy(new CS_DispatchOperationOfInterfaceStrategy());
locus.getFactory().setStrategy(new CS_NameBased_StructuralFeatureOfInterfaceAccessStrategy());
locus.getFactory().setStrategy(new CS_DefaultRequestPropagationStrategy());
locus.getFactory().setStrategy(new CS_NotNormativeDefaultConstructStrategy());
locus.getFactory().setStrategy(new DefaultGetAssociationStrategy());
locus.getFactory().setStrategy(new DefaultCreateObjectActionStrategy());
}
}
/**
* @see {@link IDebuggableExecutionEngine#suspendThread(Object)}
*/
@Override
public IDebuggableExecutionEngineThread<IObject_, ISemanticVisitor> getThread(String identifier) {
IDebuggableExecutionEngineThread<IObject_, ISemanticVisitor> thread = null;
if(!debuggableThreadLock.isHeldByCurrentThread()) {
debuggableThreadLock.lock();
}
thread = debuggableThread.get(identifier);
if(debuggableThreadLock.isHeldByCurrentThread()) {
debuggableThreadLock.unlock();
}
return thread;
}
/**
* @see {@link IDebuggableExecutionEngine#suspendThread(Object)}
*
* Execution of this active object is suspended
*/
public void suspendThread(IDebuggableExecutionEngineThread<IObject_, ISemanticVisitor> debuggableThread) {
controller.getExecutionLoop().suspend(new IsTargetThreadCondition(debuggableThread.getThread()));
}
/**
* @see {@link IDebuggableExecutionEngine#resumeThread(Object)}
*
* Execution of this active object is resumed
*/
public void resumeThread(IDebuggableExecutionEngineThread<IObject_, ISemanticVisitor> debuggableThread) {
controller.getExecutionLoop().resume(new IsTargetThreadCondition(debuggableThread.getThread()));
}
/**
* @see {@link IDebuggableExecutionEngine#terminateThread(Object)}
*
* Execution of this active object is terminated
*/
public void terminateThread(IDebuggableExecutionEngineThread<IObject_, ISemanticVisitor> debuggableThread) {
controller.getExecutionLoop().terminate(new IsTargetThreadCondition(debuggableThread.getThread()));
}
}