Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: c3bf77c9a5867bb57b4eebb090b551e93aa71f8d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*******************************************************************************
* 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.processor.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);
	}

}

Back to the top