/******************************************************************************* * Copyright (c) 2009, 2013 Tasktop Technologies and others. * 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: * Tasktop Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.discovery.core.util; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.net.URI; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.commons.net.AbstractWebLocation; import org.eclipse.mylyn.internal.discovery.core.DiscoveryCore; /** * A utility for accessing web resources * * @author David Green */ public class WebUtil { /** * implementors are capable of processing character content * * @see WebUtil#readResource(AbstractWebLocation, TextContentProcessor, IProgressMonitor) */ public interface TextContentProcessor { public void process(Reader reader) throws IOException; } private static ITransportService transport; /** * Download an HTTP-based resource * * @param target * the target file to which the content is saved * @param location * the web location of the content * @param monitor * the monitor * @return * @throws IOException * if a network or IO problem occurs */ public static IStatus download(URI uri, File target, IProgressMonitor monitor) throws IOException { IStatus result; OutputStream out = new BufferedOutputStream(new FileOutputStream(target)); try { result = download(uri, out, monitor); } finally { out.close(); } if (!result.isOK()) { target.delete(); if (result.getException() instanceof IOException) { throw (IOException) result.getException(); } throw new IOWithCauseException(result.getException()); } return result; } /** * Read a web-based resource at the specified location using the given processor. * * @param location * the web location of the content * @param processor * the processor that will handle content * @param monitor * the monitor * @throws IOException * if a network or IO problem occurs * @throws CoreException */ public static void readResource(URI uri, TextContentProcessor processor, IProgressMonitor monitor) throws IOException, CoreException { InputStream in = stream(uri, monitor); try { // FIXME how can the charset be determined? BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); //$NON-NLS-1$ processor.process(reader); } finally { in.close(); } } /** * Verify availability of resources at the given web locations. Normally this would be done using an HTTP HEAD. * * @param locations * the locations of the resource to verify * @param one * indicate if only one of the resources must exist * @param monitor * the monitor * @return true if the resource exists * @throws CoreException */ public static boolean verifyAvailability(List<? extends URI> locations, boolean one, IProgressMonitor monitor) { if (locations.isEmpty() || locations.size() > 5) { throw new IllegalArgumentException(); } int countFound = 0; MultiStatus status = new MultiStatus(DiscoveryCore.ID_PLUGIN, 0, "Verifying resource availability failed", //$NON-NLS-1$ new Exception()); try { for (URI location : locations) { try { getLastModified(location, monitor); if (one) { return true; } ++countFound; } catch (IOException | CoreException e) { status.add(getStatus(e)); if (!one) { return false; } continue; } } } finally { if (!status.isOK()) { StatusHandler.log(status); } } return countFound == locations.size(); } private static IStatus getStatus(Exception e) { if (e instanceof CoreException) { return ((CoreException) e).getStatus(); } return new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, e.getMessage(), e); } 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 IStatus download(URI uri, OutputStream out, IProgressMonitor monitor) { return getTransport().download(uri, out, monitor); } public static InputStream stream(URI uri, IProgressMonitor monitor) throws IOException, CoreException { return getTransport().stream(uri, monitor); } private static long getLastModified(URI location, IProgressMonitor monitor) throws CoreException, IOException { return getTransport().getLastModified(location, monitor); } public static String getFileNameFor(String bundleUrl) throws IOException { if (bundleUrl.charAt(bundleUrl.length() - 1) == '/') { bundleUrl = bundleUrl.substring(0, bundleUrl.length() - 1); } if (bundleUrl.lastIndexOf('/') != -1) { bundleUrl = bundleUrl.substring(bundleUrl.lastIndexOf('/') + 1); } return bundleUrl.replaceAll("[^a-zA-Z0-9_\\.]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ } }