diff options
author | Pascal Rapicault | 2015-04-28 14:58:09 +0000 |
---|---|---|
committer | Pascal Rapicault | 2015-04-28 16:13:48 +0000 |
commit | 9b1fa1cad604207e24f41d6affcb28aa7c011ffb (patch) | |
tree | b0b19aadc828e96bf5705174886a894891caa50a /bundles/org.eclipse.equinox.p2.metadata.repository | |
parent | 60c11f0bbcbb5ed7ec2a7dc58625330b49b714da (diff) | |
download | rt.equinox.p2-9b1fa1cad604207e24f41d6affcb28aa7c011ffb.tar.gz rt.equinox.p2-9b1fa1cad604207e24f41d6affcb28aa7c011ffb.tar.xz rt.equinox.p2-9b1fa1cad604207e24f41d6affcb28aa7c011ffb.zip |
Bug 464614 - Use XZ as compression formats of metadata filesI20150429-0800I20150428-2000
Change-Id: I4107f2f4fff7ae827f5587dfb8e6b42ba2cf638a
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.metadata.repository')
3 files changed, 131 insertions, 1 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF index 28ff7ad26..a5cfb057c 100644 --- a/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.metadata.repository/META-INF/MANIFEST.MF @@ -18,7 +18,8 @@ Export-Package: org.eclipse.equinox.internal.p2.metadata.repository; org.eclipse.equinox.internal.p2.metadata.repository.io;x-friends:="org.eclipse.equinox.p2.engine", org.eclipse.equinox.p2.metadata.io Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)", - org.eclipse.equinox.registry + org.eclipse.equinox.registry, + org.tukaani.xz;bundle-version="1.3.0" Import-Package: javax.xml.parsers, org.eclipse.equinox.internal.p2.core.helpers, org.eclipse.equinox.internal.p2.metadata, diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/plugin.xml b/bundles/org.eclipse.equinox.p2.metadata.repository/plugin.xml index 3deee9519..36c77e732 100644 --- a/bundles/org.eclipse.equinox.p2.metadata.repository/plugin.xml +++ b/bundles/org.eclipse.equinox.p2.metadata.repository/plugin.xml @@ -7,6 +7,11 @@ <factory class="org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory"/> </extension> + <extension id="XZedRepository" point="org.eclipse.equinox.p2.metadata.repository.metadataRepositories"> + <filter suffix="content.xml.xz"/> + <factory class="org.eclipse.equinox.internal.p2.metadata.repository.XZedSimpleMetadataRepositoryFactory"/> + </extension> + <extension id="compositeRepository" point="org.eclipse.equinox.p2.metadata.repository.metadataRepositories"> <filter suffix="compositeContent.xml"/> <factory class="org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepositoryFactory"/> diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/XZedSimpleMetadataRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/XZedSimpleMetadataRepositoryFactory.java new file mode 100644 index 000000000..490ff3288 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/XZedSimpleMetadataRepositoryFactory.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2015 Rapicorp, 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: + * Rapicorp, Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.metadata.repository; + +import java.io.*; +import java.net.URI; +import java.util.Map; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.p2.core.helpers.Tracing; +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.metadata.IMetadataRepository; +import org.eclipse.equinox.p2.repository.metadata.spi.MetadataRepositoryFactory; +import org.eclipse.osgi.util.NLS; +import org.tukaani.xz.XZInputStream; + +public class XZedSimpleMetadataRepositoryFactory extends MetadataRepositoryFactory { + private static final String REPOSITORY_FILENAME = "content.xml.xz"; //$NON-NLS-1$ + private static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$ + + public IMetadataRepository create(URI location, String name, String type, Map<String, String> properties) { + if (location.getScheme().equals("file")) //$NON-NLS-1$ + return new LocalMetadataRepository(getAgent(), location, name, properties); + return new URLMetadataRepository(getAgent(), location, name, properties); + } + + /** + * 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 xzLocation = URIUtil.append(location, REPOSITORY_FILENAME); + // If the repository is local, we can return the repository file directly + if (PROTOCOL_FILE.equals(xzLocation.getScheme())) { + //look for a compressed local file + localFile = URIUtil.toFile(xzLocation); + 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.createCacheFromFile(URIUtil.append(location, REPOSITORY_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; + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.p2.repository.metadata.spi.MetadataRepositoryFactory#load(java.net.URL, org.eclipse.core.runtime.IProgressMonitor) + */ + public IMetadataRepository load(URI location, int flags, IProgressMonitor monitor) throws ProvisionException { + long time = 0; + final String debugMsg = "Validating and loading metadata repository "; //$NON-NLS-1$ + if (Tracing.DEBUG_METADATA_PARSING) { + Tracing.debug(debugMsg + location); + time = -System.currentTimeMillis(); + } + SubMonitor sub = SubMonitor.convert(monitor, 400); + try { + File localFile = getLocalFile(location, sub.newChild(300)); + InputStream stream = new BufferedInputStream(new FileInputStream(localFile)); + XZInputStream descriptorStream = new XZInputStream(stream); + try { + //parse the repository descriptor file + sub.setWorkRemaining(100); + IMetadataRepository result = new MetadataRepositoryIO(getAgent()).read(localFile.toURL(), descriptorStream, sub.newChild(100)); + if (result != null && (flags & IRepositoryManager.REPOSITORY_HINT_MODIFIABLE) > 0 && !result.isModifiable()) + return null; + if (result instanceof LocalMetadataRepository) + ((LocalMetadataRepository) result).initializeAfterLoad(location); + if (result instanceof URLMetadataRepository) + ((URLMetadataRepository) result).initializeAfterLoad(location); + if (Tracing.DEBUG_METADATA_PARSING) { + time += System.currentTimeMillis(); + Tracing.debug(debugMsg + "time (ms): " + time); //$NON-NLS-1$ + } + return result; + } finally { + safeClose(descriptorStream); + safeClose(stream); + } + } catch (FileNotFoundException e) { + String msg = NLS.bind(Messages.io_failedRead, location); + throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, msg, e)); + } catch (IOException e) { + 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 (monitor != null) + monitor.done(); + } + } + + /** + * Closes a stream, ignoring any secondary exceptions + */ + private void safeClose(InputStream stream) { + if (stream == null) + return; + try { + stream.close(); + } catch (IOException e) { + //ignore + } + } +} |