/* * Copyright 2000-2001,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * PortletActionEvent.java * * Created on January 29, 2003, 4:20 PM */ package org.apache.jetspeed.modules.actions.portlets; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.HashMap; import org.apache.jetspeed.portal.Portlet; import org.apache.jetspeed.portal.portlets.GenericMVCPortlet; import org.apache.jetspeed.util.PortletSessionState; import org.apache.turbine.modules.ActionEvent; import org.apache.turbine.services.velocity.TurbineVelocity; import org.apache.turbine.util.ParameterParser; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; /** * Provides form based action handling via the eventSubmit_do[action] pattern. * Works just like the mechanism described for the velocity portlet. Extends * this convienent functionality to all GenericMVCPortlets * * @author tkuebler * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a> * @version $Id: PortletActionEvent.java,v 1.3.2.1 2003/02/24 18:45:42 tkuebler Exp $ * @stereotype moment-interval */ public abstract class PortletActionEvent extends ActionEvent { /** * Cache ActionEvent methods to avoid repeated replection * method lookups. */ private static final HashMap eventMethods = new HashMap(); /** * You need to implement this in your classes that extend this * class. * * @param data A Turbine RunData object. * @exception Exception, a generic exception. */ public abstract void doPerform(RunData data) throws Exception; /** * This overrides the default Action.perform() to execute the * doEvent() method. If that fails, then it will execute the * doPerform() method instead. * * @param data A Turbine RunData object. * @exception Exception, a generic exception. */ protected void perform(RunData data) throws Exception { try { executeEvents(data, TurbineVelocity.getContext(data)); } catch (NoSuchMethodException e) { doPerform(data); } } /** * This method should be called to execute the event based system. * * @param data A Turbine RunData object. * @param context context information. * @exception Exception, a generic exception. */ public void executeEvents(RunData data, Context context) throws Exception { // Name of the button. String theButton = null; // Portlet whom this action is a target of Portlet portlet = (Portlet) context.get(GenericMVCPortlet.PORTLET); // ParameterParser. ParameterParser pp = data.getParameters(); String button = pp.convert(BUTTON); // Loop through and find the button. for (Enumeration e = pp.keys(); e.hasMoreElements();) { String key = (String) e.nextElement(); if (key.startsWith(button)) { theButton = formatString(key); break; } } if (theButton == null ) { throw new NoSuchMethodException("ActionEvent: The button was null"); } if (!fireEvent(data, Context.class, context, theButton) && PortletSessionState.isMyRequest(data, portlet)) { // Old JSP actions use Portlet instead of Context // as their event method's 2nd parameter if (!fireEvent(data, Portlet.class, portlet, theButton)) { // Attempt to execut things the old way.. super.executeEvents(data); } } } /** * Convenience method for firing portlet events. * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a> */ protected boolean fireEvent(RunData data, Class deltaClass, Object deltaValue, String theButton) { try { // The arguments to the method to find. Class[] classes = new Class[2]; classes[0] = RunData.class; classes[1] = deltaClass; // The arguments to pass to the method to execute. Object[] args = new Object[2]; String methodKey = getClass().getName()+":" +theButton+":"+classes[0].getName() +":"+classes[1].getName(); Method method = (Method)eventMethods.get(methodKey); if(method == null) { method = getClass().getMethod(theButton, classes); eventMethods.put(methodKey, method); } args[0] = data; args[1] = deltaValue; method.invoke(this, args); return true; } catch (Exception e) { return false; } } }