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.servlet;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.LinkedHashSet;
25  import java.util.List;
26  import java.util.Set;
27  
28  import javax.el.ELContext;
29  import javax.el.ELContextEvent;
30  import javax.el.ELContextListener;
31  import javax.faces.FactoryFinder;
32  import javax.faces.application.Application;
33  import javax.faces.application.ApplicationFactory;
34  import javax.faces.application.FacesMessage;
35  import javax.faces.component.UIViewRoot;
36  import javax.faces.context.ExternalContext;
37  import javax.faces.context.FacesContext;
38  import javax.faces.context.ResponseStream;
39  import javax.faces.context.ResponseWriter;
40  import javax.faces.render.RenderKit;
41  import javax.faces.render.RenderKitFactory;
42  import javax.portlet.PortletContext;
43  import javax.portlet.PortletRequest;
44  import javax.portlet.PortletResponse;
45  import javax.servlet.ServletContext;
46  import javax.servlet.ServletRequest;
47  import javax.servlet.ServletResponse;
48  
49  import org.apache.myfaces.context.ReleaseableExternalContext;
50  import org.apache.myfaces.context.ReleaseableFacesContextFactory;
51  import org.apache.myfaces.context.portlet.PortletExternalContextImpl;
52  import org.apache.myfaces.el.unified.FacesELContext;
53  import org.apache.myfaces.shared_impl.util.NullIterator;
54  
55  
56  /**
57   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
58   * @author Anton Koinov
59   * @version $Revision: 938287 $ $Date: 2010-04-26 20:34:31 -0500 (Mon, 26 Apr 2010) $
60   */
61  public class FacesContextImpl
62          extends FacesContext
63  {
64      //~ Instance fields ----------------------------------------------------------------------------
65  
66      private List                        _messageClientIds = null;
67      private List                        _messages         = null;
68      private Application                 _application;
69      private ReleaseableExternalContext  _externalContext;
70      private ResponseStream              _responseStream   = null;
71      private ResponseWriter              _responseWriter   = null;
72      private FacesMessage.Severity       _maximumSeverity  = null;
73      private UIViewRoot                  _viewRoot;
74      private boolean                     _renderResponse   = false;
75      private boolean                     _responseComplete = false;
76      private RenderKitFactory            _renderKitFactory;
77      private boolean                     _released = false;
78      private ELContext                   _elContext;
79      private ReleaseableFacesContextFactory _facesContextFactory = null;
80      
81      // Variables used to cache values
82      private RenderKit _cachedRenderKit = null;
83      private String _cachedRenderKitId = null;
84  
85      //~ Constructors -------------------------------------------------------------------------------
86  
87      @Deprecated
88      public FacesContextImpl(final PortletContext portletContext,
89              final PortletRequest portletRequest,
90              final PortletResponse portletResponse)
91      {
92          this(new PortletExternalContextImpl(portletContext,
93                                      portletRequest,
94                                      portletResponse));
95      }
96      
97      @Deprecated
98      public FacesContextImpl(final ServletContext servletContext,
99                  final ServletRequest servletRequest,
100                 final ServletResponse servletResponse)
101     {
102         this(new ServletExternalContextImpl(servletContext,
103                                     servletRequest,
104                                     servletResponse));
105     }    
106     
107     public FacesContextImpl(final ReleaseableExternalContext externalContext,
108                             final ReleaseableFacesContextFactory facesContextFactory)
109     {
110         this(externalContext);
111         _facesContextFactory = facesContextFactory;
112     }
113 
114     private FacesContextImpl(final ReleaseableExternalContext externalContext)
115     {
116         _externalContext = externalContext;
117         FacesContext.setCurrentInstance(this);  //protected method, therefore must be called from here
118         _application = ((ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
119                 .getApplication();
120         _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
121     }
122 
123     //~ Methods ------------------------------------------------------------------------------------
124 
125     public final ExternalContext getExternalContext()
126     {
127         if (_released) {
128             throw new IllegalStateException("FacesContext already released");
129         }
130         return (ExternalContext)_externalContext;
131     }
132 
133     public final FacesMessage.Severity getMaximumSeverity()
134     {
135         if (_released) {
136             throw new IllegalStateException("FacesContext already released");
137         }
138         return _maximumSeverity;
139     }
140 
141     public final Iterator getMessages()
142     {
143         if (_released) {
144             throw new IllegalStateException("FacesContext already released");
145         }
146         return (_messages != null) ? _messages.iterator() : Collections.EMPTY_LIST.iterator();
147     }
148 
149     public final Application getApplication()
150     {
151         if (_released) {
152             throw new IllegalStateException("FacesContext already released");
153         }
154 
155         return _application;
156     }
157 
158     public final Iterator getClientIdsWithMessages()
159     {
160         if (_released) {
161             throw new IllegalStateException("FacesContext already released");
162         }
163         if (_messages == null || _messages.isEmpty())
164         {
165             return NullIterator.instance();
166         }
167 
168         final Set uniqueClientIds = new LinkedHashSet(_messageClientIds);
169         return uniqueClientIds.iterator();
170     }
171 
172     public final Iterator getMessages(final String clientId)
173     {
174         if (_released) {
175             throw new IllegalStateException("FacesContext already released");
176         }
177         if (_messages == null)
178         {
179             return NullIterator.instance();
180         }
181 
182         List lst = new ArrayList();
183         for (int i = 0; i < _messages.size(); i++)
184         {
185             Object savedClientId = _messageClientIds.get(i);
186             if (clientId == null)
187             {
188                 if (savedClientId == null) lst.add(_messages.get(i));
189             }
190             else
191             {
192                 if (clientId.equals(savedClientId)) lst.add(_messages.get(i));
193             }
194         }
195         return lst.iterator();
196     }
197 
198     public final RenderKit getRenderKit()
199     {
200         if (getViewRoot() == null)
201         {
202             return null;
203         }
204 
205         String renderKitId = getViewRoot().getRenderKitId();
206 
207         if (renderKitId == null)
208         {
209             return null;
210         }
211         
212         if (_cachedRenderKitId == null || !renderKitId.equals(_cachedRenderKitId))
213         {
214             _cachedRenderKitId = renderKitId;
215             _cachedRenderKit = _renderKitFactory.getRenderKit(this, renderKitId);
216         }
217         
218         return _cachedRenderKit;
219     }
220 
221     public final boolean getRenderResponse()
222     {
223         if (_released) {
224             throw new IllegalStateException("FacesContext already released");
225         }
226         return _renderResponse;
227     }
228 
229     public final boolean getResponseComplete()
230     {
231         if (_released) {
232             throw new IllegalStateException("FacesContext already released");
233         }
234         return _responseComplete;
235     }
236 
237     public final void setResponseStream(final ResponseStream responseStream)
238     {
239         if (_released) {
240             throw new IllegalStateException("FacesContext already released");
241         }
242         if (responseStream == null)
243         {
244             throw new NullPointerException("responseStream");
245         }
246         _responseStream = responseStream;
247     }
248 
249     public final ResponseStream getResponseStream()
250     {
251         if (_released) {
252             throw new IllegalStateException("FacesContext already released");
253         }
254         return _responseStream;
255     }
256 
257     public final void setResponseWriter(final ResponseWriter responseWriter)
258     {
259         if (_released) {
260             throw new IllegalStateException("FacesContext already released");
261         }
262         if (responseWriter == null)
263         {
264             throw new NullPointerException("responseWriter");
265         }
266         _responseWriter = responseWriter;
267     }
268 
269     public final ResponseWriter getResponseWriter()
270     {
271         if (_released) {
272             throw new IllegalStateException("FacesContext already released");
273         }
274         return _responseWriter;
275     }
276 
277     public final void setViewRoot(final UIViewRoot viewRoot)
278     {
279         if (_released) {
280             throw new IllegalStateException("FacesContext already released");
281         }
282         if (viewRoot == null)
283         {
284             throw new NullPointerException("viewRoot");
285         }
286         _viewRoot = viewRoot;
287     }
288 
289     public final UIViewRoot getViewRoot()
290     {
291         if (_released) {
292             throw new IllegalStateException("FacesContext already released");
293         }
294         return _viewRoot;
295     }
296 
297     public final void addMessage(final String clientId, final FacesMessage message)
298     {
299         if (_released) {
300             throw new IllegalStateException("FacesContext already released");
301         }
302         if (message == null)
303         {
304             throw new NullPointerException("message");
305         }
306 
307         if (_messages == null)
308         {
309             _messages             = new ArrayList();
310             _messageClientIds     = new ArrayList();
311         }
312         _messages.add(message);
313         _messageClientIds.add((clientId != null) ? clientId : null);
314         FacesMessage.Severity serSeverity =  message.getSeverity();
315         if (serSeverity != null) {
316             if (_maximumSeverity == null)
317             {
318                 _maximumSeverity = serSeverity;
319             }
320             else if (serSeverity.compareTo(_maximumSeverity) > 0)
321             {
322                 _maximumSeverity = serSeverity;
323             }
324         }
325     }
326 
327     public final void release()
328     {
329         if (_released) {
330             throw new IllegalStateException("FacesContext already released");
331         }
332         if (_facesContextFactory != null)
333         {
334             _facesContextFactory.release();
335             _facesContextFactory = null;
336         }
337         if (_externalContext != null)
338         {
339             _externalContext.release();
340             _externalContext = null;
341         }
342 
343         _messageClientIds     = null;
344         _messages             = null;
345         _application          = null;
346         _responseStream       = null;
347         _responseWriter       = null;
348         _viewRoot             = null;
349         _cachedRenderKit = null;
350         _cachedRenderKitId = null;
351 
352         _released             = true;
353         FacesContext.setCurrentInstance(null);
354     }
355 
356     public final void renderResponse()
357     {
358         if (_released) {
359             throw new IllegalStateException("FacesContext already released");
360         }
361         _renderResponse = true;
362     }
363 
364     public final void responseComplete()
365     {
366         if (_released) {
367             throw new IllegalStateException("FacesContext already released");
368         }
369         _responseComplete = true;
370     }
371 
372     // Portlet need to do this to change from ActionRequest/Response to
373     // RenderRequest/Response
374     public final void setExternalContext(ReleaseableExternalContext extContext)
375     {
376         _externalContext = extContext;
377         FacesContext.setCurrentInstance(this); //TODO: figure out if I really need to do this
378     }
379 
380     public final ELContext getELContext() {
381         if (_elContext != null) return _elContext;
382         
383         
384         _elContext = new FacesELContext(getApplication().getELResolver(), this);
385         
386         ELContextEvent event = new ELContextEvent(_elContext);
387         for (ELContextListener listener : getApplication().getELContextListeners()) {
388             listener.contextCreated(event);
389         }
390         
391         return _elContext;
392     }
393     
394 }