Coverage Report - org.apache.myfaces.portlet.MyFacesGenericPortlet
 
Classes in this File Line Coverage Branch Coverage Complexity
MyFacesGenericPortlet
0%
0/135
0%
0/58
2.682
 
 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.portlet;
 20  
 
 21  
 import java.io.IOException;
 22  
 
 23  
 import javax.faces.FactoryFinder;
 24  
 import javax.faces.application.Application;
 25  
 import javax.faces.application.ApplicationFactory;
 26  
 import javax.faces.application.ViewHandler;
 27  
 import javax.faces.component.UIViewRoot;
 28  
 import javax.faces.context.ExternalContext;
 29  
 import javax.faces.context.FacesContext;
 30  
 import javax.faces.context.FacesContextFactory;
 31  
 import javax.faces.lifecycle.Lifecycle;
 32  
 import javax.faces.lifecycle.LifecycleFactory;
 33  
 import javax.faces.webapp.FacesServlet;
 34  
 import javax.portlet.ActionRequest;
 35  
 import javax.portlet.ActionResponse;
 36  
 import javax.portlet.GenericPortlet;
 37  
 import javax.portlet.PortletContext;
 38  
 import javax.portlet.PortletException;
 39  
 import javax.portlet.PortletRequest;
 40  
 import javax.portlet.PortletResponse;
 41  
 import javax.portlet.RenderRequest;
 42  
 import javax.portlet.RenderResponse;
 43  
 import javax.portlet.UnavailableException;
 44  
 
 45  
 import org.apache.commons.logging.Log;
 46  
 import org.apache.commons.logging.LogFactory;
 47  
 import org.apache.myfaces.context.ReleaseableExternalContext;
 48  
 import org.apache.myfaces.context.portlet.PortletExternalContextImpl;
 49  
 import org.apache.myfaces.context.servlet.FacesContextImpl;
 50  
 import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
 51  
 
 52  
 /**
 53  
  * This portlet initializes MyFaces and converts portlet requests into
 54  
  * JSF requests.
 55  
  *
 56  
  * @deprecated Replaced by jsr 301 portlet bridge. 
 57  
  * @author  Stan Silvert (latest modification by $Author: lu4242 $)
 58  
  * @version $Revision: 827879 $ $Date: 2009-10-20 22:10:03 -0500 (Tue, 20 Oct 2009) $
 59  
  */
 60  
 public class MyFacesGenericPortlet extends GenericPortlet
 61  
 {
 62  0
     private static final Log log = LogFactory.getLog(MyFacesGenericPortlet.class);
 63  
 
 64  
     // PortletRequest parameter
 65  0
     public static final String VIEW_ID =
 66  
         MyFacesGenericPortlet.class.getName() + ".VIEW_ID";
 67  
 
 68  
     // PortletSession attribute
 69  0
     protected static final String CURRENT_FACES_CONTEXT =
 70  
         MyFacesGenericPortlet.class.getName() + ".CURRENT_FACES_CONTEXT";
 71  
 
 72  
     // portlet config parameter from portlet.xml
 73  
     protected static final String DEFAULT_VIEW = "default-view";
 74  
 
 75  
     // portlet config parameter from portlet.xml
 76  
     protected static final String DEFAULT_VIEW_SELECTOR = "default-view-selector";
 77  
 
 78  0
     protected static final String FACES_INIT_DONE =
 79  
         MyFacesGenericPortlet.class.getName() + ".FACES_INIT_DONE";
 80  
 
 81  
     protected PortletContext portletContext;
 82  
 
 83  
     protected FacesContextFactory facesContextFactory;
 84  
     protected Lifecycle lifecycle;
 85  
 
 86  
     protected String defaultView;
 87  
     protected DefaultViewSelector defaultViewSelector;
 88  
 
 89  
     /**
 90  
      * Creates a new instance of MyFacesPortlet
 91  
      */
 92  
     public MyFacesGenericPortlet()
 93  0
     {
 94  0
     }
 95  
 
 96  
     /**
 97  
      * Portlet lifecycle.
 98  
      */
 99  
     public void destroy()
 100  
     {
 101  0
         super.destroy();
 102  0
         FactoryFinder.releaseFactories();
 103  0
     }
 104  
 
 105  
     /**
 106  
      * Portlet lifecycle.
 107  
      */
 108  
     public void init() throws PortletException, UnavailableException
 109  
     {
 110  0
         this.portletContext = getPortletContext();
 111  0
         setDefaultView();
 112  0
         setDefaultViewSelector();
 113  0
         initMyFaces();
 114  
 
 115  0
         facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
 116  
 
 117  
         // Javadoc says: Lifecycle instance is shared across multiple simultaneous requests, it must be
 118  
         // implemented in a thread-safe manner.  So we can acquire it here once:
 119  0
         LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
 120  0
         lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
 121  0
     }
 122  
 
 123  
     protected void setDefaultView() throws UnavailableException
 124  
     {
 125  0
         this.defaultView = getPortletConfig().getInitParameter(DEFAULT_VIEW);
 126  0
         if (defaultView == null)
 127  
         {
 128  0
             String msg = "Fatal: must specify a JSF view id as the default view in portlet.xml";
 129  0
             throw new UnavailableException(msg);
 130  
         }
 131  0
     }
 132  
 
 133  
     protected void setDefaultViewSelector() throws UnavailableException
 134  
     {
 135  0
         String selectorClass = getPortletConfig().getInitParameter(DEFAULT_VIEW_SELECTOR);
 136  0
         if (selectorClass == null) return;
 137  
 
 138  
         try
 139  
         {
 140  0
             this.defaultViewSelector = (DefaultViewSelector)Class.forName(selectorClass).newInstance();
 141  0
             this.defaultViewSelector.setPortletContext(getPortletContext());
 142  
         }
 143  0
         catch (Exception e)
 144  
         {
 145  0
             log.error("Failed to load " + DEFAULT_VIEW_SELECTOR, e);
 146  0
             throw new UnavailableException(e.getMessage());
 147  0
         }
 148  0
     }
 149  
 
 150  
     protected void setContentType(RenderRequest request, RenderResponse response)
 151  
     {
 152  
 
 153  0
         if (response.getContentType() == null)
 154  
         {
 155  0
             String portalPreferredContentType = request.getResponseContentType();
 156  0
             if (portalPreferredContentType != null)
 157  
             {
 158  0
                 response.setContentType(portalPreferredContentType);
 159  
             }
 160  
             else
 161  
             {
 162  0
                 response.setContentType("text/html");
 163  
             }
 164  
         }
 165  0
     }
 166  
 
 167  
     protected String getLifecycleId()
 168  
     {
 169  0
         String lifecycleId = getPortletConfig().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
 170  0
         return lifecycleId != null ? lifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
 171  
     }
 172  
 
 173  
     protected void initMyFaces()
 174  
     {
 175  
         try
 176  
         {
 177  0
             Boolean b = (Boolean)portletContext.getAttribute(FACES_INIT_DONE);
 178  
 
 179  0
             if (b == null || b.booleanValue() == false)
 180  
             {
 181  0
                 log.trace("Initializing MyFaces");
 182  
 
 183  
                 //Load the configuration
 184  0
                 ExternalContext externalContext = new PortletExternalContextImpl(portletContext, null, null);
 185  
 
 186  
                 //And configure everything
 187  
                 
 188  
                 // TODO: FIX PORTLET STUFF FOR JSF 1.2
 189  
                 // new FacesConfigurator(externalContext).configure();
 190  
 
 191  
                 // parse web.xml - not sure if this is needed for portlet
 192  0
                 WebXml.init(externalContext);
 193  
 
 194  0
                 portletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
 195  0
             }
 196  
             else
 197  
             {
 198  0
                 log.info("MyFaces already initialized");
 199  
             }
 200  
         }
 201  0
         catch (Exception ex)
 202  
         {
 203  0
             log.error("Error initializing MyFacesGenericPortlet", ex);
 204  0
         }
 205  
 
 206  0
         log.info("PortletContext '" + portletContext.getRealPath("/") + "' initialized.");
 207  0
     }
 208  
 
 209  
     /**
 210  
      * Called by the portlet container to allow the portlet to process an action request.
 211  
      */
 212  
     public void processAction(ActionRequest request, ActionResponse response)
 213  
             throws PortletException, IOException
 214  
     {
 215  0
         if (log.isTraceEnabled()) log.trace("called processAction");
 216  
 
 217  0
         if (sessionTimedOut(request)) return;
 218  
 
 219  0
         setPortletRequestFlag(request);
 220  
 
 221  0
         FacesContext facesContext = facesContext(request, response);
 222  
 
 223  
         try
 224  
         {
 225  0
             lifecycle.execute(facesContext);
 226  
 
 227  0
             if (!facesContext.getResponseComplete())
 228  
             {
 229  0
                 response.setRenderParameter(VIEW_ID, facesContext.getViewRoot().getViewId());
 230  
             }
 231  
 
 232  0
             request.getPortletSession().setAttribute(CURRENT_FACES_CONTEXT, facesContext);
 233  
         }
 234  0
         catch (Throwable e)
 235  
         {
 236  0
             facesContext.release();
 237  0
             handleExceptionFromLifecycle(e);
 238  0
         }
 239  0
     }
 240  
 
 241  
     protected void handleExceptionFromLifecycle(Throwable e)
 242  
             throws PortletException, IOException
 243  
     {
 244  0
         logException(e, null);
 245  
 
 246  0
         if (e instanceof IOException)
 247  
         {
 248  0
             throw (IOException)e;
 249  
         }
 250  
 
 251  0
         if (e instanceof PortletException)
 252  
         {
 253  0
             throw (PortletException)e;
 254  
         }
 255  
 
 256  0
         if (e.getMessage() != null)
 257  
         {
 258  0
             throw new PortletException(e.getMessage(), e);
 259  
         }
 260  
 
 261  0
         throw new PortletException(e);
 262  
     }
 263  
 
 264  
     /**
 265  
      * Helper method to serve up the view mode.
 266  
      */
 267  
     protected void doView(RenderRequest request, RenderResponse response)
 268  
             throws PortletException, IOException
 269  
     {
 270  0
         facesRender(request, response);
 271  0
     }
 272  
 
 273  
     /**
 274  
      * Helper method to serve up the edit mode.  Can be overridden to add
 275  
      * the edit mode concept to a JSF application.
 276  
      */
 277  
     protected void doEdit(RenderRequest request, RenderResponse response)
 278  
             throws PortletException, IOException
 279  
     {
 280  0
         facesRender(request, response);
 281  0
     }
 282  
 
 283  
     /**
 284  
      * Helper method to serve up the edit mode.  Can be overridden to add
 285  
      * the help mode concept to a JSF application.
 286  
      */
 287  
     protected void doHelp(RenderRequest request, RenderResponse response)
 288  
             throws PortletException, IOException
 289  
     {
 290  0
         facesRender(request, response);
 291  0
     }
 292  
 
 293  
     /**
 294  
      * This method follows JSF Spec section 2.1.1.  It renders the default view from a non-faces
 295  
      * request.
 296  
      *
 297  
      * @param request The portlet render request.
 298  
      * @param response The portlet render response.
 299  
      */
 300  
     protected void nonFacesRequest(RenderRequest request, RenderResponse response) throws PortletException
 301  
     {
 302  0
         nonFacesRequest(request, response, selectDefaultView(request, response));
 303  0
     }
 304  
 
 305  
     /**
 306  
      * This method follows JSF Spec section 2.1.1.  It renders a view from a non-faces
 307  
      * request.  This is useful for a default view as well as for views that need to
 308  
      * be rendered from the portlet's edit and help buttons.
 309  
      *
 310  
      * @param request The portlet render request.
 311  
      * @param response The portlet render response.
 312  
      * @param view The name of the view that needs to be rendered.
 313  
      */
 314  
     protected void nonFacesRequest(RenderRequest request, RenderResponse response, String view)
 315  
             throws PortletException
 316  
     {
 317  0
         if (log.isTraceEnabled()) log.trace("Non-faces request: contextPath = " + request.getContextPath());
 318  0
         setContentType(request, response); // do this in case nonFacesRequest is called by a subclass
 319  0
         ApplicationFactory appFactory =
 320  
             (ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
 321  0
         Application application = appFactory.getApplication();
 322  0
         ViewHandler viewHandler = application.getViewHandler();
 323  0
         FacesContext facesContext = facesContext(request, response);
 324  0
         UIViewRoot viewRoot = viewHandler.createView(facesContext, view);
 325  0
         viewRoot.setViewId(view);
 326  0
         facesContext.setViewRoot(viewRoot);
 327  0
         lifecycle.render(facesContext);
 328  0
     }
 329  
 
 330  
     protected String selectDefaultView(RenderRequest request, RenderResponse response) throws PortletException
 331  
     {
 332  0
         String view = this.defaultView;
 333  0
         if (this.defaultViewSelector != null)
 334  
         {
 335  0
             String selectedView = this.defaultViewSelector.selectViewId(request, response);
 336  0
             if (selectedView != null)
 337  
             {
 338  0
                 view = selectedView;
 339  
             }
 340  
         }
 341  
 
 342  0
         return view;
 343  
     }
 344  
 
 345  
     protected FacesContext facesContext(PortletRequest request,
 346  
                                         PortletResponse response)
 347  
     {
 348  0
         return facesContextFactory.getFacesContext(portletContext,
 349  
                                                    request,
 350  
                                                    response,
 351  
                                                    lifecycle);
 352  
     }
 353  
 
 354  
     protected ReleaseableExternalContext makeExternalContext(PortletRequest request,
 355  
                                                              PortletResponse response)
 356  
     {
 357  0
         return new PortletExternalContextImpl(portletContext, request, response);
 358  
     }
 359  
 
 360  
     protected boolean sessionTimedOut(PortletRequest request)
 361  
     {
 362  0
         return request.getPortletSession(false) == null;
 363  
     }
 364  
 
 365  
     protected void setPortletRequestFlag(PortletRequest request)
 366  
     {
 367  0
         request.getPortletSession().setAttribute(PortletUtil.PORTLET_REQUEST_FLAG, "true");
 368  0
     }
 369  
 
 370  
     /**
 371  
      * Render a JSF view.
 372  
      */
 373  
     protected void facesRender(RenderRequest request, RenderResponse response)
 374  
             throws PortletException, java.io.IOException
 375  
     {
 376  0
         if (log.isTraceEnabled()) log.trace("called facesRender");
 377  
 
 378  0
         setContentType(request, response);
 379  
 
 380  0
         String viewId = request.getParameter(VIEW_ID);
 381  0
         if ((viewId == null) || sessionTimedOut(request))
 382  
         {
 383  0
             setPortletRequestFlag(request);
 384  0
             nonFacesRequest(request,  response);
 385  0
             return;
 386  
         }
 387  
 
 388  0
         setPortletRequestFlag(request);
 389  
 
 390  
         try
 391  
         {
 392  0
             FacesContextImpl facesContext = (FacesContextImpl)request.
 393  
                                                    getPortletSession().
 394  
                                                    getAttribute(CURRENT_FACES_CONTEXT);
 395  
 
 396  
             // TODO: not sure if this can happen.  Also double check this against spec section 2.1.3
 397  0
             if (facesContext.getResponseComplete()) return;
 398  
 
 399  0
             facesContext.setExternalContext(makeExternalContext(request, response));
 400  0
             lifecycle.render(facesContext);
 401  
         }
 402  0
         catch (Throwable e)
 403  
         {
 404  0
             handleExceptionFromLifecycle(e);
 405  0
         }
 406  0
     }
 407  
 
 408  
     protected void logException(Throwable e, String msgPrefix) {
 409  
         String msg;
 410  0
         if (msgPrefix == null)
 411  
         {
 412  0
             if (e.getMessage() == null)
 413  
             {
 414  0
                 msg = "Exception in FacesServlet";
 415  
             }
 416  
             else
 417  
             {
 418  0
                 msg = e.getMessage();
 419  
             }
 420  
         }
 421  
         else
 422  
         {
 423  0
             if (e.getMessage() == null)
 424  
             {
 425  0
                 msg = msgPrefix;
 426  
             }
 427  
             else
 428  
             {
 429  0
                 msg = msgPrefix + ": " + e.getMessage();
 430  
             }
 431  
         }
 432  
 
 433  0
         portletContext.log(msg, e);
 434  
 
 435  0
         Throwable cause = e.getCause();
 436  0
         if (cause != null && cause != e)
 437  
         {
 438  0
             logException(cause, "Root cause");
 439  
         }
 440  
 
 441  0
         if(e instanceof PortletException)
 442  
         {
 443  0
             cause = ((PortletException) e).getCause();
 444  
 
 445  0
             if(cause != null && cause != e)
 446  
             {
 447  0
                 logException(cause, "Root cause of PortletException");
 448  
             }
 449  
         }
 450  0
     }
 451  
 
 452  
 }