/*******************************************************************************
* Copyright (c) 2008, 2009 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.runtime.util;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalStdLibrary;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ImportToNonTransformCtxHelper;
import org.eclipse.m2m.internal.qvt.oml.evaluator.QvtOperationalEvaluationVisitorImpl;
import org.eclipse.m2m.internal.qvt.oml.expressions.Helper;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.library.Context;
/**
* This class represents an execution context which is not a QVT transformation but a generic
* executor.
* <p>
* The motivation of this class is allowing a generic client to reuse existing QVT Libraries in
* other execution environments. Operation call objects can be invoked within a given execution context.
* <p>
* The execution context is constructed with as set of library modules that are imported into the scope of
* the context. Only QVT libraries and its helper operations are supported, only operations from the
* libraries that are already imported in the context can be called.
* </p>
* See the following example code snippet:
<pre>
Module module = ...; // get a valid AST of a library
NonTransformationExecutionContext execContext = new NonTransformationExecutionContext(Collections.singleton(module));
// find a helper method of interest
Helper operation = findOperationByName(module, "fooHelper");
// create a call object for the operation
HelperOperationCall call = execContext.createHelperCall(operation);
// calls with the 'self' contextual instance actual parameter values
call.invoke("aContextString1", new Object[] { "aStringArg1" });
call.invoke("aContextString2", new Object[] { "aStringArg2" });
...
// we finished our work
execContext.dispose();
</pre>
*/
public class NonTransformationExecutionContext {
private QvtOperationalEvaluationVisitorImpl fEvaluator;
private LinkedHashSet<Module> fLibraryImports;
/**
* Constructs new execution context and imports the given list of
*
* @param libraryImports
* the QVT libraries to be imported into the scope of the
* execution context
*
* @exception IllegalArgumentException
* if <code>libraryImports</code> is <code>null</code>
*/
public NonTransformationExecutionContext(Set<Module> libraryImports) {
if(libraryImports == null) {
throw new IllegalArgumentException();
}
fLibraryImports = new LinkedHashSet<Module>(libraryImports);
Context context = new Context();
ImportToNonTransformCtxHelper importProvider = new ImportToNonTransformCtxHelper(fLibraryImports, true);
fEvaluator = QvtOperationalEvaluationVisitorImpl.createNonTransformationExecutionContextVisitor(context, importProvider);
}
/**
* Creates the call object for the give helper operation.
* <p>
* Note: A helper operation is either a <code>query</code> or a
* <code>helper</code> with side effects
*
* @param operation
* an operation defined in one of the libraries imported into
* this execution context
* @return the call object on which invocations with actual parameter values
* can be performed
* @exception IllegalArgumentException
* if the given operation is not from a library already
* imported to this execution context
*/
public HelperOperationCall createHelperCall(Helper operation) {
if(operation == null) {
throw new IllegalArgumentException("null operation"); //$NON-NLS-1$
}
Module owningModule = QvtOperationalParserUtil.getOwningModule(operation);
if(owningModule == null ||
!(owningModule == QvtOperationalStdLibrary.INSTANCE.getStdLibModule() ||
fLibraryImports.contains(owningModule))) {
throw new IllegalArgumentException("Operation not imported from a library"); //$NON-NLS-1$
}
return new HelperOperationCall(operation, this);
}
/**
* Disposes this execution context.
* <p>
* Frees any resources acquired by this context during execution
*/
public void dispose() {
// TODO - remove me
//getEvaluator().getOperationalEvaluationEnv().dispose();
}
/**
* Get the QVT evaluation visitor used by this execution context
*/
QvtOperationalEvaluationVisitorImpl getEvaluator() {
return fEvaluator;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
for (Module importedLib : fLibraryImports) {
buf.append(importedLib.getName());
}
return buf.toString();
}
}