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