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 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21
22 import java.util.Iterator;
23
24 import org.apache.turbine.modules.ActionEvent;
25 import org.apache.turbine.services.velocity.TurbineVelocity;
26 import org.apache.turbine.util.RunData;
27 import org.apache.turbine.util.parser.ParameterParser;
28
29 import org.apache.velocity.context.Context;
30
31 /***
32 * If you are using VelocitySite stuff, then your Action's should
33 * extend this class instead of extending the ActionEvent class. The
34 * difference between this class and the ActionEvent class is that
35 * this class will first attempt to execute one of your doMethod's
36 * with a constructor like this:
37 *
38 * <p><code>doEvent(RunData data, Context context)</code></p>
39 *
40 * <p>It gets the context from the TemplateInfo.getTemplateContext()
41 * method. If it can't find a method like that, then it will try to
42 * execute the method without the Context in it.</p>
43 *
44 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
45 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
46 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
47 * @version $Id: VelocityActionEvent.java 292717 2005-09-30 12:56:23Z seade $
48 */
49 public abstract class VelocityActionEvent extends ActionEvent
50 {
51 /*** Constant needed for Reflection */
52 private static final Class [] methodParams
53 = new Class [] { RunData.class, Context.class };
54
55 /***
56 * You need to implement this in your classes that extend this
57 * class.
58 *
59 * @param data A Turbine RunData object.
60 * @exception Exception a generic exception.
61 */
62 public abstract void doPerform(RunData data)
63 throws Exception;
64
65 /***
66 * This overrides the default Action.perform() to execute the
67 * doEvent() method. If that fails, then it will execute the
68 * doPerform() method instead.
69 *
70 * @param data A Turbine RunData object.
71 * @exception Exception a generic exception.
72 */
73 protected void perform(RunData data)
74 throws Exception
75 {
76 try
77 {
78 executeEvents(data, TurbineVelocity.getContext(data));
79 }
80 catch (NoSuchMethodException e)
81 {
82 doPerform(data);
83 }
84 }
85
86 /***
87 * This method should be called to execute the event based system.
88 *
89 * @param data A Turbine RunData object.
90 * @param context Velocity context information.
91 * @exception Exception a generic exception.
92 */
93 public void executeEvents(RunData data, Context context)
94 throws Exception
95 {
96
97 String theButton = null;
98
99
100 ParameterParser pp = data.getParameters();
101
102 String button = pp.convert(BUTTON);
103 String key = null;
104
105
106 for (Iterator it = pp.keySet().iterator(); it.hasNext();)
107 {
108 key = (String) it.next();
109 if (key.startsWith(button))
110 {
111 if (considerKey(key, pp))
112 {
113 theButton = formatString(key);
114 break;
115 }
116 }
117 }
118
119 if (theButton == null)
120 {
121 throw new NoSuchMethodException(
122 "ActionEvent: The button was null");
123 }
124
125 try
126 {
127 Method method = getClass().getMethod(theButton, methodParams);
128 Object[] methodArgs = new Object[] { data, context };
129
130 if (log.isDebugEnabled())
131 {
132 log.debug("Invoking " + method);
133 }
134
135 method.invoke(this, methodArgs);
136 }
137 catch (NoSuchMethodException nsme)
138 {
139
140 if (log.isDebugEnabled())
141 {
142 log.debug("Couldn't locate the Event ( " + theButton
143 + "), running executeEvents() in "
144 + super.getClass().getName());
145 }
146
147 super.executeEvents(data);
148 }
149 catch (InvocationTargetException ite)
150 {
151 Throwable t = ite.getTargetException();
152 if (t instanceof Exception)
153 {
154 throw (Exception) t;
155 }
156 else
157 {
158 throw ite;
159 }
160 }
161 finally
162 {
163 pp.remove(key);
164 }
165 }
166 }