• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.apache.velocity.context.InternalContextAdapter;
23 import org.apache.velocity.exception.VelocityException;
24 import org.apache.velocity.runtime.RuntimeServices;
25 import org.apache.velocity.util.introspection.Info;
26 
27 
28 /**
29  * Calls on request all registered event handlers for a particular event. Each
30  * method accepts two event cartridges (typically one from the application and
31  * one from the context). All appropriate event handlers are executed in order
32  * until a stopping condition is met. See the docs for the individual methods to
33  * see what the stopping condition is for that method.
34  *
35  * @author <a href="mailto:wglass@wglass@forio.com">Will Glass-Husain </a>
36  * @version $Id$
37  * @since 1.5
38  */
39 public class EventHandlerUtil {
40 
41 
42     /**
43      * Called before a reference is inserted. All event handlers are called in
44      * sequence. The default implementation inserts the reference as is.
45      *
46      * This is a major hotspot method called by ASTReference render.
47      *
48      * @param reference reference from template about to be inserted
49      * @param value value about to be inserted (after toString() )
50      * @param rsvc current instance of RuntimeServices
51      * @param context The internal context adapter.
52      * @return Object on which toString() should be called for output.
53      */
referenceInsert(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object value)54     public static Object referenceInsert(RuntimeServices rsvc,
55             InternalContextAdapter context, String reference, Object value)
56     {
57         try
58         {
59             value = rsvc.getApplicationEventCartridge().referenceInsert(context, reference, value);
60             EventCartridge contextCartridge = context.getEventCartridge();
61             if (contextCartridge != null)
62             {
63                 contextCartridge.setRuntimeServices(rsvc);
64                 value = contextCartridge.referenceInsert(context, reference, value);
65             }
66             return value;
67         }
68         catch (RuntimeException e)
69         {
70             throw e;
71         }
72         catch (Exception e)
73         {
74             throw new VelocityException("Exception in event handler.",e, rsvc.getLogContext().getStackTrace());
75         }
76     }
77 
78     /**
79      * Called when a method exception is generated during Velocity merge. Only
80      * the first valid event handler in the sequence is called. The default
81      * implementation simply rethrows the exception.
82      *
83      * @param claz
84      *            Class that is causing the exception
85      * @param method
86      *            method called that causes the exception
87      * @param e
88      *            Exception thrown by the method
89      * @param rsvc current instance of RuntimeServices
90      * @param context The internal context adapter.
91      * @param info exception location informations
92      * @return Object to return as method result
93      * @throws Exception
94      *             to be wrapped and propagated to app
95      */
methodException(RuntimeServices rsvc, InternalContextAdapter context, Class<?> claz, String method, Exception e, Info info)96     public static Object methodException(RuntimeServices rsvc,
97             InternalContextAdapter context, Class<?> claz, String method,
98             Exception e, Info info) throws Exception
99     {
100         try
101         {
102             EventCartridge ev = rsvc.getApplicationEventCartridge();
103             if (ev.hasMethodExceptionEventHandler())
104             {
105                 return ev.methodException(context, claz, method, e, info);
106             }
107             EventCartridge contextCartridge = context.getEventCartridge();
108             if (contextCartridge != null)
109             {
110                 contextCartridge.setRuntimeServices(rsvc);
111                 return contextCartridge.methodException(context, claz, method, e, info);
112             }
113         }
114         catch (RuntimeException re)
115         {
116             throw re;
117         }
118         catch (Exception ex)
119         {
120             throw new VelocityException("Exception in event handler.", ex, rsvc.getLogContext().getStackTrace());
121         }
122 
123         /* default behaviour is to re-throw exception */
124         throw e;
125     }
126 
127     /**
128      * Called when an include-type directive is encountered (#include or
129      * #parse). All the registered event handlers are called unless null is
130      * returned. The default implementation always processes the included
131      * resource.
132      *
133      * @param includeResourcePath
134      *            the path as given in the include directive.
135      * @param currentResourcePath
136      *            the path of the currently rendering template that includes the
137      *            include directive.
138      * @param directiveName
139      *            name of the directive used to include the resource. (With the
140      *            standard directives this is either "parse" or "include").
141      * @param rsvc current instance of RuntimeServices
142      * @param context The internal context adapter.
143      *
144      * @return a new resource path for the directive, or null to block the
145      *         include from occurring.
146      */
includeEvent(RuntimeServices rsvc, InternalContextAdapter context, String includeResourcePath, String currentResourcePath, String directiveName)147     public static String includeEvent(RuntimeServices rsvc,
148             InternalContextAdapter context, String includeResourcePath,
149             String currentResourcePath, String directiveName)
150     {
151         try
152         {
153             includeResourcePath = rsvc.getApplicationEventCartridge().includeEvent(context, includeResourcePath, currentResourcePath, directiveName);
154             EventCartridge contextCartridge = context.getEventCartridge();
155             if (contextCartridge != null)
156             {
157                 contextCartridge.setRuntimeServices(rsvc);
158                 includeResourcePath = contextCartridge.includeEvent(context, includeResourcePath, currentResourcePath, directiveName);
159             }
160             return includeResourcePath;
161         }
162         catch (RuntimeException e)
163         {
164             throw e;
165         }
166         catch (Exception e)
167         {
168             throw new VelocityException("Exception in event handler.", e, rsvc.getLogContext().getStackTrace());
169         }
170     }
171 
172 
173     /**
174      * Called when an invalid get method is encountered.
175      *
176      * @param rsvc current instance of RuntimeServices
177      * @param context the context when the reference was found invalid
178      * @param reference complete invalid reference
179      * @param object object from reference, or null if not available
180      * @param property name of property, or null if not relevant
181      * @param info contains info on template, line, col
182      * @return substitute return value for missing reference, or null if no substitute
183      */
invalidGetMethod(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object object, String property, Info info)184     public static Object invalidGetMethod(RuntimeServices rsvc,
185             InternalContextAdapter context, String reference,
186             Object object, String property, Info info)
187     {
188         try
189         {
190             Object result = rsvc.getApplicationEventCartridge().invalidGetMethod(context, reference, object, property, info);
191             EventCartridge contextCartridge = context.getEventCartridge();
192             if (contextCartridge != null)
193             {
194                 contextCartridge.setRuntimeServices(rsvc);
195                 result = contextCartridge.invalidGetMethod(context, reference, object, property, info);
196             }
197             return result;
198         }
199         catch (RuntimeException e)
200         {
201             throw e;
202         }
203         catch (Exception e)
204         {
205             throw new VelocityException("Exception in event handler.", e, rsvc.getLogContext().getStackTrace());
206         }
207     }
208 
209    /**
210      * Called when an invalid set method is encountered.
211      *
212      * @param rsvc current instance of RuntimeServices
213      * @param context the context when the reference was found invalid
214      * @param leftreference left reference being assigned to
215      * @param rightreference invalid reference on the right
216      * @param info contains info on template, line, col
217      */
invalidSetMethod(RuntimeServices rsvc, InternalContextAdapter context, String leftreference, String rightreference, Info info)218     public static void invalidSetMethod(RuntimeServices rsvc,
219             InternalContextAdapter context, String leftreference,
220             String rightreference, Info info)
221     {
222         try
223         {
224             if (!rsvc.getApplicationEventCartridge().invalidSetMethod(context, leftreference, rightreference, info))
225             {
226                 EventCartridge contextCartridge = context.getEventCartridge();
227                 if (contextCartridge != null)
228                 {
229                     contextCartridge.setRuntimeServices(rsvc);
230                     contextCartridge.invalidSetMethod(context, leftreference, rightreference, info);
231                 }
232             }
233         }
234         catch (RuntimeException e)
235         {
236             throw e;
237         }
238         catch (Exception e)
239         {
240             throw new VelocityException("Exception in event handler.", e, rsvc.getLogContext().getStackTrace());
241         }
242     }
243 
244     /**
245      * Called when an invalid method is encountered.
246      *
247      * @param rsvc current instance of RuntimeServices
248      * @param context the context when the reference was found invalid
249      * @param reference complete invalid reference
250      * @param object object from reference, or null if not available
251      * @param method name of method, or null if not relevant
252      * @param info contains info on template, line, col
253      * @return substitute return value for missing reference, or null if no substitute
254      */
invalidMethod(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object object, String method, Info info)255     public static Object invalidMethod(RuntimeServices rsvc,
256             InternalContextAdapter context,  String reference,
257             Object object, String method, Info info)
258     {
259         try
260         {
261             Object result = rsvc.getApplicationEventCartridge().invalidMethod(context, reference, object, method, info);
262             EventCartridge contextCartridge = context.getEventCartridge();
263             if (contextCartridge != null)
264             {
265                 contextCartridge.setRuntimeServices(rsvc);
266                 result = contextCartridge.invalidMethod(context, reference, object, method, info);
267             }
268             return result;
269         }
270         catch (RuntimeException e)
271         {
272             throw e;
273         }
274         catch (Exception e)
275         {
276             throw new VelocityException("Exception in event handler.", e, rsvc.getLogContext().getStackTrace());
277         }
278     }
279 }
280