1 16 package org.apache.myfaces.portlet; 17 18 import java.io.IOException ; 19 20 import javax.faces.FactoryFinder; 21 import javax.faces.application.Application; 22 import javax.faces.application.ApplicationFactory; 23 import javax.faces.application.ViewHandler; 24 import javax.faces.component.UIViewRoot; 25 import javax.faces.context.ExternalContext; 26 import javax.faces.context.FacesContext; 27 import javax.faces.context.FacesContextFactory; 28 import javax.faces.lifecycle.Lifecycle; 29 import javax.faces.lifecycle.LifecycleFactory; 30 import javax.faces.webapp.FacesServlet; 31 import javax.portlet.ActionRequest; 32 import javax.portlet.ActionResponse; 33 import javax.portlet.GenericPortlet; 34 import javax.portlet.PortletContext; 35 import javax.portlet.PortletException; 36 import javax.portlet.PortletRequest; 37 import javax.portlet.PortletResponse; 38 import javax.portlet.RenderRequest; 39 import javax.portlet.RenderResponse; 40 import javax.portlet.UnavailableException; 41 42 import org.apache.commons.logging.Log; 43 import org.apache.commons.logging.LogFactory; 44 import org.apache.myfaces.config.FacesConfigurator; 45 import org.apache.myfaces.context.ReleaseableExternalContext; 46 import org.apache.myfaces.context.portlet.PortletExternalContextImpl; 47 import org.apache.myfaces.context.servlet.ServletFacesContextImpl; 48 import org.apache.myfaces.webapp.webxml.WebXml; 49 50 67 public class MyFacesGenericPortlet extends GenericPortlet 68 { 69 private static final Log log = LogFactory.getLog(MyFacesGenericPortlet.class); 70 71 public static final String VIEW_ID = 73 MyFacesGenericPortlet.class.getName() + ".VIEW_ID"; 74 75 private static final String CURRENT_FACES_CONTEXT = 77 MyFacesGenericPortlet.class.getName() + ".CURRENT_FACES_CONTEXT"; 78 79 private static final String DEFAULT_VIEW = "default-view"; 81 82 private static final String DEFAULT_VIEW_SELECTOR = "default-view-selector"; 84 85 private static final String FACES_INIT_DONE = 86 MyFacesGenericPortlet.class.getName() + ".FACES_INIT_DONE"; 87 88 private PortletContext portletContext; 89 90 private FacesContextFactory facesContextFactory; 91 private Lifecycle lifecycle; 92 93 private String defaultView; 94 private DefaultViewSelector defaultViewSelector; 95 96 99 public MyFacesGenericPortlet() 100 { 101 } 102 103 106 public void destroy() 107 { 108 super.destroy(); 109 FactoryFinder.releaseFactories(); 110 } 111 112 115 public void init() throws PortletException, UnavailableException 116 { 117 this.portletContext = getPortletContext(); 118 setDefaultView(); 119 setDefaultViewSelector(); 120 initMyFaces(); 121 122 facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY); 123 124 LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 127 lifecycle = lifecycleFactory.getLifecycle(getLifecycleId()); 128 } 129 130 private void setDefaultView() throws UnavailableException 131 { 132 this.defaultView = getPortletConfig().getInitParameter(DEFAULT_VIEW); 133 if (defaultView == null) 134 { 135 String msg = "Fatal: must specify a JSF view id as the default view in portlet.xml"; 136 throw new UnavailableException(msg); 137 } 138 } 139 140 private void setDefaultViewSelector() throws UnavailableException 141 { 142 String selectorClass = getPortletConfig().getInitParameter(DEFAULT_VIEW_SELECTOR); 143 if (selectorClass == null) return; 144 145 try 146 { 147 this.defaultViewSelector = (DefaultViewSelector)Class.forName(selectorClass).newInstance(); 148 this.defaultViewSelector.setPortletContext(getPortletContext()); 149 } 150 catch (Exception e) 151 { 152 log.error("Failed to load " + DEFAULT_VIEW_SELECTOR, e); 153 throw new UnavailableException(e.getMessage()); 154 } 155 } 156 157 private String getLifecycleId() 158 { 159 String lifecycleId = getPortletConfig().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR); 160 return lifecycleId != null ? lifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE; 161 } 162 163 private void initMyFaces() 164 { 165 try 166 { 167 Boolean b = (Boolean )portletContext.getAttribute(FACES_INIT_DONE); 168 169 if (b == null || b.booleanValue() == false) 170 { 171 log.trace("Initializing MyFaces"); 172 173 ExternalContext externalContext = new PortletExternalContextImpl(portletContext, null, null); 175 176 new FacesConfigurator(externalContext).configure(); 178 179 WebXml.init(externalContext); 181 182 portletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE); 183 } 184 else 185 { 186 log.info("MyFaces already initialized"); 187 } 188 } 189 catch (Exception ex) 190 { 191 log.error("Error initializing MyFacesGenericPortlet", ex); 192 } 193 194 log.info("PortletContext '" + portletContext.getRealPath("/") + "' initialized."); 195 } 196 197 200 public void processAction(ActionRequest request, ActionResponse response) 201 throws PortletException, IOException 202 { 203 if (log.isTraceEnabled()) log.trace("called processAction"); 204 205 if (sessionTimedOut(request)) return; 206 207 setPortletRequestFlag(request); 208 209 FacesContext facesContext = facesContext(request, response); 210 211 try 212 { 213 lifecycle.execute(facesContext); 214 215 if (!facesContext.getResponseComplete()) 216 { 217 response.setRenderParameter(VIEW_ID, facesContext.getViewRoot().getViewId()); 218 } 219 220 request.getPortletSession().setAttribute(CURRENT_FACES_CONTEXT, facesContext); 221 } 222 catch (Throwable e) 223 { 224 facesContext.release(); 225 handleExceptionFromLifecycle(e); 226 } 227 } 228 229 private void handleExceptionFromLifecycle(Throwable e) 230 throws PortletException, IOException 231 { 232 logException(e, null); 233 234 if (e instanceof IOException ) 235 { 236 throw (IOException )e; 237 } 238 239 if (e instanceof PortletException) 240 { 241 throw (PortletException)e; 242 } 243 244 if (e.getMessage() != null) 245 { 246 throw new PortletException(e.getMessage(), e); 247 } 248 249 throw new PortletException(e); 250 } 251 252 255 protected void doView(RenderRequest request, RenderResponse response) 256 throws PortletException, IOException 257 { 258 facesRender(request, response); 259 } 260 261 265 protected void doEdit(RenderRequest request, RenderResponse response) 266 throws PortletException, IOException 267 { 268 facesRender(request, response); 269 } 270 271 275 protected void doHelp(RenderRequest request, RenderResponse response) 276 throws PortletException, IOException 277 { 278 facesRender(request, response); 279 } 280 281 protected void nonFacesRequest(RenderRequest request, RenderResponse response) throws PortletException 283 { 284 if (log.isTraceEnabled()) log.trace("Non-faces request: contextPath = " + request.getContextPath()); 285 ApplicationFactory appFactory = 286 (ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); 287 Application application = appFactory.getApplication(); 288 ViewHandler viewHandler = application.getViewHandler(); 289 FacesContext facesContext = facesContext(request, response); 290 UIViewRoot view = viewHandler.createView(facesContext, selectDefaultView(request, response)); 291 facesContext.setViewRoot(view); 292 lifecycle.render(facesContext); 293 } 294 295 private String selectDefaultView(RenderRequest request, RenderResponse response) throws PortletException 296 { 297 String view = this.defaultView; 298 if (this.defaultViewSelector != null) 299 { 300 String selectedView = this.defaultViewSelector.selectViewId(request, response); 301 if (selectedView != null) 302 { 303 view = selectedView; 304 } 305 } 306 307 return view; 308 } 309 310 private FacesContext facesContext(PortletRequest request, 311 PortletResponse response) 312 { 313 return facesContextFactory.getFacesContext(portletContext, 314 request, 315 response, 316 lifecycle); 317 } 318 319 private ReleaseableExternalContext makeExternalContext(PortletRequest request, 320 PortletResponse response) 321 { 322 return (ReleaseableExternalContext)new PortletExternalContextImpl(portletContext, request, response); 323 } 324 325 private boolean sessionTimedOut(PortletRequest request) 326 { 327 return request.getPortletSession(false) == null; 328 } 329 330 private void setPortletRequestFlag(PortletRequest request) 331 { 332 request.getPortletSession().setAttribute(PortletUtil.PORTLET_REQUEST_FLAG, "true"); 333 } 334 335 338 protected void facesRender(RenderRequest request, RenderResponse response) 339 throws PortletException, java.io.IOException 340 { 341 if (log.isTraceEnabled()) log.trace("called facesRender"); 342 343 response.setContentType("text/html"); 344 345 String viewId = request.getParameter(VIEW_ID); 346 if ((viewId == null) || sessionTimedOut(request)) 347 { 348 setPortletRequestFlag(request); 349 nonFacesRequest(request, response); 350 return; 351 } 352 353 setPortletRequestFlag(request); 354 355 try 356 { 357 ServletFacesContextImpl facesContext = (ServletFacesContextImpl)request. 358 getPortletSession(). 359 getAttribute(CURRENT_FACES_CONTEXT); 360 361 if (facesContext.getResponseComplete()) return; 363 364 facesContext.setExternalContext(makeExternalContext(request, response)); 365 lifecycle.render(facesContext); 366 } 367 catch (Throwable e) 368 { 369 handleExceptionFromLifecycle(e); 370 } 371 } 372 373 private void logException(Throwable e, String msgPrefix) { 374 String msg; 375 if (msgPrefix == null) 376 { 377 if (e.getMessage() == null) 378 { 379 msg = "Exception in FacesServlet"; 380 } 381 else 382 { 383 msg = e.getMessage(); 384 } 385 } 386 else 387 { 388 if (e.getMessage() == null) 389 { 390 msg = msgPrefix; 391 } 392 else 393 { 394 msg = msgPrefix + ": " + e.getMessage(); 395 } 396 } 397 398 portletContext.log(msg, e); 399 400 Throwable cause = e.getCause(); 401 if (cause != null && cause != e) 402 { 403 logException(cause, "Root cause"); 404 } 405 406 if(e instanceof PortletException) 407 { 408 cause = ((PortletException) e).getCause(); 409 410 if(cause != null && cause != e) 411 { 412 logException(cause, "Root cause of PortletException"); 413 } 414 } 415 } 416 417 } | Popular Tags |