You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by wg...@apache.org on 2006/10/12 09:48:48 UTC

svn commit: r463147 - in /jakarta/velocity/engine/trunk/src: java/org/apache/velocity/app/event/ test/org/apache/velocity/test/

Author: wglass
Date: Thu Oct 12 00:48:47 2006
New Revision: 463147

URL: http://svn.apache.org/viewvc?view=rev&rev=463147
Log:
Restructuring of event handler initialization & calls prepatory to 
adding another event handler interface.

Added:
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java   (with props)
Modified:
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventCartridge.java
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerUtil.java
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/IncludeEventHandler.java
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/NullSetEventHandler.java
    jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java
    jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/EventHandlingTestCase.java

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventCartridge.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventCartridge.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventCartridge.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventCartridge.java Thu Oct 12 00:48:47 2006
@@ -54,6 +54,7 @@
     private List nullSetHandlers = new ArrayList();
     private List methodExceptionHandlers = new ArrayList();
     private List includeHandlers = new ArrayList();
+    private List invalidReferenceHandlers = new ArrayList();
 
     /**
      * Ensure that handlers are not initialized more than once.
@@ -94,12 +95,19 @@
             addMethodExceptionHandler( (MethodExceptionEventHandler) ev );
             found = true;
         }
+
         if ( ev instanceof IncludeEventHandler )
         {
             addIncludeEventHandler( (IncludeEventHandler) ev );
             found = true;
         }
 
+        if ( ev instanceof InvalidReferenceEventHandler )
+        {
+            addInvalidReferenceEventHandler( (InvalidReferenceEventHandler) ev );
+            found = true;
+        }
+
         return found;
     }
 
@@ -143,6 +151,16 @@
         includeHandlers.add( ev );
     }
 
+    /**
+     *  Add an invalid reference event handler to the Cartridge.
+     *
+     *  @param ev InvalidReferenceEventHandler
+     */
+    public void addInvalidReferenceEventHandler( InvalidReferenceEventHandler ev )
+    {
+        invalidReferenceHandlers.add( ev );
+    }
+
 
     /**
      * Removes an event handler(s) from the Cartridge. This method will find all
@@ -174,6 +192,9 @@
         if ( ev instanceof IncludeEventHandler )
             return includeHandlers.remove( ev );
 
+        if ( ev instanceof InvalidReferenceEventHandler )
+            return invalidReferenceHandlers.remove( ev );
+
         return found;
     }
 
@@ -214,6 +235,15 @@
     }
 
     /**
+     * Iterate through all the stored InvalidReferenceEventHandlers objects
+     * @return iterator of handler objects
+     */
+    public Iterator getInvalidReferenceEventHandlers()
+    {
+        return invalidReferenceHandlers.iterator();
+    }
+
+    /**
      *  Attached the EventCartridge to the context
      *
      *  Final because not something one should mess with lightly :)
@@ -288,6 +318,17 @@
         }
 
         for ( Iterator i = includeHandlers.iterator(); i.hasNext(); )
+        {
+            EventHandler eh = ( EventHandler ) i.next();
+            if ( (eh instanceof RuntimeServicesAware) &&
+                    !initializedHandlers.contains(eh) )
+            {
+                ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
+                initializedHandlers.add( eh );
+            }
+        }
+
+        for ( Iterator i = invalidReferenceHandlers.iterator(); i.hasNext(); )
         {
             EventHandler eh = ( EventHandler ) i.next();
             if ( (eh instanceof RuntimeServicesAware) &&

Added: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java?view=auto&rev=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java (added)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java Thu Oct 12 00:48:47 2006
@@ -0,0 +1,51 @@
+package org.apache.velocity.app.event;
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/** 
+ * Strategy object used to execute event handler method.  Will be called
+ * while looping through all the chained event handler implementations.
+ * Each EventHandler method call should have a parallel executor object
+ * defined.  
+ *
+ * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
+ * @version $Id$
+ */
+public interface EventHandlerMethodExecutor
+{
+    /**
+     * Execute the event handler method.  If Object is not null, do not 
+     * iterate further through the handler chain.
+     * If appropriate, the returned Object will be the return value.
+     *  
+     * @param handler call the appropriate method on this handler
+     */
+    public void execute(EventHandler handler) throws Exception;
+
+    /**
+     * Called after execute() to see if iterating should stop. Should
+     * always return false before method execute() is run.
+     * @return
+     */
+    public boolean isDone();
+
+    /**
+     * Get return value at end of all the iterations
+     * @return null if no return value is required
+     */
+    public Object getReturnValue();
+}

Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Id Author Date Revision

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerUtil.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerUtil.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerUtil.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/EventHandlerUtil.java Thu Oct 12 00:48:47 2006
@@ -20,7 +20,7 @@
 
 import org.apache.velocity.context.InternalContextAdapter;
 import org.apache.velocity.runtime.RuntimeServices;
-import org.apache.velocity.util.ContextAware;
+import org.apache.velocity.util.ExceptionUtils;
 
 
 /**
@@ -34,7 +34,8 @@
  * @version $Id$
  */
 public class EventHandlerUtil {
-
+    
+    
     /**
      * Called before a reference is inserted. All event handlers are called in
      * sequence. The default implementation inserts the reference as is.
@@ -48,49 +49,37 @@
     public static Object referenceInsert(RuntimeServices rsvc,
             InternalContextAdapter context, String reference, Object value)
     {
+        // app level cartridges have already been initialized
         EventCartridge ev1 = rsvc.getApplicationEventCartridge();
-
-        /**
-         * retrieve and initialize the event cartridge handlers attached to the
-         * context (if they have not been already)
-         */
+        Iterator applicationEventHandlerIterator = 
+            (ev1 == null) ? null: ev1.getReferenceInsertionEventHandlers();              
+        
         EventCartridge ev2 = context.getEventCartridge();
+        initializeEventCartridge(rsvc, ev2);
+        Iterator contextEventHandlerIterator = 
+            (ev2 == null) ? null: ev2.getReferenceInsertionEventHandlers();              
+        
+        try 
+        {
+            EventHandlerMethodExecutor methodExecutor = 
+                new ReferenceInsertionEventHandler.referenceInsertExecutor(context, reference, value);
 
-        if (ev2 != null)
+            callEventHandlers(
+                    applicationEventHandlerIterator, 
+                    contextEventHandlerIterator, methodExecutor);
+            
+            return methodExecutor.getReturnValue();   
+        }
+        catch (RuntimeException e)
         {
-            try {
-                ev2.initialize(rsvc);
-            }
-            catch (Exception E)
-            {
-                rsvc.getLog().error("Couldn't initialize event handler.", E);
-            }
+            throw e;
+        }
+        catch (Exception e)
+        {
+            throw ExceptionUtils.createRuntimeException("Exception in event handler.",e);
         }
-
-        Object returnValue = value;
-
-        if (ev1 != null)
-            for (Iterator i = ev1.getReferenceInsertionEventHandlers(); i.hasNext();)
-            {
-                ReferenceInsertionEventHandler eh = (ReferenceInsertionEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = eh.referenceInsert(reference, returnValue);
-            }
-
-        if (ev2 != null)
-            for (Iterator i = ev2.getReferenceInsertionEventHandlers(); i
-                    .hasNext();)
-            {
-                ReferenceInsertionEventHandler eh = (ReferenceInsertionEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = eh.referenceInsert(reference, returnValue);
-            }
-
-        return returnValue;
     }
-
+    
     /**
      * Called when a null is evaluated during a #set. All event handlers are
      * called in sequence until a false is returned. The default implementation
@@ -105,51 +94,37 @@
     public static boolean shouldLogOnNullSet(RuntimeServices rsvc,
             InternalContextAdapter context, String lhs, String rhs)
     {
+        // app level cartridges have already been initialized
         EventCartridge ev1 = rsvc.getApplicationEventCartridge();
-
-        /**
-         * retrieve and initialize the event cartridge handlers attached to the
-         * context (if they have not been already)
-         */
+        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);
 
-        if (ev2 != null)
+            callEventHandlers(
+                    applicationEventHandlerIterator, 
+                    contextEventHandlerIterator, methodExecutor);
+            
+            return ((Boolean) methodExecutor.getReturnValue()).booleanValue();    
+        }
+        catch (RuntimeException e)
         {
-            try
-            {
-                ev2.initialize(rsvc);
-            }
-            catch (Exception E)
-            {
-                rsvc.getLog().error("Couldn't initialize event handler.", E);
-            }
+            throw e;
+        }
+        catch (Exception e)
+        {
+            throw ExceptionUtils.createRuntimeException("Exception in event handler.",e);
         }
-
-        boolean returnValue = true;
-
-        if (ev1 != null)
-            for (Iterator i = ev1.getNullSetEventHandlers(); i.hasNext();)
-            {
-                NullSetEventHandler eh = (NullSetEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = returnValue
-                        && eh.shouldLogOnNullSet(lhs, rhs);
-            }
-
-        if (ev2 != null)
-            for (Iterator i = ev2.getNullSetEventHandlers(); i.hasNext();)
-            {
-                NullSetEventHandler eh = (NullSetEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = returnValue
-                        && eh.shouldLogOnNullSet(lhs, rhs);
-            }
-
-        return returnValue;
     }
-
+    
     /**
      * Called when a method exception is generated during Velocity merge. Only
      * the first valid event handler in the sequence is called. The default
@@ -169,52 +144,34 @@
      */
     public static Object methodException(RuntimeServices rsvc,
             InternalContextAdapter context, Class claz, String method,
-            Exception e) throws Exception {
+            Exception e) throws Exception 
+    {
+        // app level cartridges have already been initialized
         EventCartridge ev1 = rsvc.getApplicationEventCartridge();
-
-        /**
-         * retrieve and initialize the event cartridge handlers attached to the
-         * context (if they have not been already)
-         */
+        Iterator applicationEventHandlerIterator = 
+            (ev1 == null) ? null: ev1.getMethodExceptionEventHandlers();              
+        
         EventCartridge ev2 = context.getEventCartridge();
-
-        if (ev2 != null)
+        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()) )
         {
-            try
-            {
-                ev2.initialize(rsvc);
-            }
-            catch (Exception E)
-            {
-                rsvc.getLog().error("Couldn't initialize event handler.", E);
-            }
+            throw e;
         }
-
-        if (ev1 != null)
-            for (Iterator i = ev1.getMethodExceptionEventHandlers(); i
-                    .hasNext();)
-            {
-                MethodExceptionEventHandler eh = (MethodExceptionEventHandler) i
-                        .next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                return eh.methodException(claz, method, e);
-            }
-
-        if (ev2 != null)
-            for (Iterator i = ev2.getMethodExceptionEventHandlers(); i
-                    .hasNext();)
-            {
-                MethodExceptionEventHandler eh = (MethodExceptionEventHandler) i
-                        .next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                return eh.methodException(claz, method, e);
-            }
-
-        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
@@ -239,47 +196,108 @@
             InternalContextAdapter context, String includeResourcePath,
             String currentResourcePath, String directiveName)
     {
+        // app level cartridges have already been initialized
         EventCartridge ev1 = rsvc.getApplicationEventCartridge();
-
-        /**
-         * retrieve and initialize the event cartridge handlers attached to the
-         * context (if they have not been already)
-         */
+        Iterator applicationEventHandlerIterator = 
+            (ev1 == null) ? null: ev1.getIncludeEventHandlers();              
+        
         EventCartridge ev2 = context.getEventCartridge();
-
-        if (ev2 != null)
+        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);
+        }
+    }
+    
+    /**
+     * Initialize the event cartridge if appropriate.
+     * @param rsvc
+     * @param eventCartridge
+     */
+    private static void initializeEventCartridge(RuntimeServices rsvc, EventCartridge eventCartridge)
+    {
+        if (eventCartridge != null)
         {
             try
             {
-                ev2.initialize(rsvc);
+                eventCartridge.initialize(rsvc);
             }
-            catch (Exception E)
+            catch (Exception e)
             {
-                rsvc.getLog().error("Couldn't initialize event handler.", E);
+                throw ExceptionUtils.createRuntimeException("Couldn't initialize event cartridge : ", e);
             }
         }
-
-        String returnValue = includeResourcePath;
-
-        if (ev1 != null)
-            for (Iterator i = ev1.getIncludeEventHandlers(); i.hasNext();)
-            {
-                IncludeEventHandler eh = (IncludeEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = eh.includeEvent(returnValue, currentResourcePath, directiveName);
-            }
-
-        if (ev2 != null)
-            for (Iterator i = ev2.getIncludeEventHandlers(); i.hasNext();)
+    }
+    
+    
+    /**
+     * Loop through both the application level and context-attached event handlers
+     * @param rsvc
+     * @param applicationEventHandlerIterator
+     * @param contextEventHandlerIterator
+     * @param eventExecutor
+     */
+    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 returnValue
+     * @param handlerIterator
+     * @param eventExecutor
+     */
+    private static void iterateOverEventHandlers(
+            Iterator handlerIterator,
+            EventHandlerMethodExecutor eventExecutor)
+    throws Exception
+    {
+        if (handlerIterator != null)
+        {
+            for (Iterator i = handlerIterator; i.hasNext();)
             {
-                IncludeEventHandler eh = (IncludeEventHandler) i.next();
-                if (eh instanceof ContextAware)
-                    ((ContextAware) eh).setContext(context);
-                returnValue = eh.includeEvent(returnValue, currentResourcePath, directiveName);
-            }
-
-        return returnValue;
+                EventHandler eventHandler = (EventHandler) i.next();
+                
+                if (!eventExecutor.isDone())
+                {
+                    eventExecutor.execute(eventHandler);
+                }
+            }            
+        }
     }
-
+    
 }

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/IncludeEventHandler.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/IncludeEventHandler.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/IncludeEventHandler.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/IncludeEventHandler.java Thu Oct 12 00:48:47 2006
@@ -1,5 +1,8 @@
 package org.apache.velocity.app.event;
 
+import org.apache.velocity.context.Context;
+import org.apache.velocity.util.ContextAware;
+
 /*
  * Copyright 2001-2004 The Apache Software Foundation.
  *
@@ -42,4 +45,61 @@
      *         include from occurring.
      */
     public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName );
+
+
+
+    /**
+     * Defines the execution strategy for includeEvent
+     */
+    static class IncludeEventExecutor implements EventHandlerMethodExecutor
+    {
+        private Context context;
+        private String includeResourcePath;
+        private String currentResourcePath;
+        private String directiveName;
+        
+        private boolean executed = false;
+        
+        IncludeEventExecutor(
+                Context context, 
+                String includeResourcePath,
+                String currentResourcePath,
+                String directiveName)
+        {
+            this.context = context;
+            this.includeResourcePath = includeResourcePath;
+            this.currentResourcePath = currentResourcePath;
+            this.directiveName = directiveName;
+        }
+
+        /**
+         * Call the method includeEvent()
+         *  
+         * @param handler call the appropriate method on this handler
+         */
+        public void execute(EventHandler handler)
+        {
+            IncludeEventHandler eh = (IncludeEventHandler) handler;
+            
+            if (eh instanceof ContextAware)
+                ((ContextAware) eh).setContext(context);
+
+            executed = true;
+            includeResourcePath = ((IncludeEventHandler) handler)
+                .includeEvent(includeResourcePath, currentResourcePath, directiveName); 
+        }
+
+        public Object getReturnValue()
+        {
+            return includeResourcePath;
+        }
+
+        public boolean isDone()
+        {
+            return executed && (includeResourcePath == null);
+        }        
+        
+        
+    }
+
 }

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java Thu Oct 12 00:48:47 2006
@@ -1,5 +1,8 @@
 package org.apache.velocity.app.event;
 
+import org.apache.velocity.context.Context;
+import org.apache.velocity.util.ContextAware;
+
 /*
  * Copyright 2001-2004 The Apache Software Foundation.
  *
@@ -42,4 +45,63 @@
      */
     public Object methodException( Class claz, String method, Exception e )
          throws Exception;
+
+    /**
+     * Defines the execution strategy for methodException
+     */
+    static class MethodExceptionExecutor implements EventHandlerMethodExecutor
+    {
+        private Context context;
+        private Class claz;
+        private String method;
+        private Exception e;
+        
+        private Object result;
+        private boolean executed = false;
+    
+        MethodExceptionExecutor(
+                Context context, 
+                Class claz,
+                String method,
+                Exception e)
+        {
+            this.context = context;
+            this.claz = claz;
+            this.method = method;
+            this.e = e;
+        }
+
+        /**
+         * Call the method methodException()
+         *  
+         * @param handler call the appropriate method on this handler
+         * @return null to continue iterating, any non-null object to stop.
+         */
+        public void execute(EventHandler handler) throws Exception
+        {
+            MethodExceptionEventHandler eh = (MethodExceptionEventHandler) handler;
+            
+            if (eh instanceof ContextAware)
+                ((ContextAware) eh).setContext(context);
+
+            executed = true;
+            result = ((MethodExceptionEventHandler) handler).methodException(claz, method, e);
+        }
+
+        public Object getReturnValue()
+        {
+            return result;
+        }
+
+        /**
+         * Only run the first MethodExceptionEventHandler
+         */
+        public boolean isDone()
+        {
+           return executed;
+        }        
+        
+        
+    }
+
 }

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/NullSetEventHandler.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/NullSetEventHandler.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/NullSetEventHandler.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/NullSetEventHandler.java Thu Oct 12 00:48:47 2006
@@ -1,5 +1,8 @@
 package org.apache.velocity.app.event;
 
+import org.apache.velocity.context.Context;
+import org.apache.velocity.util.ContextAware;
+
 /*
  * Copyright 2001-2004 The Apache Software Foundation.
  *
@@ -37,4 +40,54 @@
      *  @return true if log message should be written, false otherwise
      */
     public boolean shouldLogOnNullSet( String lhs, String rhs );
+
+    /**
+     * Defines the execution strategy for shouldLogOnNullSet
+     */
+    static class ShouldLogOnNullSetExecutor implements EventHandlerMethodExecutor
+    {
+        private Context context;
+        private String lhs;
+        private String rhs;
+
+        /**
+         * when this is false, quit iterating
+         */
+        private boolean result = true;
+        private boolean executed = false;
+        
+        ShouldLogOnNullSetExecutor(
+                Context context, 
+                String lhs, 
+                String rhs) 
+        {
+            this.context = context;
+            this.lhs = lhs;
+            this.rhs = rhs;
+        }
+
+        public void execute(EventHandler handler)
+        {
+            NullSetEventHandler eh = (NullSetEventHandler) handler;
+            
+            if (eh instanceof ContextAware)
+                ((ContextAware) eh).setContext(context);
+
+            executed = true;
+            result = ((NullSetEventHandler) handler).shouldLogOnNullSet(lhs, rhs); 
+        }
+
+        public Object getReturnValue()
+        {            
+            return new Boolean(result);
+        }
+
+        public boolean isDone()
+        {
+            return executed && !result;
+        }        
+        
+        
+    }
+
 }

Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java (original)
+++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java Thu Oct 12 00:48:47 2006
@@ -16,6 +16,9 @@
  * limitations under the License.
  */
 
+import org.apache.velocity.context.Context;
+import org.apache.velocity.util.ContextAware;
+
 /**
  *  Reference 'Stream insertion' event handler.  Called with object
  *  that will be inserted into stream via value.toString().
@@ -42,4 +45,56 @@
      *         output.
      */
     public Object referenceInsert( String reference, Object value  );
+
+    /**
+     * Defines the execution strategy for referenceInsert
+     */
+    static class referenceInsertExecutor implements EventHandlerMethodExecutor
+    {
+        private Context context;
+        private String reference;
+        private Object value;
+
+        referenceInsertExecutor(
+                Context context, 
+                String reference, 
+                Object value)
+        {
+            this.context = context;
+            this.reference = reference;
+            this.value = value;
+        }
+
+        /**
+         * Call the method referenceInsert()
+         *  
+         * @param handler call the appropriate method on this handler
+         */
+        public void execute(EventHandler handler)
+        {
+            ReferenceInsertionEventHandler eh = (ReferenceInsertionEventHandler) handler;
+            
+            if (eh instanceof ContextAware)
+                ((ContextAware) eh).setContext(context);
+
+            /**
+             * Every successive call will alter the same value
+             */
+            value = ((ReferenceInsertionEventHandler) handler).referenceInsert(reference, value); 
+        }
+
+        public Object getReturnValue()
+        {
+            return value;
+        }
+
+        /**
+         * Continue to end of event handler iteration
+         */
+        public boolean isDone()
+        {
+            return false;
+        }        
+    }
+
 }

Modified: jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/EventHandlingTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/EventHandlingTestCase.java?view=diff&rev=463147&r1=463146&r2=463147
==============================================================================
--- jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/EventHandlingTestCase.java (original)
+++ jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/EventHandlingTestCase.java Thu Oct 12 00:48:47 2006
@@ -145,12 +145,12 @@
          *  First, the reference insertion handler
          */
 
-        String s = "$name";
+        String s = "$name$name$name";
 
         StringWriter w = new StringWriter();
         ve.evaluate( context, w, "mystring", s );
 
-        if ( !w.toString().equals( REFERENCE_VALUE ))
+        if ( !w.toString().equals( REFERENCE_VALUE + REFERENCE_VALUE + REFERENCE_VALUE ))
         {
             fail( "Reference insertion test 1");
         }



---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org