1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
56
57
58
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
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
74 if (!"META-INF/".equals(entry.getName())) {
75 sortedList.add(entry);
76 }
77 }
78
79 Collections.sort(sortedList, new Comparator<ZipEntry>()
80 {
81 public int compare(ZipEntry o1, ZipEntry o2)
82 {
83 String n1 = o1.getName(), n2 = o2.getName();
84 if (metaOverride(n1, n2)) {
85 return -1;
86 }
87 if (metaOverride(n2, n1)) {
88 return 1;
89 }
90 return n1.compareTo(n2);
91 }
92
93
94 private boolean metaOverride(String n1, String n2) {
95 return (n1.startsWith("META-INF/") && !n2.startsWith("META-INF/"))
96 || (n1.equals("META-INF/MANIFEST.MF") && !n2.equals(n1));
97 }
98 });
99
100
101 for (int i = sortedList.size()-1; i>=0; i--)
102 {
103 final ZipEntry inputEntry = sortedList.get(i);
104 final String name = inputEntry.getName();
105 final boolean isEmptyDirectory;
106 if (inputEntry.isDirectory())
107 {
108 if (i == sortedList.size()-1)
109 {
110
111 isEmptyDirectory = true;
112 }
113 else
114 {
115 final String nextName = sortedList.get(i+1).getName();
116 isEmptyDirectory = !nextName.startsWith(name);
117 }
118 }
119 else
120 {
121 isEmptyDirectory = false;
122 }
123
124 if (isEmptyDirectory)
125 {
126 sortedList.remove(i);
127 }
128 }
129
130
131 for (int i = 0; i < sortedList.size(); i++)
132 {
133 final ZipEntry inputEntry = sortedList.get(i);
134 final ZipEntry outputEntry = new ZipEntry(inputEntry);
135 outputStream.putNextEntry(outputEntry);
136 ByteArrayOutputStream baos = new ByteArrayOutputStream();
137 final InputStream is = inputZip.getInputStream(inputEntry);
138 IoUtil.pipe(is, baos, buf);
139 is.close();
140 outputStream.write(baos.toByteArray());
141 }
142 } finally {
143 outputStream.close();
144 inputZip.close();
145 }
146
147 }
148
149 }