/* *Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * *WSO2 Inc. licenses this file to you under the Apache License, *Version 2.0 (the "License"); you may not use this file except *in compliance with the License. *You may obtain a copy of the License at * *http://www.apache.org/licenses/LICENSE-2.0 * *Unless required by applicable law or agreed to in writing, *software distributed under the License is distributed on an *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *KIND, either express or implied. See the License for the *specific language governing permissions and limitations *under the License. */ package org.wso2.carbon.automation.engine.frameworkutils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.*; import java.util.ArrayList; import java.util.Collection; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * This class handles the functionality of archive/extract files */ public class ArchiveManipulator { private static final int BUFFER_SIZE = 40960; private static Log log = LogFactory.getLog(ArchiveManipulator.class); private String archiveSourceDir; /** * Archive a directory * * @param archiveDestination archive destination * @param sourceDir source directory * @throws IOException if directory archiving failed */ public void archiveDir(String archiveDestination, String sourceDir) throws IOException { File zipDir = new File(sourceDir); if (!zipDir.isDirectory()) { throw new IOException(sourceDir + " is not a directory"); } ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(archiveDestination)); this.archiveSourceDir = sourceDir; try { zipDir(zipDir, zos); } finally { try { zos.close(); } catch (IOException e) { log.warn("Unable to close the ZipOutputStream ", e); } } } /** * Archive a file * * @param from from file path * @param to to file path * @throws IOException if file archiving failed */ public void archiveFile(String from, String to) throws IOException { ZipOutputStream out = null; FileInputStream in = new FileInputStream(from); try { out = new ZipOutputStream(new FileOutputStream(to)); byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } finally { try { in.close(); } catch (IOException e) { log.warn("Unable to close the InputStream ", e); } try { if (out != null) { out.close(); } } catch (IOException e) { log.warn("Unable to close the OutputStream ", e); } } } /** * List the contents of an archive * * @param archive archive file * @return List of Zip Entries * @throws IOException if archive listing failed */ public String[] check(String archive) throws IOException { ZipInputStream zin = null; InputStream in = null; Collection<String> entries = new ArrayList<String>(); try { in = new FileInputStream(archive); zin = new ZipInputStream(in); ZipEntry entry; while ((entry = zin.getNextEntry()) != null) { entries.add(entry.getName()); } return entries.toArray(new String[entries.size()]); } finally { try { if (zin != null) { zin.close(); } } catch (IOException e) { log.warn("Could not close ZipInputStream ", e); } try { if (in != null) { in.close(); } } catch (IOException e) { log.warn("Could not close InputStream ", e); } } } /** * Extract archive * * @param archive archive location * @param extractDir location to be extract * @throws IOException if extracting archive failed */ public void extract(String archive, String extractDir) throws IOException { FileInputStream inputStream = new FileInputStream(archive); try { extractFromStream(inputStream, extractDir); } finally { try { inputStream.close(); } catch (IOException e) { log.warn("Could not close InputStream ", e); } } } /** * Extract InputStream to a directory * * @param inputStream archive inputStream * @param extractDir location to be extract * @throws IOException if extracting InputStream failed */ public void extractFromStream(InputStream inputStream, String extractDir) throws IOException { ZipInputStream zin = null; OutputStream out = null; try { File unzipped = new File(extractDir); if (!unzipped.exists() && !unzipped.mkdirs()) { throw new IOException( "Fail to create the directory: " + unzipped.getAbsolutePath()); } // Open the ZIP file zin = new ZipInputStream(inputStream); ZipEntry entry; while ((entry = zin.getNextEntry()) != null) { String entryName = entry.getName(); File f = new File(extractDir + File.separator + entryName); if (entryName.endsWith("/") && !f.exists()) { // this is a // directory if (!f.mkdirs()) { throw new IOException( "Fail to create the directory: " + f.getAbsolutePath()); } continue; } // This is a file. Carry out File processing int lastIndexOfSlash = entryName.lastIndexOf('/'); String dirPath = ""; if (lastIndexOfSlash != -1) { dirPath = entryName.substring(0, lastIndexOfSlash); File dir = new File(extractDir + File.separator + dirPath); if (!dir.exists() && !dir.mkdirs()) { throw new IOException( "Fail to create the directory: " + dir.getAbsolutePath()); } } if (!f.isDirectory()) { out = new FileOutputStream(f); byte[] buf = new byte[BUFFER_SIZE]; // Transfer bytes from the ZIP file to the output file int len; while ((len = zin.read(buf)) > 0) { out.write(buf, 0, len); } } } } finally { try { if (zin != null) { zin.close(); } } catch (IOException e) { log.warn("Unable to close the InputStream ", e); } try { if (out != null) { out.close(); } } catch (IOException e) { log.warn("Unable to close the OutputStream ", e); } } } protected void zipDir(File zipDir, ZipOutputStream zos) throws IOException { //get a listing of the directory content String[] dirList = zipDir.list(); byte[] readBuffer = new byte[BUFFER_SIZE]; int bytesIn = 0; //loop through dirList, and zip the files if (dirList != null) { for (String dir : dirList) { File f = new File(zipDir, dir); //place the zip entry in the ZipOutputStream object zos.putNextEntry(new ZipEntry(getZipEntryPath(f))); if (f.isDirectory()) { //if the File object is a directory, call this //function again to add its content recursively zipDir(f, zos); //loop again continue; } //if we reached here, the File object f was not a directory //create a FileInputStream on top of f FileInputStream fis = new FileInputStream(f); try { //now write the content of the file to the ZipOutputStream while ((bytesIn = fis.read(readBuffer)) != -1) { zos.write(readBuffer, 0, bytesIn); } } finally { try { //close the Stream fis.close(); } catch (IOException e) { log.warn("Unable to close the FileInputStream ", e); } } } } } protected String getZipEntryPath(File f) { String entryPath = f.getPath(); entryPath = entryPath.substring(archiveSourceDir.length() + 1); if (File.separatorChar == '\\') { entryPath = entryPath.replace(File.separatorChar, '/'); } if (f.isDirectory()) { entryPath += "/"; } return entryPath; } }