![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.velocity.app.event.EventHandlerUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.portal.template.velocity
Show all versions of com.liferay.portal.template.velocity
Liferay Portal Template Velocity
The newest version!
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 java.util.Iterator;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.util.ExceptionUtils;
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 Will Glass-Husain
* @version $Id: EventHandlerUtil.java 685685 2008-08-13 21:43:27Z nbubna $
* @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)
{
// app level cartridges have already been initialized
/*
* Performance modification: EventCartridge.getReferenceInsertionEventHandlers
* now returns a null if there are no handlers. Thus we can avoid creating the
* Iterator object.
*/
EventCartridge ev1 = rsvc.getApplicationEventCartridge();
Iterator applicationEventHandlerIterator =
(ev1 == null) ? null: ev1.getReferenceInsertionEventHandlers();
EventCartridge ev2 = context.getEventCartridge();
initializeEventCartridge(rsvc, ev2);
Iterator contextEventHandlerIterator =
(ev2 == null) ? null: ev2.getReferenceInsertionEventHandlers();
try
{
/*
* Performance modification: methodExecutor is created only if one of the
* iterators is not null.
*/
EventHandlerMethodExecutor methodExecutor = null;
if( applicationEventHandlerIterator != null )
{
methodExecutor =
new ReferenceInsertionEventHandler.referenceInsertExecutor(context, reference, value);
iterateOverEventHandlers(applicationEventHandlerIterator, methodExecutor);
}
if( contextEventHandlerIterator != null )
{
if( methodExecutor == null )
methodExecutor =
new ReferenceInsertionEventHandler.referenceInsertExecutor(context, reference, value);
iterateOverEventHandlers(contextEventHandlerIterator, methodExecutor);
}
return methodExecutor != null ? methodExecutor.getReturnValue() : value;
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw ExceptionUtils.createRuntimeException("Exception in event handler.",e);
}
}
/**
* Called when a null is evaluated during a #set. All event handlers are
* called in sequence until a false is returned. The default implementation
* always returns true.
*
* @param lhs Left hand side of the expression.
* @param rhs Right hand side of the expression.
* @param rsvc current instance of RuntimeServices
* @param context The internal context adapter.
* @return true if to be logged, false otherwise
*/
public static boolean shouldLogOnNullSet(RuntimeServices rsvc,
InternalContextAdapter context, String lhs, String rhs)
{
// app level cartridges have already been initialized
EventCartridge ev1 = rsvc.getApplicationEventCartridge();
Iterator applicationEventHandlerIterator =
(ev1 == null) ? null: ev1.getNullSetEventHandlers();
EventCartridge ev2 = context.getEventCartridge();
initializeEventCartridge(rsvc, ev2);
Iterator contextEventHandlerIterator =
(ev2 == null) ? null: ev2.getNullSetEventHandlers();
try
{
EventHandlerMethodExecutor methodExecutor =
new NullSetEventHandler.ShouldLogOnNullSetExecutor(context, lhs, rhs);
callEventHandlers(
applicationEventHandlerIterator,
contextEventHandlerIterator, methodExecutor);
return ((Boolean) methodExecutor.getReturnValue()).booleanValue();
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw ExceptionUtils.createRuntimeException("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.
* @return Object to return as method result
* @throws Exception
* to be wrapped and propogated to app
*/
public static Object methodException(RuntimeServices rsvc,
InternalContextAdapter context, Class claz, String method,
Exception e) throws Exception
{
// app level cartridges have already been initialized
EventCartridge ev1 = rsvc.getApplicationEventCartridge();
Iterator applicationEventHandlerIterator =
(ev1 == null) ? null: ev1.getMethodExceptionEventHandlers();
EventCartridge ev2 = context.getEventCartridge();
initializeEventCartridge(rsvc, ev2);
Iterator contextEventHandlerIterator =
(ev2 == null) ? null: ev2.getMethodExceptionEventHandlers();
EventHandlerMethodExecutor methodExecutor =
new MethodExceptionEventHandler.MethodExceptionExecutor(context, claz, method, e);
if ( ((applicationEventHandlerIterator == null) || !applicationEventHandlerIterator.hasNext()) &&
((contextEventHandlerIterator == null) || !contextEventHandlerIterator.hasNext()) )
{
throw e;
}
callEventHandlers(
applicationEventHandlerIterator,
contextEventHandlerIterator, methodExecutor);
return methodExecutor.getReturnValue();
}
/**
* 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)
{
// app level cartridges have already been initialized
EventCartridge ev1 = rsvc.getApplicationEventCartridge();
Iterator applicationEventHandlerIterator =
(ev1 == null) ? null: ev1.getIncludeEventHandlers();
EventCartridge ev2 = context.getEventCartridge();
initializeEventCartridge(rsvc, ev2);
Iterator contextEventHandlerIterator =
(ev2 == null) ? null: ev2.getIncludeEventHandlers();
try
{
EventHandlerMethodExecutor methodExecutor =
new IncludeEventHandler.IncludeEventExecutor(
context, includeResourcePath,
currentResourcePath, directiveName);
callEventHandlers(
applicationEventHandlerIterator,
contextEventHandlerIterator, methodExecutor);
return (String) methodExecutor.getReturnValue();
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw ExceptionUtils.createRuntimeException("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)
{
return
invalidReferenceHandlerCall (
new InvalidReferenceEventHandler.InvalidGetMethodExecutor
(context, reference, object, property, info),
rsvc,
context);
}
/**
* 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)
{
/**
* ignore return value
*/
invalidReferenceHandlerCall (
new InvalidReferenceEventHandler.InvalidSetMethodExecutor
(context, leftreference, rightreference, info),
rsvc,
context);
}
/**
* 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)
{
return
invalidReferenceHandlerCall (
new InvalidReferenceEventHandler.InvalidMethodExecutor
(context, reference, object, method, info),
rsvc,
context);
}
/**
* Calls event handler method with appropriate chaining across event handlers.
*
* @param methodExecutor
* @param rsvc current instance of RuntimeServices
* @param context The current context
* @return return value from method, or null if no return value
*/
public static Object invalidReferenceHandlerCall(
EventHandlerMethodExecutor methodExecutor,
RuntimeServices rsvc,
InternalContextAdapter context)
{
// app level cartridges have already been initialized
EventCartridge ev1 = rsvc.getApplicationEventCartridge();
Iterator applicationEventHandlerIterator =
(ev1 == null) ? null: ev1.getInvalidReferenceEventHandlers();
EventCartridge ev2 = context.getEventCartridge();
initializeEventCartridge(rsvc, ev2);
Iterator contextEventHandlerIterator =
(ev2 == null) ? null: ev2.getInvalidReferenceEventHandlers();
try
{
callEventHandlers(
applicationEventHandlerIterator,
contextEventHandlerIterator, methodExecutor);
return methodExecutor.getReturnValue();
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw ExceptionUtils.createRuntimeException("Exception in event handler.",e);
}
}
/**
* Initialize the event cartridge if appropriate.
*
* @param rsvc current instance of RuntimeServices
* @param eventCartridge the event cartridge to be initialized
*/
private static void initializeEventCartridge(RuntimeServices rsvc, EventCartridge eventCartridge)
{
if (eventCartridge != null)
{
try
{
eventCartridge.initialize(rsvc);
}
catch (Exception e)
{
throw ExceptionUtils.createRuntimeException("Couldn't initialize event cartridge : ", e);
}
}
}
/**
* Loop through both the application level and context-attached event handlers.
*
* @param applicationEventHandlerIterator Iterator that loops through all global event handlers declared at application level
* @param contextEventHandlerIterator Iterator that loops through all global event handlers attached to context
* @param eventExecutor Strategy object that executes event handler method
* @exception Exception generic exception potentially thrown by event handlers
*/
private static void callEventHandlers(
Iterator applicationEventHandlerIterator,
Iterator contextEventHandlerIterator,
EventHandlerMethodExecutor eventExecutor)
throws Exception
{
/**
* First loop through the event handlers configured at the app level
* in the properties file.
*/
iterateOverEventHandlers(applicationEventHandlerIterator, eventExecutor);
/**
* Then loop through the event handlers attached to the context.
*/
iterateOverEventHandlers(contextEventHandlerIterator, eventExecutor);
}
/**
* Loop through a given iterator of event handlers.
*
* @param handlerIterator Iterator that loops through event handlers
* @param eventExecutor Strategy object that executes event handler method
* @exception Exception generic exception potentially thrown by event handlers
*/
private static void iterateOverEventHandlers(
Iterator handlerIterator,
EventHandlerMethodExecutor eventExecutor)
throws Exception
{
if (handlerIterator != null)
{
for (Iterator i = handlerIterator; i.hasNext();)
{
EventHandler eventHandler = (EventHandler) i.next();
if (!eventExecutor.isDone())
{
eventExecutor.execute(eventHandler);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy