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
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24
25 import java.util.Iterator;
26
27 import org.apache.turbine.modules.ActionEvent;
28 import org.apache.turbine.services.velocity.TurbineVelocity;
29 import org.apache.turbine.util.RunData;
30 import org.apache.turbine.util.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 * @version $Id: VelocityActionEvent.java 534527 2007-05-02 16:10:59Z tv $
51 */
52 public abstract class VelocityActionEvent extends ActionEvent
53 {
54 /*** Constant needed for Reflection */
55 private static final Class [] methodParams
56 = new Class [] { RunData.class, Context.class };
57
58 /***
59 * You need to implement this in your classes that extend this
60 * class.
61 *
62 * @param data A Turbine RunData object.
63 * @exception Exception a generic exception.
64 */
65 public abstract void doPerform(RunData data)
66 throws Exception;
67
68 /***
69 * This overrides the default Action.perform() to execute the
70 * doEvent() method. If that fails, then it will execute the
71 * doPerform() method instead.
72 *
73 * @param data A Turbine RunData object.
74 * @exception Exception a generic exception.
75 */
76 protected void perform(RunData data)
77 throws Exception
78 {
79 try
80 {
81 executeEvents(data, TurbineVelocity.getContext(data));
82 }
83 catch (NoSuchMethodException e)
84 {
85 doPerform(data);
86 }
87 }
88
89 /***
90 * This method should be called to execute the event based system.
91 *
92 * @param data A Turbine RunData object.
93 * @param context Velocity context information.
94 * @exception Exception a generic exception.
95 */
96 public void executeEvents(RunData data, Context context)
97 throws Exception
98 {
99
100 String theButton = null;
101
102
103 ParameterParser pp = data.getParameters();
104
105 String button = pp.convert(BUTTON);
106 String key = null;
107
108
109 for (Iterator it = pp.keySet().iterator(); it.hasNext();)
110 {
111 key = (String) it.next();
112 if (key.startsWith(button))
113 {
114 if (considerKey(key, pp))
115 {
116 theButton = formatString(key);
117 break;
118 }
119 }
120 }
121
122 if (theButton == null)
123 {
124 throw new NoSuchMethodException(
125 "ActionEvent: The button was null");
126 }
127
128 try
129 {
130 Method method = getClass().getMethod(theButton, methodParams);
131 Object[] methodArgs = new Object[] { data, context };
132
133 if (log.isDebugEnabled())
134 {
135 log.debug("Invoking " + method);
136 }
137
138 method.invoke(this, methodArgs);
139 }
140 catch (NoSuchMethodException nsme)
141 {
142
143 if (log.isDebugEnabled())
144 {
145 log.debug("Couldn't locate the Event ( " + theButton
146 + "), running executeEvents() in "
147 + super.getClass().getName());
148 }
149
150 super.executeEvents(data);
151 }
152 catch (InvocationTargetException ite)
153 {
154 Throwable t = ite.getTargetException();
155 if (t instanceof Exception)
156 {
157 throw (Exception) t;
158 }
159 else
160 {
161 throw ite;
162 }
163 }
164 finally
165 {
166 pp.remove(key);
167 }
168 }
169 }