in velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java [130:289]
public Object execute(Object o, InternalContextAdapter context)
throws MethodInvocationException
{
try
{
rsvc.getLogContext().pushLogContext(this, uberInfo);
VelPropertyGet vg = null;
try
{
/*
* first, see if we have this information cached.
*/
IntrospectionCacheData icd = context.icacheGet(this);
Class<?> clazz = o instanceof Class<?> ? (Class<?>)o : o.getClass();
/*
* if we have the cache data and the class of the object we are
* invoked with is the same as that in the cache, then we must
* be all right. The last 'variable' is the method name, and
* that is fixed in the template :)
*/
if ( icd != null && (icd.contextData == clazz) )
{
vg = (VelPropertyGet) icd.thingy;
}
else
{
/*
* otherwise, do the introspection, and cache it. Use the
* uberspector
*/
vg = rsvc.getUberspect().getPropertyGet(o, identifier, uberInfo);
if (vg != null && vg.isCacheable())
{
icd = new IntrospectionCacheData();
icd.contextData = clazz;
icd.thingy = vg;
context.icachePut(this,icd);
}
}
}
/*
* pass through application level runtime exceptions
*/
catch( RuntimeException e )
{
throw e;
}
catch(Exception e)
{
String msg = "ASTIdentifier.execute() : identifier = "+identifier;
log.error(msg, e);
throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace());
}
/*
* we have no getter... punt...
*/
if (vg == null)
{
if (strictRef)
{
throw new MethodInvocationException("Object '" + o.getClass().getName() +
"' does not contain property '" + identifier + "'",
null, rsvc.getLogContext().getStackTrace(), identifier,
uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn());
}
else
{
return null;
}
}
/*
* now try and execute. If we get a MIE, throw that
* as the app wants to get these. If not, log and punt.
*/
try
{
return vg.invoke(o);
}
catch(InvocationTargetException ite)
{
/*
* if we have an event cartridge, see if it wants to veto
* also, let non-Exception Throwables go...
*/
Throwable t = ite.getTargetException();
if (t instanceof Exception)
{
try
{
return EventHandlerUtil.methodException(rsvc, context, o.getClass(), vg.getMethodName(),
(Exception) t, uberInfo);
}
/*
* If the event handler throws an exception, then wrap it
* in a MethodInvocationException.
*/
catch( Exception e )
{
throw new MethodInvocationException(
"Invocation of method '" + vg.getMethodName() + "'"
+ " in " + o.getClass()
+ " threw exception "
+ ite.getTargetException().toString(),
ite.getTargetException(), rsvc.getLogContext().getStackTrace(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn());
}
}
else
{
/*
* no event cartridge to override. Just throw
*/
throw new MethodInvocationException(
"Invocation of method '" + vg.getMethodName() + "'"
+ " in " + o.getClass()
+ " threw exception "
+ ite.getTargetException().toString(),
ite.getTargetException(), rsvc.getLogContext().getStackTrace(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn());
}
}
catch(IllegalArgumentException iae)
{
return null;
}
/*
* pass through application level runtime exceptions
*/
catch( RuntimeException e )
{
throw e;
}
catch(Exception e)
{
String msg = "ASTIdentifier() : exception invoking method "
+ "for identifier '" + identifier + "' in "
+ o.getClass();
log.error(msg, e);
throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace());
}
}
finally
{
rsvc.getLogContext().popLogContext();
}
}