Package org.omnifaces.servlet

Source Code of org.omnifaces.servlet.HttpServletResponseOutputWrapper

/*
* Copyright 2012 OmniFaces.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.omnifaces.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.omnifaces.io.ResettableBuffer;
import org.omnifaces.io.ResettableBufferedOutputStream;
import org.omnifaces.io.ResettableBufferedWriter;

/**
* Convenience class for extending {@link HttpServletResponseWrapper} wherein the servlet response {@link OutputStream}
* has to be replaced by a custom implementation. This saves the developer from writing repeated
* {@link #getOutputStream()}, {@link #getWriter()} and {@link #flushBuffer()} boilerplate. All the developer has to do
* is to implement the {@link #createOutputStream()} accordingly. This will in turn be used by both
* {@link #getOutputStream()} and {@link #getWriter()}.
* <p>
* The boolean property <code>passThrough</code>, which defaults to <code>false</code> also enables the developer to
* control whether to pass through to the wrapped {@link ServletOutputStream} or not.
* <p>
*
* @author Bauke Scholtz
* @since 1.1
*/
public abstract class HttpServletResponseOutputWrapper extends HttpServletResponseWrapper {

  // Constants ------------------------------------------------------------------------------------------------------

  private static final String ERROR_GETOUTPUT_ALREADY_CALLED =
    "getOutputStream() has already been called on this response.";
  private static final String ERROR_GETWRITER_ALREADY_CALLED =
    "getWriter() has already been called on this response.";

  // Properties -----------------------------------------------------------------------------------------------------

  private ServletOutputStream output;
  private PrintWriter writer;
  private ResettableBuffer buffer;
  private boolean passThrough;

  // Constructors ---------------------------------------------------------------------------------------------------

  /**
   * Construct a new {@link HttpServletResponseOutputWrapper} which wraps the given response.
   * @param wrappedResponse The wrapped response.
   */
  public HttpServletResponseOutputWrapper(HttpServletResponse wrappedResponse) {
    super(wrappedResponse);
  }

  // Actions --------------------------------------------------------------------------------------------------------

  /**
   * Returns the custom implementation of the servlet response {@link OutputStream}.
   * @return The custom implementation of the servlet response {@link OutputStream}.
   */
  protected abstract OutputStream createOutputStream();

  @Override
  public ServletOutputStream getOutputStream() throws IOException {
    if (passThrough) {
      return super.getOutputStream();
    }

    if (writer != null) {
      throw new IllegalStateException(ERROR_GETWRITER_ALREADY_CALLED);
    }

    if (output == null) {
      buffer = new ResettableBufferedOutputStream(createOutputStream(), getBufferSize());
      output = new ServletOutputStream() {
        @Override
        public void write(int b) throws IOException {
          ((OutputStream) buffer).write(b);
        }
        @Override
        public void flush() throws IOException {
          ((OutputStream) buffer).flush();
        }
        @Override
        public void close() throws IOException {
          ((OutputStream) buffer).close();
        }
      };
    }

    return output;
  }

  @Override
  public PrintWriter getWriter() throws IOException {
    if (passThrough) {
      return super.getWriter();
    }

    if (output != null) {
      throw new IllegalStateException(ERROR_GETOUTPUT_ALREADY_CALLED);
    }

    if (writer == null) {
      buffer = new ResettableBufferedWriter(new OutputStreamWriter(createOutputStream(),
        getCharacterEncoding()), getBufferSize(), getCharacterEncoding());
      writer = new PrintWriter((Writer) buffer);
    }

    return writer;
  }

  @Override
  public void flushBuffer() throws IOException {
    super.flushBuffer();

    if (passThrough) {
      return;
    }

    if (writer != null) {
      writer.flush();
    }
    else if (output != null) {
      output.flush();
    }
  }

  /**
   * Close the response body. This closes any created writer or output stream.
   * @throws IOException When an I/O error occurs.
   */
  public void close() throws IOException {
    if (writer != null) {
      writer.close();
    }
    else if (output != null) {
      output.close();
    }
  }

  @Override
  public void reset() {
    super.reset();

    if (buffer != null) {
      buffer.reset();
    }
  }

  // Getters/setters ------------------------------------------------------------------------------------------------

  /**
   * Returns whether the response is committed or not. The response is also considered committed when the resettable
   * buffer has been flushed.
   * @return <code>true</code> if the response is committed, otherwise <code>false</code>.
   */
  @Override
  public boolean isCommitted() {
    return super.isCommitted() || (buffer != null && !buffer.isResettable());
  }

  /**
   * Returns whether the writing has to be passed through to the wrapped {@link ServletOutputStream}.
   * @return <code>true</code>, if the writing has to be passed through to the wrapped {@link ServletOutputStream},
   * otherwise <code>false</code>.
   */
  public boolean isPassThrough() {
    return passThrough;
  }

  /**
   * Sets whether the writing has to be passed through to the wrapped {@link ServletOutputStream}.
   * @param passThrough set to <code>true</code> if the writing has to be passed through to the wrapped
   * {@link ServletOutputStream}.
   */
  public void setPassThrough(boolean passThrough) {
    this.passThrough = passThrough;
  }

}
TOP

Related Classes of org.omnifaces.servlet.HttpServletResponseOutputWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.