package kubach.workers; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import javax.swing.SwingWorker; import kubach.ConfigManager; import kubach.Constants; import kubach.gui.MainFrame; import kubach.workers.DownloadFileSyncWorker.SyncTaskState; /** * Worker for file downloading * * @author Cr0s */ public class DownloadFileSyncWorker extends SwingWorker<Void, SyncTaskState> { private MainFrame nbf; private String path, pathToFile; private int totalProgressValue; private int tableRowIndex; private int numTries = 5; public DownloadFileSyncWorker(MainFrame nbf, String pathToFile, String path, int tableRowIndex) { this.nbf = nbf; this.pathToFile = pathToFile; this.path = path; this.tableRowIndex = tableRowIndex; } @Override protected Void doInBackground() { final int BUFFER_SIZE = 2048; BufferedInputStream bis = null; ByteArrayOutputStream baos; String prefix = ConfigManager.getInstance().getClientPrefix(); String addr = ConfigManager.getInstance().getProperties().getProperty("updateurl"); addr = addr.replace("%PREFIX%", prefix); addr = addr.replace("%FILE%", this.path); try { URL url = new URL(addr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("User-Agent", "User-Agent: Kubach v" + Constants.VERSION); this.totalProgressValue = connection.getContentLength(); int totalDataRead = 0; bis = new BufferedInputStream(connection.getInputStream()); baos = new ByteArrayOutputStream(); try (BufferedOutputStream bos = new BufferedOutputStream(baos, BUFFER_SIZE)) { byte[] data = new byte[BUFFER_SIZE]; int i = 0; while ((i = bis.read(data)) != -1) { totalDataRead = totalDataRead + i; baos.write(data, 0, i); publish(new SyncTaskState(addr, "Downloading (" + String.format("%.2f", totalDataRead / (float) this.totalProgressValue * 100) + "%)", totalDataRead)); } // Write file to disk File f = new File(this.pathToFile); writeBytesToFile(f, baos.toByteArray()); publish(new SyncTaskState(addr, "Finished", this.totalProgressValue, f)); } } catch (IOException ex) { ex.printStackTrace(); if (--numTries > 0) { publish(new SyncTaskState(addr, "Retrying...", 0)); this.doInBackground(); } else { publish(new SyncTaskState(addr, "FAILED", 0)); } } finally { try { bis.close(); } catch (IOException ex) { ex.printStackTrace(); if (--numTries > 0) { publish(new SyncTaskState(addr, "Retrying...", 0)); this.doInBackground(); } else { publish(new SyncTaskState(addr, "FAILED", 0)); } } } return null; } @Override protected void process(List<SyncTaskState> chunks) { for (SyncTaskState sts : chunks) { nbf.setSyncTableRow(this.tableRowIndex, sts.status, sts.progressValue, this.totalProgressValue, sts.file); } } /** * Writes the specified byte[] to the specified File. * * @param theFile File Object representing the path to write to. * @param bytes The byte[] of data to write to the File. * @throws IOException Thrown if there is problem creating or writing the * File. */ public static void writeBytesToFile(File theFile, byte[] bytes) throws IOException { BufferedOutputStream bos = null; try { FileOutputStream fos = new FileOutputStream(theFile); bos = new BufferedOutputStream(fos); bos.write(bytes); } finally { if (bos != null) { try { //flush and close the BufferedOutputStream bos.flush(); bos.close(); } catch (Exception e) { } } } } public class SyncTaskState { public String path; public String status; public int progressValue; public File file; public SyncTaskState(String path, String status, int progressValue, File file) { this.path = path; this.status = status; this.progressValue = progressValue; this.file = file; } public SyncTaskState(String path, String status, int progressValue) { this(path, status, progressValue, null); } } }