View Javadoc

1   /*
2    * Copyright 2002,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  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      // ------------------------------------------------------------ Constructors
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      // ------------------------------------------------------ Instance Variables
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      // ---------------------------------------------------------- Public Methods
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         // If this is an immediate action, or we are NOT nested in a
111         // Struts form, perform the standard processing
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         // Acquire Servlet API Object References
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         // Log this event if requested
147         if (log.isDebugEnabled()) {
148             log.debug("Performing Struts form submit for event " +
149                       " from source component '" +
150                       component.getId() + "'");
151         }
152 
153         // Invoke the appropriate request processor for this request
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     // ------------------------------------------------------ Protected Methods
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 }