View Javadoc

1   package org.apache.turbine.util.velocity;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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          // Name of the button.
97          String theButton = null;
98  
99          // ParameterParser.
100         ParameterParser pp = data.getParameters();
101 
102         String button = pp.convert(BUTTON);
103         String key = null;
104 
105         // Loop through and find the button.
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             // Attempt to execute things the old way..
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 }