/******************************************************************************* * Copyright (c) 2012 Pivotal Software, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.springsource.ide.eclipse.commons.core; import java.io.BufferedOutputStream; 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.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.osgi.util.NLS; import org.springsource.ide.eclipse.commons.core.util.IOUtil; import org.springsource.ide.eclipse.commons.internal.core.CorePlugin; import org.springsource.ide.eclipse.commons.internal.core.net.HttpClientTransportService; import org.springsource.ide.eclipse.commons.internal.core.net.ITransportService; import org.springsource.ide.eclipse.commons.internal.core.net.P2TransportService; /** * Provides helper methods for downloading files. * @author Steffen Pingel */ public class HttpUtil { private static ITransportService transport; public static IStatus download(String url, File archiveFile, File targetDirectory, IProgressMonitor monitor) { return download(url, archiveFile, targetDirectory, null, monitor); } public static IStatus download(String url, File archiveFile, File targetDirectory, String prefix, IProgressMonitor monitor) { if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } SubMonitor progress = SubMonitor.convert(monitor, 100); targetDirectory.mkdirs(); // download archive file try { try { OutputStream out = new BufferedOutputStream(new FileOutputStream(archiveFile)); try { HttpUtil.download(new URI(url), out, progress.newChild(70)); } catch (CoreException e) { return new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, NLS.bind( "I/O error while retrieving data: {0}", e.getMessage()), e); } catch (URISyntaxException e) { return new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, NLS.bind("Invalid URL: {0}", url), e); } finally { out.close(); } } catch (IOException e) { return new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, "I/O error while retrieving data", e); } // extract archive file try { URL fileUrl = archiveFile.toURI().toURL(); ZipFileUtil.unzip(fileUrl, targetDirectory, prefix, progress.newChild(30)); if (targetDirectory.listFiles().length <= 0) { String message = NLS.bind("Zip file {0} appears to be empty", archiveFile); return new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, message); } } catch (IOException e) { return new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, "Error while extracting archive", e); } } finally { archiveFile.delete(); } return Status.OK_STATUS; } public static void download(URI uri, OutputStream out, IProgressMonitor monitor) throws CoreException { String protocol = uri.getScheme(); if ("file".equals(protocol)) { // Yes. it is a bit strange that HttpUtil knows how to read from // file url. But it is just easier that // way. Don't need to special case file urls in other places. // We should consider renaming this class but it has the potential // of breaking a lot of dependencies. File f = new File(uri); FileInputStream contents = null; try { contents = new FileInputStream(f); byte[] buf = new byte[40 * 1024]; int read; while ((read = contents.read(buf)) >= 0) { // read = -1 means EOF // read == 0 probably is impossible but handle it anyway. if (read > 0) { out.write(buf, 0, read); } } } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, CorePlugin.PLUGIN_ID, e.getMessage(), e)); } finally { try { if (contents != null) { contents.close(); } } catch (IOException e) { } } } else { getTransport().download(uri, out, monitor); } } public static long getLastModified(URI location, IProgressMonitor monitor) throws CoreException { return getTransport().getLastModified(location, monitor); } public static synchronized ITransportService getTransport() { if (transport == null) { if (Platform.isRunning()) { try { transport = new P2TransportService(); } catch (ClassNotFoundException e) { // fall back to HttpClientTransport } } if (transport == null) { transport = new HttpClientTransportService(); } } return transport; } public static InputStream stream(URI uri, IProgressMonitor monitor) throws CoreException { return getTransport().stream(uri, monitor); } public static void ping(URI uri) throws MalformedURLException, IOException, CoreException { URLConnection connection = uri.toURL().openConnection(); connection.setConnectTimeout(500); InputStream input = connection.getInputStream(); IOUtil.consume(input); } }