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