blob: 0d82cd098ab186381ba83a25c2a9b905a1578616 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 Borland Software Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Borland Software Corporation - initial API and implementation
* Christopher Gerking - bug 431082
*******************************************************************************/
package org.eclipse.m2m.qvt.oml;
import java.util.Collections;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.m2m.internal.qvt.oml.InternalTransformationExecutor.TracesAwareExecutor;
import org.eclipse.m2m.internal.qvt.oml.TransformationExecutorBlackboxRegistry;
import org.eclipse.m2m.internal.qvt.oml.evaluator.QVTEvaluationOptions;
import org.eclipse.m2m.qvt.oml.util.Trace;
/**
* A utility class that enables to execute existing transformation in the
* specified execution context.
*
* @since 2.0
*/
public final class TransformationExecutor {
/**
* Support for blackbox libraries in standalone mode.
* Allows to import a Java classes by means of their fully qualified names, and call its methods directly from QVTo.
*
* <p> To make this work, there is {@code Annotation} type called 'Module' which enables annotating a Java class with
* the set of nsURIs that it requires to resolve types:
*
* <p> <blockquote><pre>
* @Module(packageURIs={"http://www.eclipse.org/emf/2002/Ecore"})
* public class Test {
* ...
* }
* </pre></blockquote>
*
* Usage example:
*
* <p> <blockquote><pre>
* TransformationExecutor.BlackboxRegistry.INSTANCE.registerModules(Test.class);
* TransformationExecutor executor = new TransformationExecutor(uri);
* ExecutionContextImpl context = new ExecutionContextImpl();
* ExecutionDiagnostic result = executor.execute(context);
* </pre></blockquote>
*
* @since 3.5
*
*/
public interface BlackboxRegistry {
BlackboxRegistry INSTANCE = new TransformationExecutorBlackboxRegistry();
Diagnostic registerModules(Class<?>... classes);
Diagnostic registerModule(Class<?> cls);
Diagnostic registerModule(Class<?> cls, String unitQualifiedName, String moduleName);
Diagnostic registerModule(Class<?> cls, String unitQualifiedName, String moduleName, String[] packageURIs);
}
private TracesAwareExecutor fExector;
/**
* Constructs the executor for the given transformation URI.
* <p>
* No attempt to resolve and load the transformation is done at this step
*
* @param uri
* the URI of an existing transformation
*/
public TransformationExecutor(URI uri) {
fExector = new TracesAwareExecutor(uri);
}
/**
* Constructs the executor for the given transformation URI.
* <p>
* No attempt to resolve and load the transformation is done at this step
*
* @param uri
* the URI of an existing transformation
* @param registry
* a package registry of meta-models to be referenced by the
* executed transformation
* @since 3.0
*/
public TransformationExecutor(URI uri, EPackage.Registry registry) {
fExector = new TracesAwareExecutor(uri, registry);
}
/**
* Attempts to load the transformation referred by this executor and checks
* if it is valid for execution.
* <p>
* <b>Remark:</b></br> Only the first performs the actual transformation
* loading, subsequent calls to this method will return the existing
* diagnostic.
*
* @return the diagnostic indicating possible problems of the load action
*/
public Diagnostic loadTransformation() {
return loadTransformation(new NullProgressMonitor());
}
/**
* Attempts to load the transformation referred by this executor and checks
* if it is valid for execution.
* <p>
* <b>Remark:</b></br> Only the first performs the actual transformation
* loading, subsequent calls to this method will return the existing
* diagnostic.
*
* @since 3.4
* @param the monitor indicating load progress and cancellation
* @return the diagnostic indicating possible problems of the load action
*/
public Diagnostic loadTransformation(IProgressMonitor monitor) {
return fExector.loadTransformation(monitor);
}
/**
* Executes the transformation referred by this executor using the given
* model parameters and execution context.
*
* @param executionContext
* the context object keeping the execution environment details
* @param modelParameters
* the actual model arguments to the transformation
*
* @return the diagnostic object indicating the execution result status,
* also keeping the details of possible problems
* @throws IllegalArgumentException
* if the context or any of the model parameters is
* <code>null</code>
*/
public ExecutionDiagnostic execute(ExecutionContext executionContext,
ModelExtent... modelParameters) {
ExecutionDiagnostic executionDiagnostic = fExector.execute(executionContext, modelParameters);
Trace trace = executionContext.getSessionData().getValue(QVTEvaluationOptions.INCREMENTAL_UPDATE_TRACE);
if (trace != null) {
trace.setTraceContent(Collections.singletonList(fExector.getTraces()));
}
return executionDiagnostic;
}
/**
* Clean all resources associated with the executor.
*
* @since 3.5
*/
public void cleanup() {
fExector.cleanup();
}
}