View Javadoc

1   package org.apache.velocity.app.event;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.util.ArrayList;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.apache.velocity.context.Context;
29  import org.apache.velocity.context.InternalEventContext;
30  import org.apache.velocity.runtime.RuntimeServices;
31  import org.apache.velocity.util.RuntimeServicesAware;
32  
33  /**
34   * Stores the event handlers. Event handlers can be assigned on a per
35   * VelocityEngine instance basis by specifying the class names in the
36   * velocity.properties file. Event handlers may also be assigned on a per-page
37   * basis by creating a new instance of EventCartridge, adding the event
38   * handlers, and then calling attachToContext. For clarity, it's recommended
39   * that one approach or the other be followed, as the second method is primarily
40   * presented for backwards compatibility.
41   *
42   * <P>
43   * Note that Event Handlers follow a filter pattern, with multiple event
44   * handlers allowed for each event. When the appropriate event occurs, all the
45   * appropriate event handlers are called in the sequence they were added to the
46   * Event Cartridge. See the javadocs of the specific event handler interfaces
47   * for more details.
48   *
49   * @author <a href="mailto:wglass@wglass@forio.com">Will Glass-Husain </a>
50   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr. </a>
51   * @author <a href="mailto:j_a_fernandez@yahoo.com">Jose Alberto Fernandez </a>
52   * @version $Id: EventCartridge.java 470256 2006-11-02 07:20:36Z wglass $
53   */
54  public class EventCartridge
55    {
56      private List referenceHandlers = new ArrayList();
57      private List nullSetHandlers = new ArrayList();
58      private List methodExceptionHandlers = new ArrayList();
59      private List includeHandlers = new ArrayList();
60      private List invalidReferenceHandlers = new ArrayList();
61  
62      /**
63       * Ensure that handlers are not initialized more than once.
64       */
65      Set initializedHandlers = new HashSet();
66  
67      /**
68       *  Adds an event handler(s) to the Cartridge.  This method
69       *  will find all possible event handler interfaces supported
70       *  by the passed in object.
71       *
72       *  @param ev object impementing a valid EventHandler-derived interface
73       *  @return true if a supported interface, false otherwise or if null
74       */
75      public boolean addEventHandler( EventHandler ev )
76      {
77          if (ev == null)
78          {
79              return false;
80          }
81  
82          boolean found = false;
83  
84          if ( ev instanceof ReferenceInsertionEventHandler)
85          {
86              addReferenceInsertionEventHandler( (ReferenceInsertionEventHandler) ev );
87              found = true;
88          }
89  
90          if ( ev instanceof NullSetEventHandler )
91          {
92              addNullSetEventHandler( (NullSetEventHandler) ev );
93              found = true;
94          }
95  
96          if ( ev instanceof MethodExceptionEventHandler )
97          {
98              addMethodExceptionHandler( (MethodExceptionEventHandler) ev );
99              found = true;
100         }
101 
102         if ( ev instanceof IncludeEventHandler )
103         {
104             addIncludeEventHandler( (IncludeEventHandler) ev );
105             found = true;
106         }
107 
108         if ( ev instanceof InvalidReferenceEventHandler )
109         {
110             addInvalidReferenceEventHandler( (InvalidReferenceEventHandler) ev );
111             found = true;
112         }
113 
114         return found;
115     }
116 
117     /**
118       *  Add a reference insertion event handler to the Cartridge.
119       *
120       *  @param ev ReferenceInsertionEventHandler
121      */
122      public void addReferenceInsertionEventHandler( ReferenceInsertionEventHandler ev )
123      {
124          referenceHandlers.add( ev );
125      }
126 
127     /**
128       *  Add a null set event handler to the Cartridge.
129       *
130       *  @param ev NullSetEventHandler
131       */
132      public void addNullSetEventHandler( NullSetEventHandler ev )
133      {
134          nullSetHandlers.add( ev );
135      }
136 
137     /**
138      *  Add a method exception event handler to the Cartridge.
139      *
140      *  @param ev MethodExceptionEventHandler
141      */
142     public void addMethodExceptionHandler( MethodExceptionEventHandler ev )
143     {
144         methodExceptionHandlers.add( ev );
145     }
146 
147     /**
148      *  Add an include event handler to the Cartridge.
149      *
150      *  @param ev IncludeEventHandler
151      */
152     public void addIncludeEventHandler( IncludeEventHandler ev )
153     {
154         includeHandlers.add( ev );
155     }
156 
157     /**
158      *  Add an invalid reference event handler to the Cartridge.
159      *
160      *  @param ev InvalidReferenceEventHandler
161      */
162     public void addInvalidReferenceEventHandler( InvalidReferenceEventHandler ev )
163     {
164         invalidReferenceHandlers.add( ev );
165     }
166 
167 
168     /**
169      * Removes an event handler(s) from the Cartridge. This method will find all
170      * possible event handler interfaces supported by the passed in object and
171      * remove them.
172      *
173      * @param ev  object impementing a valid EventHandler-derived interface
174      * @return true if event handler was previously registered, false if not
175      *         found
176      */
177     public boolean removeEventHandler( EventHandler ev )
178     {
179         if ( ev == null )
180         {
181             return false;
182         }
183 
184         boolean found = false;
185 
186         if ( ev instanceof ReferenceInsertionEventHandler )
187             return referenceHandlers.remove( ev );
188 
189         if ( ev instanceof NullSetEventHandler )
190             return nullSetHandlers.remove( ev );
191 
192         if ( ev instanceof MethodExceptionEventHandler )
193             return methodExceptionHandlers.remove(ev );
194 
195         if ( ev instanceof IncludeEventHandler )
196             return includeHandlers.remove( ev );
197 
198         if ( ev instanceof InvalidReferenceEventHandler )
199             return invalidReferenceHandlers.remove( ev );
200 
201         return found;
202     }
203 
204     /**
205      * Iterate through all the stored ReferenceInsertionEventHandler objects
206      * 
207      * @return iterator of handler objects
208      */
209     public Iterator getReferenceInsertionEventHandlers()
210     {
211         return referenceHandlers.iterator();
212     }
213 
214     /**
215      * Iterate through all the stored NullSetEventHandler objects
216      * 
217      * @return iterator of handler objects
218      */
219     public Iterator getNullSetEventHandlers()
220     {
221         return nullSetHandlers.iterator();
222     }
223 
224     /**
225      * Iterate through all the stored MethodExceptionEventHandler objects
226      * 
227      * @return iterator of handler objects
228      */
229     public Iterator getMethodExceptionEventHandlers()
230     {
231         return methodExceptionHandlers.iterator();
232     }
233 
234     /**
235      * Iterate through all the stored IncludeEventHandlers objects
236      * 
237      * @return iterator of handler objects
238      */
239     public Iterator getIncludeEventHandlers()
240     {
241         return includeHandlers.iterator();
242     }
243 
244     /**
245      * Iterate through all the stored InvalidReferenceEventHandlers objects
246      * 
247      * @return iterator of handler objects
248      */
249     public Iterator getInvalidReferenceEventHandlers()
250     {
251         return invalidReferenceHandlers.iterator();
252     }
253 
254     /**
255      *  Attached the EventCartridge to the context
256      *
257      *  Final because not something one should mess with lightly :)
258      *
259      *  @param context context to attach to
260      *  @return true if successful, false otherwise
261      */
262     public final boolean attachToContext( Context context )
263     {
264         if (  context instanceof InternalEventContext )
265         {
266             InternalEventContext iec = (InternalEventContext) context;
267 
268             iec.attachEventCartridge( this );
269 
270             /**
271              * while it's tempting to call setContext on each handler from here,
272              * this needs to be done before each method call.  This is
273              * because the specific context will change as inner contexts
274              * are linked in through macros, foreach, or directly by the user.
275              */
276 
277             return true;
278         }
279         else
280         {
281             return false;
282         }
283     }
284 
285     /**
286      * Initialize the handlers.  For global handlers this is called when Velocity
287      * is initialized. For local handlers this is called when the first handler
288      * is executed.  Handlers will not be initialized more than once.
289      * 
290      * @param rs
291      * @throws Exception
292      */
293     public void initialize (RuntimeServices rs) throws Exception
294     {
295 
296         for ( Iterator i = referenceHandlers.iterator(); i.hasNext(); )
297         {
298             EventHandler eh = ( EventHandler ) i.next();
299             if ( (eh instanceof RuntimeServicesAware) &&
300                     !initializedHandlers.contains(eh) )
301             {
302                 ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
303                 initializedHandlers.add( eh );
304             }
305         }
306 
307         for ( Iterator i = nullSetHandlers.iterator(); i.hasNext(); )
308         {
309             EventHandler eh = ( EventHandler ) i.next();
310             if ( (eh instanceof RuntimeServicesAware) &&
311                     !initializedHandlers.contains(eh) )
312             {
313                 ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
314                 initializedHandlers.add( eh );
315             }
316         }
317 
318         for ( Iterator i = methodExceptionHandlers.iterator(); i.hasNext(); )
319         {
320             EventHandler eh = ( EventHandler ) i.next();
321             if ( (eh instanceof RuntimeServicesAware) &&
322                     !initializedHandlers.contains(eh) )
323             {
324                 ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
325                 initializedHandlers.add( eh );
326             }
327         }
328 
329         for ( Iterator i = includeHandlers.iterator(); i.hasNext(); )
330         {
331             EventHandler eh = ( EventHandler ) i.next();
332             if ( (eh instanceof RuntimeServicesAware) &&
333                     !initializedHandlers.contains(eh) )
334             {
335                 ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
336                 initializedHandlers.add( eh );
337             }
338         }
339 
340         for ( Iterator i = invalidReferenceHandlers.iterator(); i.hasNext(); )
341         {
342             EventHandler eh = ( EventHandler ) i.next();
343             if ( (eh instanceof RuntimeServicesAware) &&
344                     !initializedHandlers.contains(eh) )
345             {
346                 ((RuntimeServicesAware) eh).setRuntimeServices ( rs );
347                 initializedHandlers.add( eh );
348             }
349         }
350 
351     }
352 
353 
354 }