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