Beispiel #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;
  }
Beispiel #2
0
  /**
   * @see javax.faces.view.ViewDeclarationLanguage#renderView(javax.faces.context.FacesContext,
   *     javax.faces.component.UIViewRoot)
   */
  public void renderView(FacesContext context, UIViewRoot view) throws IOException {

    // suppress rendering if "rendered" property on the component is
    // false
    if (!view.isRendered() || context.getResponseComplete()) {
      return;
    }

    ExternalContext extContext = context.getExternalContext();

    if (!Util.isViewPopulated(context, view)) {
      buildView(context, view);
    }

    // set up the ResponseWriter

    RenderKitFactory renderFactory =
        (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
    RenderKit renderKit = renderFactory.getRenderKit(context, view.getRenderKitId());

    ResponseWriter oldWriter = context.getResponseWriter();

    WriteBehindStateWriter stateWriter =
        new WriteBehindStateWriter(
            extContext.getResponseOutputWriter(), context, responseBufferSize);
    ResponseWriter newWriter;
    if (null != oldWriter) {
      newWriter = oldWriter.cloneWithWriter(stateWriter);
    } else {
      newWriter =
          renderKit.createResponseWriter(
              stateWriter, null, extContext.getRequestCharacterEncoding());
    }
    context.setResponseWriter(newWriter);

    //  Don't call startDoc and endDoc on a partial response
    if (context.getPartialViewContext().isPartialRequest()) {
      doRenderView(context, view);
      try {
        extContext.getFlash().doPostPhaseActions(context);
      } catch (UnsupportedOperationException uoe) {
        if (LOGGER.isLoggable(Level.FINE)) {
          LOGGER.fine(
              "ExternalContext.getFlash() throw UnsupportedOperationException -> Flash unavailable");
        }
      }
    } else {
      // render the view to the response
      newWriter.startDocument();
      doRenderView(context, view);
      try {
        extContext.getFlash().doPostPhaseActions(context);
      } catch (UnsupportedOperationException uoe) {
        if (LOGGER.isLoggable(Level.FINE)) {
          LOGGER.fine(
              "ExternalContext.getFlash() throw UnsupportedOperationException -> Flash unavailable");
        }
      }
      newWriter.endDocument();
    }

    // replace markers in the body content and write it to response.

    // flush directly to the response
    if (stateWriter.stateWritten()) {
      stateWriter.flushToWriter();
    }

    // clear the ThreadLocal reference.
    stateWriter.release();

    if (null != oldWriter) {
      context.setResponseWriter(oldWriter);
    }

    // write any AFTER_VIEW_CONTENT to the response
    // side effect: AFTER_VIEW_CONTENT removed
    ViewHandlerResponseWrapper wrapper =
        (ViewHandlerResponseWrapper)
            RequestStateManager.remove(context, RequestStateManager.AFTER_VIEW_CONTENT);
    if (null != wrapper) {
      wrapper.flushToWriter(
          extContext.getResponseOutputWriter(), extContext.getResponseCharacterEncoding());
    }

    extContext.responseFlushBuffer();
  }