View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.webapp.filter;
20  
21  import javax.faces.FacesException;
22  import javax.faces.context.ExternalContext;
23  import javax.faces.context.FacesContext;
24  import javax.faces.event.PhaseEvent;
25  import javax.faces.event.PhaseId;
26  import javax.faces.event.PhaseListener;
27  import javax.servlet.ServletContext;
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.myfaces.renderkit.html.util.AddResource;
34  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
35  import org.apache.myfaces.tomahawk.util.ExternalContextUtils;
36  
37  /**
38   * This listener is used for serve resources, as a replacement of 
39   * ExtensionsFilter serve resources feature.
40   * <p>
41   * The idea is map FacesServlet to org.apache.myfaces.RESOURCE_VIRTUAL_PATH
42   * (Default is "/faces/myFacesExtensionResource), so this
43   * listener can receive the request.
44   * </p>
45   * 
46   * @author Martin Marinschek (latest modification by $Author: lu4242 $)
47   * @version $Revision: 685725 $ $Date: 2008-08-13 18:14:31 -0500 (miƩ, 13 ago 2008) $
48   */
49  public class ServeResourcePhaseListener implements PhaseListener {
50  
51      /**
52       * 
53       */
54      private static final long serialVersionUID = -1044924474445136434L;
55  
56      private Log log = LogFactory.getLog(ServeResourcePhaseListener.class);
57  
58      public static final String DOLISTENER_CALLED = "org.apache.myfaces.component.html.util.ExtensionFilter.doListenerCalled";
59  
60      public void afterPhase(PhaseEvent event) {
61      }
62  
63      public void beforePhase(PhaseEvent event) {
64          if(event.getPhaseId()==PhaseId.RESTORE_VIEW || event.getPhaseId()==PhaseId.RENDER_RESPONSE) {
65  
66              FacesContext fc = event.getFacesContext();
67              ExternalContext externalContext = event.getFacesContext().getExternalContext();
68  
69              if(externalContext.getRequestMap().containsKey(ExtensionsFilter.DOFILTER_CALLED) ||
70                 externalContext.getRequestMap().containsKey(DOLISTENER_CALLED))
71              {
72                  //we have already been called (before-restore-view, and we are now in render-response),
73                  // no need to do everything again...
74                  return;
75              }
76  
77              externalContext.getRequestMap().put(DOLISTENER_CALLED,"true");
78  
79              //Use ExternalContextUtils to find if this is a portled request
80              //if(externalContext.getRequest() instanceof PortletRequest) {            
81              if(ExternalContextUtils.getRequestType(externalContext).isPortlet()) {
82                  //we are in portlet-world! in portlet 1.0 (JSR-168), we cannot do anything here, but
83                  //TODO in portlet 2.0 (JSR-286), we will write the resource to the stream here if we
84                  //get a resource-request (resource-requests are only available in 286)
85                  if(log.isDebugEnabled()) {
86                      log.debug("We are in portlet-space, but we cannot do anything here in JSR-168 - " +
87                              "for resource-serving, our resource-servlet has to be registered.");
88                  }
89              }
90              else if(externalContext.getResponse() instanceof HttpServletResponse) {
91  
92                  HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
93                  HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
94                  ServletContext context = (ServletContext) fc.getExternalContext().getContext();
95  
96                  // Serve resources
97                  AddResource addResource;
98  
99                  try
100                 {
101                     addResource= AddResourceFactory.getInstance(request, context);
102                     if( addResource.isResourceUri(context, request ) ){
103                         addResource.serveResource(context, request, response);
104                         event.getFacesContext().responseComplete();
105                         return;
106                     }
107                 }
108                 catch(Throwable th)
109                 {
110                     log.error("Exception wile retrieving addResource",th);
111                     throw new FacesException(th);
112                 }
113             }
114             else {
115                 if(log.isDebugEnabled()) {
116                     log.debug("Response of type : "+(
117                             externalContext.getResponse()==null?"null":externalContext.getResponse().getClass().getName())+" not handled so far.");
118                 }
119             }
120         }
121     }
122 
123     public PhaseId getPhaseId() {
124         return PhaseId.ANY_PHASE;
125     }
126 }