SourceZip.java revision 260f854838a06d3618a77fd643784a0ba735f932
1/*
2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21
22package com.github.javaparser.utils;
23
24import com.github.javaparser.JavaParser;
25import com.github.javaparser.ParseResult;
26import com.github.javaparser.ParserConfiguration;
27import com.github.javaparser.ast.CompilationUnit;
28
29import java.io.IOException;
30import java.nio.file.Path;
31import java.nio.file.Paths;
32import java.util.ArrayList;
33import java.util.Collections;
34import java.util.List;
35import java.util.zip.ZipEntry;
36import java.util.zip.ZipFile;
37
38import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
39import static com.github.javaparser.Providers.provider;
40import static com.github.javaparser.utils.Utils.assertNotNull;
41
42/**
43 * A collection of Java source files and its sub-directories located in a ZIP or JAR file on the file system.
44 * Files can be parsed with a callback.
45 *
46 */
47public class SourceZip {
48
49    private final Path zipPath;
50    private JavaParser javaParser;
51
52    /**
53     * Create a new ZIP parser. An instance of {@link JavaParser} with the default {@link ParserConfiguration} will be
54     * used to parse the ZIP.
55     *
56     * @param zipPath The absolute path of ZIP file to parse.
57     */
58    public SourceZip(Path zipPath) {
59        this(zipPath, new ParserConfiguration());
60    }
61
62    /**
63     * Create a new ZIP parser. An instance of {@link JavaParser} with the given configuration will be used to parse
64     * the ZIP.
65     *
66     * @param zipPath The absolute path of ZIP file to parse.
67     * @param configuration The configuration to initiate the default parser with.
68     */
69    public SourceZip(Path zipPath, ParserConfiguration configuration) {
70        assertNotNull(zipPath);
71        assertNotNull(configuration);
72        this.zipPath = zipPath.normalize();
73        this.javaParser = new JavaParser(configuration);
74        Log.info("New source zip at \"%s\"", this.zipPath);
75    }
76
77    /**
78     * Tries to parse all '.java' files in the ZIP located at this <i>SourceZip</i>'s path and returns the parse
79     * results in a list.
80     *
81     * @return A list of path-compilation unit pairs.
82     *
83     * @throws IOException If an error occurs while trying to parse the given source.
84     */
85    public List<Pair<Path, ParseResult<CompilationUnit>>> parse() throws IOException {
86        Log.info("Parsing zip at \"%s\"", zipPath);
87        try (ZipFile zipFile = new ZipFile(zipPath.toFile())) {
88            List<Pair<Path, ParseResult<CompilationUnit>>> results = new ArrayList<>();
89            for (ZipEntry entry : Collections.list(zipFile.entries())) {
90                if (!entry.isDirectory() && entry.getName().endsWith(".java")) {
91                    Log.info("Parsing zip entry \"%s\"", entry.getName());
92                    final ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT,
93                            provider(zipFile.getInputStream(entry)));
94                    results.add(new Pair<>(Paths.get(entry.getName()), result));
95                }
96            }
97            return results;
98        }
99    }
100
101    /**
102     * Tries to parse all '.java' files in the ZIP located at this <i>SourceZip</i>'s path and returns the parse
103     * results in a list.
104     *
105     * @return A list of path-compilation unit pairs.
106     *
107     * @throws IOException If an error occurs while trying to parse the given source.
108     */
109    public SourceZip parse(Callback callback) throws IOException {
110        Log.info("Parsing zip at \"%s\"", zipPath);
111        try (ZipFile zipFile = new ZipFile(zipPath.toFile())) {
112            for (ZipEntry entry : Collections.list(zipFile.entries())) {
113                if (!entry.isDirectory() && entry.getName().endsWith(".java")) {
114                    Log.info("Parsing zip entry \"%s\"", entry.getName());
115                    final ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT,
116                            provider(zipFile.getInputStream(entry)));
117                    callback.process(Paths.get(entry.getName()), result);
118                }
119            }
120        }
121        return this;
122    }
123
124    /**
125     * An interface to define a callback for each file that's parsed.
126     */
127    @FunctionalInterface
128    public interface Callback {
129
130        /**
131         * Process the given parse result.
132         *
133         * @param relativeZipEntryPath The relative path of the entry in the ZIP file that was parsed.
134         * @param result The parse result of file located at <i>absolutePath</i>.
135         */
136        void process(Path relativeZipEntryPath, ParseResult<CompilationUnit> result);
137    }
138
139    /**
140     * Get the path of the ZIP file to be parsed.
141     *
142     * @return The absolute path of this ZIP file.
143     */
144    public Path getZipPath() {
145        return zipPath;
146    }
147
148    /**
149     * Get the parser used for parsing.
150     *
151     * @return The currently set parser.
152     */
153    public JavaParser getJavaParser() {
154        return javaParser;
155    }
156
157    /**
158     * Set the parser that is used for parsing.
159     *
160     * @param javaParser The parser to use.
161     */
162    public SourceZip setJavaParser(JavaParser javaParser) {
163        assertNotNull(javaParser);
164        this.javaParser = javaParser;
165        return this;
166    }
167}
168