1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.portals.bridges.jsf;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.NoSuchElementException;
23
24 import javax.faces.FactoryFinder;
25 import javax.faces.application.Application;
26 import javax.faces.application.ApplicationFactory;
27 import javax.faces.application.FacesMessage;
28 import javax.faces.component.UIViewRoot;
29 import javax.faces.context.ExternalContext;
30 import javax.faces.context.FacesContext;
31 import javax.faces.context.ResponseStream;
32 import javax.faces.context.ResponseWriter;
33 import javax.faces.render.RenderKit;
34 import javax.faces.render.RenderKitFactory;
35
36 import javax.portlet.ActionRequest;
37 import javax.portlet.PortletContext;
38 import javax.portlet.PortletRequest;
39 import javax.portlet.PortletResponse;
40 import javax.portlet.PortletSession;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45 /***
46 * <p>
47 * See MyFaces project for servlet implementation.
48 * </p>
49 * <p>
50 * TODO There should be a base class shared with the MyFaces
51 * ServletFacesContextImpl.
52 * </p>
53 *
54 * @author <a href="dlestrat@apache.org">David Le Strat </a>
55 *
56 */
57 public class PortletFacesContextImpl extends FacesContext
58 {
59 /*** The logger. */
60 private static final Log log = LogFactory.getLog(PortletFacesContextImpl.class);
61
62 protected static final Object NULL_DUMMY = new Object();
63
64 /*** The message client ids. */
65 private List messageClientIds = null;
66
67 /*** The mesages. */
68 private List messages = null;
69
70 /*** The application. */
71 private Application application;
72
73 /*** The portlet external context. */
74 private PortletExternalContextImpl externalContext;
75
76 /*** The response stream. */
77 private ResponseStream responseStream = null;
78
79 /*** The response writer. */
80 private ResponseWriter responseWriter = null;
81
82 /*** The severity. */
83 private FacesMessage.Severity maximumSeverity = FacesMessage.SEVERITY_INFO;
84
85 /*** The view root. */
86 private UIViewRoot viewRoot;
87
88 /*** The render response. */
89 private boolean renderResponse = false;
90
91 /*** Whether the response is complete. */
92 private boolean responseComplete = false;
93
94 /*** The render kit factory. */
95 private RenderKitFactory renderKitFactory;
96
97 /*** The JSF_VIEW_ID used to maintain the state of the view action. */
98 public static final String JSF_VIEW_ID = "jsf_viewid";
99
100 /***
101 * @param portletContext The {@link PortletContext}.
102 * @param portletRequest The {@link PortletRequest}.
103 * @param portletResponse The {@link PortletResponse}.
104 */
105 public PortletFacesContextImpl(PortletContext portletContext, PortletRequest portletRequest,
106 PortletResponse portletResponse)
107 {
108 this.application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
109 .getApplication();
110 this.renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
111 this.externalContext = new PortletExternalContextImpl(portletContext, portletRequest, portletResponse);
112 FacesContext.setCurrentInstance(this);
113
114 }
115
116 public UIViewRoot resolveViewRoot(String defaultViewName, PortletRequest portletRequest)
117 {
118
119 PortletRequest request = (PortletRequest) externalContext.getRequest();
120 String viewId = request.getParameter(JSF_VIEW_ID);
121
122 if (viewId == null)
123 {
124 viewId = defaultViewName;
125 if (log.isDebugEnabled())
126 {
127 log.debug("Request view id is null. Using default view.");
128 }
129 }
130 if (log.isDebugEnabled())
131 {
132 log.debug("Resolving view root - Using view id: " + viewId);
133 }
134
135 if (portletRequest instanceof ActionRequest)
136 {
137 if (log.isDebugEnabled())
138 {
139 log.debug("Resolving action: " + viewId);
140 }
141 setViewRoot(viewRoot);
142 portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
143 return null;
144 }
145
146 UIViewRoot viewRoot = (UIViewRoot) request.getPortletSession().getAttribute(viewId,
147 PortletSession.PORTLET_SCOPE);
148 if (null == viewRoot)
149 {
150 if (log.isDebugEnabled())
151 {
152 log.debug("Creating new view root: " + viewId);
153 }
154 viewRoot = application.getViewHandler().createView(this, viewId);
155
156 viewRoot.setViewId(viewId);
157 viewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
158 request.getPortletSession().setAttribute(viewId, viewRoot, PortletSession.PORTLET_SCOPE);
159 }
160 else
161 {
162 if (log.isDebugEnabled())
163 {
164 log.debug("Using view root from session: " + viewId);
165 }
166 }
167 setViewRoot(viewRoot);
168 portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
169 return viewRoot;
170 }
171
172 /***
173 * @see javax.faces.context.FacesContext#getExternalContext()
174 */
175 public ExternalContext getExternalContext()
176 {
177 return this.externalContext;
178 }
179
180 /***
181 * @see javax.faces.context.FacesContext#getMaximumSeverity()
182 */
183 public FacesMessage.Severity getMaximumSeverity()
184 {
185 return this.maximumSeverity;
186 }
187
188 /***
189 * @see javax.faces.context.FacesContext#getMessages()
190 */
191 public Iterator getMessages()
192 {
193 return (this.messages != null) ? this.messages.iterator() : Collections.EMPTY_LIST.iterator();
194 }
195
196 /***
197 * @see javax.faces.context.FacesContext#getApplication()
198 */
199 public Application getApplication()
200 {
201 return this.application;
202 }
203
204 /***
205 * @see javax.faces.context.FacesContext#getClientIdsWithMessages()
206 */
207 public Iterator getClientIdsWithMessages()
208 {
209 if (this.messages == null || this.messages.isEmpty())
210 {
211 return NullIterator.instance();
212 }
213
214 return new Iterator()
215 {
216 private int next;
217
218 boolean nextFound;
219
220 public void remove()
221 {
222 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
223 }
224
225 public boolean hasNext()
226 {
227 if (!nextFound)
228 {
229 for (int len = messageClientIds.size(); next < len; next++)
230 {
231 if (messageClientIds.get(next) != NULL_DUMMY)
232 {
233 nextFound = true;
234 break;
235 }
236 }
237 }
238 return nextFound;
239 }
240
241 public Object next()
242 {
243 if (hasNext())
244 {
245 nextFound = false;
246 return messageClientIds.get(next++);
247 }
248 throw new NoSuchElementException();
249 }
250 };
251 }
252
253 /***
254 * @see javax.faces.context.FacesContext#getMessages(java.lang.String)
255 */
256 public Iterator getMessages(String clientId)
257 {
258 if (this.messages == null)
259 {
260 return NullIterator.instance();
261 }
262
263 List lst = new ArrayList();
264 for (int i = 0; i < this.messages.size(); i++)
265 {
266 Object savedClientId = this.messageClientIds.get(i);
267 if (clientId == null)
268 {
269 if (savedClientId == NULL_DUMMY)
270 lst.add(this.messages.get(i));
271 }
272 else
273 {
274 if (clientId.equals(savedClientId))
275 lst.add(this.messages.get(i));
276 }
277 }
278 return lst.iterator();
279 }
280
281 /***
282 * @see javax.faces.context.FacesContext#getRenderKit()
283 */
284 public RenderKit getRenderKit()
285 {
286 if (getViewRoot() == null)
287 {
288 return null;
289 }
290
291 String renderKitId = getViewRoot().getRenderKitId();
292
293 if (renderKitId == null)
294 {
295 return null;
296 }
297
298 return this.renderKitFactory.getRenderKit(this, renderKitId);
299 }
300
301 /***
302 * @see javax.faces.context.FacesContext#getRenderResponse()
303 */
304 public boolean getRenderResponse()
305 {
306 return this.renderResponse;
307 }
308
309 /***
310 * @see javax.faces.context.FacesContext#getResponseComplete()
311 */
312 public boolean getResponseComplete()
313 {
314 return this.responseComplete;
315 }
316
317 /***
318 * @see javax.faces.context.FacesContext#setResponseStream(javax.faces.context.ResponseStream)
319 */
320 public void setResponseStream(ResponseStream responseStream)
321 {
322 if (responseStream == null)
323 {
324 throw new NullPointerException("responseStream");
325 }
326 this.responseStream = responseStream;
327 }
328
329 /***
330 * @see javax.faces.context.FacesContext#getResponseStream()
331 */
332 public ResponseStream getResponseStream()
333 {
334 return this.responseStream;
335 }
336
337 /***
338 * @see javax.faces.context.FacesContext#setResponseWriter(javax.faces.context.ResponseWriter)
339 */
340 public void setResponseWriter(ResponseWriter responseWriter)
341 {
342 if (responseWriter == null)
343 {
344 throw new NullPointerException("responseWriter");
345 }
346 this.responseWriter = responseWriter;
347 }
348
349 /***
350 * @see javax.faces.context.FacesContext#getResponseWriter()
351 */
352 public ResponseWriter getResponseWriter()
353 {
354 return this.responseWriter;
355 }
356
357 /***
358 * @see javax.faces.context.FacesContext#setViewRoot(javax.faces.component.UIViewRoot)
359 */
360 public void setViewRoot(UIViewRoot viewRoot)
361 {
362 if (viewRoot == null)
363 {
364 throw new NullPointerException("viewRoot");
365 }
366 this.viewRoot = viewRoot;
367 }
368
369 /***
370 * @see javax.faces.context.FacesContext#getViewRoot()
371 */
372 public UIViewRoot getViewRoot()
373 {
374 return this.viewRoot;
375 }
376
377 /***
378 * @see javax.faces.context.FacesContext#addMessage(java.lang.String,
379 * javax.faces.application.FacesMessage)
380 */
381 public void addMessage(String clientId, FacesMessage message)
382 {
383 if (message == null)
384 {
385 throw new NullPointerException("message");
386 }
387
388 if (this.messages == null)
389 {
390 this.messages = new ArrayList();
391 this.messageClientIds = new ArrayList();
392 }
393 this.messages.add(message);
394 this.messageClientIds.add((clientId != null) ? clientId : NULL_DUMMY);
395 FacesMessage.Severity serSeverity = message.getSeverity();
396 if (serSeverity != null && serSeverity.compareTo(this.maximumSeverity) > 0)
397 {
398 this.maximumSeverity = message.getSeverity();
399 }
400 }
401
402 /***
403 * @see javax.faces.context.FacesContext#release()
404 */
405 public void release()
406 {
407 if (this.externalContext != null)
408 {
409 this.externalContext.release();
410 this.externalContext = null;
411 }
412
413 this.messageClientIds = null;
414 this.messages = null;
415 this.application = null;
416 this.responseStream = null;
417 this.responseWriter = null;
418 this.viewRoot = null;
419
420 FacesContext.setCurrentInstance(null);
421 }
422
423 /***
424 * @see javax.faces.context.FacesContext#renderResponse()
425 */
426 public void renderResponse()
427 {
428 this.renderResponse = true;
429 }
430
431 /***
432 * @see javax.faces.context.FacesContext#responseComplete()
433 */
434 public void responseComplete()
435 {
436 this.responseComplete = true;
437 }
438 }