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