001/* 002Copyright (c) 2011+, HL7, Inc 003All rights reserved. 004 005Redistribution and use in source and binary forms, with or without modification, 006are permitted provided that the following conditions are met: 007 008 * Redistributions of source code must retain the above copyright notice, this 009 list of conditions and the following disclaimer. 010 * Redistributions in binary form must reproduce the above copyright notice, 011 this list of conditions and the following disclaimer in the documentation 012 and/or other materials provided with the distribution. 013 * Neither the name of HL7 nor the names of its contributors may be used to 014 endorse or promote products derived from this software without specific 015 prior written permission. 016 017THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 018ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 019WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 020IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 021INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 023PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 024WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 025ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 026POSSIBILITY OF SUCH DAMAGE. 027 028 */ 029package org.hl7.fhir.utilities; 030 031import java.io.BufferedInputStream; 032import java.io.BufferedOutputStream; 033import java.io.ByteArrayInputStream; 034import java.io.File; 035import java.io.FileInputStream; 036import java.io.FileNotFoundException; 037import java.io.FileOutputStream; 038import java.io.IOException; 039import java.io.InputStream; 040import java.util.HashSet; 041import java.util.Set; 042import java.util.zip.CRC32; 043import java.util.zip.Deflater; 044import java.util.zip.ZipEntry; 045import java.util.zip.ZipInputStream; 046import java.util.zip.ZipOutputStream; 047 048public class ZipGenerator { 049 050 private Set<String> names = new HashSet<String>(); 051 FileOutputStream dest; 052 ZipOutputStream out; 053 054 public ZipGenerator(String filename) throws FileNotFoundException { 055 dest = new FileOutputStream(filename); 056 out = new ZipOutputStream(new BufferedOutputStream(dest)); 057 out.setLevel(Deflater.BEST_COMPRESSION); 058 } 059 060 public void close() throws IOException { 061 out.close(); 062 } 063 064 static final int BUFFER = 2048; 065 066 public void addFromZip(String zipFilename) throws IOException { 067 byte[] buf = new byte[1024]; 068 069 ZipInputStream zin = new ZipInputStream( 070 new FileInputStream(zipFilename)); 071 072 try { 073 ZipEntry entry = zin.getNextEntry(); 074 while (entry != null) { 075 String name = entry.getName(); 076 077 names.add(name); 078 // Add ZIP entry to output stream. 079 out.putNextEntry(new ZipEntry(name)); 080 // Transfer bytes from the ZIP file to the output file 081 int len; 082 while ((len = zin.read(buf)) > 0) { 083 out.write(buf, 0, len); 084 } 085 086 entry = zin.getNextEntry(); 087 } 088 } finally { 089 zin.close(); 090 } 091 } 092 093 public void addFolder(String actualDir, String statedDir, boolean omitIfExists) throws IOException { 094 File fd = new CSFile(actualDir); 095 String files[] = fd.list(); 096 for (String f : files) { 097 if (new CSFile(Utilities.path(actualDir, f)).isDirectory()) 098 addFolder(Utilities.path(actualDir, f), Utilities.pathURL(statedDir, f), omitIfExists); 099 else 100 addFileName(Utilities.pathURL(statedDir, f), Utilities.path(actualDir, f), omitIfExists); 101 } 102 } 103 104 public void addFolder(String actualDir, String statedDir, boolean omitIfExists, String noExt) throws IOException { 105 File fd = new CSFile(actualDir); 106 String files[] = fd.list(); 107 for (String f : files) { 108 if (new CSFile(Utilities.path(actualDir, f)).isDirectory()) 109 addFolder(Utilities.path(actualDir, f), Utilities.pathURL(statedDir, f), omitIfExists, noExt); 110 else if (noExt == null || !f.endsWith(noExt)) 111 addFileName(Utilities.pathURL(statedDir, f), Utilities.path(actualDir, f), omitIfExists); 112 } 113 } 114 115 public void addFiles(String actualDir, String statedDir, String ext, String noExt) throws FileNotFoundException, IOException { 116 byte data[] = new byte[BUFFER]; 117 statedDir = statedDir.replace("\\", "/"); 118 File f = new CSFile(actualDir); 119 120 String files[] = f.list(); 121 for (int i = 0; i < files.length; i++) { 122 if ( new CSFile(actualDir + files[i]).isFile() && ((ext == null || files[i].endsWith(ext)) && (noExt == null || !files[i].endsWith(noExt)))) { 123 FileInputStream fi = new FileInputStream(actualDir + files[i]); 124 BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 125 ZipEntry entry = new ZipEntry(statedDir + files[i]); 126 names.add(statedDir + files[i]); 127 out.putNextEntry(entry); 128 int count; 129 while ((count = origin.read(data, 0, BUFFER)) != -1) { 130 out.write(data, 0, count); 131 } 132 origin.close(); 133 } 134 } 135 } 136 137 public void addFilesFiltered(String actualDir, String statedDir, String ext, String[] noExt) throws FileNotFoundException, IOException { 138 byte data[] = new byte[BUFFER]; 139 statedDir = statedDir.replace("\\", "/"); 140 File f = new CSFile(actualDir); 141 142 String files[] = f.list(); 143 for (int i = 0; i < files.length; i++) { 144 if ( new CSFile(actualDir + files[i]).isFile() && ((ext == null || files[i].endsWith(ext)))) { 145 boolean ok = true; 146 for (String n : noExt) { 147 ok = ok && !files[i].endsWith(n); 148 } 149 if (ok) { 150 FileInputStream fi = new FileInputStream(actualDir + files[i]); 151 BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 152 ZipEntry entry = new ZipEntry(statedDir + files[i]); 153 names.add(statedDir + files[i]); 154 out.putNextEntry(entry); 155 int count; 156 while ((count = origin.read(data, 0, BUFFER)) != -1) { 157 out.write(data, 0, count); 158 } 159 origin.close(); 160 } 161 } 162 } 163 } 164 165 public void addFileSource(String path, String cnt, boolean omitIfExists) throws IOException { 166 File tmp = Utilities.createTempFile("tmp", ".tmp"); 167 TextFile.stringToFile(cnt, tmp.getAbsolutePath()); 168 addFileName(path, tmp.getAbsolutePath(), omitIfExists); 169 tmp.delete(); 170 } 171 172 public void addFileName(String statedPath, String actualPath, boolean omitIfExists) throws IOException { 173 if (!omitIfExists || !names.contains(statedPath)) { 174 byte data[] = new byte[BUFFER]; 175 FileInputStream fi = new FileInputStream(actualPath); 176 BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 177 ZipEntry entry = new ZipEntry(statedPath); 178 names.add(statedPath); 179 out.putNextEntry(entry); 180 int count; 181 while ((count = origin.read(data, 0, BUFFER)) != -1) { 182 out.write(data, 0, count); 183 } 184 origin.close(); 185 } 186 } 187 188 public void addBytes(String statedPath, byte[] content, boolean omitIfExists) throws IOException { 189 if (!omitIfExists || !names.contains(statedPath)) { 190 byte data[] = new byte[BUFFER]; 191 InputStream fi = new ByteArrayInputStream(content); 192 BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 193 ZipEntry entry = new ZipEntry(statedPath); 194 names.add(statedPath); 195 out.putNextEntry(entry); 196 int count; 197 while ((count = origin.read(data, 0, BUFFER)) != -1) { 198 out.write(data, 0, count); 199 } 200 origin.close(); 201 } 202 } 203 204 public void addMimeTypeFile(String statedPath, String actualPath) throws IOException { 205 // byte data[] = new byte[BUFFER]; 206 CRC32 crc = new CRC32(); 207 208 // FileInputStream fi = new FileInputStream(actualPath); 209 // BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 210 out.setLevel(0); 211 ZipEntry entry = new ZipEntry(statedPath); 212 entry.setExtra(null); 213 names.add(statedPath); 214 String contents = "application/epub+zip"; 215 crc.update(contents.getBytes()); 216 entry.setCompressedSize(contents.length()); 217 entry.setSize(contents.length()); 218 entry.setCrc(crc.getValue()); 219 entry.setMethod(ZipEntry.STORED); 220 out.putNextEntry(entry); 221 // int count; 222// while ((count = origin.read(data, 0, BUFFER)) != -1) { 223// out.write(data, 0, count); 224// } 225 // origin.close(); 226 out.write(contents.getBytes(),0,contents.length()); 227 out.setLevel(Deflater.BEST_COMPRESSION); 228 } 229 230 public void addStream(String statedPath, InputStream fi, boolean omitIfExists) throws IOException { 231 if (!omitIfExists || !names.contains(statedPath)) { 232 byte data[] = new byte[BUFFER]; 233 BufferedInputStream origin = new BufferedInputStream(fi, BUFFER); 234 ZipEntry entry = new ZipEntry(statedPath); 235 names.add(statedPath); 236 out.putNextEntry(entry); 237 int count; 238 while ((count = origin.read(data, 0, BUFFER)) != -1) { 239 out.write(data, 0, count); 240 } 241 origin.close(); 242 } 243 } 244 245}