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