diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.repository')
12 files changed, 92 insertions, 1640 deletions
diff --git a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF index 166ba9232..fba4b33b9 100644 --- a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF @@ -25,10 +25,7 @@ Export-Package: org.eclipse.equinox.internal.p2.persistence;x-friends:="org.ecli org.eclipse.equinox.p2.repository.metadata.spi;version="2.0.0", org.eclipse.equinox.p2.repository.spi;version="2.0.0" Require-Bundle: org.eclipse.equinox.common, - org.eclipse.ecf.filetransfer, - org.eclipse.ecf, - org.eclipse.equinox.registry;bundle-version="3.3.0", - org.eclipse.ecf.provider.filetransfer;bundle-version="3.0.1" + org.eclipse.equinox.registry;bundle-version="3.3.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5, J2SE-1.4, CDC-1.1/Foundation-1.1 diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Activator.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Activator.java index f4cc4713d..196f09f41 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Activator.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Activator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Cloudsmith Inc and others. + * Copyright (c) 2009, 2010 Cloudsmith Inc 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 @@ -9,15 +9,12 @@ * Cloudsmith Inc - initial API and implementation * IBM Corporation - ongoing development * Genuitec - Bug 291926 + * Sonatype, Inc. - transport split ******************************************************************************/ package org.eclipse.equinox.internal.p2.repository; -import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory; -import org.eclipse.ecf.provider.filetransfer.IFileTransferProtocolToFactoryMapper; -import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; -import org.osgi.framework.*; -import org.osgi.service.packageadmin.PackageAdmin; -import org.osgi.util.tracker.ServiceTracker; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle. @@ -27,143 +24,19 @@ import org.osgi.util.tracker.ServiceTracker; public class Activator implements BundleActivator { public static final String ID = "org.eclipse.equinox.p2.repository"; //$NON-NLS-1$ - private static final String HTTP = "http"; //$NON-NLS-1$ - private static final String HTTPS = "https"; //$NON-NLS-1$ private static BundleContext context; - // tracker for ECF service - private ServiceTracker<IRetrieveFileTransferFactory, IRetrieveFileTransferFactory> retrievalFactoryTracker; - - // tracker for protocolToFactoryMapperTracker - private ServiceTracker<IFileTransferProtocolToFactoryMapper, IFileTransferProtocolToFactoryMapper> protocolToFactoryMapperTracker = null; - - // The shared instance - private static Activator plugin; public void start(BundleContext aContext) throws Exception { Activator.context = aContext; - Activator.plugin = this; } public void stop(BundleContext aContext) throws Exception { - Activator.context = null; - Activator.plugin = null; - if (retrievalFactoryTracker != null) { - retrievalFactoryTracker.close(); - retrievalFactoryTracker = null; - } - if (protocolToFactoryMapperTracker != null) { - protocolToFactoryMapperTracker.close(); - protocolToFactoryMapperTracker = null; - } - + Activator.context = aContext; } public static BundleContext getContext() { return Activator.context; } - /** - * Get singleton instance. - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } - - /** - * Returns a {@link IRetrieveFileTransferFactory} using a {@link ServiceTracker} after having attempted - * to start the bundle "org.eclipse.ecf.provider.filetransfer". If something is wrong with the configuration - * this method returns null. - * @return a factory, or null, if configuration is incorrect - */ - public IRetrieveFileTransferFactory getRetrieveFileTransferFactory() { - return getFileTransferServiceTracker().getService(); - } - - public synchronized void useJREHttpClient() { - IFileTransferProtocolToFactoryMapper mapper = getProtocolToFactoryMapper(); - if (mapper != null) { - // remove http - // Remove browse provider - String providerId = mapper.getBrowseFileTransferFactoryId(HTTP); - if (providerId != null) { - mapper.removeBrowseFileTransferFactory(providerId); - } - // Remove retrieve provider - providerId = mapper.getRetrieveFileTransferFactoryId(HTTP); - if (providerId != null) { - mapper.removeRetrieveFileTransferFactory(providerId); - } - // Remove send provider - providerId = mapper.getSendFileTransferFactoryId(HTTP); - if (providerId != null) { - mapper.removeSendFileTransferFactory(providerId); - } - // remove https - // Remove browse provider - providerId = mapper.getBrowseFileTransferFactoryId(HTTPS); - if (providerId != null) { - mapper.removeBrowseFileTransferFactory(providerId); - } - // Remove retrieve provider - providerId = mapper.getRetrieveFileTransferFactoryId(HTTPS); - if (providerId != null) { - mapper.removeRetrieveFileTransferFactory(providerId); - } - // Remove send provider - providerId = mapper.getSendFileTransferFactoryId(HTTPS); - if (providerId != null) { - mapper.removeSendFileTransferFactory(providerId); - } - } - } - - /** - * Gets the singleton ServiceTracker for the IRetrieveFileTransferFactory and starts the bundles - * "org.eclipse.ecf" and - * "org.eclipse.ecf.provider.filetransfer" on first call. - * @return ServiceTracker - */ - private synchronized ServiceTracker<IRetrieveFileTransferFactory, IRetrieveFileTransferFactory> getFileTransferServiceTracker() { - if (retrievalFactoryTracker == null) { - retrievalFactoryTracker = new ServiceTracker<IRetrieveFileTransferFactory, IRetrieveFileTransferFactory>(Activator.getContext(), IRetrieveFileTransferFactory.class, null); - retrievalFactoryTracker.open(); - startBundle("org.eclipse.ecf"); //$NON-NLS-1$ - startBundle("org.eclipse.ecf.provider.filetransfer"); //$NON-NLS-1$ - } - return retrievalFactoryTracker; - } - - private IFileTransferProtocolToFactoryMapper getProtocolToFactoryMapper() { - if (protocolToFactoryMapperTracker == null) { - protocolToFactoryMapperTracker = new ServiceTracker<IFileTransferProtocolToFactoryMapper, IFileTransferProtocolToFactoryMapper>(context, IFileTransferProtocolToFactoryMapper.class, null); - protocolToFactoryMapperTracker.open(); - } - return protocolToFactoryMapperTracker.getService(); - } - - private boolean startBundle(String bundleId) { - PackageAdmin packageAdmin = (PackageAdmin) ServiceHelper.getService(Activator.getContext(), PackageAdmin.class.getName()); - if (packageAdmin == null) - return false; - - Bundle[] bundles = packageAdmin.getBundles(bundleId, null); - if (bundles != null && bundles.length > 0) { - for (int i = 0; i < bundles.length; i++) { - try { - if ((bundles[i].getState() & Bundle.INSTALLED) == 0) { - bundles[i].start(Bundle.START_ACTIVATION_POLICY); - bundles[i].start(Bundle.START_TRANSIENT); - return true; - } - } catch (BundleException e) { - // failed, try next bundle - } - } - } - return false; - } - } diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManager.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManager.java index 802cd6dee..2f05d37ad 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManager.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManager.java @@ -17,7 +17,6 @@ import java.net.URI; import java.util.EventObject; import java.util.HashSet; import org.eclipse.core.runtime.*; -import org.eclipse.ecf.filetransfer.UserCancelledException; import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.internal.provisional.p2.core.eventbus.SynchronousProvisioningListener; @@ -44,6 +43,8 @@ public class CacheManager { private final IAgentLocation agentLocation; + private final Transport transport; + /** * IStateful implementation of BufferedOutputStream. Class is used to get the status from * a download operation. @@ -66,8 +67,9 @@ public class CacheManager { } - public CacheManager(IAgentLocation agentLocation) { + public CacheManager(IAgentLocation agentLocation, Transport transport) { this.agentLocation = agentLocation; + this.transport = transport; } private static SynchronousProvisioningListener busListener; @@ -129,7 +131,7 @@ public class CacheManager { // bug 269588 - server may return 0 when file exists, so extra flag is needed boolean useJar = true; try { - lastModifiedRemote = getTransport().getLastModified(jarLocation, submonitor.newChild(1)); + lastModifiedRemote = transport.getLastModified(jarLocation, submonitor.newChild(1)); if (lastModifiedRemote <= 0) LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Server returned lastModified <= 0 for " + jarLocation)); //$NON-NLS-1$ } catch (AuthenticationFailedException e) { @@ -166,15 +168,13 @@ public class CacheManager { // (Status is reported based on finding the XML file as giving up on certain errors // when checking for the jar may not be correct). try { - lastModifiedRemote = getTransport().getLastModified(xmlLocation, submonitor.newChild(1)); + lastModifiedRemote = transport.getLastModified(xmlLocation, submonitor.newChild(1)); // if lastModifiedRemote is 0 - something is wrong in the communication stack, as // a FileNotFound exception should have been thrown. // bug 269588 - server may return 0 when file exists - site is not correctly configured if (lastModifiedRemote <= 0) LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Server returned lastModified <= 0 for " + xmlLocation)); //$NON-NLS-1$ - } catch (UserCancelledException e) { - throw new OperationCanceledException(); } catch (FileNotFoundException e) { throw new FileNotFoundException(NLS.bind(Messages.CacheManager_Neither_0_nor_1_found, jarLocation, xmlLocation)); } catch (AuthenticationFailedException e) { @@ -261,10 +261,6 @@ public class CacheManager { return files; } - private RepositoryTransport getTransport() { - return RepositoryTransport.getInstance(); - } - /** * Adds a {@link SynchronousProvisioningListener} to the event bus for * deleting cache files when the corresponding repository is deleted. @@ -334,7 +330,7 @@ public class CacheManager { IStatus result = null; try { submonitor.setWorkRemaining(1000); - result = getTransport().download(remoteFile, stream, submonitor.newChild(1000)); + result = transport.download(remoteFile, stream, submonitor.newChild(1000)); } catch (OperationCanceledException e) { // need to pick up the status - a new operation canceled exception is thrown at the end // as status will be CANCEL. diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManagerComponent.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManagerComponent.java index 26d5851b5..5c617e4f2 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManagerComponent.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManagerComponent.java @@ -19,7 +19,7 @@ public class CacheManagerComponent implements IAgentServiceFactory { public Object createService(IProvisioningAgent agent) {
final IProvisioningEventBus eventBus = (IProvisioningEventBus) agent.getService(IProvisioningEventBus.SERVICE_NAME);
- CacheManager cache = new CacheManager((IAgentLocation) agent.getService(IAgentLocation.SERVICE_NAME));
+ CacheManager cache = new CacheManager((IAgentLocation) agent.getService(IAgentLocation.SERVICE_NAME), (Transport) agent.getService(Transport.SERVICE_NAME));
cache.setEventBus(eventBus);
return cache;
}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Credentials.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Credentials.java index 0a9bb7e11..19f54813c 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Credentials.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Credentials.java @@ -18,11 +18,9 @@ import java.net.URI; import java.net.URLEncoder; import java.util.*; import org.eclipse.core.runtime.*; -import org.eclipse.ecf.filetransfer.UserCancelledException; import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; import org.eclipse.equinox.internal.p2.repository.helpers.DebugHelper; -import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.core.UIServices; +import org.eclipse.equinox.p2.core.*; import org.eclipse.equinox.p2.repository.IRepository; import org.eclipse.equinox.security.storage.*; @@ -106,7 +104,7 @@ public class Credentials { throw new UnsupportedEncodingException("No UTF-8 encoding and missing system property: file.encoding"); //$NON-NLS-1$ nodeKey = URLEncoder.encode(host, enc); } catch (UnsupportedEncodingException e) { - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } } if (DebugHelper.DEBUG_REPOSITORY_CREDENTIALS) { @@ -148,10 +146,10 @@ public class Credentials { prefNode = securePreferences.node(nodeName); } catch (IllegalArgumentException e) { // if the node name is illegal/malformed (should not happen). - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } catch (IllegalStateException e) { // thrown if preference store has been tampered with - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } if (!prompt) { try { @@ -175,7 +173,7 @@ public class Credentials { } return restoreFromMemory(nodeName); } catch (StorageException e) { - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } } // need to prompt user for user name and password @@ -258,9 +256,9 @@ public class Credentials { prefNode.put(IRepository.PROP_PASSWORD, loginDetails.getPassword(), true); prefNode.flush(); } catch (StorageException e1) { - throw RepositoryStatusHelper.internalError(e1); + throw internalError(e1); } catch (IOException e) { - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } } else { // if persisted earlier - the preference should be removed @@ -275,7 +273,7 @@ public class Credentials { try { prefNode.flush(); } catch (IOException e) { - throw RepositoryStatusHelper.internalError(e); + throw internalError(e); } } } @@ -481,4 +479,14 @@ public class Credentials { timestamp = System.currentTimeMillis(); } } + + /** + * Get default "InternalError" ProvisionException. + * @param t + * @return a default "InternalError" + */ + public static ProvisionException internalError(Throwable t) { + return new ProvisionException(new Status(IStatus.ERROR, Activator.ID, // + ProvisionException.INTERNAL_ERROR, Messages.repoMan_internalError, t)); + } } diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileInfoReader.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileInfoReader.java deleted file mode 100644 index c84d4e2a6..000000000 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileInfoReader.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, IBM Corporation, and others. - * The code, documentation and other materials contained herein have been - * licensed under the Eclipse Public License - v 1.0 by the copyright holder - * listed above, as the Initial Contributor under such license. The text of - * such license is available at www.eclipse.org. - * Contributors: - * IBM Corporation - initial implementation - * Cloudsmith Inc - modified API, and implementation - ******************************************************************************/ -package org.eclipse.equinox.internal.p2.repository; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.ecf.core.*; -import org.eclipse.ecf.core.security.IConnectContext; -import org.eclipse.ecf.filetransfer.*; -import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemBrowseEvent; -import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemEvent; -import org.eclipse.ecf.filetransfer.identity.*; -import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; -import org.eclipse.osgi.util.NLS; - -/** - * The FileInfoReader is a {@link Job} similar to {@link FileReader}, but without the support - * from ECF (there is currently no way to wait on a BrowseRequest job, as this is internal to - * ECF). If such support is added, this class is easily modified. - * - */ -public class FileInfoReader extends Job implements IRemoteFileSystemListener { - private Exception exception; - private IProgressMonitor theMonitor; - private final int connectionRetryCount; - private final long connectionRetryDelay; - private final IConnectContext connectContext; - final Boolean[] barrier = new Boolean[1]; - private IRemoteFile[] remoteFiles; - private IRemoteFileSystemRequest browseRequest; - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) - */ - protected IStatus run(IProgressMonitor monitor) { - synchronized (barrier) { - while (barrier[0] == null) { - try { - barrier.wait(1000); - if (theMonitor.isCanceled() && browseRequest != null) - browseRequest.cancel(); - } catch (InterruptedException e) { - //ignore - } - } - } - return Status.OK_STATUS; - } - - /** - * Waits until request is processed (barrier[0] is non null). - * This is a bit of a hack, as it would be better if the ECFBrowser worked in similar fashion to - * file transfer were a custom job can be supplied. - * TODO: log an issue for ECF. - */ - private void waitOnSelf() { - schedule(); - while (barrier[0] == null) { - boolean logged = false; - try { - join(); - } catch (InterruptedException e) { - if (!logged) - LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF browse request", e)); //$NON-NLS-1$ - } - } - } - - /** - * Create a new FileInfoReader that will retry failed connection attempts and sleep some amount of time between each - * attempt. - */ - public FileInfoReader(IConnectContext aConnectContext) { - super(Messages.repo_loading); // job label - TODO: this is a bad label - barrier[0] = null; - // Hide this job. - setSystem(true); - setUser(false); - connectionRetryCount = RepositoryPreferences.getConnectionRetryCount(); - connectionRetryDelay = RepositoryPreferences.getConnectionMsRetryDelay(); - connectContext = aConnectContext; - } - - /** - * Get the requested information. - * @return IRemoteFile[] or null if there was an error. - * @throws CoreException - * @throws FileNotFoundException - * @throws AuthenticationFailedException - * @throws JREHttpClientRequiredException - */ - public IRemoteFile[] getRemoteFiles(URI location, IProgressMonitor monitor) throws AuthenticationFailedException, FileNotFoundException, CoreException, JREHttpClientRequiredException { - if (monitor != null) - monitor.beginTask(location.toString(), 1); - try { - sendBrowseRequest(location, monitor); - waitOnSelf(); - // throw any exception received in a callback - checkException(location, connectionRetryCount); - - return remoteFiles; - } finally { - if (monitor != null) { - monitor.done(); - } - } - - } - - public IRemoteFile getRemoteFile(URI location, IProgressMonitor monitor) throws AuthenticationFailedException, FileNotFoundException, CoreException, JREHttpClientRequiredException { - - getRemoteFiles(location, monitor); - return remoteFiles != null && remoteFiles.length > 0 ? remoteFiles[0] : null; - } - - public long getLastModified(URI location, IProgressMonitor monitor) throws AuthenticationFailedException, FileNotFoundException, CoreException, JREHttpClientRequiredException { - IRemoteFile file = getRemoteFile(location, monitor); - if (file == null) - throw new FileNotFoundException(location.toString()); - return file.getInfo().getLastModified(); - } - - public void handleRemoteFileEvent(IRemoteFileSystemEvent event) { - exception = event.getException(); - if (exception != null) { - synchronized (barrier) { - barrier[0] = Boolean.TRUE; - barrier.notify(); - } - } else if (event instanceof IRemoteFileSystemBrowseEvent) { - IRemoteFileSystemBrowseEvent fsbe = (IRemoteFileSystemBrowseEvent) event; - remoteFiles = fsbe.getRemoteFiles(); - if (theMonitor != null) - theMonitor.worked(1); - synchronized (barrier) { - barrier[0] = Boolean.TRUE; - barrier.notify(); - } - } else { - synchronized (barrier) { - barrier[0] = Boolean.FALSE; // ended by unknown reason - barrier.notify(); - } - } - } - - protected void sendBrowseRequest(URI uri, IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - IContainer container; - try { - container = ContainerFactory.getDefault().createContainer(); - } catch (ContainerCreateException e) { - throw RepositoryStatusHelper.fromMessage(Messages.ecf_configuration_error); - } - - IRemoteFileSystemBrowserContainerAdapter adapter = (IRemoteFileSystemBrowserContainerAdapter) container.getAdapter(IRemoteFileSystemBrowserContainerAdapter.class); - if (adapter == null) { - throw RepositoryStatusHelper.fromMessage(Messages.ecf_configuration_error); - } - - adapter.setConnectContextForAuthentication(connectContext); - - this.exception = null; - this.theMonitor = monitor; - for (int retryCount = 0;; retryCount++) { - if (monitor != null && monitor.isCanceled()) - throw new OperationCanceledException(); - - try { - IFileID fileID = FileIDFactory.getDefault().createFileID(adapter.getBrowseNamespace(), uri.toString()); - browseRequest = adapter.sendBrowseRequest(fileID, this); - } catch (RemoteFileSystemException e) { - exception = e; - } catch (FileCreateException e) { - exception = e; - } - if (checkException(uri, retryCount)) - break; - } - } - - protected Exception getException() { - return exception; - } - - /** - * Utility method to check exception condition and determine if retry should be done. - * If there was an exception it is translated into one of the specified exceptions and thrown. - * - * @param uri the URI being read - used for logging purposes - * @param attemptCounter - the current attempt number (start with 0) - * @return true if the exception is an IOException and attemptCounter < connectionRetryCount, false otherwise - * @throws CoreException - * @throws FileNotFoundException - * @throws AuthenticationFailedException - * @throws JREHttpClientRequiredException - */ - private boolean checkException(URI uri, int attemptCounter) throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - // note that 'exception' could have been captured in a callback - if (exception != null) { - // check if HTTP client needs to be changed - RepositoryStatusHelper.checkJREHttpClientRequired(exception); - - // if this is a authentication failure - it is not meaningful to continue - RepositoryStatusHelper.checkPermissionDenied(exception); - - // if this is a file not found - it is not meaningful to continue - RepositoryStatusHelper.checkFileNotFound(exception, uri); - - Throwable t = RepositoryStatusHelper.unwind(exception); - if (t instanceof CoreException) - throw RepositoryStatusHelper.unwindCoreException((CoreException) t); - - if (t instanceof IOException && attemptCounter < connectionRetryCount) { - // TODO: Retry only certain exceptions or filter out - // some exceptions not worth retrying - // - exception = null; - try { - LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.connection_to_0_failed_on_1_retry_attempt_2, new String[] {uri.toString(), t.getMessage(), String.valueOf(attemptCounter)}), t)); - - Thread.sleep(connectionRetryDelay); - return false; - } catch (InterruptedException e) { - /* ignore */ - } - } - throw RepositoryStatusHelper.wrap(exception); - } - return true; - } -} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileReader.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileReader.java deleted file mode 100644 index fcc92c214..000000000 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/FileReader.java +++ /dev/null @@ -1,502 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2010 Cloudsmith 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: - * Cloudsmith Inc - initial API and implementation - * IBM Corporation - ongoing development - * Sonatype Inc - ongoing development - ******************************************************************************/ -package org.eclipse.equinox.internal.p2.repository; - -import java.io.*; -import java.net.SocketTimeoutException; -import java.net.URI; -import java.util.Date; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.ecf.core.security.IConnectContext; -import org.eclipse.ecf.filetransfer.*; -import org.eclipse.ecf.filetransfer.events.*; -import org.eclipse.ecf.filetransfer.identity.*; -import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory; -import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; -import org.eclipse.osgi.util.NLS; - -/** - * FileReader is an ECF FileTransferJob implementation. - */ -public final class FileReader extends FileTransferJob implements IFileTransferListener { - /** - * Class used to suppress warnings about a job being blocked by another job. - * Since we are running a job that will always be blocked by another job that - * is actually performing the transfer, these messages are unnecessary and ugly. - */ - static class SuppressBlockedMonitor extends SubProgressMonitor { - public SuppressBlockedMonitor(IProgressMonitor monitor, int ticks) { - super(monitor, ticks); - } - - public void setBlocked(IStatus reason) { - //do nothing - } - - public void clearBlocked() { - //do nothing - } - } - - private static IFileReaderProbe testProbe; - private boolean closeStreamWhenFinished = false; - private Exception exception; - private FileInfo fileInfo; - private long lastProgressCount; - private long lastStatsCount; - protected IProgressMonitor theMonitor; - private OutputStream theOutputStream; - private ProgressStatistics statistics; - private final int connectionRetryCount; - private final long connectionRetryDelay; - private final IConnectContext connectContext; - private URI requestUri; - protected IFileTransferConnectStartEvent connectEvent; - private Job cancelJob; - private boolean monitorStarted; - - /** - * Create a new FileReader that will retry failed connection attempts and sleep some amount of time between each - * attempt. - */ - public FileReader(IConnectContext aConnectContext) { - super(Messages.FileTransport_reader); // job label - - // Hide this job. - setSystem(true); - setUser(false); - connectionRetryCount = RepositoryPreferences.getConnectionRetryCount(); - connectionRetryDelay = RepositoryPreferences.getConnectionMsRetryDelay(); - connectContext = aConnectContext; - } - - public FileInfo getLastFileInfo() { - return fileInfo; - } - - /** - * A job to handle cancelation when trying to establish a socket connection. - * At this point we don't have a transfer job running yet, so we need a separate - * job to monitor for cancelation. - */ - protected class CancelHandler extends Job { - private boolean done = false; - - protected CancelHandler() { - super(Messages.FileTransport_cancelCheck); - setSystem(true); - } - - public IStatus run(IProgressMonitor jobMonitor) { - while (!done && !jobMonitor.isCanceled()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - return Status.CANCEL_STATUS; - } - if (theMonitor != null && theMonitor.isCanceled()) - if (connectEvent != null) - connectEvent.cancel(); - } - return Status.OK_STATUS; - } - - protected void canceling() { - //wake up from sleep in run method - Thread t = getThread(); - if (t != null) - t.interrupt(); - } - - } - - public synchronized void handleTransferEvent(IFileTransferEvent event) { - if (event instanceof IFileTransferConnectStartEvent) { - // keep the connect event to be able to cancel the transfer - connectEvent = (IFileTransferConnectStartEvent) event; - cancelJob = new CancelHandler(); - //schedule with a delay to avoid the overhead of an extra job on a fast connection - cancelJob.schedule(500); - } else if (event instanceof IIncomingFileTransferReceiveStartEvent) { - //we no longer need the cancel handler because we are about to fork the transfer job - if (cancelJob != null) - cancelJob.cancel(); - IIncomingFileTransfer source = ((IIncomingFileTransferEvent) event).getSource(); - try { - FileInfo fi = new FileInfo(); - Date lastModified = source.getRemoteLastModified(); - if (lastModified != null) - fi.setLastModified(lastModified.getTime()); - fi.setName(source.getRemoteFileName()); - fi.setSize(source.getFileLength()); - fileInfo = fi; - - ((IIncomingFileTransferReceiveStartEvent) event).receive(theOutputStream, this); - } catch (IOException e) { - exception = e; - return; - } - long fileLength = source.getFileLength(); - ProgressStatistics stats = new ProgressStatistics(requestUri, source.getRemoteFileName(), fileLength); - setStatistics(stats); - - if (theMonitor != null) { - theMonitor.beginTask(null, 1000); - monitorStarted = true; - theMonitor.subTask(stats.report()); - lastStatsCount = 0; - lastProgressCount = 0; - } - onStart(source); - } else if (event instanceof IIncomingFileTransferReceiveDataEvent) { - IIncomingFileTransfer source = ((IIncomingFileTransferEvent) event).getSource(); - if (theMonitor != null) { - if (theMonitor.isCanceled()) { - source.cancel(); - return; - } - - long br = source.getBytesReceived(); - long count = br - lastStatsCount; - lastStatsCount = br; - ProgressStatistics stats = getStatistics(); - if (stats != null) { - stats.increase(count); - fileInfo.setAverageSpeed(stats.getAverageSpeed()); - if (stats.shouldReport()) { - count = br - lastProgressCount; - lastProgressCount = br; - theMonitor.subTask(stats.report()); - theMonitor.worked((int) (1000 * count / stats.getTotal())); - } - } - } - onData(source); - } else if (event instanceof IIncomingFileTransferReceiveDoneEvent) { - if (closeStreamWhenFinished) - hardClose(theOutputStream); - - if (exception == null) - exception = ((IIncomingFileTransferReceiveDoneEvent) event).getException(); - onDone(((IIncomingFileTransferReceiveDoneEvent) event).getSource()); - } - } - - public InputStream read(URI url, final IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - final PipedInputStream input = new PipedInputStream(); - PipedOutputStream output; - try { - output = new PipedOutputStream(input); - } catch (IOException e) { - throw RepositoryStatusHelper.wrap(e); - } - RepositoryTracing.debug("Downloading {0}", url); //$NON-NLS-1$ - - sendRetrieveRequest(url, output, null, true, monitor); - - return new InputStream() { - public int available() throws IOException { - checkException(); - return input.available(); - } - - public void close() throws IOException { - hardClose(input); - checkException(); - } - - public void mark(int readlimit) { - input.mark(readlimit); - } - - public boolean markSupported() { - return input.markSupported(); - } - - public int read() throws IOException { - checkException(); - return input.read(); - } - - public int read(byte b[]) throws IOException { - checkException(); - return input.read(b); - } - - public int read(byte b[], int off, int len) throws IOException { - checkException(); - return input.read(b, off, len); - } - - public void reset() throws IOException { - checkException(); - input.reset(); - } - - public long skip(long n) throws IOException { - checkException(); - return input.skip(n); - } - - private void checkException() throws IOException { - if (getException() == null) - return; - - IOException e; - Throwable t = RepositoryStatusHelper.unwind(getException()); - if (t instanceof IOException) - e = (IOException) t; - else { - if (t instanceof UserCancelledException) { - Throwable cause = t; - t = new OperationCanceledException(t.getMessage()); - t.initCause(cause); - } - e = new IOException(t.getMessage()); - e.initCause(t); - } - throw e; - } - }; - } - - public void readInto(URI uri, OutputStream anOutputStream, IProgressMonitor monitor) // - throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - readInto(uri, anOutputStream, -1, monitor); - } - - public boolean belongsTo(Object family) { - return family == this; - } - - public void readInto(URI uri, OutputStream anOutputStream, long startPos, IProgressMonitor monitor) // - throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - if (monitor == null) - monitor = new NullProgressMonitor(); - try { - sendRetrieveRequest(uri, anOutputStream, (startPos != -1 ? new DownloadRange(startPos) : null), false, monitor); - Job.getJobManager().join(this, new SuppressBlockedMonitor(monitor, 0)); - if (monitor.isCanceled() && connectEvent != null) - connectEvent.cancel(); - // check and throw exception if received in callback - checkException(uri, connectionRetryCount); - } catch (InterruptedException e) { - monitor.setCanceled(true); - throw new OperationCanceledException(); - } finally { - // kill the cancelJob, if there is one - if (cancelJob != null) { - cancelJob.cancel(); - cancelJob = null; - } - // If monitor was never started, make sure it is balanced - if (!monitorStarted) - monitor.beginTask(null, 1); - monitorStarted = false; - monitor.done(); - } - } - - protected void sendRetrieveRequest(URI uri, OutputStream outputStream, DownloadRange range, boolean closeStreamOnFinish, // - IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - - IRetrieveFileTransferFactory factory = Activator.getDefault().getRetrieveFileTransferFactory(); - if (factory == null) { - throw RepositoryStatusHelper.fromMessage(Messages.ecf_configuration_error); - } - IRetrieveFileTransferContainerAdapter adapter = factory.newInstance(); - - adapter.setConnectContextForAuthentication(connectContext); - - this.exception = null; - this.closeStreamWhenFinished = closeStreamOnFinish; - this.fileInfo = null; - this.statistics = null; - this.lastProgressCount = 0L; - this.lastStatsCount = 0L; - this.theMonitor = monitor; - this.monitorStarted = false; - this.theOutputStream = outputStream; - this.requestUri = uri; - - for (int retryCount = 0;; retryCount++) { - if (monitor != null && monitor.isCanceled()) - throw new OperationCanceledException(); - - try { - IFileID fileID = FileIDFactory.getDefault().createFileID(adapter.getRetrieveNamespace(), uri.toString()); - if (range != null) - adapter.sendRetrieveRequest(fileID, range, this, null); - else - adapter.sendRetrieveRequest(fileID, this, null); - } catch (IncomingFileTransferException e) { - exception = e; - } catch (FileCreateException e) { - exception = e; - } catch (Throwable t) { - if (exception != null) - exception.printStackTrace(); - } - if (checkException(uri, retryCount)) - break; - } - } - - /** - * Utility method to check exception condition and determine if retry should be done. - * If there was an exception it is translated into one of the specified exceptions and thrown. - * - * @param uri the URI being read - used for logging purposes - * @param attemptCounter - the current attempt number (start with 0) - * @return true if the exception is an IOException and attemptCounter < connectionRetryCount, false otherwise - * @throws CoreException - * @throws FileNotFoundException - * @throws AuthenticationFailedException - */ - private boolean checkException(URI uri, int attemptCounter) throws CoreException, FileNotFoundException, AuthenticationFailedException, JREHttpClientRequiredException { - // note that 'exception' could have been captured in a callback - if (exception != null) { - // check if HTTP client needs to be changed - RepositoryStatusHelper.checkJREHttpClientRequired(exception); - - // if this is an 'authentication failure' - it is not meaningful to continue - RepositoryStatusHelper.checkPermissionDenied(exception); - - // if this is a 'file not found' - it is not meaningful to continue - RepositoryStatusHelper.checkFileNotFound(exception, uri); - - Throwable t = RepositoryStatusHelper.unwind(exception); - if (t instanceof CoreException) - throw RepositoryStatusHelper.unwindCoreException((CoreException) t); - - // not meaningful to try 'timeout again' - if a server is that busy, we - // need to wait for quite some time before retrying- it is not likely it is - // just a temporary network thing. - if (t instanceof SocketTimeoutException) - throw RepositoryStatusHelper.wrap(t); - - if (t instanceof IOException && attemptCounter < connectionRetryCount) { - // TODO: Retry only certain exceptions or filter out - // some exceptions not worth retrying - // - exception = null; - try { - LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.connection_to_0_failed_on_1_retry_attempt_2, new String[] {uri.toString(), t.getMessage(), String.valueOf(attemptCounter)}), t)); - - Thread.sleep(connectionRetryDelay); - return false; - } catch (InterruptedException e) { - /* ignore */ - } - } - throw RepositoryStatusHelper.wrap(exception); - } - return true; - } - - protected Exception getException() { - return exception; - } - - /** - * Closes input and output streams - * @param aStream - */ - public static void hardClose(Object aStream) { - if (aStream != null) { - try { - if (aStream instanceof OutputStream) - ((OutputStream) aStream).close(); - else if (aStream instanceof InputStream) - ((InputStream) aStream).close(); - } catch (IOException e) { /* ignore */ - } - } - } - - private static class DownloadRange implements IFileRangeSpecification { - - private long startPosition; - - public DownloadRange(long startPos) { - startPosition = startPos; - } - - public long getEndPosition() { - return -1; - } - - public long getStartPosition() { - return startPosition; - } - - } - - private void onDone(IIncomingFileTransfer source) { - if (testProbe != null) - testProbe.onDone(this, source, theMonitor); - } - - private void onStart(IIncomingFileTransfer source) { - if (testProbe != null) - testProbe.onStart(this, source, theMonitor); - } - - private void onData(IIncomingFileTransfer source) { - if (testProbe != null) - testProbe.onData(this, source, theMonitor); - } - - /** - * Sets a testing probe that can intercept events on the file reader for testing purposes. - * This method should only ever be called from automated test suites. - */ - public static void setTestProbe(IFileReaderProbe probe) { - testProbe = probe; - } - - /** - * Sets the progress statistics. This method is synchronized because the field - * is accessed from both the transfer thread and the thread initiating the transfer - * and we need to ensure field values are consistent across threads. - * - * @param statistics the statistics to set, or <code>null</code> - */ - private synchronized void setStatistics(ProgressStatistics statistics) { - this.statistics = statistics; - } - - /** - * Returns the progress statistics. This method is synchronized because the field - * is accessed from both the transfer thread and the thread initiating the transfer - * and we need to ensure field values are consistent across threads. - * - * @return the statistics, or <code>null</code> - */ - private synchronized ProgressStatistics getStatistics() { - return statistics; - } - - /** - * An interface to allow automated tests to hook into file reader events - * @see #setTestProbe - */ - public interface IFileReaderProbe { - public void onStart(FileReader reader, IIncomingFileTransfer source, IProgressMonitor monitor); - - public void onData(FileReader reader, IIncomingFileTransfer source, IProgressMonitor monitor); - - public void onDone(FileReader reader, IIncomingFileTransfer source, IProgressMonitor monitor); - } -} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatus.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatus.java deleted file mode 100644 index aae393d0f..000000000 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatus.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Cloudsmith Inc. 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: - * Cloudsmith Inc. - initial API and implementation - *******************************************************************************/ - -package org.eclipse.equinox.internal.p2.repository; - -import org.eclipse.equinox.p2.core.ProvisionException; - -import java.io.FileNotFoundException; -import java.net.*; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.ecf.core.identity.IDCreateException; -import org.eclipse.ecf.filetransfer.BrowseFileTransferException; -import org.eclipse.ecf.filetransfer.IncomingFileTransferException; -import org.eclipse.osgi.util.NLS; - -/** - * Utility class to transform transport errors into error messages. - * - */ -public class RepositoryStatus { - - public static String codeToMessage(int code, String toDownload) { - switch (code) { - case 400 : - return NLS.bind(Messages.TransportErrorTranslator_400, toDownload); - case 401 : - return NLS.bind(Messages.TransportErrorTranslator_401, toDownload); - case 402 : - return NLS.bind(Messages.TransportErrorTranslator_402, toDownload); - case 403 : - return NLS.bind(Messages.TransportErrorTranslator_403, toDownload); - case 404 : - return NLS.bind(Messages.TransportErrorTranslator_404, toDownload); - case 405 : - return NLS.bind(Messages.TransportErrorTranslator_405, toDownload); - case 406 : - return NLS.bind(Messages.TransportErrorTranslator_406, toDownload); - case 407 : - return NLS.bind(Messages.TransportErrorTranslator_407, toDownload); - case 408 : - return NLS.bind(Messages.TransportErrorTranslator_408, toDownload); - case 409 : - return NLS.bind(Messages.TransportErrorTranslator_409, toDownload); - case 410 : - return NLS.bind(Messages.TransportErrorTranslator_410, toDownload); - case 411 : - return NLS.bind(Messages.TransportErrorTranslator_411, toDownload); - case 412 : - return NLS.bind(Messages.TransportErrorTranslator_412, toDownload); - case 413 : - return NLS.bind(Messages.TransportErrorTranslator_413, toDownload); - case 414 : - return NLS.bind(Messages.TransportErrorTranslator_414, toDownload); - case 415 : - return NLS.bind(Messages.TransportErrorTranslator_415, toDownload); - case 416 : - return NLS.bind(Messages.TransportErrorTranslator_416, toDownload); - case 417 : - return NLS.bind(Messages.TransportErrorTranslator_417, toDownload); - case 418 : - return NLS.bind(Messages.TransportErrorTranslator_418, toDownload); - case 422 : - return NLS.bind(Messages.TransportErrorTranslator_422, toDownload); - case 423 : - return NLS.bind(Messages.TransportErrorTranslator_423, toDownload); - case 424 : - return NLS.bind(Messages.TransportErrorTranslator_424, toDownload); - case 425 : - return NLS.bind(Messages.TransportErrorTranslator_425, toDownload); - case 426 : - return NLS.bind(Messages.TransportErrorTranslator_426, toDownload); - case 449 : - return NLS.bind(Messages.TransportErrorTranslator_449, toDownload); - case 450 : - return NLS.bind(Messages.TransportErrorTranslator_450, toDownload); - - case 500 : - return NLS.bind(Messages.TransportErrorTranslator_500, toDownload); - case 501 : - return NLS.bind(Messages.TransportErrorTranslator_501, toDownload); - case 502 : - return NLS.bind(Messages.TransportErrorTranslator_502, toDownload); - case 503 : - return NLS.bind(Messages.TransportErrorTranslator_503, toDownload); - case 504 : - return NLS.bind(Messages.TransportErrorTranslator_504, toDownload); - case 505 : - return NLS.bind(Messages.TransportErrorTranslator_505, toDownload); - case 506 : - return NLS.bind(Messages.TransportErrorTranslator_506, toDownload); - case 507 : - return NLS.bind(Messages.TransportErrorTranslator_507, toDownload); - case 508 : - return NLS.bind(Messages.TransportErrorTranslator_508, toDownload); - case 510 : - return NLS.bind(Messages.TransportErrorTranslator_510, toDownload); - - default : - return NLS.bind(Messages.TransportErrorTranslator_UnknownErrorCode, Integer.toString(code), toDownload); - } - } - - public static DownloadStatus forStatus(IStatus original, URI toDownload) { - Throwable t = original.getException(); - return forException(t, toDownload); - } - - public static DownloadStatus forException(Throwable t, URI toDownload) { - if (t instanceof FileNotFoundException || (t instanceof IncomingFileTransferException && ((IncomingFileTransferException) t).getErrorCode() == 404)) - return new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.ARTIFACT_NOT_FOUND, NLS.bind(Messages.artifact_not_found, toDownload), t); - if (t instanceof ConnectException) - return new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_FAILED_READ, NLS.bind(Messages.TransportErrorTranslator_UnableToConnectToRepository_0, toDownload), t); - if (t instanceof UnknownHostException) - return new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_INVALID_LOCATION, NLS.bind(Messages.TransportErrorTranslator_UnknownHost, toDownload), t); - if (t instanceof IDCreateException) { - IStatus status = ((IDCreateException) t).getStatus(); - if (status != null && status.getException() != null) - t = status.getException(); - - return new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_INVALID_LOCATION, NLS.bind(Messages.TransportErrorTranslator_MalformedRemoteFileReference, toDownload), t); - } - int code = 0; - - // default to report as read repository error - int provisionCode = ProvisionException.REPOSITORY_FAILED_READ; - - if (t instanceof IncomingFileTransferException) - code = ((IncomingFileTransferException) t).getErrorCode(); - else if (t instanceof BrowseFileTransferException) - code = ((BrowseFileTransferException) t).getErrorCode(); - - // Switch on error codes in the HTTP error code range. - // Note that 404 uses ARTIFACT_NOT_FOUND (as opposed to REPOSITORY_NOT_FOUND, which - // is determined higher up in the calling chain). - if (code == 401) - provisionCode = ProvisionException.REPOSITORY_FAILED_AUTHENTICATION; - else if (code == 404) - provisionCode = ProvisionException.ARTIFACT_NOT_FOUND; - - // Add more specific translation here - - return new DownloadStatus(IStatus.ERROR, Activator.ID, provisionCode, // - code == 0 ? NLS.bind(Messages.io_failedRead, toDownload) // - : codeToMessage(code, toDownload.toString()), t); - } -} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatusHelper.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatusHelper.java deleted file mode 100644 index ac3d66bd0..000000000 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryStatusHelper.java +++ /dev/null @@ -1,323 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Cloudsmith Inc, and other. - * The code, documentation and other materials contained herein have been - * licensed under the Eclipse Public License - v 1.0 by the individual - * copyright holders listed above, as Initial Contributors under such license. - * The text of such license is available at www.eclipse.org. - * Contributors: - * Cloudsmith Inc. - Initial API and implementation - * IBM Corporation - Original Implementation of checkPermissionDenied - *******************************************************************************/ -package org.eclipse.equinox.internal.p2.repository; - -import org.eclipse.equinox.p2.core.ProvisionException; - -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import org.eclipse.core.runtime.*; -import org.eclipse.ecf.filetransfer.BrowseFileTransferException; -import org.eclipse.ecf.filetransfer.IncomingFileTransferException; -import org.eclipse.osgi.util.NLS; - -/** - * RepositoryStatusHelper is a utility class for processing of exceptions and status. - */ -public abstract class RepositoryStatusHelper { - - private static final long serialVersionUID = 1L; - protected static final String SERVER_REDIRECT = "Server redirected too many times"; //$NON-NLS-1$ - - public static IStatus createStatus(String nlsMessage, Object arg) { - return createExceptionStatus(null, nlsMessage, new Object[] {arg}); - } - - public static IStatus createStatus(String nlsMessage, Object arg1, Object arg2) { - return createExceptionStatus(null, nlsMessage, new Object[] {arg1, arg2}); - } - - public static IStatus createStatus(String nlsMessage, Object arg1, Object arg2, Object arg3) { - return createExceptionStatus(null, nlsMessage, new Object[] {arg1, arg2, arg3}); - } - - public static IStatus createStatus(String nlsMessage, Object[] args) { - return createExceptionStatus(null, nlsMessage, args); - } - - public static IStatus createStatus(String nlsMessage) { - return createExceptionStatus(null, nlsMessage, new Object[] {}); - } - - public static IStatus createExceptionStatus(Throwable cause) { - return (cause instanceof CoreException) ? ((CoreException) cause).getStatus() : new Status(IStatus.ERROR, Activator.ID, IStatus.OK, cause.getMessage(), cause); - } - - public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object[] args) { - if (args != null && args.length > 0) - nlsMessage = NLS.bind(nlsMessage, args); - return new Status(IStatus.ERROR, Activator.ID, IStatus.OK, nlsMessage, cause); - } - - public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1, Object arg2, Object arg3) { - return createExceptionStatus(cause, nlsMessage, new Object[] {arg1, arg2, arg3}); - } - - public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1, Object arg2) { - return createExceptionStatus(cause, nlsMessage, new Object[] {arg1, arg2}); - } - - public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1) { - return createExceptionStatus(cause, nlsMessage, new Object[] {arg1}); - } - - public static IStatus createExceptionStatus(Throwable cause, String nlsMessage) { - return createExceptionStatus(cause, nlsMessage, new Object[] {}); - } - - public static void deeplyPrint(Throwable e, PrintStream strm, boolean stackTrace) { - deeplyPrint(e, strm, stackTrace, 0); - } - - public static CoreException fromMessage(String nlsMessage, Object[] args) { - return fromExceptionMessage(null, nlsMessage, args); - } - - public static CoreException fromMessage(String nlsMessage, Object arg1) { - return fromExceptionMessage(null, nlsMessage, new Object[] {arg1}); - } - - public static CoreException fromMessage(String nlsMessage, Object arg1, Object arg2) { - return fromExceptionMessage(null, nlsMessage, new Object[] {arg1, arg2}); - } - - public static CoreException fromMessage(String nlsMessage, Object arg1, Object arg2, Object arg3) { - return fromExceptionMessage(null, nlsMessage, new Object[] {arg1, arg2, arg3}); - } - - public static CoreException fromMessage(String nlsMessage) { - return fromExceptionMessage(null, nlsMessage, new Object[] {}); - } - - public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object[] args) { - CoreException ce = new CoreException(createExceptionStatus(cause, nlsMessage, args)); - if (cause != null) - ce.initCause(cause); - return ce; - } - - public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1, Object arg2, Object arg3) { - return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1, arg2, arg3}); - } - - public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1, Object arg2) { - return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1, arg2}); - } - - public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1) { - return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1}); - } - - public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage) { - return fromExceptionMessage(cause, nlsMessage, new Object[] {}); - } - - public static Throwable unwind(Throwable t) { - for (;;) { - Class<? extends Throwable> tc = t.getClass(); - - // We don't use instanceof operator since we want - // the explicit class, not subclasses. - // - if (tc != RuntimeException.class && tc != InvocationTargetException.class && tc != IOException.class) - break; - - Throwable cause = t.getCause(); - if (cause == null) - break; - - String msg = t.getMessage(); - if (msg != null && !msg.equals(cause.toString())) - break; - - t = cause; - } - return t; - } - - public static CoreException unwindCoreException(CoreException exception) { - IStatus status = exception.getStatus(); - while (status != null && status.getException() instanceof CoreException) { - exception = (CoreException) status.getException(); - status = exception.getStatus(); - } - return exception; - } - - public static CoreException wrap(IStatus status) { - CoreException e = new CoreException(status); - Throwable t = status.getException(); - if (t != null) - e.initCause(t); - return e; - } - - public static CoreException wrap(Throwable t) { - t = unwind(t); - if (t instanceof CoreException) - return unwindCoreException((CoreException) t); - - if (t instanceof OperationCanceledException || t instanceof InterruptedException) - return new CoreException(Status.CANCEL_STATUS); - - String msg = t.toString(); - return fromExceptionMessage(t, msg); - } - - private static void appendLevelString(PrintStream strm, int level) { - if (level > 0) { - strm.print("[0"); //$NON-NLS-1$ - for (int idx = 1; idx < level; ++idx) { - strm.print('.'); - strm.print(level); - } - strm.print(']'); - } - } - - private static void deeplyPrint(CoreException ce, PrintStream strm, boolean stackTrace, int level) { - appendLevelString(strm, level); - if (stackTrace) - ce.printStackTrace(strm); - deeplyPrint(ce.getStatus(), strm, stackTrace, level); - } - - private static void deeplyPrint(IStatus status, PrintStream strm, boolean stackTrace, int level) { - appendLevelString(strm, level); - String msg = status.getMessage(); - strm.println(msg); - Throwable cause = status.getException(); - if (cause != null) { - strm.print("Caused by: "); //$NON-NLS-1$ - if (stackTrace || !(msg.equals(cause.getMessage()) || msg.equals(cause.toString()))) - deeplyPrint(cause, strm, stackTrace, level); - } - - if (status.isMultiStatus()) { - IStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) - deeplyPrint(children[i], strm, stackTrace, level + 1); - } - } - - private static void deeplyPrint(Throwable t, PrintStream strm, boolean stackTrace, int level) { - if (t instanceof CoreException) - deeplyPrint((CoreException) t, strm, stackTrace, level); - else { - appendLevelString(strm, level); - if (stackTrace) - t.printStackTrace(strm); - else { - strm.println(t.toString()); - Throwable cause = t.getCause(); - if (cause != null) { - strm.print("Caused by: "); //$NON-NLS-1$ - deeplyPrint(cause, strm, stackTrace, level); - } - } - } - } - - /** - * Check if the given exception represents that a switch to the JRE HTTP Client - * is required. ECF sets the HTTP status code 477 to indicate this. - * If the JRE HTTP client is required a JREHttpClientRequiredException is thrown. - */ - public static void checkJREHttpClientRequired(Throwable t) throws JREHttpClientRequiredException { - if (t instanceof IncomingFileTransferException) { - if (((IncomingFileTransferException) t).getErrorCode() == 477) - throw new JREHttpClientRequiredException(); - } else if (t instanceof BrowseFileTransferException) { - if (((BrowseFileTransferException) t).getErrorCode() == 477) - throw new JREHttpClientRequiredException(); - } - - } - - /** - * Check if the given exception represents a permission failure (401 for HTTP), - * and throw a AuthenticationFailedException if a permission failure was encountered. - */ - public static void checkPermissionDenied(Throwable t) throws AuthenticationFailedException { - // From Use of File Transfer - if (t instanceof IncomingFileTransferException) { - if (((IncomingFileTransferException) t).getErrorCode() == 401) - throw new AuthenticationFailedException(); - IStatus status = ((IncomingFileTransferException) t).getStatus(); - t = status == null ? t : status.getException(); - // From Use of Browse - } else if (t instanceof BrowseFileTransferException) { - if (((BrowseFileTransferException) t).getErrorCode() == 401) - throw new AuthenticationFailedException(); - IStatus status = ((BrowseFileTransferException) t).getStatus(); - t = status == null ? t : status.getException(); - } - - if (t == null || !(t instanceof IOException)) - return; - - // TODO: is this needed (for 401) now that ECF throws exceptions with codes? - // try to figure out if we have a 401 by parsing the exception message - // There is unfortunately no specific (general) exception for "redirected too many times" - which is commonly - // caused by a failed login. The message and exception are different in different implementations - // of http client. - String m = t.getMessage(); - if (m != null && (m.indexOf(" 401 ") != -1 || m.indexOf(SERVER_REDIRECT) != -1)) //$NON-NLS-1$ - throw new AuthenticationFailedException(); - if ("org.apache.commons.httpclient.RedirectException".equals(t.getClass().getName())) //$NON-NLS-1$ - throw new AuthenticationFailedException(); - } - - /** - * Translates exceptions representing "FileNotFound" into FileNotFoundException. - * @param t the throwable to check - * @param toDownload the URI the exception was thrown for - * @throws FileNotFoundException if 't' represents a file not found - */ - public static void checkFileNotFound(Throwable t, URI toDownload) throws FileNotFoundException { - if (t instanceof IncomingFileTransferException) { - IncomingFileTransferException e = (IncomingFileTransferException) t; - if (e.getErrorCode() == 404 || e.getErrorCode() == 403 || e.getErrorCode() == 300) - throw new FileNotFoundException(toDownload.toString()); - } - if (t instanceof BrowseFileTransferException) { - BrowseFileTransferException e = (BrowseFileTransferException) t; - if (e.getErrorCode() == 404 || e.getErrorCode() == 403 || e.getErrorCode() == 300) - throw new FileNotFoundException(toDownload.toString()); - } - - if (t instanceof FileNotFoundException) - throw (FileNotFoundException) t; - if (t instanceof CoreException) { - IStatus status = ((CoreException) t).getStatus(); - Throwable e = status == null ? null : status.getException(); - if (e instanceof FileNotFoundException) - throw (FileNotFoundException) e; - } - } - - /** - * Get default "InternalError" ProvisionException. - * @param t - * @return a default "InternalError" - */ - public static ProvisionException internalError(Throwable t) { - return new ProvisionException(new Status(IStatus.ERROR, Activator.ID, // - ProvisionException.INTERNAL_ERROR, Messages.repoMan_internalError, t)); - } - - public static IStatus malformedAddressStatus(String address, Throwable t) { - return new Status(IStatus.ERROR, Activator.ID, // - ProvisionException.REPOSITORY_INVALID_LOCATION, NLS.bind(Messages.exception_malformedRepoURI, address), t); - - } -} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryTransport.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryTransport.java deleted file mode 100644 index f965d83fe..000000000 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/RepositoryTransport.java +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2010, IBM Corporation and other. - * The code, documentation and other materials contained herein have been - * licensed under the Eclipse Public License - v 1.0 by the copyright holder - * listed above, as the Initial Contributor under such license. The text of - * such license is available at www.eclipse.org. - * - * Contributors - * IBM Corporation - Initial API and implementation. - * Cloudsmith Inc - Implementation - ******************************************************************************/ - -package org.eclipse.equinox.internal.p2.repository; - -import java.io.*; -import java.net.URI; -import org.eclipse.core.runtime.*; -import org.eclipse.ecf.core.security.ConnectContextFactory; -import org.eclipse.ecf.core.security.IConnectContext; -import org.eclipse.ecf.filetransfer.UserCancelledException; -import org.eclipse.equinox.internal.p2.repository.Credentials.LoginCanceledException; -import org.eclipse.equinox.internal.provisional.p2.repository.IStateful; -import org.eclipse.equinox.p2.core.ProvisionException; -import org.eclipse.equinox.p2.core.UIServices.AuthenticationInfo; -import org.eclipse.osgi.util.NLS; - -/** - * RepositoryTransport adapts p2 to ECF file download and file browsing. - * Download is performed by {@link FileReader}, and file browsing is performed by - * {@link FileInfoReader}. - */ -public class RepositoryTransport extends Transport { - private static RepositoryTransport instance; - - /** - * Returns an shared instance of Generic Transport - */ - public static synchronized RepositoryTransport getInstance() { - if (instance == null) { - instance = new RepositoryTransport(); - } - return instance; - } - - /** - * Perform a download, writing into the target output stream. Progress is reported on the - * monitor. If the <code>target</code> is an instance of {@link IStateful} the resulting status - * is also set on the target. An IStateful target is updated with status even if this methods - * throws {@link OperationCanceledException}. - * - * @returns IStatus, that is a {@link DownloadStatus} on success. - * @param toDownload URI of file to download - * @param target OutputStream where result is written - * @param startPos the starting position of the download, or -1 for from start - * @param monitor where progress should be reported - * @throws OperationCanceledException if the operation was canceled. - */ - public IStatus download(URI toDownload, OutputStream target, long startPos, IProgressMonitor monitor) { - - boolean promptUser = false; - boolean useJREHttp = false; - AuthenticationInfo loginDetails = null; - for (int i = RepositoryPreferences.getLoginRetryCount(); i > 0; i--) { - FileReader reader = null; - try { - loginDetails = Credentials.forLocation(toDownload, promptUser, loginDetails); - IConnectContext context = (loginDetails == null) ? null : ConnectContextFactory.createUsernamePasswordConnectContext(loginDetails.getUserName(), loginDetails.getPassword()); - - // perform the download - reader = new FileReader(context); - reader.readInto(toDownload, target, startPos, monitor); - - // check that job ended ok - throw exceptions otherwise - IStatus result = reader.getResult(); - if (result == null) { - String msg = NLS.bind(Messages.RepositoryTransport_failedReadRepo, toDownload); - DownloadStatus ds = new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_FAILED_READ, msg, null); - return statusOn(target, ds, reader); - } - if (result.getSeverity() == IStatus.CANCEL) - throw new UserCancelledException(); - if (!result.isOK()) - throw new CoreException(result); - - // Download status is expected on success - DownloadStatus status = new DownloadStatus(IStatus.OK, Activator.ID, Status.OK_STATUS.getMessage()); - return statusOn(target, status, reader); - } catch (UserCancelledException e) { - statusOn(target, new DownloadStatus(IStatus.CANCEL, Activator.ID, 1, "", null), reader); //$NON-NLS-1$ - throw new OperationCanceledException(); - } catch (OperationCanceledException e) { - statusOn(target, new DownloadStatus(IStatus.CANCEL, Activator.ID, 1, "", null), reader); //$NON-NLS-1$ - throw e; - } catch (CoreException e) { - if (e.getStatus().getException() == null) - return statusOn(target, RepositoryStatus.forException(e, toDownload), reader); - return statusOn(target, RepositoryStatus.forStatus(e.getStatus(), toDownload), reader); - } catch (FileNotFoundException e) { - return statusOn(target, RepositoryStatus.forException(e, toDownload), reader); - } catch (AuthenticationFailedException e) { - promptUser = true; - } catch (Credentials.LoginCanceledException e) { - DownloadStatus status = new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_FAILED_AUTHENTICATION, // - NLS.bind(Messages.UnableToRead_0_UserCanceled, toDownload), null); - return statusOn(target, status, null); - } catch (JREHttpClientRequiredException e) { - if (!useJREHttp) { - useJREHttp = true; // only do this once - i++; // need an extra retry - Activator.getDefault().useJREHttpClient(); - } - } - } - // reached maximum number of retries without success - DownloadStatus status = new DownloadStatus(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_FAILED_AUTHENTICATION, // - NLS.bind(Messages.UnableToRead_0_TooManyAttempts, toDownload), null); - return statusOn(target, status, null); - } - - /** - * Perform a download, writing into the target output stream. Progress is reported on the - * monitor. If the <code>target</code> is an instance of {@link IStateful} the resulting status - * is also set on the target. - * - * @returns IStatus, that is a {@link DownloadStatus} on success. - * @param toDownload URI of file to download - * @param target OutputStream where result is written - * @param monitor where progress should be reported - * @throws OperationCanceledException if the operation was canceled. - */ - public IStatus download(URI toDownload, OutputStream target, IProgressMonitor monitor) { - return download(toDownload, target, -1, monitor); - } - - /** - * Perform a stream download, writing into an InputStream that is returned. Performs authentication if needed. - * - * @returns InputStream a stream with the content from the toDownload URI, or null - * @param toDownload URI of file to download - * @param monitor monitor checked for cancellation - * @throws OperationCanceledException if the operation was canceled. - * @throws AuthenticationFailedException if authentication failed, or too many attempt were made - * @throws FileNotFoundException if the toDownload was reported as non existing - * @throws CoreException on errors - */ - public InputStream stream(URI toDownload, IProgressMonitor monitor) throws FileNotFoundException, CoreException, AuthenticationFailedException { - - boolean promptUser = false; - boolean useJREHttp = false; - AuthenticationInfo loginDetails = null; - for (int i = RepositoryPreferences.getLoginRetryCount(); i > 0; i--) { - FileReader reader = null; - try { - loginDetails = Credentials.forLocation(toDownload, promptUser, loginDetails); - IConnectContext context = (loginDetails == null) ? null : ConnectContextFactory.createUsernamePasswordConnectContext(loginDetails.getUserName(), loginDetails.getPassword()); - - // perform the streamed download - reader = new FileReader(context); - return reader.read(toDownload, monitor); - } catch (UserCancelledException e) { - throw new OperationCanceledException(); - } catch (AuthenticationFailedException e) { - promptUser = true; - } catch (CoreException e) { - // must translate this core exception as it is most likely not informative to a user - if (e.getStatus().getException() == null) - throw new CoreException(RepositoryStatus.forException(e, toDownload)); - throw new CoreException(RepositoryStatus.forStatus(e.getStatus(), toDownload)); - } catch (LoginCanceledException e) { - // i.e. same behavior when user cancels as when failing n attempts. - throw new AuthenticationFailedException(); - } catch (JREHttpClientRequiredException e) { - if (!useJREHttp) { - useJREHttp = true; // only do this once - i++; // need an extra retry - Activator.getDefault().useJREHttpClient(); - } - } - } - throw new AuthenticationFailedException(); - } - - /** - * Set the status on the output stream if it implements IStateful. - * Update the DownloadStatus with information from FileReader. - * @param target an OutputStream possibly implementing IStateful - * @param status a DownloadStatus configured with status message, code, etc - * @param reader a FileReade that was used to download (or null if not known). - * @throws OperationCanceledException if the operation was canceled by the user. - * @return the configured DownloadStatus status. - */ - private static DownloadStatus statusOn(OutputStream target, DownloadStatus status, FileReader reader) { - if (reader != null) { - FileInfo fi = reader.getLastFileInfo(); - if (fi != null) { - status.setFileSize(fi.getSize()); - status.setLastModified(fi.getLastModified()); - status.setTransferRate(fi.getAverageSpeed()); - } - } - if (target instanceof IStateful) - ((IStateful) target).setStatus(status); - return status; - } - - /** - * Returns the last modified date for a URI. A last modified of 0 typically indicates that - * the server response is wrong, but should not be interpreted as a file not found. - * @param toDownload - * @param monitor - * @throws OperationCanceledException if the operation was canceled by the user. - * @return last modified date (possibly 0) - */ - public long getLastModified(URI toDownload, IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException { - boolean promptUser = false; - boolean useJREHttp = false; - AuthenticationInfo loginDetails = null; - for (int i = RepositoryPreferences.getLoginRetryCount(); i > 0; i--) { - try { - loginDetails = Credentials.forLocation(toDownload, promptUser, loginDetails); - IConnectContext context = (loginDetails == null) ? null : ConnectContextFactory.createUsernamePasswordConnectContext(loginDetails.getUserName(), loginDetails.getPassword()); - // get the remote info - FileInfoReader reader = new FileInfoReader(context); - return reader.getLastModified(toDownload, monitor); - } catch (UserCancelledException e) { - throw new OperationCanceledException(); - } catch (CoreException e) { - // must translate this core exception as it is most likely not informative to a user - if (e.getStatus().getException() == null) - throw new CoreException(RepositoryStatus.forException(e, toDownload)); - throw new CoreException(RepositoryStatus.forStatus(e.getStatus(), toDownload)); - } catch (AuthenticationFailedException e) { - promptUser = true; - } catch (LoginCanceledException e) { - // same behavior as if user failed n attempts. - throw new AuthenticationFailedException(); - } catch (JREHttpClientRequiredException e) { - if (!useJREHttp) { - useJREHttp = true; // only do this once - i++; // need an extra retry - Activator.getDefault().useJREHttpClient(); - } - } - - } - // reached maximum number of authentication retries without success - throw new AuthenticationFailedException(); - } - -} diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Transport.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Transport.java index 6eba11a7e..e57216c8a 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Transport.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/Transport.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 IBM Corporation and others. + * Copyright (c) 2007, 2010 IBM Corporation 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 @@ -7,21 +7,68 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Sonatype, Inc. - transport split *******************************************************************************/ package org.eclipse.equinox.internal.p2.repository; -import java.io.OutputStream; +import java.io.*; import java.net.URI; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.provisional.p2.repository.IStateful; public abstract class Transport { + public static final String SERVICE_NAME = Transport.class.getName(); + + /** + * Perform a download, writing into the target output stream. Progress is reported on the + * monitor. If the <code>target</code> is an instance of {@link IStateful} the resulting status + * is also set on the target. An IStateful target is updated with status even if this methods + * throws {@link OperationCanceledException}. + * + * @returns IStatus, that is a {@link DownloadStatus} on success. + * @param toDownload URI of file to download + * @param target OutputStream where result is written + * @param startPos the starting position of the download, or -1 for from start + * @param monitor where progress should be reported + * @throws OperationCanceledException if the operation was canceled. + */ + public abstract IStatus download(URI toDownload, OutputStream target, long startPos, IProgressMonitor monitor); + /** + * Perform a download, writing into the target output stream. Progress is reported on the + * monitor. If the <code>target</code> is an instance of {@link IStateful} the resulting status + * is also set on the target. + * + * @returns IStatus, that is a {@link DownloadStatus} on success. + * @param toDownload URI of file to download + * @param target OutputStream where result is written + * @param monitor where progress should be reported + * @throws OperationCanceledException if the operation was canceled. + */ + public abstract IStatus download(URI toDownload, OutputStream target, IProgressMonitor monitor); + + /** + * Perform a stream download, writing into an InputStream that is returned. Performs authentication if needed. + * + * @returns InputStream a stream with the content from the toDownload URI, or null + * @param toDownload URI of file to download + * @param monitor monitor checked for cancellation + * @throws OperationCanceledException if the operation was canceled. + * @throws AuthenticationFailedException if authentication failed, or too many attempt were made + * @throws FileNotFoundException if the toDownload was reported as non existing + * @throws CoreException on errors + */ + public abstract InputStream stream(URI toDownload, IProgressMonitor monitor) throws FileNotFoundException, CoreException, AuthenticationFailedException; + + /** + * Returns the last modified date for a URI. A last modified of 0 typically indicates that + * the server response is wrong, but should not be interpreted as a file not found. * @param toDownload - * @param target - * @param pm - * @return IStatus describing outcome of the download + * @param monitor + * @throws OperationCanceledException if the operation was canceled by the user. + * @return last modified date (possibly 0) */ - public abstract IStatus download(URI toDownload, OutputStream target, IProgressMonitor pm); + public abstract long getLastModified(URI toDownload, IProgressMonitor monitor) throws CoreException, FileNotFoundException, AuthenticationFailedException; + } diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/AbstractRepositoryManager.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/AbstractRepositoryManager.java index 9e7d3e47f..b8b17e076 100644 --- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/AbstractRepositoryManager.java +++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/AbstractRepositoryManager.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Wind River - fix for bug 299227 + * Sonatype, Inc. - transport split *******************************************************************************/ package org.eclipse.equinox.internal.p2.repository.helpers; @@ -18,7 +19,8 @@ import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.equinox.internal.p2.core.helpers.*; -import org.eclipse.equinox.internal.p2.repository.*; +import org.eclipse.equinox.internal.p2.repository.Activator; +import org.eclipse.equinox.internal.p2.repository.Transport; import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.internal.provisional.p2.core.eventbus.ProvisioningListener; import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent; @@ -1165,8 +1167,8 @@ public abstract class AbstractRepositoryManager<T> implements IRepositoryManager return new URI(spec); } - private Transport getTransport() { - return RepositoryTransport.getInstance(); + protected Transport getTransport() { + return (Transport) agent.getService(Transport.SERVICE_NAME); } public void flushCache() { |