blob: fbe611479e0ddee1f4ad1139a575761dfa2600ed [file] [log] [blame]
package org.apache.velocity.app.event;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.util.introspection.Info;
/**
* Calls on request all registered event handlers for a particular event. Each
* method accepts two event cartridges (typically one from the application and
* one from the context). All appropriate event handlers are executed in order
* until a stopping condition is met. See the docs for the individual methods to
* see what the stopping condition is for that method.
*
* @author <a href="mailto:wglass@wglass@forio.com">Will Glass-Husain </a>
* @version $Id$
* @since 1.5
*/
public class EventHandlerUtil {
/**
* Called before a reference is inserted. All event handlers are called in
* sequence. The default implementation inserts the reference as is.
*
* This is a major hotspot method called by ASTReference render.
*
* @param reference reference from template about to be inserted
* @param value value about to be inserted (after toString() )
* @param rsvc current instance of RuntimeServices
* @param context The internal context adapter.
* @return Object on which toString() should be called for output.
*/
public static Object referenceInsert(RuntimeServices rsvc,
InternalContextAdapter context, String reference, Object value)
{
try
{
value = rsvc.getApplicationEventCartridge().referenceInsert(context, reference, value);
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
value = contextCartridge.referenceInsert(context, reference, value);
}
return value;
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new VelocityException("Exception in event handler.",e);
}
}
/**
* Called when a method exception is generated during Velocity merge. Only
* the first valid event handler in the sequence is called. The default
* implementation simply rethrows the exception.
*
* @param claz
* Class that is causing the exception
* @param method
* method called that causes the exception
* @param e
* Exception thrown by the method
* @param rsvc current instance of RuntimeServices
* @param context The internal context adapter.
* @param info exception location informations
* @return Object to return as method result
* @throws Exception
* to be wrapped and propagated to app
*/
public static Object methodException(RuntimeServices rsvc,
InternalContextAdapter context, Class claz, String method,
Exception e, Info info) throws Exception
{
try
{
EventCartridge ev = rsvc.getApplicationEventCartridge();
if (ev.hasMethodExceptionEventHandler())
{
return ev.methodException(context, claz, method, e, info);
}
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
return contextCartridge.methodException(context, claz, method, e, info);
}
}
catch (RuntimeException re)
{
throw re;
}
catch (Exception ex)
{
throw new VelocityException("Exception in event handler.", ex);
}
/* default behaviour is to re-throw exception */
throw e;
}
/**
* Called when an include-type directive is encountered (#include or
* #parse). All the registered event handlers are called unless null is
* returned. The default implementation always processes the included
* resource.
*
* @param includeResourcePath
* the path as given in the include directive.
* @param currentResourcePath
* the path of the currently rendering template that includes the
* include directive.
* @param directiveName
* name of the directive used to include the resource. (With the
* standard directives this is either "parse" or "include").
* @param rsvc current instance of RuntimeServices
* @param context The internal context adapter.
*
* @return a new resource path for the directive, or null to block the
* include from occurring.
*/
public static String includeEvent(RuntimeServices rsvc,
InternalContextAdapter context, String includeResourcePath,
String currentResourcePath, String directiveName)
{
try
{
includeResourcePath = rsvc.getApplicationEventCartridge().includeEvent(context, includeResourcePath, currentResourcePath, directiveName);
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
includeResourcePath = contextCartridge.includeEvent(context, includeResourcePath, currentResourcePath, directiveName);
}
return includeResourcePath;
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new VelocityException("Exception in event handler.",e);
}
}
/**
* Called when an invalid get method is encountered.
*
* @param rsvc current instance of RuntimeServices
* @param context the context when the reference was found invalid
* @param reference complete invalid reference
* @param object object from reference, or null if not available
* @param property name of property, or null if not relevant
* @param info contains info on template, line, col
* @return substitute return value for missing reference, or null if no substitute
*/
public static Object invalidGetMethod(RuntimeServices rsvc,
InternalContextAdapter context, String reference,
Object object, String property, Info info)
{
try
{
Object result = rsvc.getApplicationEventCartridge().invalidGetMethod(context, reference, object, property, info);
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
result = contextCartridge.invalidGetMethod(context, reference, object, property, info);
}
return result;
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new VelocityException("Exception in event handler.",e);
}
}
/**
* Called when an invalid set method is encountered.
*
* @param rsvc current instance of RuntimeServices
* @param context the context when the reference was found invalid
* @param leftreference left reference being assigned to
* @param rightreference invalid reference on the right
* @param info contains info on template, line, col
*/
public static void invalidSetMethod(RuntimeServices rsvc,
InternalContextAdapter context, String leftreference,
String rightreference, Info info)
{
try
{
if (!rsvc.getApplicationEventCartridge().invalidSetMethod(context, leftreference, rightreference, info))
{
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
contextCartridge.invalidSetMethod(context, leftreference, rightreference, info);
}
}
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new VelocityException("Exception in event handler.",e);
}
}
/**
* Called when an invalid method is encountered.
*
* @param rsvc current instance of RuntimeServices
* @param context the context when the reference was found invalid
* @param reference complete invalid reference
* @param object object from reference, or null if not available
* @param method name of method, or null if not relevant
* @param info contains info on template, line, col
* @return substitute return value for missing reference, or null if no substitute
*/
public static Object invalidMethod(RuntimeServices rsvc,
InternalContextAdapter context, String reference,
Object object, String method, Info info)
{
try
{
Object result = rsvc.getApplicationEventCartridge().invalidMethod(context, reference, object, method, info);
EventCartridge contextCartridge = context.getEventCartridge();
if (contextCartridge != null)
{
contextCartridge.setRuntimeServices(rsvc);
result = contextCartridge.invalidMethod(context, reference, object, method, info);
}
return result;
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new VelocityException("Exception in event handler.",e);
}
}
}