View Javadoc

1   /***
2    * @(#)ActionFactory.java
3    * 
4    * JFoxSOAF, Service-Oriented Application Framework
5    * 
6    * Copyright(c) JFoxSOAF Team
7    * 
8    * Licensed under the GNU LGPL, Version 2.1 (the "License"); 
9    * you may not use this file except in compliance with the License. 
10   * You may obtain a copy of the License at  
11   * 
12   * http://www.gnu.org/copyleft/lesser.html
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, 
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
17   * See the License for the specific language governing permissions and 
18   * limitations under the License. 
19   * 
20   * For more information, please visit:
21   * http://www.jfox.cn/confluence/display/JFoxSOAF/Home
22   * http://www.huihoo.org/jfox/jfoxsoaf
23   */
24  
25  package org.huihoo.jfox.soaf.services.useraccess.struts;
26  
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import javax.servlet.http.HttpServletRequest;
31  
32  import org.apache.struts.action.Action;
33  import org.apache.struts.action.ActionMapping;
34  import org.apache.struts.action.ActionServlet;
35  import org.huihoo.jfox.soaf.container.ServiceFactory;
36  import org.picocontainer.PicoInitializationException;
37  import org.picocontainer.PicoIntrospectionException;
38  
39  /***
40   * Uses PicoContainer to produce Actions and inject dependencies into them. 
41   * If you have your own <code>RequestProcessor</code> implementation, you can use an
42   * <code>ActionFactory</code> in your <code>RequestProcessor.processActionCreate</code> 
43   * method to Picofy your Actions.
44   * 
45   * @author Stephen Molitor
46   * @author Mauro Talevi
47   * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter Cheng </a>
48   * @version $Revision: 1.1 $ $Date: 2006/02/15 08:45:44 $
49   * @version Revision: 1.0
50   */
51  
52  public class ActionFactory {
53  	
54  	private ServiceFactory sf = ServiceFactory.getInstance();
55  	
56  	private Map classCache = new HashMap();
57  	
58  	/***
59  	 * Gets the <code>Action</code> specified by the mapping type from a
60  	 * PicoContainer. The action will be instantiated if necessary, and its
61  	 * dependencies will be injected. The action will be instantiated via a
62  	 * special PicoContainer that just contains actions. If this container
63  	 * already exists in the request attribute, this method will use it. If no
64  	 * such container exists, this method will create a new Pico container and
65  	 * place it in the request. The parent container will either be the request
66  	 * container, or if that container can not be found the session container,
67  	 * or if that container can not be found, the application container. If no
68  	 * parent container can be found, a <code>PicoInitializationException</code>
69  	 * will be thrown. The action path specified in the mapping is used as the
70  	 * component key for the action.
71  	 * 
72  	 * @param request
73  	 *            the Http servlet request.
74  	 * @param mapping
75  	 *            the Struts mapping object, whose type property tells us what
76  	 *            Action class is required.
77  	 * @param servlet
78  	 *            the Struts <code>ActionServlet</code>.
79  	 * @return the <code>Action</code> instance.
80  	 * @throws PicoIntrospectionException
81  	 *             if the mapping type does not specify a valid action.
82  	 * @throws PicoInitializationException
83  	 *             if no request, session, or application scoped Pico container
84  	 *             can be found.
85  	 *  
86  	 */
87  	public Action processAction(HttpServletRequest request,
88  			ActionMapping mapping, ActionServlet servlet)
89  			throws PicoIntrospectionException, PicoInitializationException {
90  		Object actionKey = mapping.getPath();
91  		Class actionType = getActionClass(mapping.getType());
92  
93  		Action action = (Action) sf.getService(actionKey);
94  		if (action == null) {
95  			sf.registerService(actionKey, actionType);
96  			action = (Action) sf.getService(actionKey);
97  		}
98  
99  		action.setServlet(servlet);
100 		return action;
101 	}
102 
103 	/***
104 	 * Load class.
105 	 * 
106 	 * @param className
107 	 * @return the class
108 	 * @throws PicoIntrospectionException
109 	 */
110 	private Class getActionClass(String className) throws PicoIntrospectionException {
111         try {
112             return loadClass(className);
113         } catch (ClassNotFoundException e) {
114             throw new PicoIntrospectionException("Action class '" + className + "' not found", e);
115         }
116     }
117     
118 	/***
119 	 * Load class with given name.
120 	 * 
121 	 * @param className
122 	 * @return the class
123 	 * @throws ClassNotFoundException
124 	 */
125     private Class loadClass(String className) throws ClassNotFoundException {
126         if (classCache.containsKey(className)) {
127             return (Class) classCache.get(className);
128         } else {
129             ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
130             Class result = classLoader.loadClass(className);
131             classCache.put(className, result);
132             return result;
133         }
134     }    
135 
136 }