package transfer;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import chat.connection.PrivateChatRequest;
import common.files.NamedFile;
import connection.peer.GenericPeerConnection;
public abstract class AbstractFileTransfer
{
private static final int CHUNK_LENGTH = 0x400;
public static abstract class AbstractStatus
{
private String name;
protected AbstractStatus(String name)
{
this.name = name;
}
public String toString()
{
return name;
}
}
protected NamedFile file;
protected volatile long completedSize;
private GenericPeerConnection connection = null;
private AbstractStatus status = null;
private boolean finished;
private LinkedList<TransferListenerInterface> listeners = new LinkedList<TransferListenerInterface>();
protected AbstractFileTransfer()
{
}
protected AbstractFileTransfer(NamedFile file)
{
this.file = file;
completedSize = 0;
finished = false;
}
protected AbstractFileTransfer(NamedFile file, long offset)
{
this.file = file;
completedSize = offset;
finished = false;
}
protected GenericPeerConnection getConnection()
{
return connection;
}
protected void setConnection(GenericPeerConnection connection)
{
this.connection = connection;
}
public NamedFile getFile()
{
return file;
}
public long getCompletedSize()
{
return completedSize;
}
public void setCompletedSize(long value)
{
this.completedSize = value;
}
public AbstractStatus getStatus()
{
return status;
}
protected void transitTo(AbstractStatus value)
{
this.status = value;
}
protected final void setFinished()
{
connection.terminate();
connection = null;
finished = true;
}
public final boolean isFinished()
{
return finished;
}
public void forkToChat()
{
if (connection != null)
{
new PrivateChatRequest(connection);
}
}
public void addListener(TransferListenerInterface listener)
{
listeners.add(listener);
}
private void notifyListenersOfProgress(long completed)
{
for (TransferListenerInterface listener : listeners)
{
listener.onProgress();
}
}
private void notifyListenersOfCompletion()
{
for (TransferListenerInterface listener : listeners)
{
listener.onComplete();
}
}
public void transfer(InputStream source, OutputStream destination) throws IOException
{
byte[] buffer = new byte[CHUNK_LENGTH];
while (completedSize < file.getLength())
{
completedSize += transferChunk(buffer, source, destination);
notifyListenersOfProgress(completedSize);
}
notifyListenersOfCompletion();
}
private int transferChunk(byte[] buffer, InputStream source, OutputStream destination)
throws IOException
{
int read = source.read(buffer, 0, CHUNK_LENGTH);
if (read == -1)
{
throw new IOException();
}
destination.write(buffer, 0, read);
destination.flush();
return read;
}
protected void doReadObject(ObjectInputStream in) throws IOException,
ClassNotFoundException
{
file = (NamedFile) in.readObject();
completedSize = in.readLong();
finished = in.readBoolean();
}
protected void doWriteObject(ObjectOutputStream out) throws IOException
{
out.writeObject(file);
out.writeLong(completedSize);
out.writeBoolean(finished);
}
}