/*
 * This file is part of the Vamsas Client version 0.2. 
 * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite, 
 *  Andrew Waterhouse and Dominik Lindner.
 * 
 * Earlier versions have also been incorporated into Jalview version 2.4 
 * since 2008, and TOPALi version 2 since 2007.
 * 
 * The Vamsas Client 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 3 of the License, or
 * (at your option) any later version.
 *  
 * The Vamsas Client 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 the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.
 */
package uk.ac.vamsas.client;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author jimp
 * 
 */
public class AppDataOutputStream extends DataOutputStream {
  private Log log = LogFactory.getLog(AppDataOutputStream.class);

  private boolean isOpen = true;

  /**
   * @param out
   */
  public AppDataOutputStream(OutputStream out) {
    super(out);
    isOpen = true;
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.io.DataOutputStream#flush()
   */
  public void flush() throws IOException {
    if (isOpen)
      super.flush();
    else
      log.warn("flush() called on closed AppDataOutputStream");
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.io.DataOutputStream#write(byte[], int, int)
   */
  public synchronized void write(byte[] b, int off, int len) throws IOException {
    if (isOpen) {
      super.write(b, off, len);
    } else {
      log.debug("write(b,off,len) called on closed AppDataOutputStream");
      throw new IOException("Attempt to write to closed AppDataOutputStream");
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.io.DataOutputStream#write(int)
   */
  public synchronized void write(int b) throws IOException {
    if (isOpen) {
      super.write(b);
    } else {
      log.debug("write(b) called on closed AppDataOutputStream");
      throw new IOException("Attempt to write to closed AppDataOutputStream");
    }
  }

  /**
   * Sets an internal flag preventing further write operations to the AppData
   * output stream and flushes any pending writes.
   * 
   * @see java.io.FilterOutputStream#close()
   */
  public void close() throws IOException {
    isOpen = false;
    super.flush();
    log.debug("AppDataOutputStream was closed.");
  }

  /*
   * (non-Javadoc)
   * 
   * @see java.io.FilterOutputStream#write(byte[])
   */
  public void write(byte[] b) throws IOException {
    if (isOpen) {
      super.write(b);
    } else {
      log.debug("write(b[]) called on closed AppDataOutputStream");
      throw new IOException("Attempt to write to closed AppDataOutputStream");
    }
  }

  /**
   * @return true if stream is still Open.
   */
  public boolean isOpen() {
    return isOpen;
  }

}
