Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2010-05-12 12:10:03 -0400
committerPascal Rapicault2010-05-12 12:10:03 -0400
commitdb81736ffa97bd7a22fd81b8dc8485b5927bb30a (patch)
treea9a66d564e0620eaf88f998baac4094dff8fcd95 /bundles/org.eclipse.equinox.p2.repository
parenteae2ed7cee7e29d2be03b115336958ea4feb67a7 (diff)
downloadrt.equinox.p2-db81736ffa97bd7a22fd81b8dc8485b5927bb30a.tar.gz
rt.equinox.p2-db81736ffa97bd7a22fd81b8dc8485b5927bb30a.tar.xz
rt.equinox.p2-db81736ffa97bd7a22fd81b8dc8485b5927bb30a.zip
Bug 303805 - [transport] Download is performed in the cache directory
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.repository')
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/CacheManager.java130
1 files changed, 30 insertions, 100 deletions
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 0e4eba8e5..ddb45ee23 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
@@ -11,11 +11,10 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata.repository;
-import org.eclipse.equinox.p2.core.ProvisionException;
-
import java.io.*;
import java.net.URI;
-import java.util.*;
+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;
@@ -26,6 +25,7 @@ import org.eclipse.equinox.internal.provisional.p2.core.eventbus.SynchronousProv
import org.eclipse.equinox.internal.provisional.p2.repository.IStateful;
import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
import org.eclipse.equinox.p2.core.IAgentLocation;
+import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.osgi.util.NLS;
@@ -74,8 +74,6 @@ public class CacheManager {
private static SynchronousProvisioningListener busListener;
private static final String DOWNLOADING = "downloading"; //$NON-NLS-1$
private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
- private static final String PROP_RESUMABLE = "org.eclipse.equinox.p2.metadata.repository.resumable"; //$NON-NLS-1$
- private static final String RESUME_DEFAULT = "true"; //$NON-NLS-1$
private static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$
private final HashSet<String> knownPrefixes = new HashSet<String>(5);
@@ -268,71 +266,6 @@ public class CacheManager {
return RepositoryTransport.getInstance();
}
- private boolean isResumeEnabled() {
- String resumeProp = System.getProperty(PROP_RESUMABLE, RESUME_DEFAULT);
- return Boolean.valueOf(resumeProp).booleanValue();
- }
-
- /**
- * Make cacheFile resumable and return true if it was possible.
- * @param cacheFile - the partially downloaded file to make resumeable
- * @param remoteFile The remote file being cached
- * @param status - the download status reported for the partial download
- * @return true if the file was made resumable, false otherwise
- */
- private boolean makeResumeable(File cacheFile, URI remoteFile, IStatus status) {
- if (status == null || status.isOK() || cacheFile == null || !(status instanceof DownloadStatus))
- return false;
- // check if resume feature is turned off
- if (!isResumeEnabled())
- return false;
- DownloadStatus downloadStatus = (DownloadStatus) status;
- long currentLength = cacheFile.length();
- // if cache file does not exist, or nothing was written to it, there is nothing to resume
- if (currentLength == 0L)
- return false;
-
- long reportedSize = downloadStatus.getFileSize();
- long reportedModified = downloadStatus.getLastModified();
-
- if (reportedSize == DownloadStatus.UNKNOWN_SIZE || reportedSize == 0L) {
- LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind("Download of {0} not resumable because filesize not reported.", remoteFile))); //$NON-NLS-1$
- return false;
- }
- if (reportedModified <= 0) {
- LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind("Download of {0} not resumable because last-modified not reported.", remoteFile))); //$NON-NLS-1$
- return false;
- }
-
- // if more than what was reported has been written something odd is going on, and we can't
- // trust the reported size.
- // There is a small chance that user canceled in the time window after the full download is seen, and the result is returned. In this
- // case the reported and current lengths will be equal.
- if (reportedSize < currentLength) {
- LogHelper.log(new Status(IStatus.WARNING, Activator.ID, NLS.bind("Download of {0} not resumable because more was read then reported size.", remoteFile))); //$NON-NLS-1$
- return false;
- }
- File resumeDir = new File(cacheFile.getParentFile(), DOWNLOADING);
- if (!resumeDir.mkdir()) {
- if (!(resumeDir.exists() && resumeDir.isDirectory())) {
- LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind("Could not create directory {0} for resumable download of {1}", resumeDir, remoteFile))); //$NON-NLS-1$
- return false;
- }
- }
- // move partial cache file to "downloading" directory
- File resumeFile = new File(resumeDir, cacheFile.getName());
- if (!cacheFile.renameTo(resumeFile)) {
- LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind("Could not move {0} to {1} for resumed download", cacheFile, resumeFile))); //$NON-NLS-1$
- return false;
- }
- // touch the file with remote modified time
- if (!resumeFile.setLastModified(reportedModified)) {
- LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind("Could not set last modified time on {0} for resumed download", resumeFile))); //$NON-NLS-1$
- return false;
- }
- return true;
- }
-
/**
* Adds a {@link SynchronousProvisioningListener} to the event bus for
* deleting cache files when the corresponding repository is deleted.
@@ -383,45 +316,42 @@ public class CacheManager {
private void updateCache(File cacheFile, URI remoteFile, long lastModifiedRemote, SubMonitor submonitor) throws FileNotFoundException, IOException, ProvisionException {
cacheFile.getParentFile().mkdirs();
- File resumeFile = new File(new File(cacheFile.getParentFile(), DOWNLOADING), cacheFile.getName());
- // if append should be performed or not
- boolean append = false;
- if (resumeFile.exists()) {
- // the resume file can be too old
- if (lastModifiedRemote != resumeFile.lastModified() || lastModifiedRemote <= 0)
- safeDelete(resumeFile);
- else {
- if (resumeFile.renameTo(cacheFile))
- append = true;
- else
- LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind("Could not move resumable file {0} into cache", resumeFile))); //$NON-NLS-1$
- }
- }
+ File downloadDir = new File(cacheFile.getParentFile(), DOWNLOADING);
+ if (!downloadDir.exists())
+ downloadDir.mkdir();
+ File tempFile = new File(downloadDir, cacheFile.getName());
+ // Ensure that the file from a previous download attempt is removed
+ if (tempFile.exists())
+ safeDelete(tempFile);
+
+ tempFile.createNewFile();
- StatefulStream metadata = new StatefulStream(new FileOutputStream(cacheFile, append));
+ StatefulStream stream = null;
+ try {
+ stream = new StatefulStream(new FileOutputStream(tempFile));
+ } catch (Exception e) {
+ throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
+ }
IStatus result = null;
try {
submonitor.setWorkRemaining(1000);
- // resume from cache file's length if in append mode
- result = getTransport().download(remoteFile, metadata, append ? cacheFile.length() : -1, submonitor.newChild(1000));
+ result = getTransport().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.
- result = metadata.getStatus();
+ result = stream.getStatus();
} finally {
- metadata.close();
- // result is null if a runtime error (other than OperationCanceledException)
- // occurred, just delete the cache file (or a later attempt could fail
- // with "premature end of file").
- if (result == null)
- cacheFile.delete();
+ stream.close();
+ // If there was any problem fetching the file, delete the temp file
+ if (result == null || !result.isOK())
+ safeDelete(tempFile);
+ }
+ if (result.isOK()) {
+ if (cacheFile.exists())
+ safeDelete(cacheFile);
+ if (tempFile.renameTo(cacheFile))
+ return;
}
- if (result.isOK())
- return;
-
- // if possible, keep a partial download to be resumed.
- if (!makeResumeable(cacheFile, remoteFile, result))
- cacheFile.delete();
if (result.getSeverity() == IStatus.CANCEL || submonitor.isCanceled())
throw new OperationCanceledException();

Back to the top