diff options
Diffstat (limited to 'p2/org.eclipse.cdt.p2')
20 files changed, 1476 insertions, 0 deletions
diff --git a/p2/org.eclipse.cdt.p2/.classpath b/p2/org.eclipse.cdt.p2/.classpath new file mode 100644 index 00000000000..c8ff43b0725 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/.classpath @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"> + <accessrules> + <accessrule kind="accessible" pattern="**/internal/provisional/**"/> + <accessrule kind="accessible" pattern="**/internal/p2/**"/> + </accessrules> + </classpathentry> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/p2/org.eclipse.cdt.p2/.project b/p2/org.eclipse.cdt.p2/.project new file mode 100644 index 00000000000..8808e4bb736 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.cdt.p2</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/p2/org.eclipse.cdt.p2/.settings/org.eclipse.jdt.core.prefs b/p2/org.eclipse.cdt.p2/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..aca6ee8c3da --- /dev/null +++ b/p2/org.eclipse.cdt.p2/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Sun Nov 30 21:26:19 EST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/p2/org.eclipse.cdt.p2/META-INF/MANIFEST.MF b/p2/org.eclipse.cdt.p2/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..6b9a8f9448a --- /dev/null +++ b/p2/org.eclipse.cdt.p2/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: CDT P2 customizations for SDKs +Bundle-SymbolicName: org.eclipse.cdt.p2;singleton:=true +Bundle-Version: 5.0.0 +Bundle-Activator: org.eclipse.cdt.p2.Activator +Bundle-Vendor: eclipse.org +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.equinox.p2.artifact.repository;bundle-version="1.0.2", + org.eclipse.equinox.p2.core;bundle-version="1.0.0", + org.eclipse.equinox.p2.metadata;bundle-version="1.0.0", + org.eclipse.equinox.p2.engine;bundle-version="1.0.1", + org.apache.ant;bundle-version="1.7.0" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.eclipse.cdt.p2, + org.eclipse.cdt.p2.internal.repo.artifact;x-friends:="org.eclipse.cdt.p2.generator", + org.eclipse.cdt.p2.internal.touchpoint;x-friends:="org.eclipse.cdt.p2.generator" diff --git a/p2/org.eclipse.cdt.p2/build.properties b/p2/org.eclipse.cdt.p2/build.properties new file mode 100644 index 00000000000..e9863e281ea --- /dev/null +++ b/p2/org.eclipse.cdt.p2/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/p2/org.eclipse.cdt.p2/plugin.properties b/p2/org.eclipse.cdt.p2/plugin.properties new file mode 100644 index 00000000000..007115c0829 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/plugin.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2008 Wind River Systems 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: +# Doug Schaefer (Wind River) - initial API and implementation +############################################################################### + +installArtifactRepository=Install Artifact Repository diff --git a/p2/org.eclipse.cdt.p2/plugin.xml b/p2/org.eclipse.cdt.p2/plugin.xml new file mode 100644 index 00000000000..cfbad8fef56 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/plugin.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + <extension + id="org.eclipse.cdt.p2.internal.repo.artifact.InstallArtifactRepository" + name="%installArtifactRepository" + point="org.eclipse.equinox.p2.artifact.repository.artifactRepositories"> + <factory + class="org.eclipse.cdt.p2.internal.repo.artifact.InstallArtifactRepositoryFactory"> + </factory> + <filter + suffix="installArtifact.xml"> + </filter> + </extension> + <extension + point="org.eclipse.equinox.p2.engine.touchpoints"> + <touchpoint + class="org.eclipse.cdt.p2.internal.touchpoint.SDKTouchpoint" + type="org.eclipse.cdt.p2.internal.touchpoint.SDKTouchpoint" + version="1"> + </touchpoint> + </extension> + +</plugin> diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/Activator.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/Activator.java new file mode 100644 index 00000000000..7b80dae759f --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/Activator.java @@ -0,0 +1,84 @@ +package org.eclipse.cdt.p2; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.p2"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + static public BundleContext getContext() { + return plugin.getBundle().getBundleContext(); + } + + /** + * Return a service from our context. + * + * @param name name of the service + * @return the service + */ + @SuppressWarnings("unchecked") + public <T> T getService(Class<T> clazz) { + BundleContext context = getBundle().getBundleContext(); + ServiceReference ref = context.getServiceReference(clazz.getName()); + return (ref != null) ? (T)context.getService(ref) : null; + } + + /** + * Spit out the log. + * + * @param status + */ + public void log(int severity, String message, Throwable exception) { + Platform.getLog(plugin.getBundle()).log(new Status(severity, PLUGIN_ID, message, exception)); + } + + public void log(IStatus status) { + Platform.getLog(plugin.getBundle()).log(status); + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListReader.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListReader.java new file mode 100644 index 00000000000..914b42db828 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListReader.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +/** + * @author DSchaefe + * + */ +public class FileListReader { + + private final BufferedReader in; + + public FileListReader(File fileListfile) throws IOException { + in = new BufferedReader(new FileReader(fileListfile)); + } + + public InstalledFile getNext() throws IOException { + String line = in.readLine(); + return line != null ? new InstalledFile(line) : null; + } + + public void close() throws IOException { + in.close(); + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListWriter.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListWriter.java new file mode 100644 index 00000000000..5c8144f1420 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/FileListWriter.java @@ -0,0 +1,24 @@ +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class FileListWriter { + + private final BufferedWriter out; + + public FileListWriter(File fileListFile) throws IOException { + out = new BufferedWriter(new FileWriter(fileListFile)); + } + + public void addFile(InstalledFile file) throws IOException { + file.write(out); + } + + public void close() throws IOException { + out.close(); + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepository.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepository.java new file mode 100644 index 00000000000..1aade3cc226 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepository.java @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.p2.Activator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.core.helpers.URLUtil; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.ArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRequest; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation; +import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository; +import org.eclipse.equinox.internal.provisional.p2.engine.IProfile; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; +import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.AbstractArtifactRepository; + +/** + * @author DSchaefe + * + */ +public class InstallArtifactRepository extends AbstractArtifactRepository { + + // Install directory property + public static final String INSTALL_DIR = "installDir"; //$NON-NLS-1$ + public static final String SUB_DIR = "subdir"; //$NON-NLS-1$ + public static final String FILENAME = "installArtifact.xml"; //$NON-NLS-1$ + + public static final String COMPRESSION = "compression"; + public static final String GZIP_COMPRESSON = "tar.gz"; + public static final String BZIP2_COMPRESSION = "tar.bz2"; + public static final String ZIP_COMPRESSION = "zip"; + + private static final String VERSION = "2.0.0"; //$NON-NLS-1$ + private static final String DESCRIPTION = "Wind River Metadata Repository"; //$NON-NLS-1$ + private static final String PROVIDER = "Wind River"; //$NON-NLS-1$ + + + private Map<IArtifactKey, IArtifactDescriptor> artifacts = new HashMap<IArtifactKey, IArtifactDescriptor>(); + + public InstallArtifactRepository(URL aLocation, String aName, Map aProperties) { + super(aName, InstallArtifactRepository.class.getName(), VERSION, aLocation, DESCRIPTION, PROVIDER, aProperties); + save(); + } + + /** + * Constructor for reading in from file. + * + * @param _name + * @param _type + * @param _version + * @param _description + * @param _provider + * @param _artifacts + * @param mappingRules + * @param _properties + */ + InstallArtifactRepository(String _name, String _type, String _version, URL _location, String _description, String _provider, Set<ArtifactDescriptor> _artifacts, Map _properties) { + super(_name, _type, _version, _location, _description, _provider, _properties); + for (IArtifactDescriptor descriptor : _artifacts) + artifacts.put(descriptor.getArtifactKey(), descriptor); + } + + public static URL getActualLocation(URL base) { + final String name = FILENAME; + String spec = base.toExternalForm(); + if (spec.endsWith(name)) + return base; + if (spec.endsWith("/")) //$NON-NLS-1$ + spec += name; + else + spec += "/" + name; //$NON-NLS-1$ + try { + return new URL(spec); + } catch (MalformedURLException e) { + return null; + } + } + + public static IArtifactRepository getRepository(IProfile profile) throws ProvisionException { + AgentLocation location = Activator.getDefault().getService(AgentLocation.class); + String profileId = profile.getProfileId(); + profileId = profileId.replaceAll("[:/\\\\]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + try { + URL url = location.getDataArea(Activator.PLUGIN_ID); + url = new URL(url.toExternalForm() + "installDirRepo/" + profileId + "/" + FILENAME); //$NON-NLS-1$ //$NON-NLS-2$ + IArtifactRepositoryManager repoMgr = Activator.getDefault().getService(IArtifactRepositoryManager.class); + try { + return repoMgr.loadRepository(url, null); + } catch (ProvisionException e) { + Map<String, String> properties = new HashMap<String, String>(); + properties.put(INSTALL_DIR, profile.getLocalProperty(IProfile.PROP_INSTALL_FOLDER)); + return repoMgr.createRepository(url, profile.getProfileId(), InstallArtifactRepository.class.getName(), properties); + } + } catch (MalformedURLException e) { + Activator.getDefault().log(IStatus.ERROR, "Creating install repo URI", e); //$NON-NLS-1$ + return null; + } + } + + @Override + public boolean isModifiable() { + // We're always modifiable + // TODO - unless we're a shared install... + return true; + } + + @Override + public boolean contains(IArtifactDescriptor descriptor) { + return contains(descriptor.getArtifactKey()); + } + + @Override + public boolean contains(IArtifactKey key) { + return artifacts.containsKey(key); + } + + @Override + public IStatus getArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor) { + // copying from this repository is not supported, yet... + throw new UnsupportedOperationException(); + } + + @Override + public IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key) { + // we only have one artifact descriptor per key + IArtifactDescriptor desc = artifacts.get(key); + if (desc != null) + return new IArtifactDescriptor[] { desc }; + return new IArtifactDescriptor[0]; + } + + @Override + public IArtifactKey[] getArtifactKeys() { + Set<IArtifactKey> keyset = artifacts.keySet(); + return keyset.toArray(new IArtifactKey[keyset.size()]); + } + + @Override + public IStatus getArtifacts(IArtifactRequest[] requests, IProgressMonitor monitor) { + // TODO Auto-generated method stub + return Status.OK_STATUS; + } + + @Override + public synchronized void addDescriptor(IArtifactDescriptor descriptor) { + super.addDescriptor(descriptor); + artifacts.put(descriptor.getArtifactKey(), descriptor); + save(); + } + + @Override + public synchronized void addDescriptors(IArtifactDescriptor[] descriptors) { + super.addDescriptors(descriptors); + for (IArtifactDescriptor descriptor : descriptors) + artifacts.put(descriptor.getArtifactKey(), descriptor); + save(); + } + + Collection<IArtifactDescriptor> getDescriptors() { + return artifacts.values(); + } + + private File getFileListFile(IArtifactKey artifact) throws IOException { + File file; + try { + file = new File(URLUtil.toURI(location)); + } catch (URISyntaxException e) { + throw new IOException(e); + } + if (file.getName().equals(FILENAME)) + file = file.getParentFile(); + return new File(file, artifact.getId() + "_" + artifact.getVersion()); //$NON-NLS-1$ + } + + @Override + public OutputStream getOutputStream(IArtifactDescriptor descriptor) throws ProvisionException { + // Do the modifiable check in the superclass + super.getOutputStream(descriptor); + + // Add the descriptor to the list and save it + // TODO what if it's already there? + if (!contains(descriptor)) + addDescriptor(descriptor); + + // Return the extractor + try { + String installDirName = (String)getProperties().get(INSTALL_DIR); + if (installDirName == null) + throw new ProvisionException("Install directory not set"); //$NON-NLS-1$ + File installDir = new File(installDirName); + String subDir = (String)descriptor.getProperties().get(SUB_DIR); + if (subDir != null) + installDir = new File(installDir, subDir); + PipedOutputStream out = new PipedOutputStream(); + PipedInputStream in = new PipedInputStream(out); + String compression = descriptor.getProperty(COMPRESSION); + if (ZIP_COMPRESSION.equals(compression)) { + // TODO a zip extractor + } else { + TarExtractor extractor = new TarExtractor(in, installDir, + new FileListWriter(getFileListFile(descriptor.getArtifactKey())), + compression); + extractor.start(); + } + return out; + } catch (IOException e) { + // TODO How could that happen + throw new ProvisionException(e.getLocalizedMessage()); + } + } + + private void deleteFiles(IArtifactKey artifact) { + File fileListFile = null; + try { + fileListFile = getFileListFile(artifact); + FileListReader reader = new FileListReader(fileListFile); + InstalledFile file; + while ((file = reader.getNext()) != null) { + file.uninstall(); + } + reader.close(); + } catch (IOException e) { + Activator.getDefault().log(IStatus.WARNING, "deleting file", e); //$NON-NLS-1$ + } finally { + if (fileListFile != null) + fileListFile.delete(); + } + } + + @Override + public void removeAll() { + super.removeAll(); + for (IArtifactKey artifact : artifacts.keySet()) + deleteFiles(artifact); + artifacts.clear(); + save(); + } + + @Override + public void removeDescriptor(IArtifactDescriptor descriptor) { + removeDescriptor(descriptor.getArtifactKey()); + } + + @Override + public void removeDescriptor(IArtifactKey key) { + super.removeDescriptor(key); + deleteFiles(key); + artifacts.remove(key); + save(); + } + + private void save() { + try { + OutputStream os = null; + try { + URL actualLocation = getActualLocation(location); + File artifactsFile = new File(actualLocation.getPath()); + artifactsFile.getParentFile().mkdirs(); + os = new FileOutputStream(artifactsFile); + super.setProperty(IRepository.PROP_TIMESTAMP, Long.toString(System.currentTimeMillis())); + new InstallArtifactRepositoryIO().write(this, os); + } catch (IOException e) { + // TODO proper exception handling + e.printStackTrace(); + } finally { + if (os != null) + os.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryFactory.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryFactory.java new file mode 100644 index 00000000000..55e236acd7d --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryFactory.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Map; + +import org.eclipse.cdt.p2.Activator; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.IArtifactRepositoryFactory; +import org.eclipse.osgi.util.NLS; + +/** + * @author DSchaefe + * + */ +public class InstallArtifactRepositoryFactory implements IArtifactRepositoryFactory { + + public IArtifactRepository create(URL location, String name, String type, Map properties) throws ProvisionException { + return new InstallArtifactRepository(location, name, properties); + } + + public IArtifactRepository load(URL location, IProgressMonitor monitor) throws ProvisionException { + File localFile = null; + boolean local = false; + try { + localFile = new File(InstallArtifactRepository.getActualLocation(location).getPath()); + InputStream descriptorStream = null; + try { + descriptorStream = new BufferedInputStream(new FileInputStream(localFile)); + InstallArtifactRepositoryIO io = new InstallArtifactRepositoryIO(); + return io.read(localFile.toURI().toURL(), descriptorStream); + } finally { + if (descriptorStream != null) + descriptorStream.close(); + } + } catch (FileNotFoundException e) { + String msg = NLS.bind(Messages.io_failedRead, location); + throw new ProvisionException(new Status(IStatus.ERROR, Activator.PLUGIN_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.PLUGIN_ID, ProvisionException.REPOSITORY_FAILED_READ, msg, e)); + } finally { + // TODO why is this here? + if (!local && localFile != null && !localFile.delete()) + localFile.deleteOnExit(); + } + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryIO.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryIO.java new file mode 100644 index 00000000000..5e33581a2bd --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstallArtifactRepositoryIO.java @@ -0,0 +1,479 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.cdt.p2.Activator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties; +import org.eclipse.equinox.internal.p2.metadata.ArtifactKey; +import org.eclipse.equinox.internal.p2.persistence.XMLParser; +import org.eclipse.equinox.internal.p2.persistence.XMLWriter; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.ArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStepDescriptor; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; +import org.eclipse.osgi.service.resolver.VersionRange; +import org.eclipse.osgi.util.NLS; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Version; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @author DSchaefe + * + */ +public class InstallArtifactRepositoryIO { + + /** + * Writes the given artifact repository to the stream. + * This method performs buffering, and closes the stream when finished. + */ + public void write(InstallArtifactRepository repository, OutputStream output) { + OutputStream bufferedOutput = null; + try { + try { + bufferedOutput = new BufferedOutputStream(output); + Writer repositoryWriter = new Writer(bufferedOutput); + repositoryWriter.write(repository); + } finally { + if (bufferedOutput != null) { + bufferedOutput.close(); + } + } + } catch (IOException ioe) { + // TODO shouldn't this throw a core exception? + ioe.printStackTrace(); + } + } + + /** + * Reads the artifact repository from the given stream, + * and returns the contained array of abstract artifact repositories. + * + * This method performs buffering, and closes the stream when finished. + */ + public IArtifactRepository read(URL location, InputStream input) throws ProvisionException { + BufferedInputStream bufferedInput = null; + try { + try { + bufferedInput = new BufferedInputStream(input); + Parser repositoryParser = new Parser(Activator.getContext(), Activator.PLUGIN_ID, location); + repositoryParser.parse(input); + IStatus result = repositoryParser.getStatus(); + switch (result.getSeverity()) { + case IStatus.CANCEL : + throw new OperationCanceledException(); + case IStatus.ERROR : + throw new ProvisionException(result); + case IStatus.WARNING : + case IStatus.INFO : + Activator.getDefault().log(result); + } + return repositoryParser.getRepository(); + } finally { + if (bufferedInput != null) + bufferedInput.close(); + } + } catch (IOException ioe) { + String msg = NLS.bind(Messages.io_failedRead, location); + throw new ProvisionException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ProvisionException.REPOSITORY_FAILED_READ, msg, ioe)); + } + } + + private interface XMLConstants extends org.eclipse.equinox.internal.p2.persistence.XMLConstants { + + // Constants defining the structure of the XML for a InstallArtifactRepository + + // A format version number for simple artifact repository XML. + public static final Version CURRENT_VERSION = new Version(1, 0, 0); + public static final VersionRange XML_TOLERANCE = new VersionRange(CURRENT_VERSION, true, new Version(2, 0, 0), false); + + // Constants for processing instructions + public static final String PI_REPOSITORY_TARGET = "artifactRepository"; //$NON-NLS-1$ + public static XMLWriter.ProcessingInstruction[] PI_DEFAULTS = new XMLWriter.ProcessingInstruction[] {XMLWriter.ProcessingInstruction.makeClassVersionInstruction(PI_REPOSITORY_TARGET, InstallArtifactRepository.class, CURRENT_VERSION)}; + + // Constants for artifact repository elements + public static final String REPOSITORY_ELEMENT = "repository"; //$NON-NLS-1$ + public static final String REPOSITORY_PROPERTIES_ELEMENT = "repositoryProperties"; //$NON-NLS-1$ + public static final String MAPPING_RULES_ELEMENT = "mappings"; //$NON-NLS-1$ + public static final String MAPPING_RULE_ELEMENT = "rule"; //$NON-NLS-1$ + public static final String ARTIFACTS_ELEMENT = "artifacts"; //$NON-NLS-1$ + public static final String ARTIFACT_ELEMENT = "artifact"; //$NON-NLS-1$ + public static final String PROCESSING_STEPS_ELEMENT = "processing"; //$NON-NLS-1$ + public static final String PROCESSING_STEP_ELEMENT = "step"; //$NON-NLS-1$ + + public static final String MAPPING_RULE_FILTER_ATTRIBUTE = "filter"; //$NON-NLS-1$ + public static final String MAPPING_RULE_OUTPUT_ATTRIBUTE = "output"; //$NON-NLS-1$ + + public static final String ARTIFACT_CLASSIFIER_ATTRIBUTE = CLASSIFIER_ATTRIBUTE; + + public static final String STEP_DATA_ATTRIBUTE = "data"; //$NON-NLS-1$ + public static final String STEP_REQUIRED_ATTRIBUTE = "required"; //$NON-NLS-1$ + } + + // XML writer for a InstallArtifactRepository + protected class Writer extends XMLWriter implements XMLConstants { + + public Writer(OutputStream output) throws IOException { + super(output, PI_DEFAULTS); + } + + /** + * Write the given artifact repository to the output stream. + */ + public void write(InstallArtifactRepository repository) { + start(REPOSITORY_ELEMENT); + attribute(NAME_ATTRIBUTE, repository.getName()); + attribute(TYPE_ATTRIBUTE, repository.getType()); + attribute(VERSION_ATTRIBUTE, repository.getVersion()); + attributeOptional(PROVIDER_ATTRIBUTE, repository.getProvider()); + attributeOptional(DESCRIPTION_ATTRIBUTE, repository.getDescription()); // TODO: could be cdata? + + writeProperties(repository.getProperties()); + writeArtifacts(repository.getDescriptors()); + + end(REPOSITORY_ELEMENT); + flush(); + } + + private void writeArtifacts(Collection<IArtifactDescriptor> artifactDescriptors) { + start(ARTIFACTS_ELEMENT); + attribute(COLLECTION_SIZE_ATTRIBUTE, artifactDescriptors.size()); + for (IArtifactDescriptor idescriptor : artifactDescriptors) { + ArtifactDescriptor descriptor = (ArtifactDescriptor)idescriptor; + IArtifactKey key = descriptor.getArtifactKey(); + start(ARTIFACT_ELEMENT); + attribute(ARTIFACT_CLASSIFIER_ATTRIBUTE, key.getClassifier()); + attribute(ID_ATTRIBUTE, key.getId()); + attribute(VERSION_ATTRIBUTE, key.getVersion()); + writeProcessingSteps(descriptor.getProcessingSteps()); + writeProperties(descriptor.getProperties()); + writeProperties(REPOSITORY_PROPERTIES_ELEMENT, descriptor.getRepositoryProperties()); + end(ARTIFACT_ELEMENT); + } + end(ARTIFACTS_ELEMENT); + } + + private void writeProcessingSteps(ProcessingStepDescriptor[] processingSteps) { + if (processingSteps.length > 0) { + start(PROCESSING_STEPS_ELEMENT); + attribute(COLLECTION_SIZE_ATTRIBUTE, processingSteps.length); + for (int i = 0; i < processingSteps.length; i++) { + start(PROCESSING_STEP_ELEMENT); + attribute(ID_ATTRIBUTE, processingSteps[i].getProcessorId()); + attribute(STEP_DATA_ATTRIBUTE, processingSteps[i].getData()); + attribute(STEP_REQUIRED_ATTRIBUTE, processingSteps[i].isRequired()); + end(PROCESSING_STEP_ELEMENT); + } + end(PROCESSING_STEPS_ELEMENT); + } + } + } + + /* + * Parser for the contents of a InstallArtifactRepository, + * as written by the Writer class. + */ + private class Parser extends XMLParser implements XMLConstants { + + private InstallArtifactRepository theRepository; + final URL location; + + public Parser(BundleContext _context, String _bundleId, URL _location) { + super(_context, _bundleId); + location = _location; + } + + public void parse(File file) throws IOException { + parse(new FileInputStream(file)); + } + + public synchronized void parse(InputStream stream) throws IOException { + this.status = null; + try { + // TODO: currently not caching the parser since we make no assumptions + // or restrictions on concurrent parsing + getParser(); + RepositoryHandler repositoryHandler = new RepositoryHandler(); + xmlReader.setContentHandler(new RepositoryDocHandler(REPOSITORY_ELEMENT, repositoryHandler)); + xmlReader.parse(new InputSource(stream)); + if (isValidXML()) { + theRepository = repositoryHandler.getRepository(); + } + } catch (SAXException e) { + throw new IOException(e.getMessage()); + } catch (ParserConfigurationException e) { + throw new IOException(e.getMessage()); + } finally { + stream.close(); + } + } + + public InstallArtifactRepository getRepository() { + return theRepository; + } + + @Override + protected Object getRootObject() { + return theRepository; + } + + private final class RepositoryDocHandler extends DocHandler { + + public RepositoryDocHandler(String rootName, RootHandler rootHandler) { + super(rootName, rootHandler); + } + + @Override + public void processingInstruction(String target, String data) throws SAXException { + if (PI_REPOSITORY_TARGET.equals(target)) { + // TODO: should the root handler be constructed based on class + // via an extension registry mechanism? + // String clazz = extractPIClass(data); + // TODO: version tolerance by extension + Version repositoryVersion = extractPIVersion(target, data); + if (!XML_TOLERANCE.isIncluded(repositoryVersion)) { + throw new SAXException(NLS.bind(Messages.io_incompatibleVersion, repositoryVersion, XML_TOLERANCE)); + } + } + } + + } + + private final class RepositoryHandler extends RootHandler { + + private final String[] required = new String[] {NAME_ATTRIBUTE, TYPE_ATTRIBUTE, VERSION_ATTRIBUTE}; + private final String[] optional = new String[] {DESCRIPTION_ATTRIBUTE, PROVIDER_ATTRIBUTE}; + + private String[] attrValues = new String[required.length + optional.length]; + + private PropertiesHandler propertiesHandler = null; + private ArtifactsHandler artifactsHandler = null; + + private InstallArtifactRepository repository = null; + + public RepositoryHandler() { + super(); + } + + public InstallArtifactRepository getRepository() { + return repository; + } + + @Override + protected void handleRootAttributes(Attributes attributes) { + attrValues = parseAttributes(attributes, required, optional); + attrValues[2] = checkVersion(REPOSITORY_ELEMENT, VERSION_ATTRIBUTE, attrValues[2]).toString(); + } + + @Override + public void startElement(String name, Attributes attributes) { + if (ARTIFACTS_ELEMENT.equals(name)) { + if (artifactsHandler == null) { + artifactsHandler = new ArtifactsHandler(this, attributes); + } else { + duplicateElement(this, name, attributes); + } + } else if (PROPERTIES_ELEMENT.equals(name)) { + if (propertiesHandler == null) { + propertiesHandler = new PropertiesHandler(this, attributes); + } else { + duplicateElement(this, name, attributes); + } + } else { + invalidElement(name, attributes); + } + } + + @Override + protected void finished() { + if (isValidXML()) { + Map properties = (propertiesHandler == null ? new OrderedProperties(0) // + : propertiesHandler.getProperties()); + Set<ArtifactDescriptor> artifacts = (artifactsHandler == null ? new HashSet<ArtifactDescriptor>(0) // + : artifactsHandler.getArtifacts()); + repository = new InstallArtifactRepository( + attrValues[0], attrValues[1], attrValues[2], Parser.this.location, + attrValues[3], attrValues[4], artifacts, properties); + } + } + } + + protected class ArtifactsHandler extends AbstractHandler { + + private Set<ArtifactDescriptor> artifacts; + + public ArtifactsHandler(AbstractHandler _parentHandler, Attributes attributes) { + super(_parentHandler, ARTIFACTS_ELEMENT); + String size = parseOptionalAttribute(attributes, COLLECTION_SIZE_ATTRIBUTE); + artifacts = (size != null ? new LinkedHashSet<ArtifactDescriptor>(new Integer(size).intValue()) : new LinkedHashSet<ArtifactDescriptor>(4)); + } + + public Set<ArtifactDescriptor> getArtifacts() { + return artifacts; + } + + @Override + public void startElement(String name, Attributes attributes) { + if (name.equals(ARTIFACT_ELEMENT)) { + new ArtifactHandler(this, attributes, artifacts); + } else { + invalidElement(name, attributes); + } + } + } + + protected class ArtifactHandler extends AbstractHandler { + + private final String[] required = new String[] {ARTIFACT_CLASSIFIER_ATTRIBUTE, ID_ATTRIBUTE, VERSION_ATTRIBUTE}; + + private Set<ArtifactDescriptor> artifacts; + ArtifactDescriptor currentArtifact = null; + + private PropertiesHandler propertiesHandler = null; + private PropertiesHandler repositoryPropertiesHandler = null; + private ProcessingStepsHandler processingStepsHandler = null; + + public ArtifactHandler(AbstractHandler _parentHandler, Attributes attributes, Set<ArtifactDescriptor> _artifacts) { + super(_parentHandler, ARTIFACT_ELEMENT); + this.artifacts = _artifacts; + String[] values = parseRequiredAttributes(attributes, required); + Version version = checkVersion(ARTIFACT_ELEMENT, VERSION_ATTRIBUTE, values[2]); + // TODO: resolve access restriction on ArtifactKey construction + currentArtifact = new ArtifactDescriptor(new ArtifactKey(values[0], values[1], version)); + } + + public ArtifactDescriptor getArtifact() { + return currentArtifact; + } + + @Override + public void startElement(String name, Attributes attributes) { + if (PROCESSING_STEPS_ELEMENT.equals(name)) { + if (processingStepsHandler == null) { + processingStepsHandler = new ProcessingStepsHandler(this, attributes); + } else { + duplicateElement(this, name, attributes); + } + } else if (PROPERTIES_ELEMENT.equals(name)) { + if (propertiesHandler == null) { + propertiesHandler = new PropertiesHandler(this, attributes); + } else { + duplicateElement(this, name, attributes); + } + } else if (REPOSITORY_PROPERTIES_ELEMENT.equals(name)) { + if (repositoryPropertiesHandler == null) { + repositoryPropertiesHandler = new PropertiesHandler(this, attributes); + } else { + duplicateElement(this, name, attributes); + } + } else { + invalidElement(name, attributes); + } + } + + @Override + protected void finished() { + if (isValidXML() && currentArtifact != null) { + Map properties = (propertiesHandler == null ? new OrderedProperties(0) : propertiesHandler.getProperties()); + currentArtifact.addProperties(properties); + + properties = (repositoryPropertiesHandler == null ? new OrderedProperties(0) : repositoryPropertiesHandler.getProperties()); + currentArtifact.addRepositoryProperties(properties); + + ProcessingStepDescriptor[] processingSteps = (processingStepsHandler == null ? new ProcessingStepDescriptor[0] // + : processingStepsHandler.getProcessingSteps()); + currentArtifact.setProcessingSteps(processingSteps); + artifacts.add(currentArtifact); + } + } + } + + protected class ProcessingStepsHandler extends AbstractHandler { + + private List<ProcessingStepDescriptor> processingSteps; + + public ProcessingStepsHandler(AbstractHandler _parentHandler, Attributes attributes) { + super(_parentHandler, PROCESSING_STEPS_ELEMENT); + String size = parseOptionalAttribute(attributes, COLLECTION_SIZE_ATTRIBUTE); + processingSteps = (size != null ? new ArrayList<ProcessingStepDescriptor>(new Integer(size).intValue()) : new ArrayList<ProcessingStepDescriptor>(4)); + } + + public ProcessingStepDescriptor[] getProcessingSteps() { + return processingSteps.toArray(new ProcessingStepDescriptor[processingSteps.size()]); + } + + @Override + public void startElement(String name, Attributes attributes) { + if (name.equals(PROCESSING_STEP_ELEMENT)) { + new ProcessingStepHandler(this, attributes, processingSteps); + } else { + invalidElement(name, attributes); + } + } + } + + protected class ProcessingStepHandler extends AbstractHandler { + + private final String[] required = new String[] {ID_ATTRIBUTE, STEP_REQUIRED_ATTRIBUTE}; + private final String[] optional = new String[] {STEP_DATA_ATTRIBUTE}; + + public ProcessingStepHandler(AbstractHandler _parentHandler, Attributes attributes, List<ProcessingStepDescriptor> processingSteps) { + super(_parentHandler, PROCESSING_STEP_ELEMENT); + String[] attributeValues = parseAttributes(attributes, required, optional); + processingSteps.add(new ProcessingStepDescriptor(attributeValues[0], attributeValues[1], checkBoolean(PROCESSING_STEP_ELEMENT, STEP_REQUIRED_ATTRIBUTE, attributeValues[2]).booleanValue())); + } + + @Override + public void startElement(String name, Attributes attributes) { + invalidElement(name, attributes); + } + } + + @Override + protected String getErrorMessage() { + return Messages.io_parseError; + } + + @Override + public String toString() { + // TODO: + return null; + } + + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstalledFile.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstalledFile.java new file mode 100644 index 00000000000..0cba8bdcfd7 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/InstalledFile.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; + +/** + * @author DSchaefe + * + */ +public class InstalledFile { + + private final File file; + private final long lastModified; + + public InstalledFile(File _file, long _lastModified) { + file = _file; + lastModified = _lastModified; + } + + InstalledFile(String line) { + String[] entries = line.split(","); //$NON-NLS-1$ + if (entries.length < 2) { + file = null; + lastModified = 0; + return; + } + file = new File(entries[0]); + lastModified = Long.parseLong(entries[1]); + } + + public File getFile() { + return file; + } + + public long getLastModified() { + return lastModified; + } + + public void uninstall() { + if (file != null && file.lastModified() == lastModified) { + File f = file; + while (f != null && f.delete()) + f = f.getParentFile(); + } + } + + void write(BufferedWriter out) throws IOException { + out.write(file.getAbsolutePath()); + out.write(','); + out.write(String.valueOf(lastModified)); + out.newLine(); + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/Messages.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/Messages.java new file mode 100644 index 00000000000..2e1d3cca1a6 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import org.eclipse.osgi.util.NLS; + +/** + * @author DSchaefe + * + */ +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.p2.internal.repo.artifact.messages"; //$NON-NLS-1$ + + public static String io_failedRead; + public static String io_incompatibleVersion; + public static String io_parseError; + + static { + // initialize resource bundles + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + // Do not instantiate + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/TarExtractor.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/TarExtractor.java new file mode 100644 index 00000000000..be70385deb3 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/TarExtractor.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.repo.artifact; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; + +import org.apache.tools.bzip2.CBZip2InputStream; +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarInputStream; + +/** + * @author DSchaefe + * + */ +public class TarExtractor extends Thread { + + private final InputStream in; + private final File installDir; + private final FileListWriter fileListWriter; + private final String compression; + + public TarExtractor(InputStream in, File installDir, FileListWriter fileListWriter, String compression) { + this.in = in; + this.installDir = installDir; + this.fileListWriter = fileListWriter; + this.compression = compression; + } + + @Override + public void run() { + try { + InputStream compIn; + if (InstallArtifactRepository.GZIP_COMPRESSON.equals(compression)) + compIn = new GZIPInputStream(in); + else if (InstallArtifactRepository.BZIP2_COMPRESSION.equals(compression)) { + // Skip the magic bytes first + in.read(new byte[2]); + compIn = new CBZip2InputStream(in); + } else { + // No idea + return; + } + + TarInputStream tarIn = new TarInputStream(compIn); + for (TarEntry tarEntry = tarIn.getNextEntry(); tarEntry != null; tarEntry = tarIn.getNextEntry()) { + File outFile = new File(installDir, tarEntry.getName()); + if (tarEntry.isDirectory()) { + outFile.mkdirs(); + } else { + if (outFile.exists()) + outFile.delete(); + else + outFile.getParentFile().mkdirs(); + FileOutputStream outStream = new FileOutputStream(outFile); + tarIn.copyEntryContents(outStream); + outStream.close(); + long lastModified = tarEntry.getModTime().getTime(); + outFile.setLastModified(lastModified); + fileListWriter.addFile(new InstalledFile(outFile, lastModified)); + } + } + tarIn.close(); + fileListWriter.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/messages.properties b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/messages.properties new file mode 100644 index 00000000000..a0aa4f7ad88 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/repo/artifact/messages.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2008 Wind River Systems 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: +# Doug Schaefer (Wind River) - initial API and implementation +############################################################################### + +io_failedRead=Unable to read repository at {0}. +io_incompatibleVersion=Install artifact repository has incompatible version {0}; expected {1}. +io_parseError=Error parsing install artifact repository. +
\ No newline at end of file diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/CollectAction.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/CollectAction.java new file mode 100644 index 00000000000..9b849ec57ad --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/CollectAction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.touchpoint; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.cdt.p2.internal.repo.artifact.InstallArtifactRepository; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.artifact.repository.MirrorRequest; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRequest; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.engine.IProfile; +import org.eclipse.equinox.internal.provisional.p2.engine.InstallableUnitOperand; +import org.eclipse.equinox.internal.provisional.p2.engine.ProvisioningAction; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; +import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; + +/** + * @author DSchaefe + * + */ +public class CollectAction extends ProvisioningAction { + + public static final String ACTION_NAME = "collect"; + + @Override + public IStatus execute(Map parameters) { + try { + InstallableUnitOperand operand = (InstallableUnitOperand)parameters.get("operand"); + IInstallableUnit installableUnit = operand.second(); + IProfile profile = (IProfile)parameters.get("profile"); //$NON-NLS-1$ + + IArtifactRequest[] requests; + IArtifactKey[] toDownload = installableUnit.getArtifacts(); + if (toDownload == null || toDownload.length == 0) + requests = new IArtifactRequest[0]; + else { + IArtifactRepository destination = InstallArtifactRepository.getRepository(profile); + requests = new IArtifactRequest[toDownload.length]; + for (int i = 0; i < toDownload.length; i++) + requests[i] = new MirrorRequest(toDownload[i], destination, null, null); + } + + Collection artifactRequests = (Collection)parameters.get("artifactRequests"); + artifactRequests.add(requests); + return Status.OK_STATUS; + } catch (ProvisionException e) { + return e.getStatus(); + } + } + + @Override + public IStatus undo(Map parameters) { + // No undo + return Status.OK_STATUS; + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/SDKTouchpoint.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/SDKTouchpoint.java new file mode 100644 index 00000000000..7a6279d9afa --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/SDKTouchpoint.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.touchpoint; + +import org.eclipse.equinox.internal.provisional.p2.engine.ProvisioningAction; +import org.eclipse.equinox.internal.provisional.p2.engine.Touchpoint; +import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory; +import org.eclipse.equinox.internal.provisional.p2.metadata.TouchpointType; +import org.osgi.framework.Version; + +/** + * @author DSchaefe + * + */ +public class SDKTouchpoint extends Touchpoint { + + public static final TouchpointType TOUCHPOINT_TYPE = MetadataFactory.createTouchpointType(SDKTouchpoint.class.getName(), new Version("1")); + + @Override + public ProvisioningAction getAction(String actionId) { + if (CollectAction.ACTION_NAME.equals(actionId)) + return new CollectAction(); + else if (UninstallAction.ACTION_NAME.equals(actionId)) + return new UninstallAction(); + else + return null; + } + + @Override + public TouchpointType getTouchpointType() { + return TOUCHPOINT_TYPE; + } + +} diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/UninstallAction.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/UninstallAction.java new file mode 100644 index 00000000000..85b270528c0 --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/p2/internal/touchpoint/UninstallAction.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, 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: + * Doug Schaefer - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.p2.internal.touchpoint; + +import java.util.Map; + +import org.eclipse.cdt.p2.internal.repo.artifact.InstallArtifactRepository; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.engine.IProfile; +import org.eclipse.equinox.internal.provisional.p2.engine.ProvisioningAction; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; + +/** + * @author DSchaefe + * + */ +public class UninstallAction extends ProvisioningAction { + + public static final String ACTION_NAME = "uninstall"; + + @Override + public IStatus execute(Map parameters) { + IProfile profile = (IProfile)parameters.get("profile"); + IArtifactKey artifact = (IArtifactKey)parameters.get("artifact"); + + try { + IArtifactRepository repo = InstallArtifactRepository.getRepository(profile); + repo.removeDescriptor(artifact); + } catch (ProvisionException e) { + return e.getStatus(); + } + return Status.OK_STATUS; + } + + @Override + public IStatus undo(Map parameters) { + return Status.OK_STATUS; + } + +} |