KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > modules > ActionEvent


1 package org.apache.turbine.modules;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache Turbine" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache Turbine", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.lang.reflect.InvocationTargetException JavaDoc;
58 import java.lang.reflect.Method JavaDoc;
59 import java.util.Enumeration JavaDoc;
60
61 import org.apache.fulcrum.parser.ParameterParser;
62 import org.apache.turbine.RunData;
63 import org.apache.turbine.Turbine;
64 import org.apache.turbine.TurbineException;
65
66 /**
67  * <p>
68  *
69  * This is an alternative to the Action class that allows you to do
70  * event based actions. Essentially, you label all your submit buttons
71  * with the prefix of "eventSubmit_" and the suffix of "methodName".
72  * For example, "eventSubmit_doDelete". Then any class that subclasses
73  * this class will get its "doDelete(RunData data)" method executed.
74  * If for any reason, it was not able to execute the method, it will
75  * fall back to executing the doPeform() method which is required to
76  * be implemented.
77  *
78  * <p>
79  *
80  * Limitations:
81  *
82  * <p>
83  *
84  * Because ParameterParser makes all the key values lowercase, we have
85  * to do some work to format the string into a method name. For
86  * example, a button name eventSubmit_doDelete gets converted into
87  * eventsubmit_dodelete. Thus, we need to form some sort of naming
88  * convention so that dodelete can be turned into doDelete.
89  *
90  * <p>
91  *
92  * Thus, the convention is this:
93  *
94  * <ul>
95  * <li>The variable name MUST have the prefix "eventSubmit_".</li>
96  * <li>The variable name after the prefix MUST begin with the letters
97  * "do".</li>
98  * <li>The first letter after the "do" will be capitalized and the
99  * rest will be lowercase</li>
100  * </ul>
101  *
102  * If you follow these conventions, then you should be ok with your
103  * method naming in your Action class.
104  *
105  * @author <a HREF="mailto:jon@latchkey.com">Jon S. Stevens </a>
106  * @version $Id: ActionEvent.java,v 1.5 2004/11/12 10:26:31 epugh Exp $
107  */

108 public abstract class ActionEvent
109     extends Action
110 {
111     /**
112      * You need to implement this in your classes that extend this class.
113      *
114      * @param data Turbine information.
115      * @exception Exception a generic exception.
116      */

117     public abstract void doPerform( RunData data )
118         throws Exception JavaDoc;
119
120     /** The name of the button to look for. */
121     protected static final String JavaDoc BUTTON = "eventSubmit_";
122     /** The length of the button to look for. */
123     protected static final int BUTTON_LENGTH = BUTTON.length();
124     /** The prefix of the method name. */
125     protected static final String JavaDoc METHOD_NAME_PREFIX = "do";
126     /** The length of the method name. */
127     protected static final int METHOD_NAME_LENGTH = METHOD_NAME_PREFIX.length();
128     /** The length of the button to look for. */
129     protected static final int LENGTH = BUTTON.length();
130
131     /**
132      * This overrides the default Action.perform() to execute the
133      * doEvent() method. If that fails, then it will execute the
134      * doPerform() method instead.
135      *
136      * @param data Turbine information.
137      * @exception Exception a generic exception.
138      */

139     protected void perform( RunData data )
140         throws Exception JavaDoc
141     {
142         try
143         {
144             executeEvents(data);
145         }
146         catch (NoSuchMethodException JavaDoc e)
147         {
148             doPerform( data );
149         }
150         catch (InvocationTargetException JavaDoc ite)
151         {
152             // i have not seen this exception, in stacktraces generated
153
// while doing my own testing on jdk1.3.1 and earlier. But
154
// see it increasingly from stacktraces reported by others.
155
// Its printStackTrace method should do The Right Thing, but
156
// I suspect some implementation is not.
157
// Unwrap it here, so that the original cause does not get lost.
158
Throwable JavaDoc t = ite.getTargetException();
159             if (t instanceof Exception JavaDoc)
160             {
161                 throw (Exception JavaDoc)t;
162             }
163             else if (t instanceof java.lang.Error JavaDoc)
164             {
165                 throw (java.lang.Error JavaDoc)t;
166             }
167             else
168             {
169                 // this should not happen, but something could throw
170
// an instance of Throwable
171
throw new TurbineException(t);
172             }
173         }
174     }
175
176     public void execute(RunData data)
177         throws Exception JavaDoc
178     {
179         perform(data);
180     }
181
182     /**
183      * This method should be called to execute the event based system.
184      *
185      * @param data Turbine information.
186      * @exception Exception a generic exception.
187      */

188     public void executeEvents(RunData data)
189         throws Exception JavaDoc
190     {
191         // Name of the button.
192
String JavaDoc theButton = null;
193         // Parameter parser.
194
ParameterParser pp = data.getParameters();
195         // The arguments to pass to the method to execute.
196
Object JavaDoc[] args = new Object JavaDoc[1];
197         // The arguments to the method to find.
198
Class JavaDoc[] classes = new Class JavaDoc[1];
199         classes[0] = RunData.class;
200
201         String JavaDoc button = pp.convert(BUTTON);
202
203         // Loop through and find the button.
204
for (Enumeration JavaDoc e = pp.keys() ; e.hasMoreElements() ;)
205         {
206             String JavaDoc key = (String JavaDoc) e.nextElement();
207             if (key.startsWith(button))
208             {
209                 theButton = formatString(key);
210                 break;
211             }
212         }
213
214         if (theButton == null)
215         {
216             throw new NoSuchMethodException JavaDoc(
217                 "ActionEvent: The button was null");
218         }
219
220         Method JavaDoc method = getClass().getMethod(theButton, classes);
221         args[0] = data;
222         method.invoke(this, args );
223     }
224
225     /**
226      * This method does the conversion of the lowercase method name
227      * into the proper case.
228      *
229      * @param input The unconverted method name.
230      * @return A string with the method name in the proper case.
231      */

232     protected final String JavaDoc formatString(String JavaDoc input)
233     {
234         String JavaDoc methodName = input;
235         
236         // check for image submission
237
if (input.endsWith(".x") || input.endsWith(".y"))
238         {
239            methodName = methodName.substring(0, input.length() - 2);
240         }
241         
242         String JavaDoc fold =
243             Turbine.getConfiguration().getString(
244                 Turbine.PP_URL_CASE_FOLDING,
245                 ParameterParser.URL_CASE_FOLDING_LOWER).toLowerCase();
246
247         if (! fold.equals(ParameterParser.URL_CASE_FOLDING_NONE))
248         {
249             methodName =
250                 methodName.substring(BUTTON_LENGTH + METHOD_NAME_LENGTH);
251
252             return (METHOD_NAME_PREFIX + firstLetterCaps(methodName));
253         }
254         else
255         {
256             return methodName.substring(BUTTON_LENGTH);
257         }
258     }
259
260     /**
261      * Makes the first letter caps and the rest lowercase.
262      *
263      * @param data The input string.
264      * @return A string with the described case.
265      */

266     private final String JavaDoc firstLetterCaps( String JavaDoc data )
267     {
268         String JavaDoc firstLetter = data.substring(0, 1).toUpperCase();
269         String JavaDoc restLetters = data.substring(1).toLowerCase();
270         return firstLetter + restLetters;
271     }
272 }
273
Popular Tags