diff options
author | Jeff McAffer | 2007-11-13 01:42:18 +0000 |
---|---|---|
committer | Jeff McAffer | 2007-11-13 01:42:18 +0000 |
commit | d2010141492295ff80d70e0c904dacb67712c7a0 (patch) | |
tree | 55b494fe45064bc59120a8f34acdaf9e171d04e3 /bundles/org.eclipse.equinox.p2.artifact.processors | |
parent | 11621e9ef64b984cc4dc8fb2a3e0d7fb003e94c0 (diff) | |
download | rt.equinox.p2-d2010141492295ff80d70e0c904dacb67712c7a0.tar.gz rt.equinox.p2-d2010141492295ff80d70e0c904dacb67712c7a0.tar.xz rt.equinox.p2-d2010141492295ff80d70e0c904dacb67712c7a0.zip |
add JarDelta optimizer, some tests and refactor all of the above
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.artifact.processors')
12 files changed, 222 insertions, 427 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.artifact.processors/META-INF/MANIFEST.MF index f7f3df000..b60a5af18 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/META-INF/MANIFEST.MF @@ -10,8 +10,10 @@ Require-Bundle: org.eclipse.equinox.common, org.eclipse.equinox.registry, org.eclipse.osgi Import-Package: ie.wombat.jbdiff, + org.eclipse.equinox.internal.p2.artifact.optimizers, org.eclipse.equinox.internal.p2.core.helpers, org.eclipse.equinox.internal.p2.jarprocessor, + org.eclipse.equinox.internal.p2.metadata, org.eclipse.equinox.p2.artifact.repository, org.eclipse.equinox.p2.artifact.repository.processing, org.eclipse.equinox.p2.core.repository, diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/plugin.xml b/bundles/org.eclipse.equinox.p2.artifact.processors/plugin.xml index 842276102..d80e2d3ad 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/plugin.xml +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/plugin.xml @@ -4,7 +4,7 @@ <extension point="org.eclipse.equinox.p2.artifact.repository.processingSteps" id="org.eclipse.equinox.p2.processing.Pack200Unpacker"> - <step class="org.eclipse.equinox.internal.p2.artifact.processors.pack200.Unpack200Step"/> + <step class="org.eclipse.equinox.internal.p2.artifact.processors.pack200.Pack200ProcessorStep"/> </extension> <extension point="org.eclipse.equinox.p2.artifact.repository.processingSteps" @@ -23,7 +23,7 @@ </extension> <extension point="org.eclipse.equinox.p2.artifact.repository.processingSteps" - id="MD5Verifier"> + id="org.eclipse.equinox.p2.processing.MD5Verifier"> <step class="org.eclipse.equinox.internal.p2.artifact.processors.verifier.MD5Verifier"/> </extension> </plugin> diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/AbstractDeltaPatchStep.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/AbstractDeltaProcessorStep.java index 2cc3e3369..8f0087692 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/AbstractDeltaPatchStep.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/AbstractDeltaProcessorStep.java @@ -7,58 +7,38 @@ * * Contributors: * compeople AG (Stefan Liebig) - initial API and implementation + * IBM Corporation - ongoing development *******************************************************************************/ -package org.eclipse.equinox.internal.p2.artifact.processors.jbdiff; +package org.eclipse.equinox.internal.p2.artifact.processors; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.equinox.internal.p2.artifact.processors.Activator; +import org.eclipse.equinox.internal.p2.artifact.optimizers.AbstractDeltaStep; import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; import org.eclipse.equinox.p2.artifact.repository.*; -import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStep; import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStepDescriptor; -import org.eclipse.equinox.p2.metadata.IArtifactKey; /** * The <code>AbstractDeltaPatchStep</code> is an abstract processing step that * retrieves a local artifact repository containing the serialized/encoded * artifact key. It assumes that the artifact key is stored within the data property - * of the processing step descriptor and that is encoded with the <code>ArtifactKeyDeserializerXXX</code>. + * of the processing step descriptor encoding the artifact key of the base artifact. */ -public abstract class AbstractDeltaPatchStep extends ProcessingStep { +public abstract class AbstractDeltaProcessorStep extends AbstractDeltaStep { - protected IArtifactKey key; - protected IArtifactRepository repository; - - /* (non-Javadoc) - * @see org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStep#initialize(org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStepDescriptor, org.eclipse.equinox.p2.artifact.repository.IArtifactDescriptor) - */ public void initialize(ProcessingStepDescriptor descriptor, IArtifactDescriptor context) { super.initialize(descriptor, context); - - fetchArtifactKey(descriptor); if (!status.isOK()) return; - fetchLocalArtifactRepository(); } /** - * Fetch the artifact key from the given processing step descriptor. - * @param descriptor - */ - private void fetchArtifactKey(ProcessingStepDescriptor descriptor) { - try { - key = ArtifactKeyDeSerializer.deserialize(descriptor.getData()); - } catch (IllegalArgumentException e) { - status = new Status(IStatus.ERROR, Activator.ID, "Predecessor artifact key for delta could not be deserialized. Serialized key is " + descriptor.getData(), e); - } - } - - /** * Fetch a local artifact repository containing the fetched artifact key. */ private void fetchLocalArtifactRepository() { + if (repository != null) + return; IArtifactRepositoryManager repoMgr = (IArtifactRepositoryManager) ServiceHelper.getService(Activator.getContext(), IArtifactRepositoryManager.class.getName()); if (repoMgr == null) { status = new Status(IStatus.ERROR, Activator.ID, "Could not get artifact repository manager."); diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/Activator.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/Activator.java index 1b5854b01..9de6886df 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/Activator.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/Activator.java @@ -4,7 +4,8 @@ * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * - * Contributors: IBM Corporation - initial API and implementation + * Contributors: + * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.processors; diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/DeltaApplier.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/DeltaApplier.java index 5239807a1..d5f4d16f2 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/DeltaApplier.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/DeltaApplier.java @@ -12,16 +12,18 @@ package org.eclipse.equinox.internal.p2.artifact.processors.jardelta; import java.io.*; import java.util.*; -import java.util.jar.*; +import java.util.zip.*; public class DeltaApplier { private static final String DELETE_SUFFIX = ".delete"; //$NON-NLS-1$ + private static final String MANIFEST_ENTRY_NAME = "META-INF/MANIFEST.MF"; //$NON-NLS-1$ private File delta; private File base; private File destination; - private JarFile baseJar; - private JarFile deltaJar; + private ZipFile baseJar; + private ZipFile deltaJar; private Set baseEntries; + private ZipFile manifestJar; public DeltaApplier(File base, File delta, File destination) { this.base = base; @@ -45,29 +47,37 @@ public class DeltaApplier { baseEntries = getEntries(baseJar); // remove from the base all the entries that appear in the delta for (Enumeration e = deltaJar.entries(); e.hasMoreElements();) { - JarEntry entry = ((JarEntry) e.nextElement()); + ZipEntry entry = ((ZipEntry) e.nextElement()); + checkForManifest(entry, deltaJar); String name = entry.getName(); - if (name.endsWith(DELETE_SUFFIX)) + if (name.endsWith(DELETE_SUFFIX)) { name = name.substring(0, name.length() - DELETE_SUFFIX.length()); + // if the manifest is being deleted, forget anyone who might have a manifest + if (name.equalsIgnoreCase(MANIFEST_ENTRY_NAME)) + manifestJar = null; + } baseEntries.remove(name); } } private void writeResult() { - JarOutputStream result = null; + ZipOutputStream result = null; try { try { - result = new JarOutputStream(new FileOutputStream(destination)); + result = new ZipOutputStream(new FileOutputStream(destination)); + // if the delta includes the manifest, be sure to write it first + if (manifestJar != null) + writeEntry(result, manifestJar.getEntry(MANIFEST_ENTRY_NAME), manifestJar, true); // write out the things we know are staying from the base JAR for (Iterator i = baseEntries.iterator(); i.hasNext();) { - JarEntry entry = baseJar.getJarEntry((String) i.next()); - writeEntry(result, entry, baseJar); + ZipEntry entry = baseJar.getEntry((String) i.next()); + writeEntry(result, entry, baseJar, false); } // write out the changes/additions from the delta. for (Enumeration e = deltaJar.entries(); e.hasMoreElements();) { - JarEntry entry = (JarEntry) e.nextElement(); + ZipEntry entry = (ZipEntry) e.nextElement(); if (!entry.getName().endsWith(DELETE_SUFFIX)) - writeEntry(result, entry, deltaJar); + writeEntry(result, entry, deltaJar, false); } } finally { if (result != null) @@ -79,7 +89,9 @@ public class DeltaApplier { } } - private void writeEntry(JarOutputStream result, JarEntry entry, JarFile sourceJar) throws IOException { + private void writeEntry(ZipOutputStream result, ZipEntry entry, ZipFile sourceJar, boolean manifest) throws IOException { + if (!manifest && entry.getName().equalsIgnoreCase(MANIFEST_ENTRY_NAME)) + return; // add the entry result.putNextEntry(entry); try { @@ -123,8 +135,8 @@ public class DeltaApplier { private boolean openJars() { try { - baseJar = new JarFile(base); - deltaJar = new JarFile(delta); + baseJar = new ZipFile(base); + deltaJar = new ZipFile(delta); } catch (IOException e) { return false; } @@ -148,10 +160,25 @@ public class DeltaApplier { } } - private Set getEntries(JarFile jar) { + private Set getEntries(ZipFile jar) { HashSet result = new HashSet(jar.size()); - for (Enumeration e = jar.entries(); e.hasMoreElements();) - result.add(((JarEntry) e.nextElement()).getName()); + for (Enumeration e = jar.entries(); e.hasMoreElements();) { + ZipEntry entry = (ZipEntry) e.nextElement(); + checkForManifest(entry, jar); + result.add(entry.getName()); + } return result; } + + /** + * Check to see if the given entry is the manifest. If so, remember it for use when writing + * the resultant JAR. + * @param entry + * @param jar + */ + private void checkForManifest(ZipEntry entry, ZipFile jar) { + if (entry.getName().equalsIgnoreCase(MANIFEST_ENTRY_NAME)) + manifestJar = jar; + } + } diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/JarDeltaProcessorStep.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/JarDeltaProcessorStep.java index 8e97b668e..e9e6fed37 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/JarDeltaProcessorStep.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jardelta/JarDeltaProcessorStep.java @@ -1,116 +1,74 @@ /******************************************************************************* -* Copyright (c) 2007 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 -* http://www.eclipse.org/legal/epl-v10.html -* -* Contributors: -* IBM Corporation - initial API and implementation -*******************************************************************************/ + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.processors.jardelta; import java.io.*; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.artifact.processors.AbstractDeltaProcessorStep; import org.eclipse.equinox.internal.p2.artifact.processors.Activator; -import org.eclipse.equinox.internal.p2.artifact.processors.jbdiff.AbstractDeltaPatchStep; import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; import org.eclipse.equinox.p2.artifact.repository.ArtifactDescriptor; -import org.eclipse.equinox.p2.artifact.repository.IFileArtifactRepository; /** * Processor that takes a JAR delta and applies it. */ -public class JarDeltaProcessorStep extends AbstractDeltaPatchStep { - private static final String JAR_SUFFIX = ".jar"; //$NON-NLS-1$ +public class JarDeltaProcessorStep extends AbstractDeltaProcessorStep { private File incoming; - private OutputStream tempStream; - public void write(int b) throws IOException { - OutputStream stream = getOutputStream(); - stream.write(b); + public JarDeltaProcessorStep() { + super(); } - private OutputStream getOutputStream() throws IOException { - if (tempStream != null) - return tempStream; - // store input stream in temporary file - incoming = File.createTempFile("p2.jardelta.processor.incoming", JAR_SUFFIX); - tempStream = new BufferedOutputStream(new FileOutputStream(incoming)); - return tempStream; + protected OutputStream createIncomingStream() throws IOException { + incoming = File.createTempFile(INCOMING_ROOT, JAR_SUFFIX); + return new BufferedOutputStream(new FileOutputStream(incoming)); } - public void close() throws IOException { - // When we go to close we must have seen all the content we are going to see. - // If no one wrote to the temp stream then there is nothing to do. Be sure to delete the - // the temporary file if any. - if (tempStream == null) { - if (incoming != null) - incoming.delete(); - return; - } - - // So there is content. Close the temporary stream and perform the optimization. - // Performing the optimization should result in the new content being written to - // the destination. Make sure we delete the temporary file if any. - try { - tempStream.close(); - performPatch(); - } finally { - if (incoming != null) - incoming.delete(); - } - - super.close(); - // TODO need to get real status here. sometimes the optimizers do not give - // any reasonable return status - if (status == null) - status = Status.OK_STATUS; + protected void cleanupTempFiles() { + super.cleanupTempFiles(); + if (incoming != null) + incoming.delete(); } - private void performPatch() throws IOException { - File predecessor = null; + protected void performProcessing() throws IOException { File resultFile = null; try { - // get the predecessor and perform the optimization into a temp file - predecessor = fetchPredecessor(new ArtifactDescriptor(key)); - resultFile = File.createTempFile("p2.jardelta.processor.result", JAR_SUFFIX); - new DeltaApplier(predecessor, incoming, resultFile).run(); - + resultFile = process(); // now write the optimized content to the destination if (resultFile.length() > 0) { InputStream resultStream = new BufferedInputStream(new FileInputStream(resultFile)); FileUtils.copyStream(resultStream, true, destination, false); } else { - status = new Status(IStatus.ERROR, Activator.ID, "Empty optimized file: " + resultFile); + status = new Status(IStatus.ERROR, Activator.ID, "Empty optimized file: " + resultFile); //$NON-NLS-1$ } } finally { - if (predecessor != null) - predecessor.delete(); if (resultFile != null) resultFile.delete(); } } - private File fetchPredecessor(ArtifactDescriptor descriptor) { - if (repository instanceof IFileArtifactRepository) - return ((IFileArtifactRepository) repository).getArtifactFile(descriptor); - File result = null; - OutputStream resultStream = null; + protected File process() throws IOException { + File predecessor = null; try { - try { - result = File.createTempFile("p2.jardelta.predecessor", JAR_SUFFIX); - resultStream = new BufferedOutputStream(new FileOutputStream(result)); - status = repository.getArtifact(descriptor, resultStream, monitor); - return result; - } finally { - if (resultStream != null) - resultStream.close(); - } - } catch (IOException e) { + File resultFile = File.createTempFile(RESULT_ROOT, JAR_SUFFIX); + // get the predecessor and perform the optimization into a temp file + predecessor = fetchPredecessor(new ArtifactDescriptor(key)); + new DeltaApplier(predecessor, incoming, resultFile).run(); + return resultFile; + } finally { + // if we have a predecessor and it is our temp file then clean up the file + if (predecessor != null && predecessor.getAbsolutePath().indexOf(PREDECESSOR_ROOT) > -1) + predecessor.delete(); } - return null; } }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/ArtifactKeyDeSerializer.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/ArtifactKeyDeSerializer.java deleted file mode 100644 index 7aead57b2..000000000 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/ArtifactKeyDeSerializer.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 compeople AG 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: - * compeople AG (Stefan Liebig) - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.p2.artifact.processors.jbdiff; - -import java.util.StringTokenizer; -import org.eclipse.core.runtime.Assert; -import org.eclipse.equinox.p2.metadata.IArtifactKey; -import org.osgi.framework.Version; - -/** - * The <code>ArtifactKeyDeSerializer</code> encapsulates the serialization and de-serialization - * of artifact keys into string representation and vice versa. - * This encoding pattern is used within the processing step descriptor´s data property.<p> - * <b>Note: </b>This class is a duplicate of org.eclipse.equinox.internal.p2.artifact.optimizers.jbdiff.ArtifactKeyDeSerializer. - * This has been done because this class is only relevant for the delta stuff. - */ -public class ArtifactKeyDeSerializer { - - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final String SEPARATOR = ","; //$NON-NLS-1$ - - public static IArtifactKey deserialize(String data) { - - if (data == null || data.length() == 0) - throw new IllegalArgumentException("Artifact key could not be deserialized. Null or empty. Serialized key is " + data); //$NON-NLS-1$ - - String[] parts = new String[4]; - StringTokenizer tokenizer = new StringTokenizer(data, SEPARATOR, true); - int i = 0; - int sepCount = 0; - boolean lastTokenWasSep = true; - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - if (!token.equals(SEPARATOR)) { - parts[i++] = token; - lastTokenWasSep = false; - continue; - } - sepCount++; - if (lastTokenWasSep) { - parts[i++] = EMPTY_STRING; - continue; - } - lastTokenWasSep = true; - } - - if (sepCount != 3) - throw new IllegalArgumentException("Artifact key could not be deserialized. Unexpected number of parts. Serialized key is " + data); //$NON-NLS-1$ - - if (i == 3) - parts[i++] = EMPTY_STRING; - - try { - return new ArtifactKey(parts[0], parts[1], parts[2], Version.parseVersion(parts[3])); - } catch (IllegalArgumentException e) { - throw (IllegalArgumentException) new IllegalArgumentException("Artifact key could not be deserialized. Wrong version syntay. Serialized key is " + data).initCause(e); //$NON-NLS-1$ - } - } - - public static String serialize(IArtifactKey key) { - StringBuffer data = new StringBuffer(key.getNamespace()).append(SEPARATOR); - data.append(key.getClassifier()).append(SEPARATOR); - data.append(key.getId()).append(SEPARATOR); - data.append(key.getVersion().toString()); - return data.toString(); - } - - private static class ArtifactKey implements IArtifactKey { - - private final String namespace; - private final String id; - private final String classifier; - private final Version version; - private static final char SEP_CHAR = ','; - - protected ArtifactKey(String namespace, String classifier, String id, Version version) { - super(); - Assert.isNotNull(namespace); - Assert.isNotNull(classifier); - Assert.isNotNull(id); - Assert.isNotNull(version); - if (namespace.indexOf(SEP_CHAR) != -1) - throw new IllegalArgumentException("comma not allowed in namespace"); //$NON-NLS-1$ - if (classifier.indexOf(SEP_CHAR) != -1) - throw new IllegalArgumentException("comma not allowed in classifier"); //$NON-NLS-1$ - if (id.indexOf(SEP_CHAR) != -1) - throw new IllegalArgumentException("comma not allowed in id"); //$NON-NLS-1$ - this.namespace = namespace; - this.classifier = classifier; - this.id = id; - this.version = version; - } - - public String getClassifier() { - return classifier; - } - - public String getId() { - return id; - } - - public String getNamespace() { - return namespace; - } - - public Version getVersion() { - return version; - } - - } - -} diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchStep.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchStep.java index 01423773b..c5d526217 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchStep.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchStep.java @@ -7,12 +7,13 @@ * * Contributors: * compeople AG (Stefan Liebig) - initial API and implementation + * IBM Corporation - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.processors.jbdiff; import ie.wombat.jbdiff.JBPatch; import java.io.*; -import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.artifact.processors.AbstractDeltaProcessorStep; import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; import org.eclipse.equinox.p2.artifact.repository.ArtifactDescriptor; import org.eclipse.equinox.p2.sar.DirectByteArrayOutputStream; @@ -20,55 +21,34 @@ import org.eclipse.equinox.p2.sar.DirectByteArrayOutputStream; /** * The JBPatchStep patches a JBDiff based data. */ -public class JBPatchStep extends AbstractDeltaPatchStep { +public class JBPatchStep extends AbstractDeltaProcessorStep { - protected DirectByteArrayOutputStream diff; - protected DirectByteArrayOutputStream predecessor; - - public void write(int b) throws IOException { - OutputStream stream = getOutputStream(); - stream.write(b); + public JBPatchStep() { + super(); } - private OutputStream getOutputStream() { - if (diff != null) - return diff; - diff = new DirectByteArrayOutputStream(); - return diff; + protected OutputStream createIncomingStream() throws IOException { + return new DirectByteArrayOutputStream(); } - public void close() throws IOException { - // When we go to close we must have seen all the content we are going to see - // So before closing, run patch and write the patched result to the destination - performPatch(); - super.close(); - status = Status.OK_STATUS; + protected void performProcessing() throws IOException { + DirectByteArrayOutputStream predecessor = fetchPredecessorBytes(new ArtifactDescriptor(key)); + DirectByteArrayOutputStream current = (DirectByteArrayOutputStream) incomingStream; + byte[] result = JBPatch.bspatch(predecessor.getBuffer(), predecessor.getBufferLength(), current.getBuffer(), current.getBufferLength()); + // free up the memory as soon as possible. + predecessor = null; + current = null; + incomingStream = null; + + // copy the result of the optimization to the destination. + FileUtils.copyStream(new ByteArrayInputStream(result), true, destination, false); } - protected void performPatch() throws IOException { - if (diff == null) - // hmmm, no one wrote to this stream so there is nothing to pass on - return; - // Ok, so there is content, close the diff - diff.close(); - - try { - fetchPredecessor(new ArtifactDescriptor(key)); - byte[] result = JBPatch.bspatch(predecessor.getBuffer(), predecessor.getBufferLength(), diff.getBuffer(), diff.getBufferLength()); - diff = null; - predecessor = null; - FileUtils.copyStream(new ByteArrayInputStream(result), true, destination, false); - } finally { - diff = null; - predecessor = null; - } - } - - private void fetchPredecessor(ArtifactDescriptor artifactDescriptor) throws IOException { - predecessor = new DirectByteArrayOutputStream(); - status = repository.getArtifact(artifactDescriptor, predecessor, monitor); + private DirectByteArrayOutputStream fetchPredecessorBytes(ArtifactDescriptor artifactDescriptor) throws IOException { + DirectByteArrayOutputStream result = new DirectByteArrayOutputStream(); + status = repository.getArtifact(artifactDescriptor, result, monitor); if (!status.isOK()) throw (IOException) new IOException(status.getMessage()).initCause(status.getException()); + return result; } - }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchZipStep.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchZipStep.java index 7c5bc0cab..0f2865b6a 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchZipStep.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/jbdiff/JBPatchZipStep.java @@ -7,6 +7,7 @@ * * Contributors: * compeople AG (Stefan Liebig) - initial API and implementation + * IBM Corporation - ongoing development *******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.processors.jbdiff; @@ -22,35 +23,32 @@ import org.eclipse.equinox.p2.sar.SarUtil; */ public class JBPatchZipStep extends JBPatchStep { - protected void performPatch() throws IOException { - - if (diff == null) - // hmmm, no one wrote to this stream so there is nothing to pass on - return; - // Ok, so there is content, close the diff - diff.close(); - - try { - fetchPredecessor(new ArtifactDescriptor(key)); - byte[] result = JBPatch.bspatch(predecessor.getBuffer(), predecessor.getBufferLength(), diff.getBuffer(), diff.getBufferLength()); - diff = null; - predecessor = null; - SarUtil.sarToZip(new ByteArrayInputStream(result), true, destination, false); - } finally { - diff = null; - predecessor = null; - } + public JBPatchZipStep() { + super(); } - private void fetchPredecessor(ArtifactDescriptor artifactDescriptor) throws IOException { - DirectByteArrayOutputStream zippedPredecessor = new DirectByteArrayOutputStream(); + protected void performProcessing() throws IOException { + DirectByteArrayOutputStream predecessor = fetchPredecessorBytes(new ArtifactDescriptor(key)); + DirectByteArrayOutputStream current = (DirectByteArrayOutputStream) incomingStream; + byte[] result = JBPatch.bspatch(predecessor.getBuffer(), predecessor.getBufferLength(), current.getBuffer(), current.getBufferLength()); + // free up the memory as soon as possible. + predecessor = null; + current = null; + incomingStream = null; + + // copy the result of the optimization to the destination. + SarUtil.sarToZip(new ByteArrayInputStream(result), true, destination, false); + } + private DirectByteArrayOutputStream fetchPredecessorBytes(ArtifactDescriptor artifactDescriptor) throws IOException { + DirectByteArrayOutputStream zippedPredecessor = new DirectByteArrayOutputStream(); status = repository.getArtifact(artifactDescriptor, zippedPredecessor, monitor); if (!status.isOK()) throw (IOException) new IOException(status.getMessage()).initCause(status.getException()); - predecessor = new DirectByteArrayOutputStream(); - SarUtil.zipToSar(zippedPredecessor.getInputStream(), predecessor); + DirectByteArrayOutputStream result = new DirectByteArrayOutputStream(); + SarUtil.zipToSar(zippedPredecessor.getInputStream(), result); + return result; } }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Pack200ProcessorStep.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Pack200ProcessorStep.java new file mode 100644 index 000000000..3402cf240 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Pack200ProcessorStep.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2007 compeople AG 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: + * compeople AG (Stefan Liebig) - initial API and implementation + * IBM Corporation - ongoing development + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.artifact.processors.pack200; +
import java.io.*; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.artifact.optimizers.AbstractBufferingStep; +import org.eclipse.equinox.internal.p2.artifact.processors.Activator; +import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; +import org.eclipse.equinox.internal.p2.jarprocessor.UnpackStep; +import org.eclipse.equinox.p2.artifact.repository.IArtifactDescriptor; +import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStepDescriptor; +import org.eclipse.equinox.p2.jarprocessor.JarProcessorExecutor; +import org.eclipse.equinox.p2.jarprocessor.JarProcessorExecutor.Options; + + +/** + * The Pack200Unpacker expects an input containing ".jar.pack.gz" data. + */ +public class Pack200ProcessorStep extends AbstractBufferingStep { + public static final String PACKED_SUFFIX = ".pack.gz"; //$NON-NLS-1$ + + private File incoming; + + protected OutputStream createIncomingStream() throws IOException { + incoming = File.createTempFile(INCOMING_ROOT, JAR_SUFFIX + PACKED_SUFFIX); + return new BufferedOutputStream(new FileOutputStream(incoming)); + } + + public void initialize(ProcessingStepDescriptor descriptor, IArtifactDescriptor context) { + super.initialize(descriptor, context); + if (!UnpackStep.canUnpack()) + status = new Status(IStatus.ERROR, Activator.ID, "Unpack facility not configured"); //$NON-NLS-1$ + } + + protected void cleanupTempFiles() { + super.cleanupTempFiles(); + if (incoming != null) + incoming.delete(); + } + + protected void performProcessing() throws IOException { + File resultFile = null; + try { + resultFile = process(); + // now write the processed content to the destination + if (resultFile.length() > 0) { + InputStream resultStream = new BufferedInputStream(new FileInputStream(resultFile)); + FileUtils.copyStream(resultStream, true, destination, false); + } else { + status = new Status(IStatus.ERROR, Activator.ID, "Empty intermediate file: " + resultFile); //$NON-NLS-1$ + } + } finally { + if (resultFile != null) + resultFile.delete(); + } + } + + protected File process() throws IOException { + Options options = new Options(); + options.unpack = true; + // TODO use false here assuming that all content is conditioned. Need to revise this + options.processAll = false; + options.input = incoming; + options.outputDir = getWorkDir().getPath(); + options.verbose = true; + new JarProcessorExecutor().runJarProcessor(options); + return new File(getWorkDir(), incoming.getName().substring(0, incoming.getName().length() - PACKED_SUFFIX.length())); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Unpack200Step.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Unpack200Step.java deleted file mode 100644 index c79d78d48..000000000 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/pack200/Unpack200Step.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 compeople AG 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: -* compeople AG (Stefan Liebig) - initial API and implementation -* IBM - continuing development -*******************************************************************************/ -package org.eclipse.equinox.internal.p2.artifact.processors.pack200; - -import java.io.*; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; -import org.eclipse.equinox.internal.p2.jarprocessor.UnpackStep; -import org.eclipse.equinox.p2.artifact.repository.IArtifactDescriptor; -import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStep; -import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStepDescriptor; -import org.eclipse.equinox.p2.jarprocessor.JarProcessorExecutor; -import org.eclipse.equinox.p2.jarprocessor.JarProcessorExecutor.Options; - -/** - * The Pack200Unpacker expects an input containing ".jar.pack.gz" data. - */ -public class Unpack200Step extends ProcessingStep { - public static final String ID = "org.eclipse.equinox.p2.artifact.processor.pack200"; //$NON-NLS-1$ - public static final String JAR_SUFFIX = ".jar"; //$NON-NLS-1$ - public static final String PACKED_SUFFIX = ".pack.gz"; //$NON-NLS-1$ - private final static String PACKED_EXT = JAR_SUFFIX + PACKED_SUFFIX; - - private File packed; - private OutputStream tempStream; - - public void close() throws IOException { - // When we go to close we must have seen all the content we are going to see - // So before closing, run unpack and write the unpacked result to the destination - performUnpack(); - super.close(); - if (status == null) - status = Status.OK_STATUS; - } - - private OutputStream getOutputStream() throws IOException { - if (tempStream != null) - return tempStream; - // store input stream in temporary file - packed = File.createTempFile("p2.pack200", PACKED_EXT); - tempStream = new BufferedOutputStream(new FileOutputStream(packed)); - return tempStream; - } - - public void initialize(ProcessingStepDescriptor descriptor, IArtifactDescriptor context) { - super.initialize(descriptor, context); - if (!UnpackStep.canUnpack()) - status = new Status(IStatus.ERROR, ID, "Unpack facility not configured"); - } - - private void performUnpack() throws IOException { - BufferedInputStream unpackedStream = null; - File unpacked = null; - File workDir = null; - try { - if (tempStream == null) - // hmmm, no one wrote to this stream so there is nothing to pass on - return; - // Ok, so there is content, close the tempStream - tempStream.close(); - // now create a temporary directory for the JarProcessor to work in - // TODO How to create a unique, temporary directory atomically? - workDir = File.createTempFile("p2.unpack.", ""); - if (!workDir.delete()) - throw new IOException("Could not delete file for creating temporary working dir."); - if (!workDir.mkdirs()) - throw new IOException("Could not create temporary working dir."); - - // unpack - Options options = new Options(); - options.unpack = true; - options.processAll = true; - options.input = packed; - options.outputDir = workDir.getPath(); - new JarProcessorExecutor().runJarProcessor(options); - - // now write the unpacked content to our destination - String packedFileName = packed.getName(); - unpacked = new File(workDir, packedFileName.substring(0, packedFileName.length() - PACKED_SUFFIX.length())); - if (unpacked.length() == 0) - System.out.println("Empty file unpacked: " + unpacked); - unpackedStream = new BufferedInputStream(new FileInputStream(unpacked)); - FileUtils.copyStream(unpackedStream, true, destination, false); - } finally { - // note that unpackedStream will be closed by copyStream() - if (packed != null) - packed.delete(); - if (unpacked != null) - unpacked.delete(); - if (workDir != null) - FileUtils.deleteAll(workDir); - } - } - - public void write(int b) throws IOException { - OutputStream stream = getOutputStream(); - stream.write(b); - } - -}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/verifier/MD5Verifier.java b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/verifier/MD5Verifier.java index f098c4bb0..4559d6d9b 100644 --- a/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/verifier/MD5Verifier.java +++ b/bundles/org.eclipse.equinox.p2.artifact.processors/src/org/eclipse/equinox/internal/p2/artifact/processors/verifier/MD5Verifier.java @@ -1,14 +1,14 @@ /******************************************************************************* -* Copyright (c) 2007 compeople AG 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: -* compeople AG (Stefan Liebig) - initial API and implementation -* IBM - continuing development -*******************************************************************************/ + * Copyright (c) 2007 compeople AG 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: + * compeople AG (Stefan Liebig) - initial API and implementation + * IBM Corporation - ongoing development + *******************************************************************************/ package org.eclipse.equinox.internal.p2.artifact.processors.verifier; import java.io.IOException; |