001/* 002 * Copyright 2018 Nils Hoffmann <nils.hoffmann@isas.de>. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package de.isas.mztab2.test.utils; 017 018import java.io.BufferedInputStream; 019import java.io.BufferedOutputStream; 020import java.io.File; 021import java.io.FileNotFoundException; 022import java.io.FileOutputStream; 023import java.io.IOException; 024import java.io.InputStream; 025import java.net.URL; 026import java.util.logging.Level; 027import java.util.logging.Logger; 028import java.util.zip.GZIPInputStream; 029import java.util.zip.ZipEntry; 030import java.util.zip.ZipInputStream; 031 032/** 033 * <p> 034 * ZipResourceExtractor class.</p> 035 * 036 * @author nilshoffmann 037 * 038 */ 039public class ZipResourceExtractor { 040 041 private ZipResourceExtractor() { 042 043 } 044 045 /** 046 * <p> 047 * Extract a JAR resource into the provided destination directory and return 048 * that extracted resource's location as a file.</p> 049 * 050 * @param resourcePath a {@link java.lang.String} object. 051 * @param destDir a {@link java.io.File} object. 052 * @return a {@link java.io.File} object. 053 */ 054 public static File extract(String resourcePath, File destDir) { 055 if (!destDir.exists()) { 056 destDir.mkdirs(); 057 } 058 URL resourceURL = ZipResourceExtractor.class.getResource(resourcePath); 059 if (resourceURL == null) { 060 throw new NullPointerException( 061 "Could not retrieve resource for path: " + resourcePath); 062 } 063 File outputFile = null; 064 try (InputStream resourceInputStream = resourceURL.openStream()) { 065 066 String outname = new File(resourceURL.getPath()).getName(); 067 outname = outname.replaceAll("%20", " "); 068 if (resourcePath.endsWith("zip")) { 069 outname = outname.substring(0, outname.lastIndexOf( 070 '.')); 071 return extractZipArchive(resourceInputStream, destDir); 072 } else if (resourcePath.endsWith("gz")) { 073 try (InputStream in = new GZIPInputStream( 074 new BufferedInputStream( 075 resourceInputStream))) { 076 077 outname = outname.substring(0, outname.lastIndexOf( 078 '.')); 079 return writeTo(destDir, outname, in); 080 } 081 } else { 082 try (InputStream in = new BufferedInputStream( 083 resourceInputStream)) { 084 return writeTo(destDir, outname, in); 085 } 086 } 087 088 } catch (IOException ex) { 089 Logger.getLogger(ZipResourceExtractor.class.getName()). 090 log(Level.SEVERE, null, ex); 091 } 092 093 return outputFile; 094 } 095 096 private static File writeTo(File destDir, String outname, InputStream in) throws FileNotFoundException, IOException { 097 File outputFile = new File(destDir, outname); 098 try (BufferedOutputStream out = new BufferedOutputStream( 099 new FileOutputStream(outputFile))) { 100 101 // Transfer bytes from in to out 102 byte[] buf = new byte[1024]; 103 int len; 104 while ((len = in.read(buf)) > 0) { 105 out.write(buf, 0, len); 106 } 107 } 108 return outputFile; 109 } 110 111 /** 112 * <p> 113 * extractZipArchive.</p> 114 * 115 * @param istream a {@link java.io.InputStream} object. 116 * @param outputDir a {@link java.io.File} object. 117 * @return a {@link java.io.File} object. 118 */ 119 public static File extractZipArchive(InputStream istream, File outputDir) { 120 try { 121 File outDir; 122 try (ZipInputStream zis = new ZipInputStream( 123 new BufferedInputStream(istream))) { 124 ZipEntry entry; 125 outDir = null; 126 while ((entry = zis.getNextEntry()) != null) { 127 int size; 128 byte[] buffer = new byte[2048]; 129 File outFile = new File(outputDir, entry.getName()); 130 if (entry.isDirectory()) { 131 outFile.mkdirs(); 132 if (outDir == null) { 133 outDir = outFile; 134 } 135 } else { 136 try (FileOutputStream fos = new FileOutputStream(outFile)) { 137 BufferedOutputStream bos = new BufferedOutputStream( 138 fos, buffer.length); 139 while ((size = zis.read(buffer, 0, buffer.length)) != -1) { 140 bos.write(buffer, 0, size); 141 } 142 bos.flush(); 143 bos.close(); 144 } 145 } 146 } 147 if (outDir == null) { 148 outDir = outputDir; 149 } 150 } 151 istream.close(); 152 return outDir; 153 } catch (IOException e) { 154 throw new ZipResourceExtractionException(e); 155 } 156 } 157}