The variables to be evaluated are set up in different parts of the
application. Some are system defined, some are user defined. While it is not
possible to list them all in advance and use set() to allocate values, any given
value can be obtained by through a single getProperty(key) call in the main
I am actually happy now with the implementation I have for the Expression
evaluator. I evaluate once, find the undefined variables, set those with values
from the application, the evaluate again to get a result.
What I need for the general purpose script handling is a way to
programatically callback into my application to determine the value of a given
I don't fully understand your example, but it is tantalizing. I feel I am
missing something. Am I right that you are basically 'Settting' all available
values into the NameSpace prior to evaluation? How do you reference a Spring
value in a BeanShell?
*********** REPLY SEPARATOR
On 23/06/2008 at 12:31 PM Stewart Cambridge
not sure if I understood your requirements correctly.
It seems to me
that if your scripts are truly and totally dynamic, then you cannot know
before hand what variables will need to be populated into the interpreter
context - the user could write anything.
I once used beanshell to
create a perfectly workable expression calculator and rules engine for a
financial services application.
I had such mechanisms
public interface Populatable extends
void setCode(String code);
public interface Calculatable
extends Populatable, Checkable
* Populates the
Spring ApplicationContext into the Beanshell's shared
public void setApplicationContext(
ApplicationContext cxt )
Interpreter i = new
i.eval("bsh.shared." + Calculator.APPLICATION_CONTEXT + " = " +
Calculator( CalculatorHolder holder )
this.interpreter = new
Calculator.class.getPackage().getName() ); // pre-defined calculator
// gives access to spring beans via
interpreter.eval( APPLICATION_CONTEXT + " =
bsh.shared." + APPLICATION_CONTEXT );
void init( CalculatorContext populateFromContext )
for ( int i =
0; i < populatables.length; i++ )
I have absolutely no idea if this is
helpful to you or not.
The calculation expressions and "populatables" were
configured through a database, so that ultimately there was a well defined set
of expression variables. The expressions could be changed at runtime by the
user and did reference objects (the "populatables") fetched via hibernate and
injected into the calculator context, as well as all the Spring beans my app
was built upon.
If the user tried to reference a populatable or bean that
didn't exist, I'd just catch the EvalError and report it to the
Ultimately, what else can you do? If the user doesn't set "xpos",
then it's an error, plain and simple.
You've constructed a list of unset
variable that the user needs to set before the expression is run, but if the
user doesn't set one, what can you do that's different to a general EvalError?
I suppose you can pinpoint specifically what is not set, and include that in
your friendly error message.