package fr.jayme.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.SerializationUtils;

public class DeferedSerializableStream implements Serializable {

  private static final long serialVersionUID = 1L;

  private transient InputStream serializationInput;
  private transient ByteArrayOutputStream deserializationOutput;

  public DeferedSerializableStream(InputStream serializationInput) {
    this.serializationInput = serializationInput;
  }

  private void writeObject(java.io.ObjectOutputStream out)
    throws IOException {
    out.defaultWriteObject();
    IOUtils.copy(serializationInput, out);
  }

  private void readObject(java.io.ObjectInputStream in)
    throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    deserializationOutput = new ByteArrayOutputStream();
    IOUtils.copy(in, deserializationOutput);
  }

  public ByteArrayOutputStream getDeserializedOutputStream() {
    return deserializationOutput;
  }

  public static void main(String[] args) throws Exception {
    // Create temp file
    File tmpFile = File.createTempFile("fop", "tmp");
    OutputStream fopOut = new BufferedOutputStream(new FileOutputStream(tmpFile));
    try {
      // Work with fop here using the given output stream
      byte[] input = { 0, 1, 2, 3 };
      fopOut.write(input);
    } finally {
      fopOut.close();
    }

    InputStream in = new BufferedInputStream(new FileInputStream(tmpFile));
    DeferedSerializableStream client;
    try {
      DeferedSerializableStream server = new DeferedSerializableStream(in);
      byte[] objectData = SerializationUtils.serialize(server);
      client = (DeferedSerializableStream) SerializationUtils.deserialize(objectData);
    } finally {
      in.close();
    }

    byte[] output = client.getDeserializedOutputStream().toByteArray();
    System.out.println(Arrays.toString(output));
  }
}
