gnu.jel
Class Library

java.lang.Object
  |
  +--gnu.jel.Library

public class Library
extends java.lang.Object

A namespace for JEL expressions.

There are two types of members in the library, those which are stateless (i.e. their value depends only on their arguments, if there are any) and stateful (also called here dynamic). The result of evaluation of stateful members may depend on other factors besides their arguments.

Examples of possible stateless members are : Math.sin(double), Math.PI.

Examples of possible stateful members are : Math.random(), System.currentTimeMillis().

Stateless members of this library are always static members of the classes, which define them. The inverse is generally not true. However, this library goes as far as assuming that static members are stateless, if this assumption does not hold for some of Your members it is possible to mark them as stateful using the markStateDependent() method of this class.

The most crucial difference between the two kind of members of this library is that evaluation of stateless methods is attempted by JEL at a compile time during the constants folding phase.


Constructor Summary
Library(java.lang.Class[] staticLib, java.lang.Class[] dynamicLib)
          Creates a library for JEL.
Library(java.lang.Class[] staticLib, java.lang.Class[] dynamicLib, java.lang.Class[] dotClasses)
          Creates a library for JEL.
 
Method Summary
 int getDynamicMethodClassID(Member m)
          Returns ID(position in the object array) of the dynamic Method.
 Member getMember(java.lang.Class container, java.lang.String name, java.lang.Class[] params)
          Finds the member of a given class by name.
 Member getMember(java.lang.String name, java.lang.Class[] params)
          Used to search library for method or field.
 boolean isStateless(Member o)
          Used to check if the given method is stateless.
static void main(java.lang.String[] args)
          Performs unitary test of the library.
 void markStateDependent(java.lang.String name, java.lang.Class[] params)
          This method marks a static member as having the internal state.
static void test(Tester t)
          Performs unitary test of the library.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Library

public Library(java.lang.Class[] staticLib,
               java.lang.Class[] dynamicLib)
Creates a library for JEL.

See the three argument constructor for more info.

Parameters:
staticLib - is the array of classes, whose public static methods are exported.
dynamicLib - is the array of classes, whose public virutal methods are exported.

Library

public Library(java.lang.Class[] staticLib,
               java.lang.Class[] dynamicLib,
               java.lang.Class[] dotClasses)
Creates a library for JEL.

The following should be kept in mind when constructing a library:

  1. This constructor may throw IllegalArgumentException if it does not like something in Your library. The requirements to the method names are somewhat more strict, than in Java as the class.method(..) syntax is not used.
  2. When calling the CompiledExpression.evaluate(Object[] dynalib) of the expression, using dynamic library methods it is needed to pass as dynalib parameter the array of objects, of the classes _exactly_ in the same order as they are appearing in the dynamicLib parameter of this constructor. If You do not allow to call dynamic methods (there is no sense, then, to use a compiler) it is possible to pass null istead of dynalib.
  3. Generally speaking, this class should not let You to create wrong libraries. It's methods will throw exceptions, return false's , ignore Your actions,... ;)
If methods in the library classes conflict with each other, the last conflicting method will be skipped. You will not get any messages unless debugging is ON (see gnu.jel.debug.Debug.enabled). This is done to avoid unnecessary error messages in the production code of the compiler.

The array (dotClasses), which is the third argument of this constructor determines how (and whether) to compile the dot operators encountered in expressions. These operators are of the form .(|), which means to call method (access field) of an . There can be three types of the behaviour:
1) dot operators are prohibited (dotClasses==null), this is behaviour of older version of JEL.
2) dot operators are allowed on all classes (dotClasses==new Class[0], an empty array). Depending on the types of objects returned by the static/dynamic library classes this may pose a security risk.
3) dot operators are allowed only on some classes. This is achieved by listing these classes in the dotClasses array.
Parameters:
staticLib - is the array of classes, whose public static methods are exported.
dynamicLib - is the array of classes, whose public virutal methods are exported.
dotClasses - is the array of classes on which the dot ('.') operation is allowed.
Method Detail

markStateDependent

public void markStateDependent(java.lang.String name,
                               java.lang.Class[] params)
                        throws java.lang.NoSuchMethodException
This method marks a static member as having the internal state.

If You include java.lang.Math into the library it is necessary to mark java.lang.random() as having the state. This can be done by calling markStateDependent("random",null)

Please specify parameters as close as possible, otherwise You can accidentally mark another function.

Parameters:
name - is the function name.
params - are the possible invocation parameters of the function.
Throws:
java.lang.NoSuchMethodException - if the method can't be resolved

isStateless

public boolean isStateless(Member o)
Used to check if the given method is stateless.
Parameters:
m - is method or field to check.
Returns:
true if the method is stateless and can be invoked at compile time.

getMember

public Member getMember(java.lang.String name,
                        java.lang.Class[] params)
                 throws java.lang.NoSuchMethodException
Used to search library for method or field.

The method with the same name, and closest (convertible) parameter types is returned. If there are several methods the most specific one is used. Ambiguities are detected. Example of detectable ambiguity:
You want to call : someName(int, int)
There are two applicable methods : someName(int, double), someName(double, int) , requirements to parameter types of each of those can be satisfied by _widening_ conversions.
Those methods are same specific, there is no most specific method in terms of Java Language Specification (15.11.2.2). Thus there is ambiguity and null will be returned.

Java compiler normally would not allow to define such ambiguous methods in the same class. However, as this library is assembled from several Java classes such ambiguities can happen, and should be detected.

Parameters:
name - is the name of the method to find.
params - are the types of formal parameters in the method invocation.
Returns:
the method/field object of the resolved method/field.
Throws:
java.lang.NoSuchMethodException - if the method can't be resolved

getMember

public Member getMember(java.lang.Class container,
                        java.lang.String name,
                        java.lang.Class[] params)
                 throws java.lang.NoSuchMethodException
Finds the member of a given class by name.

This method is used in compiling the dot ('.') operators. It does all necessary security checks and wraps the result into one of JEL's reflection classes.

Parameters:
container - the class to search the method within.
name - is the name of the method to find.
params - are the types of formal parameters in the method invocation.
Returns:
the method/field object of the resolved method/field.
Throws:
java.lang.NoSuchMethodException - if the method can't be resolved

getDynamicMethodClassID

public int getDynamicMethodClassID(Member m)
Returns ID(position in the object array) of the dynamic Method.

ID's are used to locate the pointers to the objects, implementing dynamic methods, in the array, argument of evaluate(Object[]) function.

Parameters:
m - method to get an ID of.
Returns:
the ID of the method or -1 if the method is static.
Throws:
NullPointerException - if method is not a dynamic method of this library.

main

public static void main(java.lang.String[] args)
Performs unitary test of the library.
Parameters:
args - ignored.

test

public static void test(Tester t)
Performs unitary test of the library.

Used if all package is being tested and not just codegen.

Parameters:
t - Tester to report test results.