Coverage Report - org.apache.myfaces.lifecycle.RestoreViewExecutor
 
Classes in this File Line Coverage Branch Coverage Complexity
RestoreViewExecutor
0%
0/190
0%
0/158
8.385
 
 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.lifecycle;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.net.URI;
 23  
 import java.net.URISyntaxException;
 24  
 import java.util.logging.Level;
 25  
 import java.util.logging.Logger;
 26  
 
 27  
 import javax.el.MethodExpression;
 28  
 import javax.faces.FacesException;
 29  
 import javax.faces.FactoryFinder;
 30  
 import javax.faces.application.Application;
 31  
 import javax.faces.application.ProjectStage;
 32  
 import javax.faces.application.ProtectedViewException;
 33  
 import javax.faces.application.ViewExpiredException;
 34  
 import javax.faces.application.ViewHandler;
 35  
 import javax.faces.component.UIViewRoot;
 36  
 import javax.faces.context.ExternalContext;
 37  
 import javax.faces.context.FacesContext;
 38  
 import javax.faces.event.PhaseEvent;
 39  
 import javax.faces.event.PhaseId;
 40  
 import javax.faces.event.PostAddToViewEvent;
 41  
 import javax.faces.flow.FlowHandler;
 42  
 import javax.faces.lifecycle.ClientWindow;
 43  
 import javax.faces.lifecycle.Lifecycle;
 44  
 import javax.faces.lifecycle.LifecycleFactory;
 45  
 import javax.faces.render.RenderKit;
 46  
 import javax.faces.render.RenderKitFactory;
 47  
 import javax.faces.render.ResponseStateManager;
 48  
 import javax.faces.view.ViewDeclarationLanguage;
 49  
 import javax.faces.view.ViewMetadata;
 50  
 import javax.faces.webapp.FacesServlet;
 51  
 import javax.servlet.http.HttpServletResponse;
 52  
 import org.apache.myfaces.event.PostClientWindowAndViewInitializedEvent;
 53  
 
 54  
 import org.apache.myfaces.renderkit.ErrorPageWriter;
 55  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 56  
 import org.apache.myfaces.shared.util.ExternalContextUtils;
 57  
 import org.apache.myfaces.shared.util.ViewProtectionUtils;
 58  
 
 59  
 /**
 60  
  * Implements the Restore View Phase (JSF Spec 2.2.1)
 61  
  * 
 62  
  * @author Nikolay Petrov (latest modification by $Author$)
 63  
  * @author Bruno Aranda (JSF 1.2)
 64  
  * @version $Revision$ $Date$
 65  
  */
 66  0
 class RestoreViewExecutor extends PhaseExecutor
 67  
 {
 68  
 
 69  
     //private static final Log log = LogFactory.getLog(RestoreViewExecutor.class);
 70  0
     private static final Logger log = Logger.getLogger(RestoreViewExecutor.class.getName());
 71  
     
 72  
     private RestoreViewSupport _restoreViewSupport;
 73  
     
 74  
     private Boolean _viewNotFoundCheck;
 75  
     
 76  0
     private RenderKitFactory _renderKitFactory = null;
 77  
     
 78  
     @Override
 79  
     public void doPrePhaseActions(FacesContext facesContext)
 80  
     {
 81  
         // Call initView() on the ViewHandler. 
 82  
         // This will set the character encoding properly for this request.
 83  
         // Note that we are doing this here, because we need the character encoding
 84  
         // to be set as early as possible (before any PhaseListener is executed).
 85  0
         facesContext.getApplication().getViewHandler().initView(facesContext);
 86  0
     }
 87  
 
 88  
     public boolean execute(FacesContext facesContext)
 89  
     {
 90  0
         if (facesContext == null)
 91  
         {
 92  0
             throw new FacesException("FacesContext is null");
 93  
         }
 94  
 
 95  
         // get some required Objects
 96  0
         Application application = facesContext.getApplication();
 97  0
         ViewHandler viewHandler = application.getViewHandler();
 98  0
         UIViewRoot viewRoot = facesContext.getViewRoot();
 99  0
         RestoreViewSupport restoreViewSupport = getRestoreViewSupport(facesContext);
 100  
 
 101  
         // Examine the FacesContext instance for the current request. If it already contains a UIViewRoot
 102  0
         if (viewRoot != null)
 103  
         {
 104  0
             if (log.isLoggable(Level.FINEST))
 105  
             {
 106  0
                 log.finest("View already exists in the FacesContext");
 107  
             }
 108  
             
 109  
             // Set the locale on this UIViewRoot to the value returned by the getRequestLocale() method on the
 110  
             // ExternalContext for this request
 111  0
             viewRoot.setLocale(facesContext.getExternalContext().getRequestLocale());
 112  
             
 113  0
             restoreViewSupport.processComponentBinding(facesContext, viewRoot);
 114  
             
 115  
             // invoke the afterPhase MethodExpression of UIViewRoot
 116  0
             _invokeViewRootAfterPhaseListener(facesContext);
 117  
             
 118  0
             return false;
 119  
         }
 120  
         
 121  0
         String viewId = restoreViewSupport.calculateViewId(facesContext);
 122  
 
 123  
         // Determine if the current request is an attempt by the 
 124  
         // servlet container to display an error page.
 125  
         // If the request is an error page request, the servlet container
 126  
         // is required to set the request parameter "javax.servlet.error.message".
 127  0
         final boolean errorPageRequest = facesContext.getExternalContext().getRequestMap()
 128  
                                                  .get("javax.servlet.error.message") != null;
 129  
         
 130  
         // Determine if this request is a postback or an initial request.
 131  
         // But if it is an error page request, do not treat it as a postback (since 2.0)
 132  0
         if (!errorPageRequest && restoreViewSupport.isPostback(facesContext))
 133  
         { // If the request is a postback
 134  0
             if (log.isLoggable(Level.FINEST))
 135  
             {
 136  0
                 log.finest("Request is a postback");
 137  
             }
 138  
 
 139  0
             if (checkViewNotFound(facesContext))
 140  
             {
 141  0
                 String derivedViewId = viewHandler.deriveLogicalViewId(facesContext, viewId);
 142  0
                 ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(facesContext, 
 143  
                     derivedViewId);
 144  
             
 145  
                 // viewHandler.deriveLogicalViewId() could trigger an InvalidViewIdException, which
 146  
                 // it is handled internally sending a 404 error code set the response as complete.
 147  0
                 if (facesContext.getResponseComplete())
 148  
                 {
 149  0
                     return true;
 150  
                 }
 151  
             
 152  0
                 if (vdl == null || derivedViewId == null)
 153  
                 {
 154  0
                     sendSourceNotFound(facesContext, viewId);
 155  0
                     return true;
 156  
                 }
 157  0
                 else if (!restoreViewSupport.checkViewExists(facesContext, derivedViewId))
 158  
                 {
 159  0
                     sendSourceNotFound(facesContext, viewId);
 160  0
                     return true;
 161  
                 }
 162  
             }
 163  
             
 164  
             try
 165  
             {
 166  0
                 facesContext.setProcessingEvents(false);
 167  
                 // call ViewHandler.restoreView(), passing the FacesContext instance for the current request and the 
 168  
                 // view identifier, and returning a UIViewRoot for the restored view.
 169  
                 
 170  0
                 viewRoot = viewHandler.restoreView(facesContext, viewId);
 171  0
                 if (viewRoot == null)
 172  
                 {
 173  0
                     if (facesContext.getResponseComplete())
 174  
                     {
 175  
                         // If the view handler cannot restore the view and the response
 176  
                         // is complete, it can be an error or some logic in restoreView.
 177  0
                         return true;
 178  
                     }
 179  
                     else
 180  
                     {
 181  
                         // If the return from ViewHandler.restoreView() is null, throw a ViewExpiredException with an 
 182  
                         // appropriate error message.
 183  0
                         throw new ViewExpiredException("No saved view state could be found for the view identifier: "
 184  
                                                    + viewId, viewId);
 185  
                     }
 186  
                 }
 187  
                 // If the view is transient (stateless), it is necessary to check the view protection
 188  
                 // in POST case.
 189  0
                 if (viewRoot.isTransient())
 190  
                 {
 191  0
                     checkViewProtection(facesContext, viewHandler, viewRoot.getViewId(), viewRoot);
 192  
                 }
 193  
                 
 194  
                 // Store the restored UIViewRoot in the FacesContext.
 195  0
                 facesContext.setViewRoot(viewRoot);
 196  
             }
 197  
             finally
 198  
             {
 199  0
                 facesContext.setProcessingEvents(true);
 200  0
             }
 201  
             
 202  
             // Restore binding
 203  
             // See https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=806
 204  0
             restoreViewSupport.processComponentBinding(facesContext, viewRoot);
 205  
             
 206  0
             ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
 207  0
             if (clientWindow != null)
 208  
             {
 209  
                 // The idea of this event is once the client window and the view is initialized, 
 210  
                 // you have the information required to clean up any scope that belongs to old
 211  
                 // clientWindow instances like flow scope (in server side state saving).
 212  0
                 facesContext.getApplication().publishEvent(facesContext, PostClientWindowAndViewInitializedEvent.class, 
 213  
                         clientWindow);
 214  
             }
 215  0
         }
 216  
         else
 217  
         { // If the request is a non-postback
 218  0
             if (log.isLoggable(Level.FINEST))
 219  
             {
 220  0
                 log.finest("Request is not a postback. New UIViewRoot will be created");
 221  
             }
 222  
             
 223  
             //viewHandler.deriveViewId(facesContext, viewId)
 224  
             //restoreViewSupport.deriveViewId(facesContext, viewId)
 225  0
             String logicalViewId = viewHandler.deriveLogicalViewId(facesContext, viewId);
 226  0
             ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(facesContext, logicalViewId);
 227  
             
 228  
             // viewHandler.deriveLogicalViewId() could trigger an InvalidViewIdException, which
 229  
             // it is handled internally sending a 404 error code set the response as complete.
 230  0
             if (facesContext.getResponseComplete())
 231  
             {
 232  0
                 return true;
 233  
             }
 234  
             
 235  0
             if (checkViewNotFound(facesContext))
 236  
             {
 237  0
                 if (vdl == null || logicalViewId == null)
 238  
                 {
 239  0
                     sendSourceNotFound(facesContext, viewId);
 240  0
                     return true;
 241  
                 }
 242  0
                 else if (!restoreViewSupport.checkViewExists(facesContext, logicalViewId))
 243  
                 {
 244  0
                     sendSourceNotFound(facesContext, viewId);
 245  0
                     return true;
 246  
                 }
 247  
             }
 248  
             
 249  0
             if (vdl != null)
 250  
             {
 251  0
                 ViewMetadata metadata = vdl.getViewMetadata(facesContext, viewId);
 252  
                 
 253  0
                 if (metadata != null)
 254  
                 {
 255  0
                     viewRoot = metadata.createMetadataView(facesContext);
 256  
                     
 257  0
                     if(facesContext.getResponseComplete())
 258  
                     {
 259  
                         // this can happen if the current request is a debug request,
 260  
                         // in this case no further processing is necessary
 261  0
                         return true;
 262  
                     }
 263  
                 }
 264  
     
 265  0
                 if (viewRoot == null)
 266  
                 {
 267  0
                     facesContext.renderResponse();
 268  
                 }
 269  0
                 else if (viewRoot != null && !ViewMetadata.hasMetadata(viewRoot))
 270  
                 {
 271  0
                     facesContext.renderResponse();
 272  
                 }
 273  0
             }
 274  
             else
 275  
             {
 276  
                 // Call renderResponse
 277  0
                 facesContext.renderResponse();
 278  
             }
 279  
 
 280  0
             checkViewProtection(facesContext, viewHandler, logicalViewId, viewRoot);
 281  
             
 282  
             // viewRoot can be null here, if ...
 283  
             //   - we don't have a ViewDeclarationLanguage (e.g. when using facelets-1.x)
 284  
             //   - there is no view metadata or metadata.createMetadataView() returned null
 285  0
             if (viewRoot == null)
 286  
             {
 287  
                 // call ViewHandler.createView(), passing the FacesContext instance for the current request and 
 288  
                 // the view identifier
 289  0
                 viewRoot = viewHandler.createView(facesContext, viewId);
 290  
             }
 291  
             
 292  0
             if (viewRoot == null && facesContext.getResponseComplete())
 293  
             {
 294  
                 // If the view handler cannot create the view and the response
 295  
                 // is complete, it can be an error, just get out of the algorithm.
 296  0
                 return true;
 297  
             }
 298  
             
 299  
             // Subscribe the newly created UIViewRoot instance to the AfterAddToParent event, passing the 
 300  
             // UIViewRoot instance itself as the listener.
 301  
             // -= Leonardo Uribe =- This line it is not necessary because it was
 302  
             // removed from jsf 2.0 section 2.2.1 when pass from EDR2 to Public Review 
 303  
             // viewRoot.subscribeToEvent(PostAddToViewEvent.class, viewRoot);
 304  
             
 305  
             // Store the new UIViewRoot instance in the FacesContext.
 306  0
             facesContext.setViewRoot(viewRoot);
 307  
 
 308  0
             ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
 309  0
             if (clientWindow != null)
 310  
             {
 311  0
                 facesContext.getApplication().publishEvent(facesContext, PostClientWindowAndViewInitializedEvent.class, 
 312  
                         clientWindow);
 313  
             }
 314  
             
 315  0
             FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
 316  0
             if (flowHandler != null)
 317  
             {
 318  0
                 flowHandler.clientWindowTransition(facesContext);
 319  
             }
 320  
 
 321  
             // Publish an AfterAddToParent event with the created UIViewRoot as the event source.
 322  0
             application.publishEvent(facesContext, PostAddToViewEvent.class, viewRoot);
 323  
         }
 324  
 
 325  
         // add the ErrorPageBean to the view map to fully support 
 326  
         // facelet error pages, if we are in ProjectStage Development
 327  
         // and currently generating an error page
 328  0
         if (errorPageRequest && facesContext.isProjectStage(ProjectStage.Development))
 329  
         {
 330  0
             facesContext.getViewRoot().getViewMap()
 331  
                     .put(ErrorPageWriter.ERROR_PAGE_BEAN_KEY, new ErrorPageWriter.ErrorPageBean());
 332  
         }
 333  
         
 334  
         // invoke the afterPhase MethodExpression of UIViewRoot
 335  0
         _invokeViewRootAfterPhaseListener(facesContext);
 336  
         
 337  0
         return false;
 338  
     }
 339  
     
 340  
     private void checkViewProtection(FacesContext facesContext, ViewHandler viewHandler, 
 341  
         String viewId, UIViewRoot root) throws ProtectedViewException
 342  
     {
 343  0
         boolean valid = true;
 344  0
         if (ViewProtectionUtils.isViewProtected(facesContext, viewId))
 345  
         {
 346  
             // "... Obtain the value of the value of the request parameter whose 
 347  
             // name is given by the value of ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM. 
 348  
             // If there is no value, throw ProtectedViewException ..."
 349  0
             String token = (String) facesContext.getExternalContext().getRequestParameterMap().get(
 350  
                 ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM);
 351  0
             if (token != null && token.length() > 0)
 352  
             {
 353  0
                 String renderKitId = null;
 354  0
                 if (root != null)
 355  
                 {
 356  0
                     renderKitId = root.getRenderKitId();
 357  
                 }
 358  0
                 if (renderKitId == null)
 359  
                 {
 360  0
                     renderKitId = viewHandler.calculateRenderKitId(facesContext);
 361  
                 }
 362  0
                 RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
 363  0
                 ResponseStateManager rsm = renderKit.getResponseStateManager();
 364  
                 
 365  0
                 String storedToken = rsm.getCryptographicallyStrongTokenFromSession(facesContext);
 366  0
                 if (token.equals(storedToken))
 367  
                 {
 368  0
                     if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
 369  
                     {
 370  
                         // Any check beyond this point only has sense for servlet requests.
 371  0
                         String referer = facesContext.getExternalContext().
 372  
                             getRequestHeaderMap().get("Referer");
 373  0
                         if (referer != null)
 374  
                         {
 375  0
                             valid = valid && checkRefererOrOriginHeader(
 376  
                                 facesContext, viewHandler, referer);
 377  
                         }
 378  0
                         String origin = facesContext.getExternalContext().
 379  
                             getRequestHeaderMap().get("Origin");
 380  0
                         if (valid && origin != null)
 381  
                         {
 382  0
                             valid = valid && checkRefererOrOriginHeader(
 383  
                                 facesContext, viewHandler, origin);
 384  
                         }
 385  0
                     }
 386  
                 }
 387  
                 else
 388  
                 {
 389  0
                     valid = false;
 390  
                 }
 391  0
             }
 392  
             else
 393  
             {
 394  0
                 valid = false;
 395  
             }
 396  
         }
 397  0
         if (!valid)
 398  
         {
 399  0
             throw new ProtectedViewException();
 400  
         }
 401  0
     }
 402  
     
 403  
     private boolean checkRefererOrOriginHeader(FacesContext facesContext, 
 404  
         ViewHandler viewHandler, String refererOrOrigin)
 405  
     {
 406  
         try
 407  
         {
 408  
             // The referer can be absolute or relative. 
 409  0
             ExternalContext ectx = facesContext.getExternalContext();
 410  0
             URI refererURI = new URI(refererOrOrigin);
 411  0
             String path = refererURI.getPath();
 412  0
             String appContextPath = ectx.getApplicationContextPath();
 413  0
             if (refererURI.isAbsolute())
 414  
             {
 415  
                 // Check if the referer comes from the same host
 416  0
                 String host = refererURI.getHost();
 417  0
                 int port = refererURI.getPort();
 418  0
                 String serverHost = ectx.getRequestServerName();
 419  0
                 int serverPort = ectx.getRequestServerPort();
 420  
 
 421  0
                 boolean matchPort = true;
 422  0
                 if (serverPort != -1 && port != -1)
 423  
                 {
 424  0
                     matchPort = (serverPort == port);
 425  
                 }
 426  0
                 boolean isStrictJsf2OriginHeaderAppPath = 
 427  
                                 MyfacesConfig.getCurrentInstance(ectx).isStrictJsf2OriginHeaderAppPath();
 428  0
                 if (!path.equals(""))
 429  
                 {
 430  0
                     if (serverHost.equals(host) && matchPort && path.contains(appContextPath))
 431  
                     {
 432  
                         // Referer Header match
 433  
                     }
 434  
                     else
 435  
                     {
 436  
                         // Referer Header does not match
 437  0
                         return false;
 438  
                     }
 439  
                 }
 440  
                 else
 441  
                 {
 442  0
                     if (serverHost.equals(host) && matchPort && !isStrictJsf2OriginHeaderAppPath)
 443  
                     {
 444  
                         // Origin Header match and 
 445  
                         // STRICT_JSF_2_ORIGIN_HEADER_APP_PATH property is set to false (default)
 446  
                         // Because we don't want to strictly follow JSF 2.x spec
 447  
                     }
 448  
                     else
 449  
                     {
 450  
                         // Origin Header does not match
 451  0
                         return false;
 452  
                     }
 453  
                 }
 454  
             }
 455  
             // In theory path = appContextPath + servletPath + pathInfo. 
 456  0
             int appContextPathIndex = appContextPath != null ? path.indexOf(appContextPath) : -1;
 457  0
             int servletPathIndex = -1;
 458  0
             int pathInfoIndex = -1;
 459  0
             if (ectx.getRequestServletPath() != null && ectx.getRequestPathInfo() != null)
 460  
             {
 461  0
                 servletPathIndex = ectx.getRequestServletPath() != null ? 
 462  
                     path.indexOf(ectx.getRequestServletPath(), 
 463  
                                  appContextPathIndex >= 0 ? appContextPathIndex : 0) : -1;
 464  0
                 if (servletPathIndex != -1)
 465  
                 {
 466  0
                     pathInfoIndex = servletPathIndex + ectx.getRequestServletPath().length();
 467  
                 }
 468  
             }
 469  
             else
 470  
             {
 471  0
                 servletPathIndex = -1;
 472  0
                 pathInfoIndex = (appContextPathIndex >= 0 ? appContextPathIndex : 0) + appContextPath.length();
 473  
             }
 474  
 
 475  
             // If match appContextPath(if any) and match servletPath or pathInfo referer header is ok
 476  0
             if ((appContextPath == null || appContextPathIndex >= 0) && 
 477  
                 (servletPathIndex >= 0 || pathInfoIndex >= 0))
 478  
             {
 479  
                 String refererViewId;
 480  0
                 if (pathInfoIndex >= 0)
 481  
                 {
 482  0
                     refererViewId = path.substring(pathInfoIndex);
 483  
                 }
 484  
                 else
 485  
                 {
 486  0
                     refererViewId = path.substring(servletPathIndex);
 487  
                 }
 488  
                 
 489  0
                 String logicalViewId = viewHandler.deriveViewId(facesContext, refererViewId);
 490  
                     
 491  
                 // If the header is present, use the protected view API to determine if any of
 492  
                 // the declared protected views match the value of the Referer header.
 493  
                 // - If so, conclude that the previously visited page is also a protected 
 494  
                 //   view and it is therefore safe to continue.
 495  
                 // - Otherwise, try to determine if the value of the Referer header corresponds 
 496  
                 //   to any of the views in the current web application.
 497  
                 // -= Leonardo Uribe =- All views that are protected also should exists!. the
 498  
                 // only relevant check is use ViewHandler.deriveViewId(...) here. Check if the
 499  
                 // view is protected here is not necessary.
 500  0
                 if (logicalViewId != null)
 501  
                 {
 502  0
                     return true;
 503  
                 }
 504  
                 else
 505  
                 {
 506  
                     // View do not exists
 507  
                 }
 508  
             }
 509  0
             return true;
 510  
         }
 511  0
         catch (URISyntaxException ex)
 512  
         {
 513  0
             return false;
 514  
         }
 515  
     }
 516  
     
 517  
     /**
 518  
      * Invoke afterPhase MethodExpression of UIViewRoot.
 519  
      * Note: In this phase it is not possible to invoke the beforePhase method, because we
 520  
      * first have to restore the view to get its attributes. Also it is not really possible
 521  
      * to call the afterPhase method inside of UIViewRoot for this phase, thus it was decided
 522  
      * in the JSF 2.0 spec rev A to put this here.
 523  
      * @param facesContext
 524  
      */
 525  
     private void _invokeViewRootAfterPhaseListener(FacesContext facesContext)
 526  
     {
 527  
         // get the UIViewRoot (note that it must not be null at this point)
 528  0
         UIViewRoot root = facesContext.getViewRoot();
 529  0
         MethodExpression afterPhaseExpression = root.getAfterPhaseListener();
 530  0
         if (afterPhaseExpression != null)
 531  
         {
 532  0
             PhaseEvent event = new PhaseEvent(facesContext, getPhase(), _getLifecycle(facesContext));
 533  
             try
 534  
             {
 535  0
                 afterPhaseExpression.invoke(facesContext.getELContext(), new Object[] { event });
 536  
             }
 537  0
             catch (Throwable t) 
 538  
             {
 539  0
                 log.log(Level.SEVERE, "An Exception occured while processing " +
 540  
                         afterPhaseExpression.getExpressionString() + 
 541  
                         " in Phase " + getPhase(), t);
 542  0
             }
 543  
         }
 544  0
     }
 545  
     
 546  
     /**
 547  
      * Gets the current Lifecycle instance from the LifecycleFactory
 548  
      * @param facesContext
 549  
      * @return
 550  
      */
 551  
     private Lifecycle _getLifecycle(FacesContext facesContext)
 552  
     {
 553  0
         LifecycleFactory factory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
 554  0
         String id = facesContext.getExternalContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
 555  0
         if (id == null)
 556  
         {
 557  0
             id = LifecycleFactory.DEFAULT_LIFECYCLE;
 558  
         }
 559  0
         return factory.getLifecycle(id);  
 560  
     }
 561  
     
 562  
     protected RestoreViewSupport getRestoreViewSupport()
 563  
     {
 564  0
         return getRestoreViewSupport(FacesContext.getCurrentInstance());
 565  
     }
 566  
     
 567  
     protected RestoreViewSupport getRestoreViewSupport(FacesContext context)
 568  
     {
 569  0
         if (_restoreViewSupport == null)
 570  
         {
 571  0
             _restoreViewSupport = new DefaultRestoreViewSupport(context);
 572  
         }
 573  0
         return _restoreViewSupport;
 574  
     }
 575  
 
 576  
     protected RenderKitFactory getRenderKitFactory()
 577  
     {
 578  0
         if (_renderKitFactory == null)
 579  
         {
 580  0
             _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
 581  
         }
 582  0
         return _renderKitFactory;
 583  
     }
 584  
     
 585  
     /**
 586  
      * @param restoreViewSupport
 587  
      *            the restoreViewSupport to set
 588  
      */
 589  
     public void setRestoreViewSupport(RestoreViewSupport restoreViewSupport)
 590  
     {
 591  0
         _restoreViewSupport = restoreViewSupport;
 592  0
     }
 593  
 
 594  
     public PhaseId getPhase()
 595  
     {
 596  0
         return PhaseId.RESTORE_VIEW;
 597  
     }
 598  
     
 599  
     protected boolean checkViewNotFound(FacesContext facesContext)
 600  
     {
 601  0
         if (_viewNotFoundCheck == null)
 602  
         {
 603  
             
 604  0
             _viewNotFoundCheck = MyfacesConfig.getCurrentInstance(
 605  
                 facesContext.getExternalContext()).isStrictJsf2ViewNotFound();
 606  
         }
 607  0
         return _viewNotFoundCheck;
 608  
     }
 609  
     
 610  
     private void sendSourceNotFound(FacesContext context, String message)
 611  
     {
 612  0
         HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
 613  
         try
 614  
         {
 615  0
             context.responseComplete();
 616  0
             response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
 617  
         }
 618  0
         catch (IOException ioe)
 619  
         {
 620  0
             throw new FacesException(ioe);
 621  0
         }
 622  0
     }
 623  
 }