Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsliebig2007-11-06 14:29:04 +0000
committersliebig2007-11-06 14:29:04 +0000
commit2badfd3121cad9b9859a3287cc08b9b4cd07ba93 (patch)
tree02719b15cd4ac631a6d8ffdca0367711ee64078f /bundles/org.eclipse.equinox.p2.sar/src
parent163fb6a827a525bfe749276a9ee61547b5e46afa (diff)
downloadrt.equinox.p2-2badfd3121cad9b9859a3287cc08b9b4cd07ba93.tar.gz
rt.equinox.p2-2badfd3121cad9b9859a3287cc08b9b4cd07ba93.tar.xz
rt.equinox.p2-2badfd3121cad9b9859a3287cc08b9b4cd07ba93.zip
initial load
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.sar/src')
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/Activator.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/DirectByteArrayOutputStream.java72
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarConstants.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarEntry.java157
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarInputStream.java207
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarOutputStream.java208
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarUtil.java232
7 files changed, 943 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/Activator.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/Activator.java
new file mode 100644
index 000000000..9874234f0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/Activator.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/DirectByteArrayOutputStream.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/DirectByteArrayOutputStream.java
new file mode 100644
index 000000000..ab610b31a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/DirectByteArrayOutputStream.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * The DirectByteArrayOutputStream discloses its guts (internal byte buffer and
+ * byte buffer length) to avoid unnecessary allocation of byte arrays usually
+ * involved with toByteArray().
+ */
+public class DirectByteArrayOutputStream extends ByteArrayOutputStream {
+
+ /**
+ * Creates a new direct byte array output stream. The buffer capacity is
+ * initially as defined by super class.
+ */
+ public DirectByteArrayOutputStream() {
+ super();
+ }
+
+ /**
+ * Creates a new byte array output stream, with a buffer capacity of the
+ * specified size, in bytes.
+ *
+ * @param size
+ * the initial size.
+ * @throws IllegalArgumentException
+ * if size is negative.
+ */
+ public DirectByteArrayOutputStream(int size) {
+ super(size);
+ }
+
+ /**
+ * Return the actual internal byte buffer.
+ *
+ * @return internal byte buffer
+ */
+ public final byte[] getBuffer() {
+ return super.buf;
+ }
+
+ /**
+ * Return the actual length of the internal byte buffer.
+ *
+ * @return actual length of the buffer
+ */
+ public final int getBufferLength() {
+ return super.count;
+ }
+
+ /**
+ * Return an input stream containing all the (shared) bytes this output
+ * stream has already consumed.
+ *
+ * @return
+ */
+ public ByteArrayInputStream getInputStream() {
+ return new ByteArrayInputStream(super.buf, 0, super.count);
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarConstants.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarConstants.java
new file mode 100644
index 000000000..216cb418c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarConstants.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+/**
+ * Sar constants
+ */
+public interface SarConstants {
+
+ /** <code>SARFILE_MARKER</code> */
+ String SARFILE_MARKER = "SarFile";
+
+ /** <code>SARFILE_VERSION</code> */
+ int SARFILE_VERSION = 2;
+
+ /**
+ * Comment for <code>DEFAULT_ENCODING</code>
+ */
+ String DEFAULT_ENCODING = "UTF-8";
+
+ /**
+ * Debug
+ */
+ boolean DEBUG = false;
+}
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarEntry.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarEntry.java
new file mode 100644
index 000000000..4644cdda0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarEntry.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+
+/**
+ * A SarEntry is the header information for an entry within a org.eclipse.equinox.p2.sar stream.
+ */
+public class SarEntry extends ZipEntry {
+
+ private boolean isEof;
+ private boolean isZip;
+
+ /**
+ * The name of the eof org.eclipse.equinox.p2.sar entry.
+ */
+ private static final String EOF_ENTRY_NAME = "<eof-org.eclipse.equinox.p2.sar>";
+
+ private static final boolean DEBUG = SarConstants.DEBUG;
+
+ /**
+ * Creates an eof org.eclipse.equinox.p2.sar entry
+ */
+ public SarEntry() {
+ super( EOF_ENTRY_NAME );
+ setMethod( ZipEntry.DEFLATED );
+ this.isEof = true;
+ this.isZip = false;
+ }
+
+ /**
+ * @param zipEntry
+ */
+ public SarEntry( ZipEntry zipEntry ) {
+ super( zipEntry );
+ this.isZip = false;
+ this.isEof = false;
+ }
+
+ /**
+ * @param zipEntry
+ * @param isZip
+ */
+ public SarEntry( ZipEntry zipEntry, boolean isZip ) {
+ super( zipEntry );
+ this.isZip = isZip;
+ this.isEof = false;
+ }
+
+ /**
+ * @param sarInputStream
+ * @throws IOException
+ */
+ public SarEntry( SarInputStream sarInputStream ) throws IOException {
+ // read name!
+ super( sarInputStream.readString() );
+
+ String comment = sarInputStream.readString();
+ long compressedSize = sarInputStream.readLong();
+ long crc = sarInputStream.readLong();
+ byte[] extra = sarInputStream.readBytes();
+ int method = sarInputStream.readInt();
+ long size = sarInputStream.readLong();
+ long time = sarInputStream.readLong();
+ boolean isEof = sarInputStream.readBoolean();
+ boolean isZip = sarInputStream.readBoolean();
+
+ if ( DEBUG ) {
+ System.out.println( getName() + "," + comment + "," + compressedSize + "," + crc + "," + extra + "," + method + "," + size + "," + time + ","
+ + isEof + "," + isZip );
+ }
+
+ if ( method == ZipEntry.STORED ) {
+ setCompressedSize( compressedSize );
+ setCrc( crc );
+ setSize( size );
+ }
+
+ setComment( comment );
+ setExtra( extra );
+ setMethod( method );
+ setTime( time );
+ setEof( isEof );
+ setZip( isZip );
+ }
+
+ /**
+ * @param sarOutputStream
+ * @throws IOException
+ */
+ public void writeTo( SarOutputStream sarOutputStream ) throws IOException {
+ String comment = this.getComment();
+ long compressedSize = this.getCompressedSize();
+ long crc = this.getCrc();
+ byte[] extra = this.getExtra();
+ int method = this.getMethod();
+ String name = this.getName();
+ long size = this.getSize();
+ long time = this.getTime();
+ boolean isZip = this.isZip();
+ boolean isEof = this.isEof();
+
+ if ( DEBUG ) {
+ System.out.println( name + "," + comment + "," + compressedSize + "," + crc + "," + extra + "," + method + "," + size + "," + time + "," + isEof
+ + "," + isZip );
+ }
+
+ sarOutputStream.writeString( name );
+ sarOutputStream.writeString( comment );
+ sarOutputStream.writeLong( compressedSize );
+ sarOutputStream.writeLong( crc );
+ sarOutputStream.writeBytes( extra );
+ sarOutputStream.writeInt( method );
+ sarOutputStream.writeLong( size );
+ sarOutputStream.writeLong( time );
+ sarOutputStream.writeBool( isEof );
+ sarOutputStream.writeBool( isZip );
+ }
+
+ /**
+ * Is this the eof org.eclipse.equinox.p2.sar entry?
+ *
+ * @return the answer
+ */
+ public boolean isEof() {
+ return isEof;
+ }
+
+ private void setEof( boolean isEof ) {
+ this.isEof = isEof;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isZip() {
+ return isZip;
+ }
+
+ /**
+ * @param isZip
+ */
+ private void setZip( boolean isZip ) {
+ this.isZip = isZip;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarInputStream.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarInputStream.java
new file mode 100644
index 000000000..f69916d9a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarInputStream.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The SarInputStream reads a streaming archive as an InputStream. Methods are
+ * provided to position at each successive entry in the archive, and the read
+ * each entry as a normal input stream using read().
+ */
+public class SarInputStream extends InputStream {
+
+ private final DataInputStream dataInputStream;
+ private final int version;
+ private InputStream contentStream;
+
+ /**
+ * Constructor for SarInputStream.
+ *
+ * @param inputStream
+ * the input stream to use
+ * @throws IOException
+ */
+ public SarInputStream(InputStream inputStream) throws IOException {
+
+ this.dataInputStream = new DataInputStream(inputStream);
+
+ // SarFile marker
+ String marker = readString();
+ if (!marker.equals(SarConstants.SARFILE_MARKER)) {
+ throw new IOException(
+ "Does not contain org.eclipse.equinox.p2.sar marker.");
+ }
+
+ // SarFile version
+ version = dataInputStream.readInt();
+ if (version != SarConstants.SARFILE_VERSION) {
+ throw new IOException("Unsupported version.");
+ }
+ }
+
+ /**
+ * Closes this stream.
+ *
+ * @throws IOException
+ * on error
+ */
+ public void close() throws IOException {
+ dataInputStream.close();
+ }
+
+ /**
+ * Since we do not support marking just yet, we return false.
+ *
+ * @return False.
+ */
+ public boolean markSupported() {
+ return false;
+ }
+
+ /**
+ * Since we do not support marking just yet, we do nothing.
+ *
+ * @param markLimit
+ * The limit to mark.
+ */
+ public void mark(int markLimit) {
+ // nothing
+ }
+
+ /**
+ * Since we do not support marking just yet, we do nothing.
+ */
+ public void reset() {
+ // nothing
+ }
+
+ /**
+ * Get the next entry in this org.eclipse.equinox.p2.sar archive. This will skip
+ * over any remaining data in the current entry, if there is one, and place
+ * the input stream at the header of the next entry, and read the header and
+ * instantiate a new SarEntry from the header bytes and return that entry.
+ * If there are no more entries in the archive, null will be returned to
+ * indicate that the end of the archive has been reached.
+ *
+ * @return the next SarEntry in the archive, or null.
+ * @throws IOException
+ * on error
+ */
+ public SarEntry getNextEntry() throws IOException {
+ SarEntry sarEntry = new SarEntry(this);
+ if (sarEntry.isEof())
+ return null;
+
+ byte[] content = readBytes();
+ contentStream = new ByteArrayInputStream(content);
+ return sarEntry;
+
+ }
+
+ /**
+ * Close the entry.
+ *
+ * @throws IOException
+ */
+ public void closeEntry() throws IOException {
+ contentStream.close();
+ }
+
+ /**
+ * @return
+ * @throws IOException
+ */
+ String readString() throws IOException {
+ byte[] bytes = readBytes();
+ if (bytes == null)
+ return null;
+
+ return new String(bytes, SarConstants.DEFAULT_ENCODING);
+ }
+
+ /**
+ * @return
+ * @throws IOException
+ */
+ byte[] readBytes() throws IOException {
+ int length = dataInputStream.readInt();
+ if (length == -1)
+ return null;
+
+ byte[] bytes = new byte[length];
+ dataInputStream.readFully(bytes, 0, length);
+ return bytes;
+ }
+
+ /**
+ * @return
+ * @throws IOException
+ */
+ int readInt() throws IOException {
+ return dataInputStream.readInt();
+ }
+
+ /**
+ * @return
+ * @throws IOException
+ */
+ boolean readBoolean() throws IOException {
+ return dataInputStream.readBoolean();
+ }
+
+ /**
+ * @return
+ * @throws IOException
+ */
+ long readLong() throws IOException {
+ return dataInputStream.readLong();
+ }
+
+ /**
+ * Reads a byte from the current tar archive entry.
+ *
+ * This method simply calls read( byte[], int, int ).
+ *
+ * @return The byte read, or -1 at EOF.
+ * @throws IOException
+ * on error
+ */
+ public int read() throws IOException {
+ return contentStream.read();
+ }
+
+ /**
+ * Reads bytes from the current tar archive entry.
+ *
+ * This method is aware of the boundaries of the current entry in the
+ * archive and will deal with them as if they were this stream's start and
+ * EOF.
+ *
+ * @param buffer
+ * The buffer into which to place bytes read.
+ * @param offset
+ * The offset at which to place bytes read.
+ * @param numToRead
+ * The number of bytes to read.
+ * @return The number of bytes read, or -1 at EOF.
+ * @throws IOException
+ * on error
+ */
+ public int read(byte[] buffer, int offset, int numToRead)
+ throws IOException {
+ return contentStream.read(buffer, offset, numToRead);
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarOutputStream.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarOutputStream.java
new file mode 100644
index 000000000..14fa07503
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarOutputStream.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The SarOutputStream writes a stream archive as an OutputStream. Methods are
+ * provided to put entries, and then write their contents by writing to this
+ * stream using write().
+ */
+public class SarOutputStream extends OutputStream {
+
+ private boolean finished;
+ private final DataOutputStream dataOutputStream;
+ private final DirectByteArrayOutputStream entryContent;
+
+ /**
+ * @param outputStream
+ * @throws IOException
+ */
+ public SarOutputStream(OutputStream outputStream) throws IOException {
+ dataOutputStream = new DataOutputStream(outputStream);
+ entryContent = new DirectByteArrayOutputStream(16 * 1024);
+ writeString(SarConstants.SARFILE_MARKER);
+ dataOutputStream.writeInt(SarConstants.SARFILE_VERSION);
+ finished = false;
+ }
+
+ /**
+ * Ends the SAR archive and closes the underlying OutputStream.
+ *
+ * @see java.io.Closeable#close()
+ */
+ // @Override
+ public void close() throws IOException {
+ finish();
+ super.close();
+ }
+
+ /**
+ * Finish this SAR archive but does not close the underlying output stream.
+ *
+ * @throws IOException
+ */
+ public void finish() throws IOException {
+ if (finished)
+ return;
+
+ writeEOFRecord();
+ finished = true;
+ }
+
+ /**
+ * Put an entry on the output stream. This writes the entry's header record
+ * and positions the output stream for writing the contents of the entry.
+ * Once this method is called, the stream is ready for calls to write() to
+ * write the entry's contents. Once the contents are written, closeEntry()
+ * <B>MUST </B> be called to ensure that all buffered data is completely
+ * written to the output stream.
+ *
+ * @param entry
+ * the SarEntry to be written to the archive.
+ * @throws IOException
+ */
+ public void putNextEntry(SarEntry entry) throws IOException {
+ entry.writeTo(this);
+ }
+
+ /**
+ * Close an entry. This method MUST be called for all file entries that
+ * contain data. The reason is that we must buffer data written to the
+ * stream in order to satisfy the buffer's record based writes. Thus, there
+ * may be data fragments still being assembled that must be written to the
+ * output stream before this entry is closed and the next entry written.
+ *
+ * @throws IOException
+ */
+ public void closeEntry() throws IOException {
+ writeBytes(entryContent.getBuffer(), entryContent.getBufferLength());
+ entryContent.reset();
+ }
+
+ /**
+ * @param s
+ * @throws IOException
+ */
+ void writeString(String s) throws IOException {
+ byte[] bytes = null;
+ if (s != null)
+ bytes = s.getBytes(SarConstants.DEFAULT_ENCODING);
+
+ writeBytes(bytes);
+ }
+
+ /**
+ * @param bytes
+ * @throws IOException
+ */
+ void writeBytes(byte[] bytes) throws IOException {
+ writeBytes(bytes, bytes != null ? bytes.length : -1);
+ }
+
+ /**
+ * @param bytes
+ * @throws IOException
+ */
+ void writeBytes(byte[] bytes, int length) throws IOException {
+ if (bytes != null) {
+ dataOutputStream.writeInt(length);
+ dataOutputStream.write(bytes, 0, length);
+ } else {
+ dataOutputStream.writeInt(-1);
+ }
+ }
+
+ /**
+ * @param v
+ * @throws IOException
+ */
+ void writeInt(int v) throws IOException {
+ dataOutputStream.writeInt(v);
+ }
+
+ /**
+ * @param bool
+ * @throws IOException
+ */
+ public void writeBool(boolean bool) throws IOException {
+ dataOutputStream.writeBoolean(bool);
+ }
+
+ /**
+ * @param v
+ * @throws IOException
+ */
+ void writeLong(long v) throws IOException {
+ dataOutputStream.writeLong(v);
+ }
+
+ /**
+ * Writes a byte to the current org.eclipse.equinox.p2.sar archive entry.
+ *
+ * @param b
+ * the byte written.
+ * @throws IOException
+ *
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException {
+ byte[] bytes = new byte[1];
+ bytes[0] = (byte) b;
+ entryContent.write(bytes);
+ }
+
+ /**
+ * Writes bytes to the current org.eclipse.equinox.p2.sar archive entry.
+ *
+ * @param bytes
+ * The buffer to write to the archive.
+ * @throws IOException
+ *
+ * @see java.io.OutputStream#write(byte[])
+ */
+ public void write(byte[] bytes) throws IOException {
+ entryContent.write(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Writes bytes to the current org.eclipse.equinox.p2.sar archive entry.
+ *
+ * @param bytes
+ * The buffer to write to the archive.
+ * @param offset
+ * The offset in the buffer from which to get bytes.
+ * @param numToWrite
+ * The number of bytes to write.
+ *
+ * @throws IOException
+ *
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public void write(byte[] bytes, int offset, int numToWrite)
+ throws IOException {
+ entryContent.write(bytes, offset, numToWrite);
+ }
+
+ /**
+ * Write an EOF (end of archive) entry to the org.eclipse.equinox.p2.sar archive.
+ *
+ * @throws IOException
+ */
+ private void writeEOFRecord() throws IOException {
+ SarEntry eofEntry = new SarEntry();
+ eofEntry.writeTo(this);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarUtil.java b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarUtil.java
new file mode 100644
index 000000000..1dd31eca0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.sar/src/org/eclipse/equinox/p2/sar/SarUtil.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * 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.p2.sar;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Helper class for converting Zips/Jars to Sars and vice versa.
+ */
+public class SarUtil {
+
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final boolean DEBUG = SarConstants.DEBUG;
+
+ /**
+ *
+ */
+ private SarUtil() {
+ // utility class
+ }
+
+ /**
+ * Normalize the given zip/jar.
+ *
+ * @param zipSource
+ * @param zipTarget
+ * @throws IOException
+ */
+ public static void normalize(File zipSource, File zipTarget)
+ throws IOException {
+ File tempSar = File.createTempFile("temp", ".sar");
+ try {
+ zipToSar(zipSource, tempSar);
+ sarToZip(tempSar, zipTarget);
+ } finally {
+ tempSar.delete();
+ }
+ }
+
+ /**
+ * Normalize the given zip/jar.
+ *
+ * @param zipSource
+ * @param zipTarget
+ * @throws IOException
+ */
+ public static void normalize(InputStream zipSource, OutputStream zipTarget)
+ throws IOException {
+ DirectByteArrayOutputStream tempSar = new DirectByteArrayOutputStream();
+ zipToSar(zipSource, tempSar);
+ sarToZip(tempSar.getInputStream(), zipTarget);
+ }
+
+ /**
+ * @param zipFile
+ * @return
+ * @throws IOException
+ */
+ public static void zipToSar(File zipFile, File sarFile) throws IOException {
+ InputStream zipInputStream = new BufferedInputStream(
+ new FileInputStream(zipFile));
+ OutputStream sarOutputStream = new BufferedOutputStream(
+ new FileOutputStream(sarFile));
+ SarUtil.zipToSar(zipInputStream, sarOutputStream);
+ }
+
+ /**
+ * @param zippedInputStream
+ * @param saredOutputStream
+ * @throws IOException
+ */
+ public static void zipToSar(InputStream zippedInputStream,
+ OutputStream saredOutputStream) throws IOException {
+ zipToSar(zippedInputStream, true, saredOutputStream, true);
+ }
+
+ /**
+ * @param zippedInputStream
+ * @param closeIn
+ * @param saredOutputStream
+ * @param closeOut
+ * @throws IOException
+ */
+ public static void zipToSar(InputStream zippedInputStream, boolean closeIn,
+ OutputStream saredOutputStream, boolean closeOut)
+ throws IOException {
+ zipToSarNoClose(zippedInputStream, saredOutputStream);
+
+ if (closeIn)
+ zippedInputStream.close();
+ if (closeOut)
+ saredOutputStream.close();
+ }
+
+ /**
+ * @param sarFile
+ * @param zipFile
+ * @throws IOException
+ */
+ public static void sarToZip(File sarFile, File zipFile) throws IOException {
+ InputStream saredInputStream = new BufferedInputStream(
+ new FileInputStream(sarFile));
+ OutputStream zippedOutputStream = new BufferedOutputStream(
+ new FileOutputStream(zipFile));
+
+ sarToZip(saredInputStream, zippedOutputStream);
+ }
+
+ /**
+ * @param saredInputStream
+ * @param zippedOutputStream
+ * @param level
+ * @throws IOException
+ */
+ public static void sarToZip(InputStream saredInputStream,
+ OutputStream zippedOutputStream) throws IOException {
+ sarToZip(saredInputStream, true, zippedOutputStream, true);
+ }
+
+ /**
+ * @param saredInputStream
+ * @param closeIn
+ * @param zippedOutputStream
+ * @param closeOut
+ * @throws IOException
+ */
+ public static void sarToZip(InputStream saredInputStream, boolean closeIn,
+ OutputStream zippedOutputStream, boolean closeOut)
+ throws IOException {
+ sarToZipNoClose(saredInputStream, zippedOutputStream);
+
+ if (closeIn)
+ saredInputStream.close();
+ if (closeOut)
+ zippedOutputStream.close();
+ }
+
+ /**
+ * @param zippedInputStream
+ * @param saredOutputStream
+ * @throws IOException
+ */
+ private static void zipToSarNoClose(InputStream zippedInputStream,
+ OutputStream saredOutputStream) throws IOException {
+
+ ZipInputStream zipInputStream = new ZipInputStream(zippedInputStream);
+ SarOutputStream sarOutputStream = new SarOutputStream(saredOutputStream);
+
+ ZipEntry zipEntry;
+ byte[] buf = new byte[BUFFER_SIZE];
+ while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+ boolean isZip = isZip(zipEntry);
+ SarEntry sarEntry = new SarEntry(zipEntry, isZip);
+ sarOutputStream.putNextEntry(sarEntry);
+ if (isZip) {
+ zipToSarNoClose(zipInputStream, sarOutputStream);
+ } else {
+ int read;
+ while ((read = zipInputStream.read(buf)) != -1) {
+ if (DEBUG) {
+ System.out.println("Content: "
+ + new String(buf, 0, read));
+ }
+ sarOutputStream.write(buf, 0, read);
+ }
+ }
+ zipInputStream.closeEntry();
+ sarOutputStream.closeEntry();
+ }
+ sarOutputStream.finish();
+ }
+
+ /**
+ * @param saredInputStream
+ * @param zippedOutputStream
+ * @param level
+ * @throws IOException
+ */
+ private static void sarToZipNoClose(InputStream saredInputStream,
+ OutputStream zippedOutputStream) throws IOException {
+
+ SarInputStream sarInputStream = new SarInputStream(saredInputStream);
+ ZipOutputStream zipOutputStream = new ZipOutputStream(
+ zippedOutputStream);
+
+ SarEntry sarEntry;
+ byte[] buf = new byte[BUFFER_SIZE];
+ while ((sarEntry = sarInputStream.getNextEntry()) != null) {
+ ZipEntry zipEntry = new ZipEntry(sarEntry);
+ zipOutputStream.putNextEntry(zipEntry);
+ if (sarEntry.isZip()) {
+ sarToZipNoClose(sarInputStream, zipOutputStream);
+ } else {
+ int read;
+ while ((read = sarInputStream.read(buf)) != -1) {
+ if (DEBUG) {
+ System.out.println("Content: "
+ + new String(buf, 0, read));
+ }
+ zipOutputStream.write(buf, 0, read);
+ }
+ }
+ sarInputStream.closeEntry();
+ zipOutputStream.closeEntry();
+ }
+
+ zipOutputStream.finish();
+ }
+
+ private static boolean isZip(ZipEntry zipEntry) {
+ String name = zipEntry.getName().toLowerCase();
+ return name.endsWith(".zip") || name.endsWith(".jar");
+ }
+}

Back to the top