1 package org.apache.turbine.util.velocity;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23
24 import java.util.Iterator;
25
26 import org.apache.turbine.modules.ActionEvent;
27 import org.apache.turbine.pipeline.PipelineData;
28 import org.apache.turbine.services.velocity.TurbineVelocity;
29 import org.apache.turbine.util.RunData;
30 import org.apache.fulcrum.parser.ParameterParser;
31
32 import org.apache.velocity.context.Context;
33
34 /***
35 * If you are using VelocitySite stuff, then your Action's should
36 * extend this class instead of extending the ActionEvent class. The
37 * difference between this class and the ActionEvent class is that
38 * this class will first attempt to execute one of your doMethod's
39 * with a constructor like this:
40 *
41 * <p><code>doEvent(RunData data, Context context)</code></p>
42 *
43 * <p>It gets the context from the TemplateInfo.getTemplateContext()
44 * method. If it can't find a method like that, then it will try to
45 * execute the method without the Context in it.</p>
46 *
47 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
48 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
49 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
50 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
51 * @version $Id: VelocityActionEvent.java 349547 2005-11-28 23:02:03Z epugh $
52 */
53 public abstract class VelocityActionEvent extends ActionEvent
54 {
55 /*** Constant needed for Reflection */
56 private static final Class [] methodParams
57 = new Class [] { RunData.class, Context.class };
58
59 /*** Indicates whether or not this module has been initialized. */
60 protected boolean initialized = false;
61
62 /***
63 * You need to implement this in your classes that extend this
64 * class.
65 *
66 * @deprecated Use PipelineData version instead.
67 * @param data A Turbine RunData object.
68 * @exception Exception a generic exception.
69 */
70 public abstract void doPerform(RunData data)
71 throws Exception;
72
73 /***
74 * You need to implement this in your classes that extend this class.
75 * Should revert to abstract once RunData is gone.
76 * @param data Turbine information.
77 * @exception Exception a generic exception.
78 */
79 public void doPerform(PipelineData pipelineData)
80 throws Exception
81 {
82 RunData data = (RunData) getRunData(pipelineData);
83 doPerform(data);
84 }
85 /***
86 * Provides a means of initializing the module.
87 *
88 * @throws Exception a generic exception.
89 */
90 protected abstract void initialize()
91 throws Exception;
92
93 /***
94 * This overrides the default Action.perform() to execute the
95 * doEvent() method. If that fails, then it will execute the
96 * doPerform() method instead.
97 *
98 * @deprecated Use PipelineData version instead.
99 * @param data A Turbine RunData object.
100 * @exception Exception a generic exception.
101 */
102 protected void perform(RunData data)
103 throws Exception
104 {
105 try
106 {
107 if (!initialized)
108 {
109 initialize();
110 }
111 executeEvents(data, TurbineVelocity.getContext(data));
112 }
113 catch (NoSuchMethodException e)
114 {
115 doPerform(data);
116 }
117 }
118
119 /***
120 * This overrides the default Action.perform() to execute the
121 * doEvent() method. If that fails, then it will execute the
122 * doPerform() method instead.
123 *
124 * @param data A Turbine RunData object.
125 * @exception Exception a generic exception.
126 */
127 protected void perform(PipelineData pipelineData)
128 throws Exception
129 {
130 RunData data = (RunData) getRunData(pipelineData);
131 try
132 {
133 if (!initialized)
134 {
135 initialize();
136 }
137 executeEvents(pipelineData, TurbineVelocity.getContext(pipelineData));
138 }
139 catch (NoSuchMethodException e)
140 {
141 doPerform(pipelineData);
142 }
143 }
144 /***
145 * This method should be called to execute the event based system.
146 * @deprecated Use PipelineData version instead.
147 * @param data A Turbine RunData object.
148 * @param context Velocity context information.
149 * @exception Exception a generic exception.
150 */
151 public void executeEvents(RunData data, Context context)
152 throws Exception
153 {
154
155 String theButton = null;
156
157
158 ParameterParser pp = data.getParameters();
159
160 String button = pp.convert(BUTTON);
161 String key = null;
162
163
164 for (Iterator it = pp.keySet().iterator(); it.hasNext();)
165 {
166 key = (String) it.next();
167 if (key.startsWith(button))
168 {
169 if (considerKey(key, pp))
170 {
171 theButton = formatString(key);
172 break;
173 }
174 }
175 }
176
177 if (theButton == null)
178 {
179 throw new NoSuchMethodException(
180 "ActionEvent: The button was null");
181 }
182
183 Method method = null;
184 try
185 {
186 method = getClass().getMethod(theButton, methodParams);
187 Object[] methodArgs = new Object[] { data, context };
188
189 if (log.isDebugEnabled())
190 {
191 log.debug("Invoking " + method);
192 }
193
194 method.invoke(this, methodArgs);
195 }
196 catch (NoSuchMethodException nsme)
197 {
198
199 if (log.isDebugEnabled())
200 {
201 log.debug("Couldn't locate the Event ( " + theButton
202 + "), running executeEvents() in "
203 + super.getClass().getName());
204 }
205
206 super.executeEvents(data);
207 }
208 catch (InvocationTargetException ite)
209 {
210 Throwable t = ite.getTargetException();
211 log.error("Invokation of " + method , t);
212 throw ite;
213 }
214 finally
215 {
216 pp.remove(key);
217 }
218 }
219
220 /***
221 * This method should be called to execute the event based system.
222 *
223 * @param data A Turbine RunData object.
224 * @param context Velocity context information.
225 * @exception Exception a generic exception.
226 */
227 public void executeEvents(PipelineData pipelineData, Context context)
228 throws Exception
229 {
230 RunData data = (RunData) getRunData(pipelineData);
231
232 String theButton = null;
233
234
235 ParameterParser pp = data.getParameters();
236
237 String button = pp.convert(BUTTON);
238 String key = null;
239
240
241 for (Iterator it = pp.keySet().iterator(); it.hasNext();)
242 {
243 key = (String) it.next();
244 if (key.startsWith(button))
245 {
246 if (considerKey(key, pp))
247 {
248 theButton = formatString(key);
249 break;
250 }
251 }
252 }
253
254 if (theButton == null)
255 {
256 throw new NoSuchMethodException(
257 "ActionEvent: The button was null");
258 }
259
260 Method method = null;
261 try
262 {
263 method = getClass().getMethod(theButton, methodParams);
264 Object[] methodArgs = new Object[] { pipelineData, context };
265
266 if (log.isDebugEnabled())
267 {
268 log.debug("Invoking " + method);
269 }
270
271 method.invoke(this, methodArgs);
272 }
273 catch (NoSuchMethodException nsme)
274 {
275
276 if (log.isDebugEnabled())
277 {
278 log.debug("Couldn't locate the Event ( " + theButton
279 + "), running executeEvents() in "
280 + super.getClass().getName());
281 }
282
283 super.executeEvents(pipelineData);
284 }
285 catch (InvocationTargetException ite)
286 {
287 Throwable t = ite.getTargetException();
288 log.error("Invokation of " + method , t);
289 throw ite;
290 }
291 finally
292 {
293 pp.remove(key);
294 }
295 }
296
297 }