001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.util;
006:
007: import org.apache.commons.io.IOUtils;
008:
009: import java.io.BufferedInputStream;
010: import java.io.BufferedOutputStream;
011: import java.io.File;
012: import java.io.FileInputStream;
013: import java.io.FileOutputStream;
014: import java.io.IOException;
015: import java.io.InputStream;
016: import java.util.HashSet;
017: import java.util.zip.CRC32;
018: import java.util.zip.ZipEntry;
019: import java.util.zip.ZipInputStream;
020: import java.util.zip.ZipOutputStream;
021:
022: /**
023: * NOT THREAD SAFE
024: */
025: public class ZipBuilder implements ArchiveBuilder {
026:
027: private final CRC32 crc32 = new CRC32();
028: private final ZipOutputStream zout;
029: private final HashSet dirSet = new HashSet();
030: private final HashSet entrySet = new HashSet();
031:
032: public ZipBuilder(File archiveFile, boolean useCompression)
033: throws IOException {
034: zout = getArchiveOutputStream(archiveFile);
035: if (useCompression) {
036: zout.setMethod(ZipEntry.DEFLATED);
037: zout.setLevel(9);
038: } else {
039: zout.setMethod(ZipEntry.STORED);
040: zout.setLevel(0);
041: }
042: }
043:
044: public final void putTraverseDirectory(File dir, String dirName)
045: throws IOException {
046: if (!dir.isDirectory())
047: throw new IOException("Unexpected Exception: " + dir
048: + "\nis not a directory");
049: putDirEntry(dirName);
050: String[] files = dir.list();
051: for (int i = 0; i < files.length; i++) {
052: File file = new File(dir + File.separator + files[i]);
053: if (file.isDirectory()) {
054: putTraverseDirectory(file, dirName + File.separator
055: + file.getName());
056: continue;
057: }
058: putEntry(dirName + File.separator + files[i],
059: readFile(file));
060: }
061: }
062:
063: public final void putDirEntry(String file) throws IOException {
064: if (dirSet.contains(file))
065: return;
066: dirSet.add(file);
067: String dirEntry = archivePath(file) + "/";
068: ZipEntry entry = createEntry(dirEntry);
069: entry.setSize(0);
070: entry.setCrc(0);
071: zout.putNextEntry(entry);
072: System.out.println(dirEntry);
073: }
074:
075: public final void putEntry(String file, byte[] bytes)
076: throws IOException {
077: if (entrySet.contains(file.toString()))
078: return;
079: entrySet.add(file.toString());
080: String fileEntry = archivePath(file);
081: ZipEntry entry = createEntry(fileEntry);
082: entry.setSize(bytes.length);
083: entry.setCrc(getCrc32(bytes));
084: zout.putNextEntry(entry);
085: zout.write(bytes, 0, bytes.length);
086: System.out.println(fileEntry);
087: }
088:
089: public final void finish() throws IOException {
090: zout.close();
091: }
092:
093: public final byte[] readFile(File file) throws IOException {
094: BufferedInputStream in = new BufferedInputStream(
095: new FileInputStream(file));
096: byte[] bytes = new byte[in.available()];
097: in.read(bytes);
098: in.close();
099: return bytes;
100: }
101:
102: protected ZipEntry createEntry(String name) {
103: return new ZipEntry(name);
104: }
105:
106: protected ZipOutputStream getArchiveOutputStream(File archiveFile)
107: throws IOException {
108: if (zout != null)
109: throw new IllegalStateException(
110: "ArchiveOutputStream has already been instantiated.");
111: return new ZipOutputStream(new BufferedOutputStream(
112: new FileOutputStream(archiveFile)));
113: }
114:
115: private long getCrc32(byte[] bytes) {
116: crc32.update(bytes);
117: long checksum = crc32.getValue();
118: crc32.reset();
119: return checksum;
120: }
121:
122: private String archivePath(String file) {
123: if (File.separator.equals("/"))
124: return file;
125: return file.replaceAll("\\\\", "/");
126: }
127:
128: public static void unzip(InputStream archive, File destDir)
129: throws IOException {
130: ZipInputStream zis = null;
131: try {
132: zis = new ZipInputStream(archive);
133: ZipEntry entry;
134: while ((entry = zis.getNextEntry()) != null) {
135: File file = new File(destDir, entry.getName());
136: if (entry.isDirectory()) {
137: file.mkdirs();
138: } else {
139: IOUtils.copy(zis, new FileOutputStream(file));
140: }
141: zis.closeEntry();
142: }
143: } catch (IOException e) {
144: e.printStackTrace();
145: throw e;
146: } finally {
147: if (zis != null)
148: zis.close();
149: }
150: }
151: }
|