import java.io.*; import java.net.*; import java.text.DecimalFormat; import java.text.NumberFormat; import javax.swing.JOptionPane; // Referenced classes of package inteplan.viewer3D: // NetUtils, ProgressWindow public class DownloadManager { static class DefaultProgressWindow implements Progress { public void downloadBegin() { progress = new ProgressWindow(); progress.setNumLabels(2); progress.show(); progress.setTitle("Download Progress"); } public void downloadProgress(int numBytesReceived, int numBytesTotal, int whichAttempt, int totalNumAttempts, String pFile) { int percent = (int)(((double)numBytesReceived / (double)numBytesTotal) * 100D); progress.setLabelText(0, "File = " + pFile); progress.setLabelText(1, DownloadManager.format(numBytesReceived) + " of " + DownloadManager.format(numBytesTotal) + " (" + percent + "%)"); progress.setProgress(percent); } public void downloadEnd(boolean success) { progress.hide(); } public boolean mStopped() { return progress.aStopped; } private ProgressWindow progress; DefaultProgressWindow() { } } public static interface Progress { public abstract void downloadBegin(); public abstract void downloadEnd(boolean flag); public abstract void downloadProgress(int i, int j, int k, int l, String s); public abstract boolean mStopped(); } public DownloadManager() { numAttempts = 4; timeout = 0xf4240; } public void setNumAttempts(int num) { numAttempts = num; } public int getNumAttempts() { return numAttempts; } public void setTimeout(int millis) { timeout = millis; } public int getTimeout() { return timeout; } public boolean download(URL url, File destDir, Progress progress) { if(!url.getProtocol().equals("http")) return false; String filename = namedFile(url); if(filename == null) return false; File destFile = new File(destDir, filename); if(alreadyDone(url, destFile)) return true; byte buf[] = new byte[32768]; if(progress != null) progress.downloadBegin(); boolean success = false; int i = 0; do { if(i >= numAttempts) break; if(tryDownload(url, destFile, progress, buf, i + 1)) { success = true; break; } if(progress != null && progress.mStopped()) return false; i++; } while(true); if(progress != null) progress.downloadEnd(success); return success; } public static Progress getDefaultProgressWindow() { return new DefaultProgressWindow(); } private boolean alreadyDone(URL url, File destFile) { try { boolean done = false; if(destFile.exists()) { HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.connect(); if(destFile.length() == (long)conn.getContentLength()) done = true; conn.disconnect(); } return done; } catch(IOException e) { return false; } } private boolean tryDownload(URL url, File destFile, Progress progress, byte buf[], int attemptNum) { try { HttpURLConnection conn = (HttpURLConnection)url.openConnection(); boolean append = false; int readSoFar = 0; if(destFile.exists()) { long len = destFile.length(); conn.addRequestProperty("Range", "bytes=" + len + "-"); readSoFar = (int)len; append = true; } conn.connect(); NetUtils.setSocketTimeout(conn, timeout); InputStream in = conn.getInputStream(); int len = conn.getContentLength(); OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile, append)); int numRead = 0; try { do { if(len <= 0 || progress.mStopped()) break; numRead = in.read(buf, 0, buf.length); if(numRead > 0) { out.write(buf, 0, numRead); readSoFar += numRead; len -= numRead; if(progress != null) progress.downloadProgress(readSoFar, readSoFar + len, attemptNum, numAttempts, destFile.toString()); } } while(true); } catch(SocketTimeoutException e) { JOptionPane.showConfirmDialog(null, "SocketTimeoutException" + endl, "Confirm Retry", 0, 2, null); } in.close(); conn.disconnect(); out.flush(); out.close(); return len == 0; } catch(IOException e) { return false; } } private static String namedFile(URL url) { String file = url.getFile(); int lastIdx = file.lastIndexOf('/'); if(lastIdx < 0 || lastIdx == file.length() - 1) return null; else return file.substring(lastIdx + 1); } private static String format(int n) { StringBuffer buf = new StringBuffer(); if(n < 0x100000) buf.append(n / 1024).append("K"); else buf.append(dot1Fmt.format((float)n / 1048576F)).append("M"); return buf.toString(); } private static String fileSep = System.getProperty("file.separator"); private static final String endl = System.getProperty("line.separator"); private int numAttempts; private int timeout; private static final int K = 1024; private static final int M = 0x100000; private static final NumberFormat dot1Fmt = new DecimalFormat("######.0"); }