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.orchestra.requestParameterProvider.jsf;
20  
21  import org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterResponseWrapper;
22  import org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterServletFilter;
23  
24  import javax.faces.FacesException;
25  import javax.faces.context.FacesContext;
26  import javax.faces.context.FacesContextFactory;
27  import javax.faces.lifecycle.Lifecycle;
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  
31  /***
32   * Ensure that a custom wrapper is put aroung the HttpServletResponse so that encodeURL can be 
33   * intercepted and modified.
34   * <p>
35   * There is a servlet filter (RequestParameterServletFilter) that does this in the obvious way, but
36   * it is a nuisance to have to set up filters in the web.xml. This class implements a sneaky hack
37   * to get this to happen automatically for JSF applications, ie no servlet filter is needed when
38   * this is specified in the faces-config.xml file as the FacesContextFactory.
39   * <p>
40   * If you have to deal with a mixed environment e.g. JSP/JSF it would be better to use the
41   * {@link org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterServletFilter}.
42   */
43  public class RequestParameterFacesContextFactory extends FacesContextFactory
44  {
45  	private final FacesContextFactory original;
46  
47  	public RequestParameterFacesContextFactory(FacesContextFactory original)
48  	{
49  		this.original = original;
50  	}
51  
52  	public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle) throws FacesException
53  	{
54  		if (response instanceof HttpServletResponse)
55  		{
56  			HttpServletRequest httpServletRequest = (HttpServletRequest) request;
57  			
58  			// Wrap this request only if something else (eg a RequestParameterServletFilter) has not already wrapped it.
59  			if (!Boolean.TRUE.equals(httpServletRequest.getAttribute(RequestParameterServletFilter.REQUEST_PARAM_FILTER_CALLED)))
60  			{
61  				// No servlet filter has wrapped the response, so do it now for the response referenced by this FacesContext.
62  				// Note that this wrapper will therefore apply to all output generated via the FacesContext, but not to
63  				// anything that might be written by filters etc.
64                  response = new RequestParameterResponseWrapper((HttpServletResponse) response);
65  
66                  // We now need to reassure the RequestParameterProviderManager that the response has indeed been
67                  // wrapped; it checks and reports an error if not as it is easy to stuff up this configuration.
68                  //
69                  // However we can not just set the REQUEST_PARAMETER_FILTER_CALLED flag here. If code creates its own
70                  // FacesContext instance for any reason while a request is running, then this method is called again.
71  				// On the second call this flag would already be set and the response would not be wrapped as required.
72  				//
73  				// Therefore we have two separate flags; RequestParameterProviderManager checks whether either
74                  // REQUEST_PARAM_FILTER_CALLED or REQUEST_PARAM_RESPONSE_WRAPPED has been set.
75  
76                  httpServletRequest.setAttribute(RequestParameterServletFilter.REQUEST_PARAM_RESPONSE_WRAPPED, Boolean.TRUE);
77  
78  			}
79  		}
80  
81  		return original.getFacesContext(context, request, response, lifecycle);
82  	}
83  }