package model;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import requests.AddFileToExperiment;
import requests.DownloadFileRequest;
import requests.RequestFactory;
import responses.AddFileToExperimentResponse;
import responses.ResponseParser;
import util.Constants;
import util.RequestException;
import communication.Connection;
import communication.ConnectionFactory;
import communication.DownloadHandler;
import communication.HTTPURLUpload;
public class UpdaterModel {
private CopyOnWriteArrayList<DownloadHandler> ongoingDownloads;
private CopyOnWriteArrayList<HTTPURLUpload> ongoingUploads;
private TickingThread ticker;
public UpdaterModel() {
this.ongoingDownloads = new CopyOnWriteArrayList<>();
this.ongoingUploads = new CopyOnWriteArrayList<>();
this.ticker = new TickingThread();
}
public void uploadFile(String expName, File f, String type,
boolean isPrivate, String release) throws RequestException,
IllegalArgumentException, IOException {
// TODO: Trace comments. also "metameta"
// System.out.println("ska uploada fil: " + f.getName());
String username = User.getInstance().getName();
AddFileToExperiment request = RequestFactory.makeAddFile(expName,
f.getName(), type, "metameta", username, username, isPrivate,
release);
Connection conn = SessionHandler.getInstance().makeConnection();
conn.sendRequest(request, User.getInstance().getToken(), Constants.JSON);
AddFileToExperimentResponse aFTER = ResponseParser
.parseUploadResponse(conn.getResponseBody());
HTTPURLUpload upload = new HTTPURLUpload(aFTER.URLupload,
f.getAbsolutePath(), f.getName());
ongoingUploads.add(upload);
upload.sendFile(User.getInstance().getToken());
}
public void addUpload(HTTPURLUpload upload) {
ongoingUploads.add(upload);
}
public void addDownload(DownloadHandler handler) {
ongoingDownloads.add(handler);
}
public CopyOnWriteArrayList<DownloadHandler> getOngoingDownloads() {
return ongoingDownloads;
}
public CopyOnWriteArrayList<HTTPURLUpload> getOngoingUploads() {
return ongoingUploads;
}
public void downloadFile(final String url, String fileID,
final String path, String fileName) throws RequestException {
// TODO: Use this until search works on the server
DownloadFileRequest request = RequestFactory.makeDownloadFileRequest(
fileID);
Connection conn = SessionHandler.getInstance().makeConnection();
conn.sendRequest(request, User.getInstance().getToken(),
Constants.TEXT_PLAIN);
final DownloadHandler handler = new DownloadHandler(User.getInstance()
.getToken(), fileName);
addDownload(handler);
new Thread(new Runnable() {
@Override
public void run() {
handler.download(url, path);
}
}).start();
}
/**
* Setup new lists with downloads and uploads, and also clear the ticking
* thread of things to do.
*/
public void resetUpdaterModel() {
ongoingDownloads = new CopyOnWriteArrayList<>();
ongoingUploads = new CopyOnWriteArrayList<>();
clearTickingThread();
}
/**
* Completely stop and clear the ticking thread.
*/
public void clearTickingThread() {
ticker.clearTasks();
ticker.stopTicking();
}
/**
* Add a new ticking task
*
* @param task
*/
public void addTickingTask(Runnable task) {
ticker.addTask(task);
ticker.startTicking();
}
private class TickingThread {
private final int DELAY = 100; // ms
private final Runnable tick = new Runnable() {
@Override
public void run() {
while (isTicking) {
for (Runnable task : tasks) {
task.run();
}
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
isTicking = false;
}
}
}
};
private Thread ticker;
private boolean isTicking;
private CopyOnWriteArrayList<Runnable> tasks;
/**
* Create a new unstarted ticker.
*/
public TickingThread() {
isTicking = false;
ticker = null;
tasks = new CopyOnWriteArrayList<Runnable>();
}
/**
* Start a new ticking thread. Does nothing if already running.
*/
public synchronized void startTicking() {
if (ticker != null) return;
isTicking = true;
ticker = new Thread(tick);
ticker.start();
}
/**
* Stop the ticker Thread, interrupting it and joining it to current.
*/
public synchronized void stopTicking() {
isTicking = false;
if (ticker == null) return;
ticker.interrupt();
try {
ticker.join();
} catch (InterruptedException e) {
ErrorLogger.log(e);
}
ticker = null;
}
/**
* Add a new task to be performed each tick.
*
* @param task
* to perform
*/
public void addTask(Runnable task) {
tasks.add(task);
}
/**
* Remove all tasks in the list, but keep ticking.
*/
public void clearTasks() {
tasks.clear();
}
}
}