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.context;
20  
21  import java.lang.reflect.Field;
22  import java.util.logging.Level;
23  import java.util.logging.Logger;
24  
25  import javax.faces.FacesException;
26  import javax.faces.FactoryFinder;
27  import javax.faces.application.ApplicationFactory;
28  import javax.faces.context.ExceptionHandlerFactory;
29  import javax.faces.context.ExternalContext;
30  import javax.faces.context.ExternalContextFactory;
31  import javax.faces.context.FacesContext;
32  import javax.faces.context.FacesContextFactory;
33  import javax.faces.context.PartialViewContextFactory;
34  import javax.faces.lifecycle.Lifecycle;
35  import javax.faces.render.RenderKitFactory;
36  import javax.servlet.ServletContext;
37  
38  import org.apache.myfaces.context.servlet.FacesContextImpl;
39  import org.apache.myfaces.shared.util.ClassUtils;
40  
41  /**
42   * DOCUMENT ME!
43   * 
44   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
45   * @version $Revision: 1296667 $ $Date: 2012-03-03 11:54:07 -0500 (Sat, 03 Mar 2012) $
46   */
47  public class FacesContextFactoryImpl extends FacesContextFactory
48      implements ReleaseableFacesContextFactory
49  {
50      //private static final Log log = LogFactory.getLog(FacesContextFactoryImpl.class);
51      private static final Logger log = Logger.getLogger(FacesContextFactoryImpl.class.getName());
52      
53      /**
54       * Reference to factory to prevent unnecessary lookups
55       */
56      private final ExternalContextFactory _externalContextFactory;
57      
58      /**
59       * Reference to factory to prevent unnecessary lookups
60       */
61      private final ExceptionHandlerFactory _exceptionHandlerFactory;
62      
63      private final ApplicationFactory _applicationFactory;
64      
65      private final RenderKitFactory _renderKitFactory;
66      
67      private final PartialViewContextFactory _partialViewContextFactory;
68      
69      /**
70       * This var is assigned as the same as javax.faces.context.ExternalContext._firstInstance,
71       * and since it is a static reference and does not change, we can cache it here safely.
72       * 
73       * We need
74       */
75      private final ThreadLocal<ExternalContext> _firstExternalContextInstance;
76      
77      @SuppressWarnings("unchecked")
78      public FacesContextFactoryImpl()
79      {
80          super();
81          ThreadLocal<ExternalContext> firstExternalContextInstance = null;
82          try
83          {
84              Class clazz = ClassUtils.classForName("javax.faces.context._MyFacesExternalContextHelper");
85              Field externalContextFirstInstance = clazz.getDeclaredField("_firstInstance");
86              externalContextFirstInstance.setAccessible(true);
87              
88              if (externalContextFirstInstance != null)
89              {
90                  if (firstExternalContextInstance == null)
91                  {
92                      firstExternalContextInstance = 
93                          (ThreadLocal<ExternalContext>) externalContextFirstInstance.get(null);
94                  }
95              }
96          }
97          catch (SecurityException e)
98          {
99              // It could happen, but we can ignore it.
100             if (log.isLoggable(Level.FINE))
101             {
102                 log.log(Level.FINE, "Cannot access field _firstInstance"
103                         + "from _MyFacesExternalContextHelper ", e);
104             }
105         }
106         catch (Exception e)
107         {
108             if (log.isLoggable(Level.SEVERE))
109             {
110                 log.log(Level.SEVERE, "Cannot find field _firstInstance"
111                         + "from _MyFacesExternalContextHelper ", e);
112             }
113         }
114         
115         _firstExternalContextInstance = firstExternalContextInstance;
116         
117         _externalContextFactory = (ExternalContextFactory)
118             FactoryFinder.getFactory(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
119 
120         _exceptionHandlerFactory = (ExceptionHandlerFactory)
121             FactoryFinder.getFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
122         
123         _applicationFactory = (ApplicationFactory)
124             FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
125         
126         _renderKitFactory = (RenderKitFactory)
127             FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
128 
129         _partialViewContextFactory = (PartialViewContextFactory) 
130             FactoryFinder.getFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
131     }
132 
133     @Override
134     public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
135         throws FacesException
136     {
137         if (context == null)
138         {
139             throw new NullPointerException("context");
140         }
141         if (request == null)
142         {
143             throw new NullPointerException("request");
144         }
145         if (response == null)
146         {
147             throw new NullPointerException("response");
148         }
149         if (lifecycle == null)
150         {
151             throw new NullPointerException("lifecycle");
152         }
153         
154         ExternalContext externalContext = _externalContextFactory.getExternalContext(context, request, response);
155 
156         ExternalContext defaultExternalContext = null;
157         
158         if (_firstExternalContextInstance != null)
159         {
160             defaultExternalContext = (ExternalContext)
161                 externalContext.getRequestMap().remove(
162                         ExternalContextFactoryImpl.EXTERNAL_CONTEXT_KEY);
163             
164             if (defaultExternalContext != null)
165             {
166                 // Initialize the firstExternalContext that old jsf 1.2 or lower
167                 // implementations of ExternalContext should fall when call jsf 2.0
168                 // methods.
169                 _firstExternalContextInstance.set(defaultExternalContext);
170             }
171         }
172         
173         //if (context instanceof ServletContext)
174         //{
175             FacesContext facesContext;
176             if (externalContext instanceof ReleaseableExternalContext)
177             {
178                 facesContext = new FacesContextImpl(externalContext, (ReleaseableExternalContext) externalContext,
179                                                     this, _applicationFactory, _renderKitFactory, 
180                                                     _partialViewContextFactory);
181             }
182             else if (defaultExternalContext != null && defaultExternalContext instanceof ReleaseableExternalContext)
183             {
184                 facesContext = new FacesContextImpl(externalContext,
185                                                     (ReleaseableExternalContext) defaultExternalContext, this,
186                                                     _applicationFactory, _renderKitFactory, 
187                                                     _partialViewContextFactory);
188             }
189             else
190             {
191                 facesContext = new FacesContextImpl(externalContext, null, this,
192                                                     _applicationFactory, _renderKitFactory, 
193                                                     _partialViewContextFactory);
194             }
195             
196             facesContext.setExceptionHandler(_exceptionHandlerFactory.getExceptionHandler());
197             
198             return facesContext;
199             //return new FacesContextImpl((ServletContext)context, (ServletRequest)request, (ServletResponse)response);
200         //}
201 
202         //throw new FacesException("Unsupported context type " + context.getClass().getName());
203     }
204 
205     public void release()
206     {
207         if (_firstExternalContextInstance != null)
208         {
209             _firstExternalContextInstance.remove();
210         }
211     }
212 }