|
|||||
|
|||||
Interceptors
MVEL provides the ability to place interceptors within a compiled expression. This can be particularly useful for implementing change listeners or firing external events based from within an expression. An interceptor declaration uses the @Syntax, similar to annotations in Java. You declare interceptors before a statement you wish to enclose, and as such, an interceptor may implement either before or after listeners, or both. For example: @Intercept
foreach (item : fooItems) {
total += fooItems.price;
}
In this particular statement, the interceptor encloses the entire foreach block, so if the interceptor implements the after listener, that action will be fired when the foreach has completed. The org.mvel.intergration.Interceptor Interfacepublic interface Interceptor { public int doBefore(ASTNode node, VariableResolverFactory factory); public int doAfter(Object exitStackValue, ASTNode node, VariableResolverFactory factory); } The Interceptor interface provides two methods to be implemented: doBefore and doAfter. Here we will describe the meaning of the values passed into the methods from the MVEL runtime. doBeforeThe doBefore method is called before the enclosing statement is executed. org.mvel.ASTNode::node The handle to the ASTNode is a reference to the ASTNode which is wrapped by the interceptor. This can be used to obtain information about the actual compiled code.
org.mvel.integration.VariableResolverFactory::factory The variable resolver factory provides access to the current scope of variables in the expression. Please see [Variable Resolvers] for more information. doAfterThe doAfter method is called after the enclosing statement has executed. java.lang.Object::exitStackValue The doAfter method is executed after the enclosing statement has executed, but not before the end of the frame. Therefore, any value left on the stack at the end of the operation will still be present and therefore accessible to the interceptor. For example: @Intercept cost += value; In this particular case, the reduced value of cost = cost + value will be present on the stack until the end of the execution frame, and therefore this value will be available as the exitStackValue in the doAfter call. org.mvel.ASTNode::node This is the same AST element as is passed to doBefore. See the last section for more details. org.mvel.intergration.VariableResolverFactory::factory See the last section for more details. Using Interceptors in the CompilerInterceptors must be provided to the compiler prior to compiling the expression in order to wire the interceptors into the expression. So it should be noted here that interceptors may not be used with the MVEL interpreter. A Map is used to provide the compiler with the interceptors with the key representing the name of the interceptor, and the value being the interceptor instance. For example: // Create a new ParserContext ParserContext context = new ParserContext(); Map<String, Interceptor> myInterceptors = new HashMap<String, Interceptor>(); // Create a simple interceptor. Interceptor myInterceptor = new Interceptor() { public int doBefore(ASTNode node, VariableResolverFactory factory) { System.out.println("BEFORE!"); } public int doAfter((Object value, ASTNode node, VariableResolverFactory factory) { System.out.println("AFTER!"); } }; // Now add the interceptor to the map. myInterceptors.put("Foo", myInterceptor); // Add the interceptors map to the parser context. context.setInterceptors(myInterceptors); // Compile the expression. Serializable compiledExpression = MVEL.compileExpression(expression, context);
|
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||