Package org.exoplatform.commons.utils

Source Code of org.exoplatform.commons.utils.OutputStreamPrinter

/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.exoplatform.commons.utils;

import org.gatein.common.io.UndeclaredIOException;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

/**
* <p>An extension of {@link Printer} that encodes the text with a provided encoder and sends the resulting
* bytes on an {@link java.io.OutputStream}. The instance can be configured to have different behavior
* on failure of the output stream.</p>
*
* <p>The <tt>ignoreOnFailure</tt> property will stop to make further invocations to the output stream if an exception
* is thrown by the output stream except for the {@link #close()} method.</p>
*
* <p>The <tt>failureFlow</tt> property modifies the control flow of the method invocation when the output stream throws an
* {@link java.io.IOException}.
*
* <ul>
* <li>The {@link IOFailureFlow#IGNORE} value ignores the exception.</li>
* <li>The {@link IOFailureFlow#RETHROW} value rethrows the exception.</li>
* <li>The {@link IOFailureFlow#THROW_UNDECLARED} value throws instead a
* {@link UndeclaredIOException} exception wrapping the original exception.</li>
* </ul>
*
* </p>
*
* <p>The class provides direct write access to the underlying output stream when the client of the stream can provides
* bytes directly.</p>
*
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
public class OutputStreamPrinter extends Printer implements BinaryOutput
{

   private final IOFailureFlow failureFlow;

   private final boolean ignoreOnFailure;

   private final OutputStream out;

   private final TextEncoder encoder;

   private boolean failed;

   private final boolean flushOnClose;

   /**
    * Builds an instance with the failureFlow being {@link IOFailureFlow#RETHROW} and
    * a the ignoreOnFailure property set to false.
    *
    * @param encoder the encoder
    * @param out the output
    * @param flushOnClose flush when stream is closed
    * @throws IllegalArgumentException if any argument is null
    */
   public OutputStreamPrinter(TextEncoder encoder, OutputStream out, boolean flushOnClose) throws IllegalArgumentException
   {
      this(encoder, out, IOFailureFlow.RETHROW, false, flushOnClose, 0, false);
   }

   /**
    * Builds an instance with the failureFlow being {@link IOFailureFlow#RETHROW} and
    * a the ignoreOnFailure property set to false.
    *
    * @param encoder the encoder
    * @param out the output
    * @param flushOnClose flush when stream is closed
    * @param bufferSize the size of the buffer
    * @throws IllegalArgumentException if any argument is null
    */
   public OutputStreamPrinter(TextEncoder encoder, OutputStream out, boolean flushOnClose, int bufferSize) throws IllegalArgumentException
   {
      this(encoder, out, IOFailureFlow.RETHROW, false, flushOnClose, bufferSize, false);
   }

   /**
    * Builds an instance with the failureFlow being {@link IOFailureFlow#RETHROW} and
    * a the ignoreOnFailure property set to false.
    *
    * @param encoder the encoder
    * @param out the output
    * @param flushOnClose flush when stream is closed
    * @param bufferSize the initial size of the buffer
    * @param growing if the buffer should grow in size once full
    * @throws IllegalArgumentException if any argument is null
    */
   public OutputStreamPrinter(TextEncoder encoder, OutputStream out, boolean flushOnClose, int bufferSize, boolean growing) throws IllegalArgumentException
   {
      this(encoder, out, IOFailureFlow.RETHROW, false, flushOnClose, bufferSize, growing);
   }
  
   /**
    * Builds an instance with the failureFlow being {@link IOFailureFlow#RETHROW} and
    * a the ignoreOnFailure property set to false.
    *
    * @param encoder the encoder
    * @param out the output
    * @throws IllegalArgumentException if any argument is null
    */
   public OutputStreamPrinter(TextEncoder encoder, OutputStream out) throws IllegalArgumentException
   {
      this(encoder, out, IOFailureFlow.RETHROW, false, false, 0, false);
   }

   /**
    * Builds a new instance with the specified parameters and the delegate output.
    *
    * @param encoder the encoder
    * @param out the output
    * @param failureFlow the control flow failureFlow
    * @param ignoreOnFailure the behavior on failure
    * @param flushOnClose flush when stream is closed
    * @param bufferSize the buffer size
    * @throws IllegalArgumentException if any argument is null
    */
   public OutputStreamPrinter(
          TextEncoder encoder,
          OutputStream out,
          IOFailureFlow failureFlow,
          boolean ignoreOnFailure,
          boolean flushOnClose,
          int bufferSize)
          throws IllegalArgumentException
   {
     this(encoder, out, failureFlow, ignoreOnFailure, flushOnClose, bufferSize, false);
   }
  
  
   public OutputStreamPrinter(
      TextEncoder encoder,
      OutputStream out,
      IOFailureFlow failureFlow,
      boolean ignoreOnFailure,
      boolean flushOnClose,
      int bufferSize,
      boolean growing
      )
      throws IllegalArgumentException
   {
      if (encoder == null)
      {
         throw new IllegalArgumentException("No null encoder accepted");
      }
      if (out == null)
      {
         throw new IllegalArgumentException("No null output stream accepted");
      }
      if (failureFlow == null)
      {
         throw new IllegalArgumentException("No null control flow mode accepted");
      }
      if (bufferSize < 0)
      {
         throw new IllegalArgumentException("Invalid negative max buffer size: " + bufferSize);
      }

      //
      if (bufferSize > 0 && !growing)
      {
         out = new BufferingOutputStream(out, bufferSize);
      }
      else if (growing)
      {
       out = new GrowingOutputStream(out, bufferSize);
      }

      //
      this.encoder = encoder;
      this.out = out;
      this.failureFlow = failureFlow;
      this.failed = false;
      this.ignoreOnFailure = ignoreOnFailure;
      this.flushOnClose = flushOnClose;
   }

   public final Charset getCharset()
   {
      return encoder.getCharset();
   }

   /**
    * Returns the failure flow.
    *
    * @return the failure flow
    */
   public final IOFailureFlow getFailureFlow()
   {
      return failureFlow;
   }

   /**
    * Returns the ignore on failure property.
    *
    * @return the ignore on failure property
    */
   public final boolean getIgnoreOnFailure()
   {
      return ignoreOnFailure;
   }

   public final boolean isFailed()
   {
      return failed;
   }

   // Bytes access interface

   public final void write(byte b) throws IOException
   {
      if (!failed)
      {
         try
         {
            out.write(b);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   public final void write(byte[] bytes) throws IOException
   {
      if (!failed)
      {
         try
         {
            out.write(bytes);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   public final void write(byte[] bytes, int off, int len) throws IOException
   {
      if (!failed)
      {
         try
         {
            out.write(bytes, off, len);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   //

   @Override
   // Note that the parent method has a synchronisation that we want to avoid
   // for performance reasons
   public final void write(int c) throws IOException
   {
      if (!failed)
      {
         try
         {
            encoder.encode((char)c, out);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   @Override
   public final void write(char[] cbuf) throws IOException
   {
      if (!failed)
      {
         try
         {
            encoder.encode(cbuf, 0, cbuf.length, out);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   @Override
   public final void write(String str) throws IOException
   {
      if (!failed)
      {
         try
         {
            encoder.encode(str, 0, str.length(), out);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   @Override
   // Note that the parent method has a synchronisation that we want to avoid
   // for performance reasons
   public final void write(String str, int off, int len) throws IOException
   {
      if (!failed)
      {
         try
         {
            encoder.encode(str, off, len, out);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   public final void write(char[] cbuf, int off, int len) throws IOException
   {
      if (!failed)
      {
         try
         {
            encoder.encode(cbuf, off, len, out);
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   public final void flush() throws IOException
   {
      if (!failed && !flushOnClose)
      {
         try
         {
            out.flush();
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }

   public final void close() throws IOException
   {
      try
      {
         out.close();
      }
      catch (IOException e)
      {
         handle(e);
      }
   }

   private void handle(IOException e) throws IOException
   {
      if (ignoreOnFailure)
      {
         failed = true;
      }
      switch (failureFlow)
      {
         case IGNORE :
            break;
         case THROW_UNDECLARED :
            throw new UndeclaredIOException(e);
         case RETHROW :
            throw e;
      }
   }
  
   /**
    * Flush the output stream. This allows for the outputstream
    * to be independently flushed regardless of the flushOnClose setting.
    */
   public void flushOutputStream() throws IOException
   {
      if (!failed)
      {
         try
         {
            out.flush();
         }
         catch (IOException e)
         {
            handle(e);
         }
      }
   }
}
TOP

Related Classes of org.exoplatform.commons.utils.OutputStreamPrinter

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.