View Javadoc

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