/*
 * ******************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * ******************************************************************************
 */
package com.ibm.icu.dev.tool.tzu;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

/**
 * A class that represents an updatable ICU4J jar file. A file is an updatable
 * ICU4J jar file if it
 * <ul>
 * <li>exists</li>
 * <li>is a file (ie. not a directory)</li>
 * <li>does not end with .ear or .war (these file types are unsupported)</li>
 * <li>ends with .jar</li>
 * <li>is updatable according the <code>isUpdatable</code></li>
 * <li>is not signed.</li>
 * </ul>
 */
public class ICUFile {
    /**
     * ICU version to use if one cannot be found.
     */
    public static final String ICU_VERSION_UNKNOWN = "Unknown";

    /**
     * A directory entry that is found in every updatable ICU4J jar file.
     */
    public static final String TZ_ENTRY_DIR = "com/ibm/icu/impl";

    /**
     * Prefix of the timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME_PREFIX = "zoneinfo";

    /**
     * Extension of the timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME_EXTENSION = ".res";

    /**
     * The timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME = TZ_ENTRY_FILENAME_PREFIX
            + TZ_ENTRY_FILENAME_EXTENSION;

    /**
     * Key to use when getting the version of a timezone resource.
     */
    public static final String TZ_VERSION_KEY = "TZVersion";

    /**
     * Timezone version to use if one cannot be found.
     */
    public static final String TZ_VERSION_UNKNOWN = "Unknown";

    /**
     * The buffer size to use for copying data.
     */
    private static final int BUFFER_SIZE = 1024;

    /**
     * A map that caches links from URLs to time zone data to their downloaded
     * File counterparts.
     */
    private static final Map cacheMap = new HashMap();

    /**
     * Determines the version of a timezone resource as a standard file without
     * locking the file.
     * 
     * @param tzFile
     *            The file representing the timezone resource.
     * @param logger
     *            The current logger.
     * @return The version of the timezone resource.
     */
    public static String findFileTZVersion(File tzFile, Logger logger) {
        ICUFile rawTZFile = new ICUFile(logger);

        try {
            File temp = File.createTempFile("zoneinfo", ".res");
            temp.deleteOnExit();
            rawTZFile.copyFile(tzFile, temp);
            return findTZVersion(temp, logger);
        } catch (IOException ex) {
            logger.errorln(ex.getMessage());
            return null;
        }
    }

    /**
     * Determines the version of a timezone resource as a standard file, but
     * locks the file for the duration of the program.
     * 
     * @param tzFile
     *            The file representing the timezone resource.
     * @param logger
     *            The current logger.
     * @return The version of the timezone resource.
     */
    private static String findTZVersion(File tzFile, Logger logger) {
        try {
            String filename = tzFile.getName();
            String entryname = filename.substring(0, filename.length()
                    - ".res".length());

            URL url = new URL(tzFile.getAbsoluteFile().getParentFile().toURL()
                    .toString());
            ClassLoader loader = new URLClassLoader(new URL[] { url });

            // UResourceBundle bundle = UResourceBundle.getBundleInstance("",
            // entryname, loader);

            URL bundleURL = new URL(new File("icu4j.jar").toURL().toString());
            URLClassLoader bundleLoader = new URLClassLoader(
                    new URL[] { bundleURL });
            Class bundleClass = bundleLoader
                    .loadClass("com.ibm.icu.util.UResourceBundle");
            Method bundleGetInstance = bundleClass.getMethod(
                    "getBundleInstance", new Class[] { String.class,
                            String.class, ClassLoader.class });
            Object bundle = bundleGetInstance.invoke(null, new Object[] { "",
                    entryname, loader });

            if (bundle != null) {
                Method bundleGetString = bundleClass.getMethod("getString",
                        new Class[] { String.class });
                String tzVersion = (String) bundleGetString.invoke(bundle,
                        new Object[] { TZ_VERSION_KEY });
                if (tzVersion != null)
                    return tzVersion;
            }
        } catch (MalformedURLException ex) {
            // this should never happen
            logger.errorln("Internal program error.");
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            // this would most likely happen when UResourceBundle cannot be
            // resolved, which is when icu4j.jar is not where it should be
            logger.errorln("icu4j.jar not found");
        } catch (NoSuchMethodException ex) {
            // this can only be caused by a very unlikely scenario
            logger.errorln("icu4j.jar not correct");
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            // this can only be caused by a very unlikely scenario
            logger.errorln("icu4j.jar not correct");
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            // if this is holding a MissingResourceException, then this is not
            // an error -- some zoneinfo files are missing version numbers
            if (!(ex.getTargetException() instanceof MissingResourceException)) {
                logger.errorln("icu4j.jar not correct");
                ex.printStackTrace();
            }
        }

        return TZ_VERSION_UNKNOWN;
    }

    /**
     * Finds the jar entry in the jar file that represents a timezone resource
     * and returns it, or null if none is found.
     * 
     * @param jar
     *            The jar file to search.
     * @return The jar entry representing the timezone resource in the jar file,
     *         or null if none is found.
     */
    private static JarEntry getTZEntry(JarFile jar) {
        JarEntry tzEntry = null;
        Enumeration e = jar.entries();
        while (e.hasMoreElements()) {
            tzEntry = (JarEntry) e.nextElement();
            if (tzEntry.getName().endsWith(TZ_ENTRY_FILENAME))
                return tzEntry;
        }
        return null;
    }

    /**
     * The ICU4J jar file represented by this ICUFile.
     */
    private File icuFile;

    /**
     * The ICU version of the ICU4J jar.
     */
    private String icuVersion;

    /**
     * The current logger.
     */
    private Logger logger;

    /**
     * The entry for the timezone resource inside the ICU4J jar.
     */
    private JarEntry tzEntry;

    /**
     * The version of the timezone resource inside the ICU4J jar.
     */
    private String tzVersion;

    /**
     * Constructs an ICUFile around a file. See <code>initialize</code> for
     * details.
     * 
     * @param file
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    public ICUFile(File file, Logger logger) throws IOException {
        initialize(file, logger);
    }

    /**
     * Constructs an ICUFile around a file. See <code>initialize</code> for
     * details.
     * 
     * @param filename
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    public ICUFile(String filename, Logger logger) throws IOException {
        if (filename == null || filename.trim().length() == 0)
            throw new IOException("cannot be blank");

        initialize(new File(filename), logger);
    }

    /**
     * Constructs a blank ICUFile. Used internally for timezone resource files
     * that are not contained within a jar.
     * 
     * @param logger
     *            The current logger.
     */
    private ICUFile(Logger logger) {
        this.logger = logger;
    }

    /**
     * Compares two ICUFiles by the file they represent.
     * 
     * @param other
     *            The other ICUFile to compare to.
     * @return Whether the files represented by the two ICUFiles are equal.
     */
    public boolean equals(Object other) {
        return (!(other instanceof ICUFile)) ? false : icuFile
                .getAbsoluteFile().equals(
                        ((ICUFile) other).icuFile.getAbsoluteFile());
    }

    /**
     * Determines the version of a timezone resource in a jar file without
     * locking the jar file.
     * 
     * @return The version of the timezone resource.
     */
    public String findEntryTZVersion() {
        try {
            File temp = File.createTempFile("zoneinfo", ".res");
            temp.deleteOnExit();
            copyEntry(icuFile, tzEntry, temp);
            return findTZVersion(temp, logger);
        } catch (IOException ex) {
            logger.errorln(ex.getMessage());
            return null;
        }
    }

    /**
     * Returns the File object represented by this ICUFile object.
     * 
     * @return The File object represented by this ICUFile object.
     */
    public File getFile() {
        return icuFile;
    }

    /**
     * Returns the filename of this ICUFile object, without the path.
     * 
     * @return The filename of this ICUFile object, without the path.
     */
    public String getFilename() {
        return icuFile.getName();
    }

    /**
     * Returns the ICU version of this ICU4J jar.
     * 
     * @return The ICU version of this ICU4J jar.
     */
    public String getICUVersion() {
        return icuVersion;
    }

    /**
     * Returns the path of this ICUFile object, without the filename.
     * 
     * @return The path of this ICUFile object, without the filename.
     */
    public String getPath() {
        return icuFile.getAbsoluteFile().getParent();
    }

    // public static String findURLTZVersion(File tzFile) {
    // try {
    // File temp = File.createTempFile("zoneinfo", ".res");
    // temp.deleteOnExit();
    // copyFile(tzFile, temp);
    // return findTZVersion(temp);
    // } catch (IOException ex) {
    // ex.printStackTrace();
    // return null;
    // }
    // }

    /**
     * Returns the timezone resource version.
     * 
     * @return The timezone resource version.
     */
    public String getTZVersion() {
        return tzVersion;
    }

    /**
     * Returns the result of getFile().toString().
     * 
     * @return The result of getFile().toString().
     */
    public String toString() {
        return getFile().toString();
    }

    /**
     * Updates the timezone resource in this ICUFile using
     * <code>insertURL</code> as the source of the new timezone resource and
     * the backup directory <code>backupDir</code> to store a copy of the
     * ICUFile.
     * 
     * @param insertURL
     *            The url location of the timezone resource to use.
     * @param backupDir
     *            The directory to store a backup for this ICUFile, or null if
     *            no backup.
     * @throws IOException
     * @throws InterruptedException
     */
    public void update(URL insertURL, File backupDir) throws IOException,
            InterruptedException {
        String message = "Updating " + icuFile.getPath() + " ...";
        logger.printlnToBoth("");
        logger.printlnToBoth(message);
        logger.setStatus(message);

        if (!icuFile.canRead() || !icuFile.canWrite())
            throw new IOException("Missing permissions for "
                    + icuFile.getPath());
        if ((insertURL = getCachedURL(insertURL)) == null)
            throw new IOException(
                    "Could not download the Time Zone data, skipping update for this jar.");
        File backupFile = null;
        if ((backupFile = createBackupFile(icuFile, backupDir)) == null)
            throw new IOException(
                    "Could not create an empty backup file (the original jar file remains unchanged).");
        if (!copyFile(icuFile, backupFile))
            throw new IOException(
                    "Could not copy the original jar file to the backup location (the original jar file remains unchanged).");
        logger.printlnToBoth("Backup location: " + backupFile.getPath());
        if (!createUpdatedJar(backupFile, icuFile, tzEntry, insertURL))
            throw new IOException(
                    "Could not create an updated jar file at the original location (the original jar file is at the backup location).");

        // get the new timezone resource version
        tzVersion = findEntryTZVersion();

        message = "Successfully updated " + icuFile.getPath();
        logger.printlnToBoth(message);
        logger.setStatus(message);
    }

    /**
     * Copies the jar entry <code>insertEntry</code> in <code>inputFile</code>
     * to <code>outputFile</code>.
     * 
     * @param inputFile
     *            The jar file containing <code>insertEntry</code>.
     * @param inputEntry
     *            The entry to copy.
     * @param outputFile
     *            The output file.
     * @return Whether the operation was successful.
     */
    private boolean copyEntry(File inputFile, JarEntry inputEntry,
            File outputFile) {
        logger.loglnToBoth("Copying from " + inputFile + "!/" + inputEntry
                + " to " + outputFile + ".");
        JarFile jar = null;
        InputStream istream = null;
        OutputStream ostream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            jar = new JarFile(inputFile);
            istream = jar.getInputStream(inputEntry);
            ostream = new FileOutputStream(outputFile);

            while ((bytesRead = istream.read(buffer)) != -1)
                ostream.write(buffer, 0, bytesRead);

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                }
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Copies <code>inputFile</code> to <code>outputFile</code>.
     * 
     * @param inputFile
     *            The input file.
     * @param outputFile
     *            The output file.
     * @return Whether the operation was successful.
     */
    private boolean copyFile(File inputFile, File outputFile) {
        logger.loglnToBoth("Copying from " + inputFile + " to " + outputFile
                + ".");
        InputStream istream = null;
        OutputStream ostream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            istream = new FileInputStream(inputFile);
            ostream = new FileOutputStream(outputFile);

            while ((bytesRead = istream.read(buffer)) != -1)
                ostream.write(buffer, 0, bytesRead);

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Creates a temporary file for the jar file <code>inputFile</code> under
     * the directory <code>backupBase</code> and returns it, or returns null
     * if a temporary file could not be created. Does not put any data in the
     * newly created file yet.
     * 
     * @param inputFile
     *            The file to backup.
     * @param backupBase
     *            The directory where backups are to be stored.
     * @return The temporary file that was created.
     */
    private File createBackupFile(File inputFile, File backupBase) {
        logger.loglnToBoth("Creating backup file for " + inputFile + " at "
                + backupBase + ".");
        String filename = inputFile.getName();
        String suffix = ".jar";
        String prefix = filename.substring(0, filename.length()
                - suffix.length());

        if (backupBase == null) {
            try {
                // no backup directory means we need to create a temporary file
                // that will be deleted on exit
                File backupFile = File.createTempFile(prefix + "~", suffix);
                backupFile.deleteOnExit();
                return backupFile;
            } catch (IOException ex) {
                return null;
            }
        }

        File backupFile = null;
        File backupDesc = null;
        File backupDir = new File(backupBase.getPath(), prefix);
        PrintStream ostream = null;

        try {
            backupBase.mkdir();
            backupDir.mkdir();
            backupFile = File.createTempFile(prefix + "~", suffix, backupDir);
            backupDesc = new File(backupDir.getPath(), backupFile.getName()
                    .substring(0,
                            backupFile.getName().length() - suffix.length())
                    + ".txt");
            backupDesc.createNewFile();
            ostream = new PrintStream(new FileOutputStream(backupDesc));
            ostream.println(inputFile.getPath());
            logger.loglnToBoth("Successfully created backup file at "
                    + backupFile + ".");
        } catch (IOException ex) {
            logger.loglnToBoth("Failed to create backup file.");
            if (backupFile != null)
                backupFile.delete();
            if (backupDesc != null)
                backupDesc.delete();
            backupDir.delete();
            backupFile = null;
        } finally {
            if (ostream != null)
                ostream.close();
        }

        return backupFile;
    }

    /**
     * Copies <code>inputFile</code> to <code>outputFile</code>, replacing
     * <code>insertEntry</code> with <code>inputURL</code>.
     * 
     * @param inputFile
     *            The input jar file.
     * @param outputFile
     *            The output jar file.
     * @param insertEntry
     *            The entry to be replaced.
     * @param inputURL
     *            The URL to use in replacing the entry.
     * @return Whether the operation was successful.
     */
    private boolean createUpdatedJar(File inputFile, File outputFile,
            JarEntry insertEntry, URL inputURL) {
        logger.loglnToBoth("Copying " + inputFile + " to " + outputFile
                + ", replacing " + insertEntry + " with " + inputURL + ".");
        JarFile jar = null;
        JarOutputStream ostream = null;
        InputStream istream = null;
        InputStream jstream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            jar = new JarFile(inputFile);
            ostream = new JarOutputStream(new FileOutputStream(outputFile));
            URLConnection con = inputURL.openConnection();
            con.setRequestProperty("user-agent", System.getProperty("http.agent"));
            istream = con.getInputStream();

            Enumeration e = jar.entries();
            while (e.hasMoreElements()) {
                JarEntry currentEntry = (JarEntry) e.nextElement();

                if (!currentEntry.getName().equals(insertEntry.getName())) {
                    // if the current entry isn't the one that needs updating
                    // write a copy of the old entry from the old file
                    ostream.putNextEntry(new JarEntry(currentEntry.getName()));

                    jstream = jar.getInputStream(currentEntry);
                    while ((bytesRead = jstream.read(buffer)) != -1)
                        ostream.write(buffer, 0, bytesRead);
                    jstream.close();
                } else {
                    // if the current entry *is* the one that needs updating
                    // write a new entry based on the input stream (from the
                    // URL)
                    // currentEntry.setTime(System.currentTimeMillis());
                    ostream.putNextEntry(new JarEntry(currentEntry.getName()));

                    while ((bytesRead = istream.read(buffer)) != -1)
                        ostream.write(buffer, 0, bytesRead);
                }
            }

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
            if (jstream != null)
                try {
                    jstream.close();
                } catch (IOException ex) {
                }
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Performs the shared work of the constructors. Throws an IOException if
     * <code>file</code>...
     * <ul>
     * <li>does not exist</li>
     * <li>is not a file</li>
     * <li>ends with .ear or .war (these file types are unsupported)</li>
     * <li>does not end with .jar</li>
     * <li>is not updatable according the <code>isUpdatable</code></li>
     * <li>is signed.</li>
     * </ul>
     * If an exception is not thrown, the ICUFile is fully initialized.
     * 
     * @param file
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    private void initialize(File file, Logger log) throws IOException {
        this.icuFile = file;
        this.logger = log;
        String message = null;

        if (!file.exists()) {
            message = "Skipped " + file.getPath() + " (does not exist).";
        } else if (!file.isFile()) {
            message = "Skipped " + file.getPath() + " (not a file).";
        } else if (file.getName().endsWith(".ear")
                || file.getName().endsWith(".war")) {
            message = "Skipped " + file.getPath()
                    + " (this tool does not support .ear and .war files).";
            logger.loglnToBoth(message);
        } else if (!file.canRead() || !file.canWrite()) {
            message = "Skipped " + file.getPath() + " (missing permissions).";
        } else if (!file.getName().endsWith(".jar")) {
            message = "Skipped " + file.getPath() + " (not a jar file).";
        } else if (!isUpdatable()) {
            message = "Skipped " + file.getPath()
                    + " (not an updatable ICU4J jar).";
        } else if (isSigned()) {
            message = "Skipped " + file.getPath()
                    + " (cannot update signed jars).";
            logger.loglnToBoth(message);
        } else if (isEclipseFragment()) {
            message = "Skipped " + file.getPath()
                    + " (eclipse fragments must be updated through ICU).";
            logger.loglnToBoth(message);
        }

        if (message != null)
            throw new IOException(message);

        tzVersion = findEntryTZVersion();
    }

    /**
     * Determines whether the current jar is an Eclipse Data Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseDataFragment() {
        return (icuFile.getPath().indexOf(
                "plugins" + File.separator + "com.ibm.icu.data.update") >= 0 && icuFile
                .getName().equalsIgnoreCase("icu-data.jar"));
    }

    /**
     * Determines whether the current jar is an Eclipse Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseFragment() {
        return (isEclipseDataFragment() || isEclipseMainFragment());
    }

    /**
     * Determines whether the current jar is an Eclipse Main Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseMainFragment() {
        return (icuFile.getPath().indexOf("plugins") >= 0 && icuFile.getName()
                .startsWith("com.ibm.icu_"));
    }

    /**
     * Determines whether a timezone resource in a jar file is signed.
     * 
     * @return Whether a timezone resource in a jar file is signed.
     */
    private boolean isSigned() {
        return tzEntry.getCertificates() != null;
    }

    /**
     * Gathers information on the jar file represented by this ICUFile object
     * and returns whether it is an updatable ICU4J jar file.
     * 
     * @return Whether the jar file represented by this ICUFile object is an
     *         updatable ICU4J jar file.
     */
    private boolean isUpdatable() {
        JarFile jar = null;
        boolean success = false;

        try {
            // open icuFile as a jar file
            jar = new JarFile(icuFile);

            // get its manifest to determine the ICU version
            Manifest manifest = jar.getManifest();
            icuVersion = ICU_VERSION_UNKNOWN;
            if (manifest != null) {
                Iterator iter = manifest.getEntries().values().iterator();
                while (iter.hasNext()) {
                    Attributes attr = (Attributes) iter.next();
                    String ver = attr
                            .getValue(Attributes.Name.IMPLEMENTATION_VERSION);
                    if (ver != null) {
                        icuVersion = ver;
                        break;
                    }
                }
            }

            // if the jar's directory structure contains TZ_ENTRY_DIR and there
            // is a timezone resource in the jar, then the jar is updatable
            success = (jar.getJarEntry(TZ_ENTRY_DIR) != null)
                    && ((this.tzEntry = getTZEntry(jar)) != null);
        } catch (IOException ex) {
            // unable to create the JarFile or unable to get the Manifest
            // log the unexplained i/o error, but we must drudge on
            logger.loglnToBoth("Error reading " + icuFile.getPath() + ".");
        } finally {
            // close the jar gracefully
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                    logger.errorln("Could not properly close the jar file "
                            + icuFile + ".");
                }
        }

        // return whether the jar is updatable or not
        return success;
    }

    private URL getCachedURL(URL url) {
        File outputFile = (File) cacheMap.get(url);
        if (outputFile != null) {
            try {
                return outputFile.toURL();
            } catch (MalformedURLException ex) {
                return null;
            }
        } else {
            InputStream istream = null;
            OutputStream ostream = null;
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            boolean success = false;

            try {
                outputFile = File.createTempFile("zoneinfo", "res");
                outputFile.deleteOnExit();

                logger.loglnToBoth("Downloading from " + url + " to "
                        + outputFile.getPath() + ".");

                URLConnection con = url.openConnection();
                con.setRequestProperty("user-agent", System.getProperty("http.agent"));
                istream = con.getInputStream();
                ostream = new FileOutputStream(outputFile);

                while ((bytesRead = istream.read(buffer)) != -1)
                    ostream.write(buffer, 0, bytesRead);

                success = true;
                logger.loglnToBoth("Download successful.");
            } catch (IOException ex) {
                outputFile.delete();
                logger.loglnToBoth("Download failed.");
            } finally {
                // safely close the streams
                if (istream != null)
                    try {
                        istream.close();
                    } catch (IOException ex) {
                    }
                if (ostream != null)
                    try {
                        ostream.close();
                    } catch (IOException ex) {
                    }
            }
            try {
                return (success && outputFile != null) ? outputFile.toURL()
                        : null;
            } catch (MalformedURLException ex) {
                return null;
            }
        }
    }
}
