Ejemplo n.º 1
0
  /**
   * Execute the target view. If the HTTP status code range is not 2xx, then return true to indicate
   * the response should be immediately flushed by the caller so that conditions such as 404 are
   * properly handled.
   *
   * @param context the <code>FacesContext</code> for the current request
   * @param viewToExecute the view to build
   * @return <code>true</code> if the response should be immediately flushed to the client,
   *     otherwise <code>false</code>
   * @throws java.io.IOException if an error occurs executing the page
   */
  private boolean executePageToBuildView(FacesContext context, UIViewRoot viewToExecute)
      throws IOException {

    if (null == context) {
      String message =
          MessageUtils.getExceptionMessageString(
              MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context");
      throw new NullPointerException(message);
    }
    if (null == viewToExecute) {
      String message =
          MessageUtils.getExceptionMessageString(
              MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "viewToExecute");
      throw new NullPointerException(message);
    }

    ExternalContext extContext = context.getExternalContext();

    if ("/*".equals(RequestStateManager.get(context, RequestStateManager.INVOCATION_PATH))) {
      throw new FacesException(
          MessageUtils.getExceptionMessageString(MessageUtils.FACES_SERVLET_MAPPING_INCORRECT_ID));
    }

    String requestURI = viewToExecute.getViewId();

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("About to execute view " + requestURI);
    }

    // update the JSTL locale attribute in request scope so that JSTL
    // picks up the locale from viewRoot. This attribute must be updated
    // before the JSTL setBundle tag is called because that is when the
    // new LocalizationContext object is created based on the locale.
    if (extContext.getRequest() instanceof ServletRequest) {
      Config.set(
          (ServletRequest) extContext.getRequest(),
          Config.FMT_LOCALE,
          context.getViewRoot().getLocale());
    }
    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Before dispacthMessage to viewId " + requestURI);
    }

    // save the original response
    Object originalResponse = extContext.getResponse();

    // replace the response with our wrapper
    ViewHandlerResponseWrapper wrapped = getWrapper(extContext);
    extContext.setResponse(wrapped);

    try {

      // build the view by executing the page
      extContext.dispatch(requestURI);

      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.fine("After dispacthMessage to viewId " + requestURI);
      }
    } finally {
      // replace the original response
      extContext.setResponse(originalResponse);
    }

    // Follow the JSTL 1.2 spec, section 7.4,
    // on handling status codes on a forward
    if (wrapped.getStatus() < 200 || wrapped.getStatus() > 299) {
      // flush the contents of the wrapper to the response
      // this is necessary as the user may be using a custom
      // error page - this content should be propagated
      wrapped.flushContentToWrappedResponse();
      return true;
    }

    // Put the AFTER_VIEW_CONTENT into request scope
    // temporarily
    RequestStateManager.set(context, RequestStateManager.AFTER_VIEW_CONTENT, wrapped);

    return false;
  }