/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.dlect.update; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author lee */ public class UpdateImpl { public static final String UPDATE_DOWNLOAD_URL = "http://uqlectures.sourceforge.net/?h=dl"; private static final int READ_SIZE = (int) 1e7; private static final Set<Listener> listeners = new HashSet<>(); public static void addListener(Listener l) { listeners.add(l); } public static void removeListener(Listener l) { listeners.remove(l); } private static void publish(Pair<String, Integer> m) { for (Listener l : listeners) { l.update(m); } } private static void setMax(int max) { for (Listener l : listeners) { l.setMax(max); } } public static File downloadUpdate() throws IOException { publish(Pair.of("Starting up", 0)); File tempFile = File.createTempFile("DLect New Update", ".jar"); InputStream nc = null; FileOutputStream fc = null; HttpURLConnection con = null; long currentPosition = 0; int lastRead; int max = 1; boolean hasContentLength = false; try { con = getToDownload(); if (con.getHeaderFieldInt("Content-Length", -1) != -1) { System.out.println("Content Length Exists"); max = con.getHeaderFieldInt("Content-Length", 0) + 1; hasContentLength = true; } else { max = 3; } setMax(max); nc = con.getInputStream(); fc = new FileOutputStream(tempFile); byte[] reads = new byte[READ_SIZE]; publish(Pair.of("Connecting & Preparing to Download", 1)); long startTime = System.currentTimeMillis(); while ((lastRead = nc.read(reads, 0, READ_SIZE)) > 0) { fc.write(reads, 0, lastRead); currentPosition += lastRead; if (currentPosition > (max / 2)) { try { Thread.sleep(5000); } catch (InterruptedException ex) { Logger.getLogger(UpdateImpl.class.getName()).log(Level.SEVERE, null, ex); } } publish(Pair.of("Downloading at " + toSpeed(currentPosition / ((double) (System.currentTimeMillis() - startTime))), hasContentLength ? (int) currentPosition : 2)); } } finally { if (con != null) { con.disconnect(); } if (nc != null) { nc.close(); } if (fc != null) { fc.close(); } publish(Pair.of("Completed", max)); } return tempFile; } protected static HttpURLConnection getToDownload() throws IOException { return getToDownload(UPDATE_DOWNLOAD_URL); } protected static HttpURLConnection getToDownload(final String downloadURL) throws IOException { HttpURLConnection con; HttpURLConnection.setFollowRedirects(true); con = (HttpURLConnection) new URL(downloadURL).openConnection(); con.connect(); debugHeaders(con); while (con.getHeaderField("Location") != null) { con = (HttpURLConnection) new URL(con.getHeaderField("Location")).openConnection(); con.setUseCaches(false); con.connect(); debugHeaders(con); } return con; } private static String toSpeed(double speed) { if (Double.isInfinite(speed) || Double.isNaN(speed)) { return "Unkown Speed"; } double bytesSec = speed * 1000; String unit = "B/s"; if (bytesSec > 1024) { unit = "KB/s"; bytesSec /= 1024; } if (bytesSec > 1024) { unit = "MB/s"; bytesSec /= 1024; } if (bytesSec > 1024) { unit = "GB/s"; bytesSec /= 1024; } return String.format("%01.2f %s", bytesSec, unit); } private static void debugHeaders(HttpURLConnection con) throws IOException { if (con == null) { return; } System.out.println("------------------------------------"); System.out.println("Responce Code: " + con.getResponseCode()); for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) { String string = entry.getKey(); List<String> list = entry.getValue(); System.out.print(string + ": "); if (list.size() < 2) { System.out.println(list.isEmpty() ? "-----------" : list.get(0)); } else { System.out.println(); for (String s : list) { System.out.println("\t\t" + s); } } } System.out.println("------------------------------------\n\n"); } public static interface Listener { public void setMax(int max); public void update(Pair<String, Integer> s); } }