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 String requestType = (String)portletRequest.getAttribute(FacesPortlet.REQUEST_TYPE);
136 if (requestType != null && requestType.equals(FacesPortlet.ACTION_REQUEST))
137 {
138 if (log.isDebugEnabled())
139 {
140 log.debug("Resolving action: " + viewId);
141 }
142 setViewRoot(viewRoot);
143 portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
144 return null;
145 }
146
147 UIViewRoot viewRoot = (UIViewRoot) request.getPortletSession().getAttribute(viewId,
148 PortletSession.PORTLET_SCOPE);
149 if (null == viewRoot)
150 {
151 if (log.isDebugEnabled())
152 {
153 log.debug("Creating new view root: " + viewId);
154 }
155 viewRoot = application.getViewHandler().createView(this, viewId);
156
157 UIViewRoot newViewRoot = new PortletUIViewRoot(viewRoot);
158 viewRoot = newViewRoot;
159 viewRoot.setViewId(viewId);
160 viewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
161 request.getPortletSession().setAttribute(viewId, viewRoot, PortletSession.PORTLET_SCOPE);
162 }
163 else
164 {
165 if (log.isDebugEnabled())
166 {
167 log.debug("Using view root from session: " + viewId);
168 }
169 }
170 setViewRoot(viewRoot);
171 portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
172 return viewRoot;
173 }
174
175 /***
176 * @see javax.faces.context.FacesContext#getExternalContext()
177 */
178 public ExternalContext getExternalContext()
179 {
180 return this.externalContext;
181 }
182
183 /***
184 * @see javax.faces.context.FacesContext#getMaximumSeverity()
185 */
186 public FacesMessage.Severity getMaximumSeverity()
187 {
188 return this.maximumSeverity;
189 }
190
191 /***
192 * @see javax.faces.context.FacesContext#getMessages()
193 */
194 public Iterator getMessages()
195 {
196 return (this.messages != null) ? this.messages.iterator() : Collections.EMPTY_LIST.iterator();
197 }
198
199 /***
200 * @see javax.faces.context.FacesContext#getApplication()
201 */
202 public Application getApplication()
203 {
204 return this.application;
205 }
206
207 /***
208 * @see javax.faces.context.FacesContext#getClientIdsWithMessages()
209 */
210 public Iterator getClientIdsWithMessages()
211 {
212 if (this.messages == null || this.messages.isEmpty())
213 {
214 return NullIterator.instance();
215 }
216
217 return new Iterator()
218 {
219 private int next;
220
221 boolean nextFound;
222
223 public void remove()
224 {
225 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
226 }
227
228 public boolean hasNext()
229 {
230 if (!nextFound)
231 {
232 for (int len = messageClientIds.size(); next < len; next++)
233 {
234 if (messageClientIds.get(next) != NULL_DUMMY)
235 {
236 nextFound = true;
237 break;
238 }
239 }
240 }
241 return nextFound;
242 }
243
244 public Object next()
245 {
246 if (hasNext())
247 {
248 nextFound = false;
249 return messageClientIds.get(next++);
250 }
251 throw new NoSuchElementException();
252 }
253 };
254 }
255
256 /***
257 * @see javax.faces.context.FacesContext#getMessages(java.lang.String)
258 */
259 public Iterator getMessages(String clientId)
260 {
261 if (this.messages == null)
262 {
263 return NullIterator.instance();
264 }
265
266 List lst = new ArrayList();
267 for (int i = 0; i < this.messages.size(); i++)
268 {
269 Object savedClientId = this.messageClientIds.get(i);
270 if (clientId == null)
271 {
272 if (savedClientId == NULL_DUMMY)
273 lst.add(this.messages.get(i));
274 }
275 else
276 {
277 if (clientId.equals(savedClientId))
278 lst.add(this.messages.get(i));
279 }
280 }
281 return lst.iterator();
282 }
283
284 /***
285 * @see javax.faces.context.FacesContext#getRenderKit()
286 */
287 public RenderKit getRenderKit()
288 {
289 if (getViewRoot() == null)
290 {
291 return null;
292 }
293
294 String renderKitId = getViewRoot().getRenderKitId();
295
296 if (renderKitId == null)
297 {
298 return null;
299 }
300
301 return this.renderKitFactory.getRenderKit(this, renderKitId);
302 }
303
304 /***
305 * @see javax.faces.context.FacesContext#getRenderResponse()
306 */
307 public boolean getRenderResponse()
308 {
309 return this.renderResponse;
310 }
311
312 /***
313 * @see javax.faces.context.FacesContext#getResponseComplete()
314 */
315 public boolean getResponseComplete()
316 {
317 return this.responseComplete;
318 }
319
320 /***
321 * @see javax.faces.context.FacesContext#setResponseStream(javax.faces.context.ResponseStream)
322 */
323 public void setResponseStream(ResponseStream responseStream)
324 {
325 if (responseStream == null)
326 {
327 throw new NullPointerException("responseStream");
328 }
329 this.responseStream = responseStream;
330 }
331
332 /***
333 * @see javax.faces.context.FacesContext#getResponseStream()
334 */
335 public ResponseStream getResponseStream()
336 {
337 return this.responseStream;
338 }
339
340 /***
341 * @see javax.faces.context.FacesContext#setResponseWriter(javax.faces.context.ResponseWriter)
342 */
343 public void setResponseWriter(ResponseWriter responseWriter)
344 {
345 if (responseWriter == null)
346 {
347 throw new NullPointerException("responseWriter");
348 }
349 this.responseWriter = responseWriter;
350 }
351
352 /***
353 * @see javax.faces.context.FacesContext#getResponseWriter()
354 */
355 public ResponseWriter getResponseWriter()
356 {
357 return this.responseWriter;
358 }
359
360 /***
361 * @see javax.faces.context.FacesContext#setViewRoot(javax.faces.component.UIViewRoot)
362 */
363 public void setViewRoot(UIViewRoot viewRoot)
364 {
365 if (viewRoot == null)
366 {
367 throw new NullPointerException("viewRoot");
368 }
369 this.viewRoot = viewRoot;
370 }
371
372 /***
373 * @see javax.faces.context.FacesContext#getViewRoot()
374 */
375 public UIViewRoot getViewRoot()
376 {
377 return this.viewRoot;
378 }
379
380 /***
381 * @see javax.faces.context.FacesContext#addMessage(java.lang.String,
382 * javax.faces.application.FacesMessage)
383 */
384 public void addMessage(String clientId, FacesMessage message)
385 {
386 if (message == null)
387 {
388 throw new NullPointerException("message");
389 }
390
391 if (this.messages == null)
392 {
393 this.messages = new ArrayList();
394 this.messageClientIds = new ArrayList();
395 }
396 this.messages.add(message);
397 this.messageClientIds.add((clientId != null) ? clientId : NULL_DUMMY);
398 FacesMessage.Severity serSeverity = message.getSeverity();
399 if (serSeverity != null && serSeverity.compareTo(this.maximumSeverity) > 0)
400 {
401 this.maximumSeverity = message.getSeverity();
402 }
403 }
404
405 /***
406 * @see javax.faces.context.FacesContext#release()
407 */
408 public void release()
409 {
410 if (this.externalContext != null)
411 {
412 this.externalContext.release();
413 this.externalContext = null;
414 }
415
416 this.messageClientIds = null;
417 this.messages = null;
418 this.application = null;
419 this.responseStream = null;
420 this.responseWriter = null;
421 this.viewRoot = null;
422
423 FacesContext.setCurrentInstance(null);
424 }
425
426 /***
427 * @see javax.faces.context.FacesContext#renderResponse()
428 */
429 public void renderResponse()
430 {
431 this.renderResponse = true;
432 }
433
434 /***
435 * @see javax.faces.context.FacesContext#responseComplete()
436 */
437 public void responseComplete()
438 {
439 this.responseComplete = true;
440 }
441 }