diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java')
-rw-r--r-- | bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java | 137 |
1 files changed, 75 insertions, 62 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java index d9cd59a79..4ebeb06ad 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java +++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepositoryFactory.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Sonatype Inc - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.repository.simple; @@ -19,8 +20,7 @@ import org.eclipse.core.runtime.*; import org.eclipse.equinox.internal.p2.artifact.repository.Activator; import org.eclipse.equinox.internal.p2.artifact.repository.Messages; import org.eclipse.equinox.internal.p2.core.helpers.Tracing; -import org.eclipse.equinox.internal.p2.repository.RepositoryTransport; -import org.eclipse.equinox.internal.p2.repository.Transport; +import org.eclipse.equinox.internal.p2.repository.CacheManager; import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.repository.IRepositoryManager; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; @@ -28,86 +28,90 @@ import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactRepositoryFactory; import org.eclipse.osgi.util.NLS; public class SimpleArtifactRepositoryFactory extends ArtifactRepositoryFactory { + private static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$ + private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$ + private static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$ + public SimpleArtifactRepositoryFactory() { super(); } + /** + * Returns a file in the local file system that contains the contents of the + * metadata repository at the given location. + */ + private File getLocalFile(URI location, IProgressMonitor monitor) throws IOException, ProvisionException { + File localFile = null; + URI jarLocation = SimpleArtifactRepository.getActualLocation(location, true); + URI xmlLocation = SimpleArtifactRepository.getActualLocation(location, false); + // If the repository is local, we can return the repository file directly + if (PROTOCOL_FILE.equals(xmlLocation.getScheme())) { + //look for a compressed local file + localFile = URIUtil.toFile(jarLocation); + if (localFile.exists()) + return localFile; + //look for an uncompressed local file + localFile = URIUtil.toFile(xmlLocation); + if (localFile.exists()) + return localFile; + String msg = NLS.bind(Messages.io_failedRead, location); + throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, msg, null)); + } + // file is not local, create a cache of the repository metadata + CacheManager cache = (CacheManager) getAgent().getService(CacheManager.SERVICE_NAME); + if (cache == null) + throw new IllegalArgumentException("Cache manager service not available"); //$NON-NLS-1$ + localFile = cache.createCache(location, SimpleArtifactRepository.CONTENT_FILENAME, monitor); + if (localFile == null) { + // there is no remote file in either form - this should not really happen as + // createCache should bail out with exception if something is wrong. This is an internal + // error. + throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, Messages.repoMan_internalError, null)); + } + return localFile; + } + public IArtifactRepository load(URI location, int flags, IProgressMonitor monitor) throws ProvisionException { - final String PROTOCOL_FILE = "file"; //$NON-NLS-1$ long time = 0; final String debugMsg = "Restoring artifact repository "; //$NON-NLS-1$ if (Tracing.DEBUG_METADATA_PARSING) { Tracing.debug(debugMsg + location); time = -System.currentTimeMillis(); } - File localFile = null; - boolean local = false; + SubMonitor sub = SubMonitor.convert(monitor, 400); try { - SubMonitor sub = SubMonitor.convert(monitor, 300); - OutputStream artifacts = null; - // try with compressed - boolean compress = true; - if (PROTOCOL_FILE.equals(location.getScheme())) { - local = true; - localFile = URIUtil.toFile(SimpleArtifactRepository.getActualLocation(location, true)); - if (!localFile.exists()) { - localFile = URIUtil.toFile(SimpleArtifactRepository.getActualLocation(location, false)); - compress = false; - } - } else { - //not local, return null if the caller wanted a modifiable repo - if ((flags & IRepositoryManager.REPOSITORY_HINT_MODIFIABLE) > 0) { - return null; - } - - //download to local temp file - localFile = File.createTempFile("artifacts", ".xml"); //$NON-NLS-1$ //$NON-NLS-2$ - try { - artifacts = new BufferedOutputStream(new FileOutputStream(localFile)); - IStatus status = getTransport().download(SimpleArtifactRepository.getActualLocation(location, compress), artifacts, sub.newChild(100)); - if (!status.isOK()) { - // not meaningful to continue on an authentication exception (user will likely just be prompted again) - if (status.getCode() == ProvisionException.REPOSITORY_FAILED_AUTHENTICATION) - throw new ProvisionException(status); - // retry uncompressed - compress = false; - status = getTransport().download(SimpleArtifactRepository.getActualLocation(location, compress), artifacts, sub.newChild(100)); - if (!status.isOK()) - throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, status.getMessage(), null)); - } - } finally { - if (artifacts != null) - artifacts.close(); - } - } - InputStream descriptorStream = null; + File localFile = getLocalFile(location, sub.newChild(300)); + InputStream inStream = new BufferedInputStream(new FileInputStream(localFile)); + JarInputStream jarStream = null; try { - descriptorStream = new BufferedInputStream(new FileInputStream(localFile)); - if (compress) { - URI actualLocation = SimpleArtifactRepository.getActualLocation(location, false); - JarInputStream jInStream = new JarInputStream(descriptorStream); - JarEntry jarEntry = jInStream.getNextJarEntry(); - String filename = URIUtil.lastSegment(actualLocation); - while (jarEntry != null && filename != null && !(filename.equals(jarEntry.getName()))) { - jarEntry = jInStream.getNextJarEntry(); + //if reading from a jar, obtain a stream on the entry with the actual contents + if (localFile.getAbsolutePath().endsWith(JAR_EXTENSION)) { + jarStream = new JarInputStream(inStream); + JarEntry jarEntry = jarStream.getNextJarEntry(); + String entryName = SimpleArtifactRepository.CONTENT_FILENAME + XML_EXTENSION; + while (jarEntry != null && (!entryName.equals(jarEntry.getName()))) { + jarEntry = jarStream.getNextJarEntry(); } - if (jarEntry == null) { - //there is a jar but the entry is missing or invalid, so treat this as an invalid repository - throw new IOException(NLS.bind(Messages.io_invalidLocation, actualLocation.getPath())); - } - descriptorStream = jInStream; + //if there is a jar but the entry is missing or invalid, treat this as an invalid repository + if (jarEntry == null) + throw new IOException(NLS.bind(Messages.io_invalidLocation, location)); } + //parse the repository descriptor file + sub.setWorkRemaining(100); + InputStream descriptorStream = jarStream != null ? jarStream : inStream; SimpleArtifactRepositoryIO io = new SimpleArtifactRepositoryIO(getAgent()); SimpleArtifactRepository result = (SimpleArtifactRepository) io.read(localFile.toURL(), descriptorStream, sub.newChild(100)); result.initializeAfterLoad(location); + if (result != null && (flags & IRepositoryManager.REPOSITORY_HINT_MODIFIABLE) > 0 && !result.isModifiable()) + return null; if (Tracing.DEBUG_METADATA_PARSING) { time += System.currentTimeMillis(); Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ } return result; } finally { - if (descriptorStream != null) - descriptorStream.close(); + safeClose(jarStream); + safeClose(inStream); } } catch (FileNotFoundException e) { String msg = NLS.bind(Messages.io_failedRead, location); @@ -116,8 +120,8 @@ public class SimpleArtifactRepositoryFactory extends ArtifactRepositoryFactory { String msg = NLS.bind(Messages.io_failedRead, location); throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_FAILED_READ, msg, e)); } finally { - if (!local && localFile != null && !localFile.delete()) - localFile.deleteOnExit(); + if (monitor != null) + monitor.done(); } } @@ -125,7 +129,16 @@ public class SimpleArtifactRepositoryFactory extends ArtifactRepositoryFactory { return new SimpleArtifactRepository(getAgent(), name, location, properties); } - private Transport getTransport() { - return RepositoryTransport.getInstance(); + /** + * Closes a stream, ignoring any secondary exceptions + */ + private void safeClose(InputStream stream) { + if (stream == null) + return; + try { + stream.close(); + } catch (IOException e) { + //ignore + } } } |