/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.epl.script.mvel;
import com.espertech.esper.epl.core.EngineImportService;
import com.espertech.esper.epl.expression.core.ExprValidationException;
import com.espertech.esper.epl.script.ExprNodeScript;
import com.espertech.esper.epl.spec.ExpressionScriptCompiled;
import com.espertech.esper.epl.spec.ExpressionScriptProvided;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Map;
/**
* =============
* Without MVEL dependencies in classpath, this call verifies and compiles an MVEL script.
* =============
*/
public class MVELHelper {
private static final Logger log = LoggerFactory.getLogger(MVELHelper.class);
/**
* Verify MVEL script (not compiling it).
* Compiling is done by the first expression node using the expression since only then parameter types can be bound.
*
* @param script to verify/analyze
* @param engineImportService engine imports
* @throws ExprValidationException when not all parameters are resolved
*/
public static void verifyScript(ExpressionScriptProvided script, EngineImportService engineImportService) throws ExprValidationException {
// Reflective invocation - do not add MVEL to classpath
Object parserContext = MVELInvoker.newParserContext(engineImportService);
// this populates the parser context with the actual undefined MVEL input parameters expected
try {
MVELInvoker.analysisCompile(script.getExpression(), parserContext, engineImportService);
} catch (InvocationTargetException ex) {
throw handleTargetException(script.getName(), ex);
} catch (Exception ex) {
throw handleGeneralException(script.getName(), ex);
}
// obtain input params
Map<String, Class> scriptRequiredInputs = MVELInvoker.getParserContextInputs(parserContext);
// ensure each of the input params (excluding 'epl' context) is provided as a parameter
for (Map.Entry<String, Class> input : scriptRequiredInputs.entrySet()) {
if (input.getKey().toLowerCase(Locale.ENGLISH).trim().equals(ExprNodeScript.CONTEXT_BINDING_NAME)) {
continue;
}
if (script.getParameterNames().contains(input.getKey())) {
continue;
}
throw new ExprValidationException("For script '" + script.getName() + "' the variable '" + input.getKey() + "' has not been declared and is not a parameter");
}
}
public static ExpressionScriptCompiled compile(String scriptName, String expression, Map<String, Class> mvelInputParamTypes, EngineImportService engineImportService)
throws ExprValidationException {
// Reflective invocation - do not add MVEL to classpath
Object parserContext = MVELInvoker.newParserContext(engineImportService);
MVELInvoker.setParserContextStrongTyping(parserContext);
MVELInvoker.setParserContextInputs(parserContext, mvelInputParamTypes);
Object executable;
try {
executable = MVELInvoker.compileExpression(expression, parserContext);
} catch (InvocationTargetException ex) {
throw handleTargetException(scriptName, ex);
} catch (Exception ex) {
throw handleGeneralException(scriptName, ex);
}
return new ExpressionScriptCompiledMVEL(executable);
}
private static ExprValidationException handleTargetException(String scriptName, InvocationTargetException ex) {
Throwable mvelException = ex.getTargetException();
String message = "Exception compiling MVEL script '" + scriptName + "': " + mvelException.getMessage();
log.info(message, mvelException);
return new ExprValidationException(message, mvelException);
}
private static ExprValidationException handleGeneralException(String scriptName, Exception ex) {
String message = "Exception compiling MVEL script '" + scriptName + "': " + ex.getMessage();
log.info(message, ex);
return new ExprValidationException(message, ex);
}
}