blob: 1aa27c046ac4c0820fb4b5814060909074b5b5e3 [file] [log] [blame]
/*
* Copyright (c) 2007, 2010 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:
* Dmitry Stadnik (Borland) - initial API and implementation
*/
«IMPORT 'http://www.eclipse.org/gmf/2009/GenModel'»
«DEFINE OCLExpressionFactory FOR gmfgen::GenExpressionInterpreter
«EXPAND xpt::Common::copyright FOR container.editorGen
package «container.expressionsPackageName»;
«EXPAND xpt::Common::generatedClassComment»
public class «className» {
«EXPAND _initInterpreterFactory»
«EXPAND xpt::Common::generatedMemberComment»
public static «container.getAbstractExpressionQualifiedClassName()» getExpression(String body, org.eclipse.emf.ecore.EClassifier context, java.util.Map«EXPAND CodeStyle::G2('String', 'org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram» environment) {
return new Expression(body, context, environment);
}
«EXPAND xpt::Common::generatedMemberComment('This method will become private in the next release')»«REM»FIXME private or completely remove in the next release «ENDREM»
public static «container.getAbstractExpressionQualifiedClassName()» getExpression(String body, org.eclipse.emf.ecore.EClassifier context) {
return getExpression(body, context, «EXPAND CodeStyle::emptyMap('String, org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram»);
}
«EXPAND xpt::Common::generatedMemberComment»
private static class Expression extends «container.getAbstractExpressionQualifiedClassName()» {
«EXPAND xpt::Common::generatedMemberComment»
private final org.eclipse.ocl.ecore.OCL oclInstance;
«EXPAND xpt::Common::generatedMemberComment»
private org.eclipse.ocl.ecore.OCLExpression oclExpression;
«EXPAND xpt::Common::generatedMemberComment»
public Expression(String body, org.eclipse.emf.ecore.EClassifier context, java.util.Map«EXPAND CodeStyle::G2('String', 'org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram» environment) {
super(body, context);
oclInstance = org.eclipse.ocl.ecore.OCL.newInstance();
initCustomEnv(oclInstance.getEnvironment(), environment);
«REM»
I've moved expression initialization right into constructor because:
- Caching and weak references done at the caller are more effective for this usecase (we have an instance/static field to reference this Expression anyway)
- Expression's status is known right away, not only after protected getQuery get invoked
«ENDREM»«-»
org.eclipse.ocl.ecore.OCL.Helper oclHelper = oclInstance.createOCLHelper();
oclHelper.setContext(context());
try {
oclExpression = oclHelper.createQuery(body());
setStatus(org.eclipse.core.runtime.IStatus.OK, null, null);
} catch (org.eclipse.ocl.ParserException e) {
setStatus(org.eclipse.core.runtime.IStatus.ERROR, e.getMessage(), e);
}
}
«EXPAND xpt::Common::generatedMemberComment»
«EXPAND CodeStyle::SuppressWarnings('"rawtypes"') FOR container.editorGen.diagram
protected Object doEvaluate(Object context, java.util.Map env) {
if (oclExpression == null) {
return null;
}
// on the first call, both evalEnvironment and extentMap are clear, for later we have finally, below.
org.eclipse.ocl.EvaluationEnvironment«EXPAND CodeStyle::G('?,?,?,?,?') FOR container.editorGen.diagram» evalEnv = oclInstance.getEvaluationEnvironment();
// initialize environment«REM»Using Object below because Map env comes as raw type, and Object(unlike String) works fine for both Iterator<Type> = iterable.iterator() and for (Type a : iterable) code styles «ENDREM»
«EXPAND CodeStyle::iterate('nextKey', 'Object', 'env.keySet()') FOR container.editorGen.diagram
evalEnv.replace((String) nextKey, env.get(nextKey));
}
try {
Object result = oclInstance.evaluate(context, oclExpression);
return oclInstance.isInvalid(result) ? null : result;
} finally {
evalEnv.clear();
oclInstance.setExtentMap(null); // clear allInstances cache, and get the oclInstance ready for the next call
}
}
«EXPAND xpt::Common::generatedMemberComment»
private static void initCustomEnv(org.eclipse.ocl.Environment«EXPAND CodeStyle::G('?,org.eclipse.emf.ecore.EClassifier,?,?,?,org.eclipse.emf.ecore.EParameter,?,?,?,?,?,?') FOR container.editorGen.diagram» ecoreEnv, java.util.Map«EXPAND CodeStyle::G2('String', 'org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram» environment) {
«EXPAND initializeEnvironment('ecoreEnv')-»
«EXPAND CodeStyle::iterate('varName', 'String', 'environment.keySet()') FOR container.editorGen.diagram
org.eclipse.emf.ecore.EClassifier varType = «EXPAND CodeStyle::castTyped('org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram»environment.get(varName);
ecoreEnv.addElement(varName, createVar(ecoreEnv, varName, varType), false);
}
}
«EXPAND xpt::Common::generatedMemberComment»
private static org.eclipse.ocl.ecore.Variable createVar(org.eclipse.ocl.Environment«EXPAND CodeStyle::G('?,org.eclipse.emf.ecore.EClassifier,?,?,?,?,?,?,?,?,?,?') FOR container.editorGen.diagram» ecoreEnv, String name, org.eclipse.emf.ecore.EClassifier type) {
org.eclipse.ocl.ecore.Variable var = org.eclipse.ocl.ecore.EcoreFactory.eINSTANCE.createVariable();
var.setName(name);
var.setTypeEXPAND CodeStyle::castTyped('org.eclipse.emf.ecore.EClassifier') FOR container.editorGen.diagram»ecoreEnv.getUMLReflection().getOCLType(type));
return var;
}
}
«EXPAND additions
}
«ENDDEFINE»
«REM»
Clients may override if they don't need
«ENDREM»
«DEFINE initializeEnvironment(String environmentVar) FOR gmfgen::GenExpressionInterpreter-»
// Use EObject as implicit root class for any object, to allow eContainer() and other EObject operations from OCL expressions
org.eclipse.ocl.options.ParsingOptions.setOption(«environmentVar», org.eclipse.ocl.options.ParsingOptions.implicitRootClass(«environmentVar»), org.eclipse.emf.ecore.EcorePackage.eINSTANCE.getEObject());
«ENDDEFINE»
«DEFINE additions FOR gmfgen::GenExpressionInterpreter»«ENDDEFINE»
// just to avoid identical piece of template in the RegexpExpressionFactory
«DEFINE _initInterpreterFactory FOR gmfgen::GenExpressionInterpreter-»
«EXPAND xpt::Common::generatedMemberComment»
private final «container.getAbstractExpressionQualifiedClassName()»[] expressions;
«EXPAND xpt::Common::generatedMemberComment»
protected «className»() {
this.expressions = new «container.getAbstractExpressionQualifiedClassName()»[«expressions->size()»];
}
«EXPAND xpt::Common::generatedMemberComment»
public static «container.getAbstractExpressionQualifiedClassName()» getExpression(int index, org.eclipse.emf.ecore.EClassifier context) {
«className» cached = «EXPAND plugin::Activator::instanceAccess FOR container.editorGen».get«className»();
if (cached == null) {
«EXPAND plugin::Activator::instanceAccess FOR container.editorGen».set«className»(cached = new «className»());
}
if (index < 0 || index >= cached.expressions.length) {
throw new IllegalArgumentException();
}
if (cached.expressions[index] == null) {
final String[] exprBodies = new String[] {
«FOREACH expressions.getBodyString() AS b»«b», «EXPAND xpt::Common::nonNLS»
«ENDFOREACH-»
};
cached.expressions[index] = getExpression(exprBodies[index], context);
}
return cached.expressions[index];
}
«ENDDEFINE»