001 package org.apache.turbine.util.velocity;
002
003
004 /*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements. See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership. The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License. You may obtain a copy of the License at
012 *
013 * http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied. See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024 import java.lang.reflect.InvocationTargetException;
025 import java.lang.reflect.Method;
026 import java.util.Iterator;
027
028 import org.apache.fulcrum.parser.ParameterParser;
029 import org.apache.turbine.modules.ActionEvent;
030 import org.apache.turbine.pipeline.PipelineData;
031 import org.apache.turbine.services.velocity.TurbineVelocity;
032 import org.apache.turbine.util.RunData;
033 import org.apache.velocity.context.Context;
034
035 /**
036 * If you are using VelocitySite stuff, then your Action's should
037 * extend this class instead of extending the ActionEvent class. The
038 * difference between this class and the ActionEvent class is that
039 * this class will first attempt to execute one of your doMethod's
040 * with a constructor like this:
041 *
042 * <p><code>doEvent(RunData data, Context context)</code></p>
043 *
044 * <p>It gets the context from the TemplateInfo.getTemplateContext()
045 * method. If it can't find a method like that, then it will try to
046 * execute the method without the Context in it.</p>
047 *
048 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
049 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
050 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
051 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
052 * @version $Id: VelocityActionEvent.java 1073174 2011-02-21 22:18:45Z tv $
053 */
054 public abstract class VelocityActionEvent extends ActionEvent
055 {
056 /** Constant needed for Reflection */
057 private static final Class [] methodParams
058 = new Class [] { RunData.class, Context.class };
059
060 /** Indicates whether or not this module has been initialized. */
061 protected boolean initialized = false;
062
063 /**
064 * You need to implement this in your classes that extend this
065 * class.
066 *
067 * @deprecated Use PipelineData version instead.
068 * @param data A Turbine RunData object.
069 * @exception Exception a generic exception.
070 */
071 @Deprecated
072 @Override
073 public abstract void doPerform(RunData data)
074 throws Exception;
075
076 /**
077 * You need to implement this in your classes that extend this class.
078 * Should revert to abstract once RunData is gone.
079 * @param data Turbine information.
080 * @exception Exception a generic exception.
081 */
082 @Override
083 public void doPerform(PipelineData pipelineData)
084 throws Exception
085 {
086 RunData data = getRunData(pipelineData);
087 doPerform(data);
088 }
089 /**
090 * Provides a means of initializing the module.
091 *
092 * @throws Exception a generic exception.
093 */
094 protected abstract void initialize()
095 throws Exception;
096
097 /**
098 * This overrides the default Action.perform() to execute the
099 * 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 }