View Javadoc

1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*
17   * PortletActionEvent.java
18   *
19   * Created on January 29, 2003, 4:20 PM
20   */
21  package org.apache.jetspeed.modules.actions.portlets;
22  
23  import java.lang.reflect.Method;
24  
25  import java.util.Enumeration;
26  import java.util.HashMap;
27  
28  import org.apache.jetspeed.portal.Portlet;
29  import org.apache.jetspeed.portal.portlets.GenericMVCPortlet;
30  import org.apache.jetspeed.util.PortletSessionState;
31  import org.apache.turbine.modules.ActionEvent;
32  import org.apache.turbine.services.velocity.TurbineVelocity;
33  import org.apache.turbine.util.ParameterParser;
34  import org.apache.turbine.util.RunData;
35  
36  import org.apache.velocity.context.Context;
37  
38  
39  /***
40   * Provides form based action handling via the eventSubmit_do[action] pattern.
41   * Works just like the mechanism described for the velocity portlet.  Extends
42   * this convienent functionality to all GenericMVCPortlets
43   * 
44   * @author  tkuebler
45   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
46   * @version $Id: PortletActionEvent.java,v 1.3.2.1 2003/02/24 18:45:42 tkuebler Exp $
47   * @stereotype moment-interval
48   */
49  public abstract class PortletActionEvent
50      extends ActionEvent
51    {
52    	
53    	/***
54    	 * Cache ActionEvent methods to avoid repeated replection
55    	 * method lookups.
56    	 */
57    	private static final HashMap eventMethods = new HashMap();
58  
59      /***
60       * You need to implement this in your classes that extend this
61       * class.
62       *
63       * @param data A Turbine RunData object.
64       * @exception Exception, a generic exception.
65       */
66      public abstract void doPerform(RunData data)
67                              throws Exception;
68  
69      /***
70       * This overrides the default Action.perform() to execute the
71       * doEvent() method.  If that fails, then it will execute the
72       * doPerform() method instead.
73       *
74       * @param data A Turbine RunData object.
75       * @exception Exception, a generic exception.
76       */
77      protected void perform(RunData data)
78                      throws Exception
79        {
80  
81          try
82            {
83              executeEvents(data, TurbineVelocity.getContext(data));
84            }
85          catch (NoSuchMethodException e)
86            {
87              doPerform(data);
88            }
89        }
90  
91      /***
92       * This method should be called to execute the event based system.
93       *
94       * @param data A Turbine RunData object.
95       * @param context context information.
96       * @exception Exception, a generic exception.
97       */
98      public void executeEvents(RunData data, Context context)
99                         throws Exception
100       {
101 
102         // Name of the button.
103         String theButton = null;
104         
105         // Portlet whom this action is a target of
106         Portlet portlet = (Portlet) context.get(GenericMVCPortlet.PORTLET);
107 
108         // ParameterParser.
109         ParameterParser pp = data.getParameters();
110         String button = pp.convert(BUTTON);
111 
112         // Loop through and find the button.
113         for (Enumeration e = pp.keys(); e.hasMoreElements();)
114           {
115 
116             String key = (String) e.nextElement();
117 
118             if (key.startsWith(button))
119               {
120                 theButton = formatString(key);
121 
122                 break;
123               }
124           }
125 
126         if (theButton == null )
127           {
128             throw new NoSuchMethodException("ActionEvent: The button was null");
129           }
130 
131  
132 
133 		if (!fireEvent(data, Context.class, context, theButton) && PortletSessionState.isMyRequest(data, portlet))
134 		{
135 			// Old JSP actions use Portlet instead of Context
136 			// as their event method's 2nd parameter
137 			if (!fireEvent(data, Portlet.class,
138 				portlet,
139 				theButton))
140 			{
141 				// Attempt to execut things the old way..
142 				super.executeEvents(data);
143 			}
144 		}            
145 
146       }
147       
148     /***
149      * Convenience method for firing portlet events.
150 	 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
151      */
152 	protected boolean fireEvent(RunData data, Class deltaClass, Object deltaValue, String theButton)		
153 	{
154 		try
155 		{
156 			// The arguments to the method to find.
157 			Class[] classes = new Class[2];
158 			classes[0] = RunData.class;
159 			classes[1] = deltaClass;
160 			
161 			// The arguments to pass to the method to execute.
162 			Object[] args = new Object[2];
163 			
164 			String methodKey = getClass().getName()+":"
165 			                   +theButton+":"+classes[0].getName()
166 			                   +":"+classes[1].getName();
167 			
168 			Method method = (Method)eventMethods.get(methodKey);
169 			if(method == null)
170 			{
171 				method = getClass().getMethod(theButton, classes);
172 				eventMethods.put(methodKey, method);
173 			}
174 			args[0] = data;
175 			args[1] = deltaValue;
176 			method.invoke(this, args);
177 			return true;
178 		}
179 		catch (Exception e)
180 		{
181 			return false;
182 		}
183 		
184 	}
185       
186      
187   }