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