package communication;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import util.RequestException;
import model.ErrorLogger;
// TODO: Borde denna klass vara en runnable?
/**
* Class for handling file downloads.
*
* Created by Christoffer on 2014-04-30.
*/
public class DownloadHandler {
private HttpsURLConnection conn;
private String userID;
private String fileName;
private boolean finished;
private int totalDownload;
private int perSecond;
// TODO: userID = anv�ndarnamn? varf�r beh�vs den h�r?
/**
* Constructs a new DownloadHandler object with a given user ID and
* filename.
*
* @param userID
* the user id
* @param fileName
* the filename
*/
public DownloadHandler(String userID, String fileName) {
this.userID = userID;
this.fileName = fileName;
}
// TODO: returv�rdet anv�nds aldrig.
/**
* Downloads a file from a given URL, to a given local file path
*
* @param url
* the URL
* @param localFilePath
* the local file path
* @return true if successful, false if URL is bad or IO error occurs
* @throws RequestException
*/
public boolean download(String url, String localFilePath) {
try {
// TODO: JSON encoded '=' may need to be escaped (OO)
url = url.replaceFirst("\\u003d", "=");
URL targetUrl = new URL(url);
conn = (HttpsURLConnection) targetUrl.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "text/plain");
conn.setRequestProperty("Authorization", userID);
int responseCode = conn.getResponseCode();
if (responseCode != 200) {
return false;
}
File file = new File(localFilePath);
if (file.isFile()) {
fileName = file.getName();
}
totalDownload = 0;
// TODO Ta bort if-sats efter testning
/* If not "binary file", treat as text file and copy to local file */
// if (isBinaryFile()) {
downloadBinaryFile(file);
// downloadTextFile(file);
// }
finished = true;
conn.disconnect();
} catch (MalformedURLException e) {
ErrorLogger.log(e);
return false;
} catch (IOException e) {
System.err.println(e.getMessage());
ErrorLogger.log(e);
return false;
}
return true;
}
// TODO Ta bort skiten, men testa med alla olika filer innan.
// private void downloadTextFile(File file) throws IOException {
// int previousDownload = 0;
// Long previousTime = System.currentTimeMillis();
// InputStream in = conn.getInputStream();
// String buffer;
// BufferedReader reader = new BufferedReader(
// new InputStreamReader(in));
// BufferedWriter writer = new BufferedWriter(new FileWriter(file));
// while ((buffer = reader.readLine()) != null && !isFinished()) {
// writer.write(buffer);
// totalDownload += buffer.length();
// writer.newLine();
// totalDownload += System.getProperty("line.separator")
// .length();
// if (System.currentTimeMillis() - previousTime > 1000) {
// previousTime = System.currentTimeMillis();
// perSecond = totalDownload - previousDownload;
// previousDownload = totalDownload;
// }
// }
// writer.close();
// reader.close();
// in.close();
// }
private void downloadBinaryFile(File file) throws IOException,
FileNotFoundException {
Long previousTime = System.currentTimeMillis();
int previousDownload = 0;
InputStream in = conn.getInputStream();
FileOutputStream fileOut = new FileOutputStream(file);
if ( conn.getContentLength() == -1 ){
throw new IOException( "Could not get content length!");
}
byte[] buff = new byte[conn.getContentLength() + 1];
int count = in.read(buff, 0, conn.getContentLength());
totalDownload += count;
fileOut.write(buff, 0, count);
while ((count = in.read(buff)) != -1 && !isFinished()) {
totalDownload += count;
if (count > 0) {
fileOut.write(buff, 0, count);
}
if (System.currentTimeMillis() - previousTime > 1000) {
previousTime = System.currentTimeMillis();
perSecond = totalDownload - previousDownload;
previousDownload = totalDownload;
}
}
fileOut.close();
in.close();
}
/**
* Returns the total size of the file
*
* @return the total size, or -1 if no file is being downloaded
*/
public int getTotalSize() {
if (conn != null) {
return conn.getContentLength();
}
return -1;
}
// TODO: Fixa namnet? borde vara private (anv�nds bara i denna klass)?
/**
* Checks if the requested file to download is "binary"
*
* @return true if filename ends with .jpg, .png, .jpeg, .gif, .tar.gz, or
* .tar.xz, false otherwise.
*/
public boolean isBinaryFile() {
return fileName.endsWith(".jpg") || fileName.endsWith(".png")
|| fileName.endsWith(".jpeg") || fileName.endsWith(".gif")
|| fileName.endsWith(".tar.gz") || fileName.endsWith(".tar.xz");
}
/**
* Return the download progress
*
* @return the download progress
*/
public int getCurrentProgress() {
return totalDownload;
}
/**
* Returns the download speed in bytes per second?
*
* @return the download speed in bytes per second
*/
public int getCurrentSpeed() {
return perSecond;
}
/**
* Returns the filename of the file being downloaded
*
* @return the filename
*/
public String getFileName() {
return fileName;
}
/**
* Checks if the handler is finished downloading
*
* @return true if finished, otherwise false
*/
public boolean isFinished() {
return finished;
}
/**
* Sets the download finished status
*
* @param isFinished
*/
public void setFinished(boolean isFinished) {
finished = isFinished;
}
}