Home | History | Annotate | Download | only in util
      1 /**
      2  * Copyright 2008 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.tonicsystems.jarjar.util;
     18 
     19 import java.io.*;
     20 import java.util.ArrayList;
     21 import java.util.Collections;
     22 import java.util.Comparator;
     23 import java.util.Enumeration;
     24 import java.util.zip.ZipEntry;
     25 import java.util.zip.ZipFile;
     26 import java.util.zip.ZipOutputStream;
     27 
     28 class IoUtil {
     29     private IoUtil() {}
     30 
     31     public static void pipe(InputStream is, OutputStream out, byte[] buf) throws IOException {
     32         for (;;) {
     33             int amt = is.read(buf);
     34             if (amt < 0)
     35                 break;
     36             out.write(buf, 0, amt);
     37         }
     38     }
     39 
     40     public static void copy(File from, File to, byte[] buf) throws IOException {
     41         InputStream in = new FileInputStream(from);
     42         try {
     43             OutputStream out = new FileOutputStream(to);
     44             try {
     45                 pipe(in, out, buf);
     46             } finally {
     47                 out.close();
     48             }
     49         } finally {
     50             in.close();
     51         }
     52     }
     53 
     54     /**
     55      * Create a copy of an zip file without its empty directories.
     56      * @param inputFile
     57      * @param outputFile
     58      * @throws IOException
     59      */
     60     public static void copyZipWithoutEmptyDirectories(final File inputFile, final File outputFile) throws IOException
     61     {
     62         final byte[] buf = new byte[0x2000];
     63 
     64         final ZipFile inputZip = new ZipFile(inputFile);
     65         final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(outputFile));
     66         try
     67         {
     68             // read a the entries of the input zip file and sort them
     69             final Enumeration<? extends ZipEntry> e = inputZip.entries();
     70             final ArrayList<ZipEntry> sortedList = new ArrayList<ZipEntry>();
     71             while (e.hasMoreElements()) {
     72                 final ZipEntry entry = e.nextElement();
     73                 sortedList.add(entry);
     74             }
     75 
     76             Collections.sort(sortedList, new Comparator<ZipEntry>()
     77             {
     78                 public int compare(ZipEntry o1, ZipEntry o2)
     79                 {
     80                     return o1.getName().compareTo(o2.getName());
     81                 }
     82             });
     83 
     84             // treat them again and write them in output, wenn they not are empty directories
     85             for (int i = sortedList.size()-1; i>=0; i--)
     86             {
     87                 final ZipEntry inputEntry = sortedList.get(i);
     88                 final String name = inputEntry.getName();
     89                 final boolean isEmptyDirectory;
     90                 if (inputEntry.isDirectory())
     91                 {
     92                     if (i == sortedList.size()-1)
     93                     {
     94                         // no item afterwards; it was an empty directory
     95                         isEmptyDirectory = true;
     96                     }
     97                     else
     98                     {
     99                         final String nextName = sortedList.get(i+1).getName();
    100                         isEmptyDirectory  = !nextName.startsWith(name);
    101                     }
    102                 }
    103                 else
    104                 {
    105                     isEmptyDirectory = false;
    106                 }
    107 
    108 
    109                 // write the entry
    110                 if (isEmptyDirectory)
    111                 {
    112                     sortedList.remove(inputEntry);
    113                 }
    114                 else
    115                 {
    116                     final ZipEntry outputEntry = new ZipEntry(inputEntry);
    117                     outputStream.putNextEntry(outputEntry);
    118                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
    119                     final InputStream is = inputZip.getInputStream(inputEntry);
    120                     IoUtil.pipe(is, baos, buf);
    121                     is.close();
    122                     outputStream.write(baos.toByteArray());
    123                 }
    124             }
    125         } finally {
    126             outputStream.close();
    127         }
    128 
    129     }
    130 
    131 }
    132