1 /* 2 * Copyright (C) 2007-2010 Jlio 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 22 package com.github.javaparser.utils; 23 24 import com.github.javaparser.JavaParser; 25 import com.github.javaparser.ParseResult; 26 import com.github.javaparser.ParserConfiguration; 27 import com.github.javaparser.ast.CompilationUnit; 28 29 import java.io.IOException; 30 import java.nio.file.Path; 31 import java.nio.file.Paths; 32 import java.util.ArrayList; 33 import java.util.Collections; 34 import java.util.List; 35 import java.util.zip.ZipEntry; 36 import java.util.zip.ZipFile; 37 38 import static com.github.javaparser.ParseStart.COMPILATION_UNIT; 39 import static com.github.javaparser.Providers.provider; 40 import 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 */ 47 public class SourceZip { 48 49 private final Path zipPath; 50 private ParserConfiguration parserConfiguration; 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.parserConfiguration = 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 List<Pair<Path, ParseResult<CompilationUnit>>> results = new ArrayList<>(); 88 parse((path, result) -> results.add(new Pair<>(path, result))); 89 return results; 90 } 91 92 /** 93 * Tries to parse all '.java' files in the ZIP located at this <i>SourceZip</i>'s path and returns the parse 94 * results in a list. 95 * 96 * @return A list of path-compilation unit pairs. 97 * 98 * @throws IOException If an error occurs while trying to parse the given source. 99 */ 100 public SourceZip parse(Callback callback) throws IOException { 101 Log.info("Parsing zip at \"%s\"", zipPath); 102 JavaParser javaParser = new JavaParser(parserConfiguration); 103 try (ZipFile zipFile = new ZipFile(zipPath.toFile())) { 104 for (ZipEntry entry : Collections.list(zipFile.entries())) { 105 if (!entry.isDirectory() && entry.getName().endsWith(".java")) { 106 Log.info("Parsing zip entry \"%s\"", entry.getName()); 107 final ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, 108 provider(zipFile.getInputStream(entry))); 109 callback.process(Paths.get(entry.getName()), result); 110 } 111 } 112 } 113 return this; 114 } 115 116 /** 117 * An interface to define a callback for each file that's parsed. 118 */ 119 @FunctionalInterface 120 public interface Callback { 121 122 /** 123 * Process the given parse result. 124 * 125 * @param relativeZipEntryPath The relative path of the entry in the ZIP file that was parsed. 126 * @param result The parse result of file located at <i>absolutePath</i>. 127 */ 128 void process(Path relativeZipEntryPath, ParseResult<CompilationUnit> result); 129 } 130 131 /** 132 * Get the path of the ZIP file to be parsed. 133 * 134 * @return The absolute path of this ZIP file. 135 */ 136 public Path getZipPath() { 137 return zipPath; 138 } 139 140 /** 141 * @deprecated store ParserConfiguration now 142 */ 143 @Deprecated 144 public JavaParser getJavaParser() { 145 return new JavaParser(parserConfiguration); 146 } 147 148 /** 149 * Set the parser that is used for parsing by default. 150 * 151 * @deprecated store ParserConfiguration now 152 */ 153 @Deprecated 154 public SourceZip setJavaParser(JavaParser javaParser) { 155 assertNotNull(javaParser); 156 this.parserConfiguration = javaParser.getParserConfiguration(); 157 return this; 158 } 159 160 public ParserConfiguration getParserConfiguration() { 161 return parserConfiguration; 162 } 163 164 public SourceZip setParserConfiguration(ParserConfiguration parserConfiguration) { 165 assertNotNull(parserConfiguration); 166 this.parserConfiguration = parserConfiguration; 167 return this; 168 } 169 } 170