001: package org.apache.turbine.util.velocity;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License")
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.lang.reflect.InvocationTargetException;
020: import java.lang.reflect.Method;
021:
022: import java.util.Iterator;
023:
024: import org.apache.turbine.modules.ActionEvent;
025: import org.apache.turbine.services.velocity.TurbineVelocity;
026: import org.apache.turbine.util.RunData;
027: import org.apache.turbine.util.parser.ParameterParser;
028:
029: import org.apache.velocity.context.Context;
030:
031: /**
032: * If you are using VelocitySite stuff, then your Action's should
033: * extend this class instead of extending the ActionEvent class. The
034: * difference between this class and the ActionEvent class is that
035: * this class will first attempt to execute one of your doMethod's
036: * with a constructor like this:
037: *
038: * <p><code>doEvent(RunData data, Context context)</code></p>
039: *
040: * <p>It gets the context from the TemplateInfo.getTemplateContext()
041: * method. If it can't find a method like that, then it will try to
042: * execute the method without the Context in it.</p>
043: *
044: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
045: * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
046: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
047: * @version $Id: VelocityActionEvent.java 292717 2005-09-30 12:56:23Z seade $
048: */
049: public abstract class VelocityActionEvent extends ActionEvent {
050: /** Constant needed for Reflection */
051: private static final Class[] methodParams = new Class[] {
052: RunData.class, Context.class };
053:
054: /**
055: * You need to implement this in your classes that extend this
056: * class.
057: *
058: * @param data A Turbine RunData object.
059: * @exception Exception a generic exception.
060: */
061: public abstract void doPerform(RunData data) throws Exception;
062:
063: /**
064: * This overrides the default Action.perform() to execute the
065: * doEvent() method. If that fails, then it will execute the
066: * doPerform() method instead.
067: *
068: * @param data A Turbine RunData object.
069: * @exception Exception a generic exception.
070: */
071: protected void perform(RunData data) throws Exception {
072: try {
073: executeEvents(data, TurbineVelocity.getContext(data));
074: } catch (NoSuchMethodException e) {
075: doPerform(data);
076: }
077: }
078:
079: /**
080: * This method should be called to execute the event based system.
081: *
082: * @param data A Turbine RunData object.
083: * @param context Velocity context information.
084: * @exception Exception a generic exception.
085: */
086: public void executeEvents(RunData data, Context context)
087: throws Exception {
088: // Name of the button.
089: String theButton = null;
090:
091: // ParameterParser.
092: ParameterParser pp = data.getParameters();
093:
094: String button = pp.convert(BUTTON);
095: String key = null;
096:
097: // Loop through and find the button.
098: for (Iterator it = pp.keySet().iterator(); it.hasNext();) {
099: key = (String) it.next();
100: if (key.startsWith(button)) {
101: if (considerKey(key, pp)) {
102: theButton = formatString(key);
103: break;
104: }
105: }
106: }
107:
108: if (theButton == null) {
109: throw new NoSuchMethodException(
110: "ActionEvent: The button was null");
111: }
112:
113: try {
114: Method method = getClass().getMethod(theButton,
115: methodParams);
116: Object[] methodArgs = new Object[] { data, context };
117:
118: if (log.isDebugEnabled()) {
119: log.debug("Invoking " + method);
120: }
121:
122: method.invoke(this , methodArgs);
123: } catch (NoSuchMethodException nsme) {
124: // Attempt to execute things the old way..
125: if (log.isDebugEnabled()) {
126: log.debug("Couldn't locate the Event ( " + theButton
127: + "), running executeEvents() in "
128: + super .getClass().getName());
129: }
130:
131: super .executeEvents(data);
132: } catch (InvocationTargetException ite) {
133: Throwable t = ite.getTargetException();
134: if (t instanceof Exception) {
135: throw (Exception) t;
136: } else {
137: throw ite;
138: }
139: } finally {
140: pp.remove(key);
141: }
142: }
143: }
|