1ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba/**
2ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * Copyright 2007 Google Inc.
3ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba *
4ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * Licensed under the Apache License, Version 2.0 (the "License");
5ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * you may not use this file except in compliance with the License.
6ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * You may obtain a copy of the License at
7ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba *
8ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * http://www.apache.org/licenses/LICENSE-2.0
9ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba *
10ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * Unless required by applicable law or agreed to in writing, software
11ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * distributed under the License is distributed on an "AS IS" BASIS,
12ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * See the License for the specific language governing permissions and
14ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba * limitations under the License.
15ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba */
16ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
17ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibapackage com.tonicsystems.jarjar.util;
18ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
19ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.util.jar.JarEntry;
20ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.util.jar.JarFile;
21ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.util.jar.JarOutputStream;
22ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.util.Enumeration;
23ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.io.*;
24ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibaimport java.util.*;
25ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
26ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosibapublic class StandaloneJarProcessor
27ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba{
28ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba    public static void run(File from, File to, JarProcessor proc) throws IOException {
29ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        byte[] buf = new byte[0x2000];
30ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
31ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        JarFile in = new JarFile(from);
32ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        final File tmpTo = File.createTempFile("jarjar", ".jar");
33ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        JarOutputStream out = new JarOutputStream(new FileOutputStream(tmpTo));
34ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        Set<String> entries = new HashSet<String>();
35ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        try {
36ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            EntryStruct struct = new EntryStruct();
37ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            Enumeration<JarEntry> e = in.entries();
38ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            while (e.hasMoreElements()) {
39ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                JarEntry entry = e.nextElement();
40ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                struct.name = entry.getName();
41ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                struct.time = entry.getTime();
42ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                ByteArrayOutputStream baos = new ByteArrayOutputStream();
43ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                IoUtil.pipe(in.getInputStream(entry), baos, buf);
44ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                struct.data = baos.toByteArray();
45ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                if (proc.process(struct)) {
46ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                    if (entries.add(struct.name)) {
47ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        entry = new JarEntry(struct.name);
48ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        entry.setTime(struct.time);
49ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        entry.setCompressedSize(-1);
50ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        out.putNextEntry(entry);
51ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        out.write(struct.data);
52ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                    } else if (struct.name.endsWith("/")) {
53ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        // TODO(chrisn): log
54ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                    } else {
55ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                        throw new IllegalArgumentException("Duplicate jar entries: " + struct.name);
56ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                    }
57ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba                }
58ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            }
59ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
60ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        }
61ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        finally {
62ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            in.close();
63ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba            out.close();
64ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        }
65ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
66ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba         // delete the empty directories
67ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        IoUtil.copyZipWithoutEmptyDirectories(tmpTo, to);
68ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba        tmpTo.delete();
69ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba
70ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba    }
71ab61347a2cb3254688c42c993278cefd43e5d99dMarcin Kosiba}
72