1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.struts.faces.application;
18
19
20 import javax.faces.component.ActionSource;
21 import javax.faces.component.UIComponent;
22 import javax.faces.component.UIForm;
23 import javax.faces.context.FacesContext;
24 import javax.faces.event.AbortProcessingException;
25 import javax.faces.event.ActionEvent;
26 import javax.faces.event.ActionListener;
27 import javax.servlet.ServletContext;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.struts.Globals;
33 import org.apache.struts.action.ActionServlet;
34 import org.apache.struts.action.RequestProcessor;
35 import org.apache.struts.config.ModuleConfig;
36 import org.apache.struts.faces.Constants;
37 import org.apache.struts.faces.component.FormComponent;
38 import org.apache.struts.util.RequestUtils;
39 import org.apache.struts.util.ModuleUtils;
40
41
42 /***
43 * <p>Concrete implementation of <code>ActionListener</code> that replaces
44 * the default provided implementation. It converts application-level events
45 * into execution of the corresponding Struts request processing lifecycle.
46 * </p>
47 *
48 * @version $Rev: 421138 $ $Date: 2006-07-11 22:41:40 -0700 (Tue, 11 Jul 2006) $
49 */
50
51 public final class ActionListenerImpl implements ActionListener {
52
53
54
55
56
57 /***
58 * <p>Construct a new default <code>ActionListener</code> instance,
59 * passing it the previously configured one.</p>
60 *
61 * @param original Original default <code>ActionListener</code>
62 *
63 * @exception NullPointerException if <code>original</code>
64 * is <code>null</code>
65 */
66 public ActionListenerImpl(ActionListener original) {
67
68 if (original == null) {
69 throw new NullPointerException();
70 }
71 this.original = original;
72 if (log.isInfoEnabled()) {
73 log.info("Create ActionListener wrapping instance of type '" +
74 original.getClass().getName() + "'");
75 }
76
77 }
78
79
80
81
82
83
84 /***
85 * <p>The logger for this instance.</p>
86 */
87 private static final Log log = LogFactory.getLog(ActionListenerImpl.class);
88
89
90 /***
91 * <p>The previously configured <code>ActionListener</code> instance.</p>
92 */
93 private ActionListener original;
94
95
96
97
98
99 /***
100 * <p>Process the specified <code>ActionEvent</code>.</p>
101 *
102 * @param event The <code>ActionEvent</code> to be processed
103 *
104 * @exception AbortProcessingException to signal that no further
105 * event processing should be performed
106 */
107 public void processAction(ActionEvent event)
108 throws AbortProcessingException {
109
110
111
112 UIComponent component = event.getComponent();
113 ActionSource source = (ActionSource) component;
114 boolean standard = source.isImmediate();
115 if (!standard) {
116 UIComponent parent = component.getParent();
117 while (parent != null) {
118 if (parent instanceof UIForm) {
119 if (!(parent instanceof FormComponent)) {
120 standard = true;
121 }
122 break;
123 }
124 parent = parent.getParent();
125 }
126 }
127 if (standard) {
128 if (log.isDebugEnabled()) {
129 log.debug("Performing standard handling for event " +
130 "from source component '" + component.getId() + "'");
131 }
132 original.processAction(event);
133 return;
134 }
135
136
137
138 FacesContext context = FacesContext.getCurrentInstance();
139 ServletContext servletContext = (ServletContext)
140 context.getExternalContext().getContext();
141 HttpServletRequest request = (HttpServletRequest)
142 context.getExternalContext().getRequest();
143 HttpServletResponse response = (HttpServletResponse)
144 context.getExternalContext().getResponse();
145
146
147 if (log.isDebugEnabled()) {
148 log.debug("Performing Struts form submit for event " +
149 " from source component '" +
150 component.getId() + "'");
151 }
152
153
154 try {
155 request.setAttribute(Constants.ACTION_EVENT_KEY, event);
156 ModuleUtils.getInstance().selectModule(request, servletContext);
157 ModuleConfig moduleConfig = (ModuleConfig)
158 request.getAttribute(Globals.MODULE_KEY);
159 if (log.isTraceEnabled()) {
160 log.trace("Assigned to module with prefix '" +
161 moduleConfig.getPrefix() + "'");
162 }
163 RequestProcessor processor =
164 getRequestProcessor(moduleConfig, servletContext);
165 if (log.isTraceEnabled()) {
166 log.trace("Invoking request processor instance " + processor);
167 }
168 processor.process(request, response);
169 context.responseComplete();
170 } catch (Exception e) {
171 log.error("Exception processing action event " + event, e);
172 } finally {
173 request.removeAttribute(Constants.ACTION_EVENT_KEY);
174 }
175
176 }
177
178
179
180
181
182 /***
183 * <p>Look up and return the <code>RequestProcessor</code> responsible for
184 * the specified module, creating a new one if necessary. This method is
185 * based on the corresponding code in <code>ActionServlet</code>, which
186 * cannot be used directly because it is a protected method.</p>
187 *
188 * @param config The module configuration for which to
189 * acquire and return a RequestProcessor
190 * @param context The <code>ServletContext</code> instance
191 * for this web application
192 *
193 * @exception IllegalStateException if we cannot instantiate a
194 * RequestProcessor instance
195 */
196 protected RequestProcessor getRequestProcessor(ModuleConfig config,
197 ServletContext context) {
198
199 String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
200 RequestProcessor processor =
201 (RequestProcessor) context.getAttribute(key);
202
203 if (processor == null) {
204 try {
205 if (log.isDebugEnabled()) {
206 log.debug("Instantiating RequestProcessor of class " +
207 config.getControllerConfig().getProcessorClass());
208 }
209 ActionServlet servlet = (ActionServlet)
210 context.getAttribute(Globals.ACTION_SERVLET_KEY);
211 processor =
212 (RequestProcessor) RequestUtils.applicationInstance(
213 config.getControllerConfig().getProcessorClass());
214 processor.init(servlet, config);
215 context.setAttribute(key, processor);
216 } catch (Exception e) {
217 log.error("Cannot instantiate RequestProcessor of class "
218 + config.getControllerConfig().getProcessorClass(),
219 e);
220 throw new IllegalStateException(
221 "Cannot initialize RequestProcessor of class "
222 + config.getControllerConfig().getProcessorClass()
223 + ": "
224 + e);
225 }
226
227 }
228 return (processor);
229
230 }
231
232
233 }