in src/main/java/org/apache/commons/ognl/enhance/ExpressionCompiler.java [479:573]
public void compileExpression( OgnlContext context, Node expression, Object root )
throws Exception
{
// System.out.println("Compiling expr class " + expression.getClass().getName() + " and root " + root);
if ( expression.getAccessor() != null )
{
return;
}
String getBody, setBody;
EnhancedClassLoader loader = getClassLoader( context );
ClassPool classPool = getClassPool( context, loader );
CtClass newClass = classPool.makeClass(
expression.getClass().getName() + expression.hashCode() + classCounter++ + "Accessor" );
newClass.addInterface( getCtClass( ExpressionAccessor.class ) );
CtClass ognlClass = getCtClass( OgnlContext.class );
CtClass objClass = getCtClass( Object.class );
CtMethod valueGetter = new CtMethod( objClass, "get", new CtClass[] { ognlClass, objClass }, newClass );
CtMethod valueSetter =
new CtMethod( CtClass.voidType, "set", new CtClass[] { ognlClass, objClass, objClass }, newClass );
CtField nodeMember = null; // will only be set if uncompilable exception is thrown
CtClass nodeClass = getCtClass( Node.class );
CtMethod setExpression = null;
try
{
getBody = generateGetter( context, newClass, objClass, classPool, valueGetter, expression, root );
}
catch ( UnsupportedCompilationException uc )
{
nodeMember = new CtField( nodeClass, "_node", newClass );
newClass.addField( nodeMember );
getBody = generateOgnlGetter( newClass, valueGetter, nodeMember );
setExpression = CtNewMethod.setter( "setExpression", nodeMember );
newClass.addMethod( setExpression );
}
try
{
setBody = generateSetter( context, newClass, objClass, classPool, valueSetter, expression, root );
}
catch ( UnsupportedCompilationException uc )
{
if ( nodeMember == null )
{
nodeMember = new CtField( nodeClass, "_node", newClass );
newClass.addField( nodeMember );
}
setBody = generateOgnlSetter( newClass, valueSetter, nodeMember );
if ( setExpression == null )
{
setExpression = CtNewMethod.setter( "setExpression", nodeMember );
newClass.addMethod( setExpression );
}
}
try
{
newClass.addConstructor( CtNewConstructor.defaultConstructor( newClass ) );
Class<?> clazz = classPool.toClass( newClass );
newClass.detach();
expression.setAccessor( (ExpressionAccessor) clazz.newInstance() );
// need to set expression on node if the field was just defined.
if ( nodeMember != null )
{
expression.getAccessor().setExpression( expression );
}
}
catch ( Throwable t )
{
throw new IllegalStateException( "Error compiling expression on object " + root + " with expression node "
+ expression + " getter body: " + getBody + " setter body: " + setBody, t );
}
}