1/**
2 * Copyright 2007 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
17package com.tonicsystems.jarjar.util;
18
19import java.io.*;
20import java.util.*;
21import org.apache.tools.ant.BuildException;
22import org.apache.tools.ant.taskdefs.Jar;
23import org.apache.tools.ant.types.ZipFileSet;
24import org.apache.tools.zip.JarMarker;
25import org.apache.tools.zip.ZipExtraField;
26import org.apache.tools.zip.ZipOutputStream;
27
28abstract public class AntJarProcessor extends Jar
29{
30    private EntryStruct struct = new EntryStruct();
31    private JarProcessor proc;
32    private byte[] buf = new byte[0x2000];
33
34    private Set<String> dirs = new HashSet<String>();
35    private boolean filesOnly;
36
37    protected boolean verbose;
38
39    private static final ZipExtraField[] JAR_MARKER = new ZipExtraField[] {
40        JarMarker.getInstance()
41    };
42
43    public void setVerbose(boolean verbose) {
44        this.verbose = verbose;
45    }
46
47    public abstract void execute() throws BuildException;
48
49    public void execute(JarProcessor proc) throws BuildException {
50        this.proc = proc;
51        super.execute();
52    }
53
54    public void setFilesonly(boolean f) {
55        super.setFilesonly(f);
56        filesOnly = f;
57    }
58
59    protected void zipDir(File dir, ZipOutputStream zOut, String vPath, int mode)
60        throws IOException {
61    }
62
63    protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
64                                     long lastModified, File fromArchive, int mode) throws IOException {
65        ByteArrayOutputStream baos = new ByteArrayOutputStream();
66        IoUtil.pipe(is, baos, buf);
67        struct.data = baos.toByteArray();
68        struct.name = vPath;
69        struct.time = lastModified;
70        if (proc.process(struct)) {
71            if (mode == 0)
72                mode = ZipFileSet.DEFAULT_FILE_MODE;
73            if (!filesOnly) {
74              addParentDirs(struct.name, zOut);
75            }
76            super.zipFile(new ByteArrayInputStream(struct.data),
77                          zOut, struct.name, struct.time, fromArchive, mode);
78        }
79    }
80
81    private void addParentDirs(String file, ZipOutputStream zOut) throws IOException {
82      int slash = file.lastIndexOf('/');
83      if (slash >= 0) {
84        String dir = file.substring(0, slash);
85        if (dirs.add(dir)) {
86          addParentDirs(dir, zOut);
87          super.zipDir((File) null, zOut, dir + "/", ZipFileSet.DEFAULT_DIR_MODE, JAR_MARKER);
88        }
89      }
90    }
91
92    public void reset() {
93        super.reset();
94        cleanHelper();
95    }
96
97    protected void cleanUp() {
98        super.cleanUp();
99        cleanHelper();
100    }
101
102    protected void cleanHelper() {
103        verbose = false;
104        filesOnly = false;
105        dirs.clear();
106    }
107}
108