KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > io > archive > zip > Zip32OutputArchive


1 /*
2  * Zip32OutputArchive.java
3  *
4  * Created on 27. Februar 2006, 01:10
5  */

6 /*
7  * Copyright 2006 Schlichtherle IT Services
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package de.schlichtherle.io.archive.zip;
23
24 import de.schlichtherle.io.*;
25 import de.schlichtherle.io.archive.spi.*;
26 import de.schlichtherle.util.zip.*;
27
28 import java.io.*;
29 import java.util.*;
30 import java.util.zip.*;
31
32 /**
33  * An implementation of {@link OutputArchive} to write ZIP32 archives.
34  *
35  * @see Zip32Driver
36  *
37  * @author Christian Schlichtherle
38  * @version @version@
39  * @since TrueZIP 6.0
40  */

41 public class Zip32OutputArchive
42         extends BasicZipOutputStream
43         implements OutputArchive {
44
45     private final Zip32InputArchive source;
46     private OutputArchiveMetaData metaData;
47     
48     /**
49      * Creates a new instance of <code>Zip32OutputArchive</code> which always
50      * uses the best compression level.
51      */

52     public Zip32OutputArchive(
53             final OutputStream out,
54             final String JavaDoc encoding,
55             final Zip32InputArchive source)
56     throws NullPointerException JavaDoc,
57             UnsupportedEncodingException,
58             IOException {
59         super(out, encoding);
60         super.setLevel(Deflater.BEST_COMPRESSION);
61
62         this.source = source;
63         if (source != null) {
64             // Retain comment and preamble of input ZIP32 archive.
65
super.setComment(source.getComment());
66             if (source.getPreambleLength() > 0) {
67                 final InputStream in = source.getPreambleInputStream();
68                 try {
69                     de.schlichtherle.io.File.cat(
70                             in, source.offsetsConsiderPreamble() ? this : out);
71                 } finally {
72                     in.close();
73                 }
74             }
75         }
76     }
77
78     public int getNumArchiveEntries() {
79         return size();
80     }
81
82     public Enumeration getArchiveEntries() {
83         return entries();
84     }
85
86     public ArchiveEntry getArchiveEntry(final String JavaDoc name) {
87         return (Zip32Entry) getEntry(name);
88     }
89
90     public OutputStream getOutputStream(
91             final ArchiveEntry entry,
92             final ArchiveEntry srcEntry)
93     throws IOException {
94         if (busy())
95             throw new OutputArchiveBusyException(entry);
96
97         final Zip32Entry zipEntry = (Zip32Entry) entry;
98         if (srcEntry instanceof Zip32Entry) {
99             // Copy some entry attributes for Direct Data Copying (DDC).
100
final Zip32Entry srcZipEntry = (Zip32Entry) srcEntry;
101             zipEntry.setMethod(srcZipEntry.getMethod());
102             zipEntry.setCrc(srcZipEntry.getCrc());
103             zipEntry.setSize(srcZipEntry.getSize());
104             zipEntry.setCompressedSize(srcZipEntry.getCompressedSize());
105         }
106
107         return createEntryOutputStream(zipEntry, srcEntry);
108     }
109
110     protected OutputStream createEntryOutputStream(
111             final Zip32Entry entry,
112             final ArchiveEntry srcEntry)
113     throws IOException {
114         return new EntryOutputStream(entry, !(srcEntry instanceof Zip32Entry));
115     }
116
117     protected class EntryOutputStream extends FilterOutputStream {
118         public EntryOutputStream(Zip32Entry entry, boolean deflate)
119         throws IOException {
120             super(Zip32OutputArchive.this);
121             putNextEntry(entry, deflate);
122         }
123
124         public void write(int b) throws IOException {
125             out.write(b);
126         }
127
128         public void write(byte[] b) throws IOException {
129             out.write(b);
130         }
131
132         public void write(byte[] b, int off, int len) throws IOException {
133             out.write(b, off, len);
134         }
135
136         public void close() throws IOException {
137             assert out == Zip32OutputArchive.this;
138             closeEntry();
139         }
140     } // class EntryOutputStream
141

142     public void storeDirectory(ArchiveEntry entry)
143     throws IOException {
144         assert entry.isDirectory();
145         final Zip32Entry ze = (Zip32Entry) entry;
146         ze.setMethod(Zip32Entry.STORED);
147         ze.setCrc(0);
148         ze.setSize(0);
149         putNextEntry(ze);
150         closeEntry();
151     }
152
153     /**
154      * Retain the postamble of the source ZIP archive, if any.
155      */

156     public void finish() throws IOException {
157         super.finish();
158
159         if (source == null)
160             return;
161
162         final long ipl = source.getPostambleLength();
163         if (ipl <= 0)
164             return;
165
166         final long il = source.length();
167         final long ol = length();
168
169         final InputStream in = source.getPostambleInputStream();
170         try {
171             // Second, if the output ZIP compatible file differs in length from
172
// the input ZIP compatible file pad the output to the next four byte
173
// boundary before appending the postamble.
174
// This might be required for self extracting files on some platforms
175
// (e.g. Wintel).
176
if (ol + ipl != il)
177                 write(new byte[(int) (ol % 4)]);
178
179             // Finally, write the postamble.
180
de.schlichtherle.io.File.cat(in, this);
181         } finally {
182             in.close();
183         }
184     }
185
186     //
187
// Metadata implementation.
188
//
189

190     public OutputArchiveMetaData getMetaData() {
191         return metaData;
192     }
193
194     public void setMetaData(OutputArchiveMetaData metaData) {
195         this.metaData = metaData;
196     }
197 }
198
Popular Tags