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,v 1.18.2.2 2004/05/20 03:28:01 seade Exp $
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 Method method = null;
126 try
127 {
128 method = getClass().getMethod(theButton, methodParams);
129 Object[] methodArgs = new Object[] { data, context };
130
131 if (log.isDebugEnabled())
132 {
133 log.debug("Invoking " + method);
134 }
135
136 method.invoke(this, methodArgs);
137 }
138 catch (NoSuchMethodException nsme)
139 {
140
141 if (log.isDebugEnabled())
142 {
143 log.debug("Couldn't locate the Event ( " + theButton
144 + "), running executeEvents() in "
145 + super.getClass().getName());
146 }
147
148 super.executeEvents(data);
149 }
150 catch (InvocationTargetException ite)
151 {
152 Throwable t = ite.getTargetException();
153 log.error("Invokation of " + method , t);
154 }
155 finally
156 {
157 pp.remove(key);
158 }
159 }
160 }