001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.core.util.jar;
019:
020: import java.io.ByteArrayOutputStream;
021: import java.io.File;
022: import java.io.FileOutputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.util.Enumeration;
026: import java.util.jar.JarEntry;
027: import java.util.jar.JarOutputStream;
028:
029: /**
030: * An output stream that is used by EnhancedJarFile to write entries to a jar.
031: * This implementation uses a ByteArrayOutputStream to buffer the output
032: * until the stream is closed. When the stream is closed, the output is written
033: * to the jar.
034: *
035: * Copyright 2002 Sapient
036: * @since carbon 1.0
037: * @author Douglas Voet, April 2002
038: * @version $Revision: 1.9 $($Author: dvoet $ / $Date: 2003/05/05 21:21:23 $)
039: */
040: public class JarEntryOutputStream extends ByteArrayOutputStream {
041:
042: private EnhancedJarFile jar;
043: private String jarEntryName;
044:
045: /**
046: * Constructor
047: *
048: * @param jar the EnhancedJarFile that this instance will write to
049: * @param jarEntryName the name of the entry to be written
050: */
051: public JarEntryOutputStream(EnhancedJarFile jar, String jarEntryName) {
052: super ();
053:
054: this .jarEntryName = jarEntryName;
055: this .jar = jar;
056: }
057:
058: /**
059: * Closes the stream and writes entry to the jar
060: */
061: public void close() throws IOException {
062: writeToJar();
063: super .close();
064: }
065:
066: /**
067: * Writes the entry to a the jar file. This is done by creating a
068: * temporary jar file, copying the contents of the existing jar to the
069: * temp jar, skipping the entry named by this.jarEntryName if it exists.
070: * Then, if the stream was written to, then contents are written as a
071: * new entry. Last, a callback is made to the EnhancedJarFile to
072: * swap the temp jar in for the old jar.
073: */
074: private void writeToJar() throws IOException {
075:
076: File jarDir = new File(this .jar.getName()).getParentFile();
077: // create new jar
078: File newJarFile = File.createTempFile("config", ".jar", jarDir);
079: newJarFile.deleteOnExit();
080: JarOutputStream jarOutputStream = new JarOutputStream(
081: new FileOutputStream(newJarFile));
082:
083: try {
084: Enumeration entries = this .jar.entries();
085:
086: // copy all current entries into the new jar
087: while (entries.hasMoreElements()) {
088: JarEntry nextEntry = (JarEntry) entries.nextElement();
089: // skip the entry named jarEntryName
090: if (!this .jarEntryName.equals(nextEntry.getName())) {
091: // the next 3 lines of code are a work around for
092: // bug 4682202 in the java.sun.com bug parade, see:
093: // http://developer.java.sun.com/developer/bugParade/bugs/4682202.html
094: JarEntry entryCopy = new JarEntry(nextEntry);
095: entryCopy.setCompressedSize(-1);
096: jarOutputStream.putNextEntry(entryCopy);
097:
098: InputStream intputStream = this .jar
099: .getInputStream(nextEntry);
100: // write the data
101: for (int data = intputStream.read(); data != -1; data = intputStream
102: .read()) {
103:
104: jarOutputStream.write(data);
105: }
106: }
107: }
108:
109: // write the new or modified entry to the jar
110: if (size() > 0) {
111: jarOutputStream.putNextEntry(new JarEntry(
112: this .jarEntryName));
113: jarOutputStream.write(super .buf, 0, size());
114: jarOutputStream.closeEntry();
115: }
116: } finally {
117: // close close everything up
118: try {
119: if (jarOutputStream != null) {
120: jarOutputStream.close();
121: }
122: } catch (IOException ioe) {
123: // eat it, just wanted to close stream
124: }
125: }
126:
127: // swap the jar
128: this.jar.swapJars(newJarFile);
129: }
130:
131: }
|