package transfer.download;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import transfer.AbstractTransferManager;
import ui.misc.MessageBox;
import main.settings.Settings;
import common.files.NamedFile;
import common.files.SerializableFile;
import common.info.FileSource;
import common.util.NonNullObjectInputStream;
import connection.server.ConnectionStateAdapter;
import connection.server.ServerConnection;
import static main.ClientMain.*;
public class DownloadManager extends AbstractTransferManager
{
private ConcurrentHashMap<SerializableFile, DownloadRequest> requests;
private ConcurrentHashMap<SerializableFile, FileDownload> downloads;
private ConnectionManager connectionManager;
public DownloadManager()
{
tryToLoadDownloadStatus();
connectionManager = new ConnectionManager();
}
private class ConnectionManager extends ConnectionStateAdapter
{
public void onConnected(ServerConnection newConnection)
{
for (DownloadRequest request : requests.values())
{
request.query(newConnection);
}
for (FileDownload download : downloads.values())
{
download.query(newConnection);
}
}
}
@SuppressWarnings("unchecked")
private void tryToLoadDownloadStatus()
{
try
{
FileInputStream is = new FileInputStream(new File(
Settings.application.files.downloads));
NonNullObjectInputStream ois = new NonNullObjectInputStream(is);
requests = (ConcurrentHashMap<SerializableFile, DownloadRequest>) ois
.readObject();
downloads = (ConcurrentHashMap<SerializableFile, FileDownload>) ois
.readObject();
}
catch (Exception e)
{
requests = new ConcurrentHashMap<SerializableFile, DownloadRequest>();
downloads = new ConcurrentHashMap<SerializableFile, FileDownload>();
return;
}
getTableModel().putData(requests.values(), downloads.values());
}
public void terminateAllDownloads()
{
for (FileDownload download : downloads.values())
{
download.interrupt();
}
}
public synchronized boolean saveDownloadStatus()
{
try
{
FileOutputStream fos = new FileOutputStream(new File(
Settings.application.files.downloads));
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(requests);
os.writeObject(downloads);
os.flush();
}
catch (IOException e)
{
return false;
}
return true;
}
public void addDownload(NamedFile file)
{
if (requests.containsKey(file) || downloads.containsKey(file))
{
return;
}
if (!checkExistingFile(file))
{
return;
}
DownloadRequest request = new DownloadRequest(file);
if (requests.putIfAbsent(file, request) != null)
{
return;
}
getTableModel().add(request);
getGuiManager().flashTransfersTab();
request.query(connectionManager.getConnection());
}
private boolean checkExistingFile(NamedFile file)
{
if (!getSharedFilesTable().hasFile(file))
{
return true;
}
Collection<String> existingNames = getSharedFilesTable().getNamesFor(file);
String message = "You asked to download the file:\n\n\t"
+ file.getName()
+ "\n\nbut you seem to already have that file saved as the following shared file(s):\n\n";
for (String name : existingNames)
{
message += "\t" + name + "\n";
}
message += "\nDo you want to download it anyway?";
return MessageBox.yesNoConfirm(message, "File already indexed");
}
public void startRequest(SerializableFile file, long chunkLength)
{
DownloadRequest request = requests.get(file);
if (request == null)
{
return;
}
getTableModel().remove(request);
FileDownload download = new FileDownload(request.getFile(), chunkLength);
if (downloads.putIfAbsent(file, download) == null)
{
getTableModel().add(download);
}
requests.remove(file);
updateDownload(download);
}
public void updateDownload(FileDownload download)
{
ServerConnection serverConnection;
try
{
serverConnection = connectionManager.getConnection();
}
catch (IllegalStateException e)
{
return;
}
download.query(serverConnection);
}
public void notifyInvalidFile(SerializableFile returnedFile)
{
DownloadRequest request = requests.get(returnedFile);
if (request != null)
{
request.notifyQueryFailed();
return;
}
FileDownload download = downloads.get(returnedFile);
if (download != null)
{
download.notifyNoSources();
}
}
public void updateSources(SerializableFile file, Collection<FileSource> sources)
{
FileDownload download = downloads.get(file);
if (download != null)
{
download.contactSources(sources);
}
}
}