• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
IoUtil()29     private IoUtil() {}
30 
pipe(InputStream is, OutputStream out, byte[] buf)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 
copy(File from, File to, byte[] buf)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      */
copyZipWithoutEmptyDirectories(final File inputFile, final File outputFile)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