/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.io; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.osgi.util.NLS; import org.xmind.ui.internal.ToolkitPlugin; public class DownloadJob extends Job { public static final int SUCCESS = IStatus.OK; public static final int FAILED = IStatus.ERROR; public static final int CANCELED = IStatus.WARNING; private String pluginId; private String sourceURL; private String targetPath; private OutputStream targetStream; public DownloadJob(String jobName, String sourceURL, String targetPath) { this(jobName, sourceURL, targetPath, ToolkitPlugin.PLUGIN_ID); } public DownloadJob(String jobName, String sourceURL, String targetPath, String pluginId) { super(jobName); Assert.isNotNull(sourceURL); Assert.isNotNull(targetPath); this.sourceURL = sourceURL; this.targetPath = targetPath; this.pluginId = pluginId; } public DownloadJob(String jobName, String sourceURL, OutputStream targetStream) { this(jobName, sourceURL, targetStream, ToolkitPlugin.PLUGIN_ID); } public DownloadJob(String jobName, String sourceURL, OutputStream targetStream, String pluginId) { super(jobName); Assert.isNotNull(sourceURL); Assert.isNotNull(targetStream); this.sourceURL = sourceURL; this.targetStream = targetStream; this.pluginId = pluginId; } public String getPluginId() { return pluginId; } public String getSourceURL() { return sourceURL; } public String getTargetPath() { return targetPath; } protected IStatus run(IProgressMonitor monitor) { monitor.beginTask(null, 100); URL url; try { url = new URL(sourceURL); } catch (MalformedURLException e) { return errorStatus(e); } monitor.subTask(NLS.bind(Messages.ConnectingSource, getSourceURL())); URLConnection connection; int length; try { connection = url.openConnection(); length = connection.getContentLength(); } catch (IOException e) { return errorStatus(e); } InputStream is; try { is = connection.getInputStream(); } catch (IOException e) { return errorStatus(e); } monitor.subTask(NLS.bind(Messages.InitializingTarget, getTargetPath())); OutputStream os; if (targetStream != null) { os = targetStream; } else { try { os = new FileOutputStream(targetPath); } catch (FileNotFoundException e) { safeClose(is); return errorStatus(e); } } is = new MonitoredInputStream(is, monitor); os = new MonitoredOutputStream(os, monitor); monitor.subTask(Messages.TransferingData); IProgressMonitor monitor2 = length < 0 ? null : new SubProgressMonitor( monitor, 100); if (monitor2 != null) { monitor2.beginTask(null, Math.max(1, length / 1024)); } String total = length < 0 ? null : String.format("%.1fK", //$NON-NLS-1$ length / 1024.0d); byte[] buffer = new byte[1024]; int downloaded = 0; int num; int worked = 0; try { while ((num = is.read(buffer)) > 0) { os.write(buffer, 0, num); downloaded += num; String taskName = (total == null ? String.format("(%.1fK)", //$NON-NLS-1$ (downloaded / 1024.0)) : String.format("(%.1fK/%s)", //$NON-NLS-1$ (downloaded / 1024.0), total)); monitor.subTask(Messages.TransferingData + " " + taskName); //$NON-NLS-1$ if (monitor2 != null) { monitor2.worked(1); } else { if (worked < 99) { worked++; monitor.worked(1); } } } } catch (IOException e) { if (e instanceof InterruptedIOException) { return new Status(IStatus.WARNING, pluginId, CANCELED, NLS .bind(Messages.DownloadCanceled, getSourceURL(), getTargetPath()), null); } else { return errorStatus(e); } } finally { safeClose(is); safeClose(os); } monitor.done(); return new Status(IStatus.OK, pluginId, SUCCESS, NLS.bind( Messages.DownloadFinished, getSourceURL(), getTargetPath()), null); } private static void safeClose(InputStream is) { try { is.close(); } catch (IOException ignore) { } } private static void safeClose(OutputStream os) { try { os.close(); } catch (IOException ignore) { } } private IStatus errorStatus(Throwable e) { return new Status(IStatus.ERROR, pluginId, FAILED, NLS.bind( Messages.DownloadFailed, getSourceURL(), getTargetPath()), e); } }