tboudreau@18372
|
1 |
/*
|
tboudreau@18301
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
tboudreau@18301
|
3 |
*
|
tboudreau@18301
|
4 |
* Copyright (C) 1997-2015 Oracle and/or its affiliates. All rights reserved.
|
tboudreau@18301
|
5 |
*
|
tboudreau@18301
|
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
|
tboudreau@18301
|
7 |
* Other names may be trademarks of their respective owners.
|
tboudreau@18301
|
8 |
*
|
tboudreau@18301
|
9 |
* The contents of this file are subject to the terms of either the GNU
|
tboudreau@18301
|
10 |
* General Public License Version 2 only ("GPL") or the Common
|
tboudreau@18301
|
11 |
* Development and Distribution License("CDDL") (collectively, the
|
tboudreau@18301
|
12 |
* "License"). You may not use this file except in compliance with the
|
tboudreau@18301
|
13 |
* License. You can obtain a copy of the License at
|
tboudreau@18301
|
14 |
* http://www.netbeans.org/cddl-gplv2.html
|
tboudreau@18301
|
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
tboudreau@18301
|
16 |
* specific language governing permissions and limitations under the
|
tboudreau@18301
|
17 |
* License. When distributing the software, include this License Header
|
tboudreau@18301
|
18 |
* Notice in each file and include the License file at
|
tboudreau@18301
|
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
|
tboudreau@18301
|
20 |
* particular file as subject to the "Classpath" exception as provided
|
tboudreau@18301
|
21 |
* by Oracle in the GPL Version 2 section of the License file that
|
tboudreau@18301
|
22 |
* accompanied this code. If applicable, add the following below the
|
tboudreau@18301
|
23 |
* License Header, with the fields enclosed by brackets [] replaced by
|
tboudreau@18301
|
24 |
* your own identifying information:
|
tboudreau@18301
|
25 |
* "Portions Copyrighted [year] [name of copyright owner]"
|
tboudreau@18301
|
26 |
*
|
tboudreau@18301
|
27 |
* Contributor(s):
|
tboudreau@18301
|
28 |
*
|
tboudreau@18301
|
29 |
* The Original Software is NetBeans. The Initial Developer of the Original
|
tboudreau@18301
|
30 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
|
tboudreau@18301
|
31 |
* Microsystems, Inc. All Rights Reserved.
|
tboudreau@18301
|
32 |
*
|
tboudreau@18301
|
33 |
* If you wish your version of this file to be governed by only the CDDL
|
tboudreau@18301
|
34 |
* or only the GPL Version 2, indicate your decision by adding
|
tboudreau@18301
|
35 |
* "[Contributor] elects to include this software in this distribution
|
tboudreau@18301
|
36 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
tboudreau@18301
|
37 |
* single choice of license, a recipient has the option to distribute
|
tboudreau@18301
|
38 |
* your version of this file under either the CDDL, the GPL Version 2 or
|
tboudreau@18301
|
39 |
* to extend the choice of license to its licensees as provided above.
|
tboudreau@18301
|
40 |
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
tboudreau@18301
|
41 |
* Version 2 license, then the option applies only if the new code is
|
tboudreau@18301
|
42 |
* made subject to such option by the copyright holder.
|
tboudreau@18301
|
43 |
*/
|
tboudreau@18301
|
44 |
package org.netbeans.lib.callgraph;
|
tboudreau@18301
|
45 |
|
tboudreau@18301
|
46 |
import java.io.File;
|
tboudreau@18372
|
47 |
import java.io.IOException;
|
tboudreau@18301
|
48 |
import java.util.Collections;
|
tboudreau@18301
|
49 |
import java.util.HashSet;
|
tboudreau@18301
|
50 |
import java.util.Iterator;
|
tboudreau@18301
|
51 |
import java.util.LinkedList;
|
tboudreau@18301
|
52 |
import java.util.List;
|
tboudreau@18301
|
53 |
import java.util.Set;
|
tboudreau@18301
|
54 |
|
tboudreau@18301
|
55 |
/**
|
tboudreau@18301
|
56 |
* Parses and validates command-line arguments.
|
tboudreau@18301
|
57 |
*
|
tboudreau@18301
|
58 |
* @author Tim Boudreau
|
tboudreau@18301
|
59 |
*/
|
tboudreau@18301
|
60 |
final class Arguments implements CallgraphControl {
|
tboudreau@18301
|
61 |
|
tboudreau@18301
|
62 |
private Set<File> folders = new HashSet<>();
|
tboudreau@18301
|
63 |
private static final Command[] commands = new Command[]{
|
tboudreau@18301
|
64 |
new NoSelfReferencesCommand(),
|
tboudreau@18301
|
65 |
new ShortNamesCommand(),
|
tboudreau@18374
|
66 |
new ExtendedPropertiesCommand(),
|
tboudreau@18374
|
67 |
new AntCommand(),
|
tboudreau@18301
|
68 |
new MavenCommand(),
|
tboudreau@18372
|
69 |
new GradleCommand(),
|
tboudreau@18372
|
70 |
new IgnoreCommand(),
|
tboudreau@18301
|
71 |
new OutfileCommand(),
|
tboudreau@18301
|
72 |
new ExcludeCommand(),
|
tboudreau@18301
|
73 |
new PackageGraphFileCommand(),
|
tboudreau@18301
|
74 |
new ClassGraphFileCommand(),
|
tboudreau@18301
|
75 |
new OmitAbstractCommand(),
|
tboudreau@18301
|
76 |
new DisableEightBitStringsCommand(),
|
tboudreau@18301
|
77 |
new OmitAbstractCommand(),
|
tboudreau@18301
|
78 |
new QuietCommand(),
|
tboudreau@18301
|
79 |
new ReverseCommand(),
|
tboudreau@18374
|
80 |
new AggressiveCommand(),
|
tboudreau@18301
|
81 |
new VerboseCommand()
|
tboudreau@18301
|
82 |
};
|
tboudreau@18301
|
83 |
private boolean noSelfReferences = false;
|
tboudreau@18301
|
84 |
private boolean shortNames = false;
|
tboudreau@18301
|
85 |
private boolean maven = false;
|
tboudreau@18372
|
86 |
private boolean gradle = false;
|
tboudreau@18374
|
87 |
private boolean ant = false;
|
tboudreau@18374
|
88 |
private boolean xprop = false;
|
tboudreau@18374
|
89 |
private boolean aggressive = false;
|
tboudreau@18301
|
90 |
private File outfile;
|
tboudreau@18301
|
91 |
private Set<String> exclude = new HashSet<>();
|
tboudreau@18372
|
92 |
private Set<String> ignore = new HashSet<>();
|
tboudreau@18301
|
93 |
private boolean quiet;
|
tboudreau@18301
|
94 |
private File classGraphFile;
|
tboudreau@18301
|
95 |
private File packageGraphFile;
|
tboudreau@18301
|
96 |
private boolean verbose;
|
tboudreau@18301
|
97 |
private boolean omitAbstract;
|
tboudreau@18301
|
98 |
private boolean disableEightBitStrings;
|
tboudreau@18301
|
99 |
private boolean reverse;
|
tboudreau@18301
|
100 |
|
tboudreau@18372
|
101 |
Arguments(String... args) throws IOException {
|
tboudreau@18301
|
102 |
this(true, args);
|
tboudreau@18301
|
103 |
}
|
tboudreau@18301
|
104 |
|
tboudreau@18372
|
105 |
Arguments(boolean abortIfWillNotOutput, String... args) throws IOException {
|
tboudreau@18301
|
106 |
List<String> unknownArguments = new LinkedList<>();
|
tboudreau@18301
|
107 |
List<String> errors = new LinkedList<>();
|
tboudreau@18301
|
108 |
for (int i = 0; i < args.length;) {
|
tboudreau@18301
|
109 |
int oldPos = i;
|
tboudreau@18301
|
110 |
for (Command c : commands) {
|
tboudreau@18301
|
111 |
try {
|
tboudreau@18301
|
112 |
@SuppressWarnings("LeakingThisInConstructor")
|
tboudreau@18301
|
113 |
int increment = c.parse(i, args, this);
|
tboudreau@18301
|
114 |
if (increment > 0) {
|
tboudreau@18301
|
115 |
i += increment;
|
tboudreau@18301
|
116 |
break;
|
tboudreau@18301
|
117 |
}
|
tboudreau@18301
|
118 |
} catch (IllegalArgumentException ex) {
|
tboudreau@18301
|
119 |
errors.add(c.name + ": " + ex.getMessage());
|
tboudreau@18301
|
120 |
}
|
tboudreau@18301
|
121 |
}
|
tboudreau@18301
|
122 |
if (oldPos == i) {
|
tboudreau@18301
|
123 |
unknownArguments.add(args[i]);
|
tboudreau@18301
|
124 |
i++;
|
tboudreau@18301
|
125 |
}
|
tboudreau@18301
|
126 |
}
|
tboudreau@18301
|
127 |
Set<String> folders = new HashSet<>();
|
tboudreau@18301
|
128 |
for (String unknown : unknownArguments) {
|
tboudreau@18301
|
129 |
if (unknown.startsWith("-")) {
|
tboudreau@18301
|
130 |
// bad line switch
|
tboudreau@18301
|
131 |
errors.add("Unknown argument '" + unknown + "'");
|
tboudreau@18301
|
132 |
} else {
|
tboudreau@18301
|
133 |
folders.add(unknown);
|
tboudreau@18301
|
134 |
}
|
tboudreau@18301
|
135 |
}
|
tboudreau@18301
|
136 |
if (folders.isEmpty()) {
|
tboudreau@18301
|
137 |
errors.add("No folders of Java sources specified");
|
tboudreau@18301
|
138 |
} else {
|
tboudreau@18301
|
139 |
for (String folderName : folders) {
|
tboudreau@18301
|
140 |
File folder = new File(folderName);
|
tboudreau@18301
|
141 |
if (!folder.exists()) {
|
tboudreau@18301
|
142 |
errors.add("Folder does not exist: " + folderName);
|
tboudreau@18301
|
143 |
} else if (!folder.isDirectory()) {
|
tboudreau@18301
|
144 |
errors.add("Not a folder: " + folderName);
|
tboudreau@18301
|
145 |
} else {
|
tboudreau@18372
|
146 |
this.folders.add(folder.getCanonicalFile());
|
tboudreau@18301
|
147 |
}
|
tboudreau@18301
|
148 |
}
|
tboudreau@18301
|
149 |
}
|
tboudreau@18374
|
150 |
if ((maven && gradle) || (ant && gradle) || (ant && maven)) {
|
tboudreau@18374
|
151 |
errors.add("--maven, --ant and --gradle are mutually exclusive");
|
tboudreau@18372
|
152 |
} else if (maven) {
|
tboudreau@18301
|
153 |
findMavenSubfolders(errors);
|
tboudreau@18372
|
154 |
} else if (gradle) {
|
tboudreau@18372
|
155 |
findGradleSubfolders(errors);
|
tboudreau@18374
|
156 |
} else if (ant) {
|
tboudreau@18374
|
157 |
findAntSubfolders(errors);
|
tboudreau@18301
|
158 |
}
|
tboudreau@18372
|
159 |
Set<File> toIgnore = new HashSet<>();
|
tboudreau@18372
|
160 |
for (String ig : ignore) {
|
tboudreau@18372
|
161 |
File ff = new File(ig);
|
tboudreau@18372
|
162 |
if (ff.exists() && ff.isDirectory()) {
|
tboudreau@18372
|
163 |
ff = ff.getCanonicalFile();
|
tboudreau@18372
|
164 |
for (File f : this.folders()) {
|
tboudreau@18372
|
165 |
File f1 = f.getCanonicalFile();
|
tboudreau@18372
|
166 |
if (f1.equals(ff)) {
|
tboudreau@18372
|
167 |
toIgnore.add(f1);
|
tboudreau@18372
|
168 |
} else {
|
tboudreau@18372
|
169 |
if (f1.getPath().startsWith(ff.getPath())) {
|
tboudreau@18372
|
170 |
toIgnore.add(f1);
|
tboudreau@18372
|
171 |
}
|
tboudreau@18372
|
172 |
}
|
tboudreau@18372
|
173 |
}
|
tboudreau@18372
|
174 |
} else {
|
tboudreau@18372
|
175 |
for (String u : unknownArguments) {
|
tboudreau@18372
|
176 |
if (!u.startsWith("-")) {
|
tboudreau@18372
|
177 |
File f = new File(u);
|
tboudreau@18372
|
178 |
if (f.exists()) {
|
tboudreau@18372
|
179 |
f = f.getCanonicalFile();
|
tboudreau@18372
|
180 |
File maybeIgnore = new File(f, ig);
|
tboudreau@18372
|
181 |
if (maybeIgnore.exists() && maybeIgnore.isDirectory()) {
|
tboudreau@18372
|
182 |
maybeIgnore = maybeIgnore.getCanonicalFile();
|
tboudreau@18372
|
183 |
for (File fld : this.folders()) {
|
tboudreau@18372
|
184 |
if (fld.equals(maybeIgnore)) {
|
tboudreau@18372
|
185 |
toIgnore.add(fld);
|
tboudreau@18372
|
186 |
} else if (fld.getAbsolutePath().startsWith(maybeIgnore.getAbsolutePath())) {
|
tboudreau@18372
|
187 |
toIgnore.add(fld);
|
tboudreau@18372
|
188 |
}
|
tboudreau@18372
|
189 |
}
|
tboudreau@18372
|
190 |
}
|
tboudreau@18372
|
191 |
}
|
tboudreau@18372
|
192 |
}
|
tboudreau@18372
|
193 |
}
|
tboudreau@18372
|
194 |
}
|
tboudreau@18372
|
195 |
}
|
tboudreau@18372
|
196 |
if (verbose && !toIgnore.isEmpty()) {
|
tboudreau@18372
|
197 |
System.err.println("Ignoring the following projects:");
|
tboudreau@18372
|
198 |
for (File ti : toIgnore) {
|
tboudreau@18372
|
199 |
System.err.println(" - " + ti.getAbsolutePath());
|
tboudreau@18372
|
200 |
}
|
tboudreau@18372
|
201 |
}
|
tboudreau@18372
|
202 |
this.folders.removeAll(toIgnore);
|
tboudreau@18374
|
203 |
if (verbose && !this.folders.isEmpty()) {
|
tboudreau@18374
|
204 |
System.err.println("Will scan the following source roots:");
|
tboudreau@18374
|
205 |
for (File f : folders()) {
|
tboudreau@18374
|
206 |
System.err.println(" " + f.getAbsolutePath());
|
tboudreau@18374
|
207 |
}
|
tboudreau@18374
|
208 |
}
|
tboudreau@18372
|
209 |
|
tboudreau@18301
|
210 |
if (packageGraphFile != null) {
|
tboudreau@18301
|
211 |
File parent = packageGraphFile.getParentFile();
|
tboudreau@18301
|
212 |
if (!parent.exists() || !parent.isDirectory()) {
|
tboudreau@18301
|
213 |
errors.add("Parent folder for package graph output file does not exist: " + parent);
|
tboudreau@18301
|
214 |
}
|
tboudreau@18301
|
215 |
}
|
tboudreau@18301
|
216 |
if (classGraphFile != null) {
|
tboudreau@18301
|
217 |
File parent = classGraphFile.getParentFile();
|
tboudreau@18301
|
218 |
if (!parent.exists() || !parent.isDirectory()) {
|
tboudreau@18301
|
219 |
errors.add("Parent folder for class graph output file does not exist: " + parent);
|
tboudreau@18301
|
220 |
}
|
tboudreau@18301
|
221 |
}
|
tboudreau@18301
|
222 |
if (outfile != null) {
|
tboudreau@18301
|
223 |
File parent = outfile.getParentFile();
|
tboudreau@18301
|
224 |
if (!parent.exists() || !parent.isDirectory()) {
|
tboudreau@18301
|
225 |
errors.add("Parent folder for output file does not exist: " + parent);
|
tboudreau@18301
|
226 |
}
|
tboudreau@18301
|
227 |
} else if (abortIfWillNotOutput && quiet && packageGraphFile == null && classGraphFile == null) {
|
tboudreau@18301
|
228 |
errors.add("-q or --quiet specified, but no output file specified - would not produce any output at all");
|
tboudreau@18301
|
229 |
}
|
tboudreau@18301
|
230 |
// XXX check if any folders are children of each other?
|
tboudreau@18301
|
231 |
if (!errors.isEmpty()) {
|
tboudreau@18301
|
232 |
throw new InvalidArgumentsException(help(errors), errors);
|
tboudreau@18301
|
233 |
}
|
tboudreau@18301
|
234 |
}
|
tboudreau@18301
|
235 |
|
tboudreau@18301
|
236 |
private void findMavenSubfolders(List<String> errors) {
|
tboudreau@18301
|
237 |
Set<File> flds = new HashSet<>(this.folders);
|
tboudreau@18301
|
238 |
this.folders.clear();
|
tboudreau@18301
|
239 |
for (File f : flds) {
|
tboudreau@18301
|
240 |
recurseSubfoldersLookingForMavenProjects(f);
|
tboudreau@18301
|
241 |
}
|
tboudreau@18301
|
242 |
if (this.folders.isEmpty()) {
|
tboudreau@18301
|
243 |
errors.add("Did not find any maven projects (looked for pom.xml and src/main/java in all subfolders of folder list)");
|
tboudreau@18301
|
244 |
}
|
tboudreau@18301
|
245 |
}
|
tboudreau@18301
|
246 |
|
tboudreau@18301
|
247 |
private void recurseSubfoldersLookingForMavenProjects(File file) {
|
tboudreau@18301
|
248 |
if (file.isDirectory()) {
|
tboudreau@18301
|
249 |
if (hasPom(file)) {
|
tboudreau@18301
|
250 |
File sources = srcMainJavaFolder(file);
|
tboudreau@18301
|
251 |
if (sources != null) {
|
tboudreau@18301
|
252 |
this.folders.add(sources);
|
tboudreau@18301
|
253 |
}
|
tboudreau@18301
|
254 |
}
|
tboudreau@18301
|
255 |
for (File child : file.listFiles()) {
|
tboudreau@18301
|
256 |
recurseSubfoldersLookingForMavenProjects(child);
|
tboudreau@18301
|
257 |
}
|
tboudreau@18301
|
258 |
}
|
tboudreau@18301
|
259 |
}
|
tboudreau@18301
|
260 |
|
tboudreau@18301
|
261 |
private boolean hasPom(File fld) {
|
tboudreau@18301
|
262 |
File pom = new File(fld, "pom.xml");
|
tboudreau@18301
|
263 |
return pom.exists() && pom.isFile() && pom.canRead();
|
tboudreau@18301
|
264 |
}
|
tboudreau@18301
|
265 |
|
tboudreau@18374
|
266 |
void findAntSubfolders(List<String> errors) {
|
tboudreau@18374
|
267 |
Set<File> flds = new HashSet<>(this.folders);
|
tboudreau@18374
|
268 |
this.folders.clear();
|
tboudreau@18374
|
269 |
for (File f : flds) {
|
tboudreau@18374
|
270 |
recurseSubfoldersLookingForAntProjects(f);
|
tboudreau@18374
|
271 |
}
|
tboudreau@18374
|
272 |
if (this.folders.isEmpty()) {
|
tboudreau@18374
|
273 |
errors.add("Did not find any ant projects (looked for build.xml and src/ in all subfolders of folder list)");
|
tboudreau@18374
|
274 |
}
|
tboudreau@18374
|
275 |
}
|
tboudreau@18374
|
276 |
|
tboudreau@18374
|
277 |
private void recurseSubfoldersLookingForAntProjects(File file) {
|
tboudreau@18374
|
278 |
if (file.isDirectory()) {
|
tboudreau@18374
|
279 |
if (hasBuildXml(file)) {
|
tboudreau@18374
|
280 |
File sources = new File(file, "src");
|
tboudreau@18374
|
281 |
if (sources.exists() && sources.isDirectory()) {
|
tboudreau@18374
|
282 |
this.folders.add(sources);
|
tboudreau@18374
|
283 |
}
|
tboudreau@18374
|
284 |
}
|
tboudreau@18374
|
285 |
for (File child : file.listFiles()) {
|
tboudreau@18374
|
286 |
recurseSubfoldersLookingForAntProjects(child);
|
tboudreau@18374
|
287 |
}
|
tboudreau@18374
|
288 |
}
|
tboudreau@18374
|
289 |
}
|
tboudreau@18374
|
290 |
|
tboudreau@18374
|
291 |
private boolean hasBuildXml(File fld) {
|
tboudreau@18374
|
292 |
File pom = new File(fld, "build.xml");
|
tboudreau@18374
|
293 |
return pom.exists() && pom.isFile() && pom.canRead();
|
tboudreau@18374
|
294 |
}
|
tboudreau@18374
|
295 |
|
tboudreau@18372
|
296 |
void findGradleSubfolders(List<String> errors) {
|
tboudreau@18372
|
297 |
Set<File> flds = new HashSet<>(this.folders);
|
tboudreau@18372
|
298 |
this.folders.clear();
|
tboudreau@18372
|
299 |
for (File f : flds) {
|
tboudreau@18372
|
300 |
recurseSubfoldersLookingForGradleProjects(f);
|
tboudreau@18372
|
301 |
}
|
tboudreau@18372
|
302 |
if (this.folders.isEmpty()) {
|
tboudreau@18372
|
303 |
errors.add("Did not find any gradle projects (looked for *.gradle and src/main/java in all subfolders of folder list)");
|
tboudreau@18372
|
304 |
}
|
tboudreau@18372
|
305 |
}
|
tboudreau@18372
|
306 |
|
tboudreau@18372
|
307 |
private void recurseSubfoldersLookingForGradleProjects(File file) {
|
tboudreau@18372
|
308 |
if (file.isDirectory()) {
|
tboudreau@18372
|
309 |
if (hasGradleFile(file)) {
|
tboudreau@18372
|
310 |
File sources = srcMainJavaFolder(file);
|
tboudreau@18372
|
311 |
if (sources != null) {
|
tboudreau@18372
|
312 |
this.folders.add(sources);
|
tboudreau@18372
|
313 |
}
|
tboudreau@18372
|
314 |
}
|
tboudreau@18372
|
315 |
for (File child : file.listFiles()) {
|
tboudreau@18372
|
316 |
recurseSubfoldersLookingForGradleProjects(child);
|
tboudreau@18372
|
317 |
}
|
tboudreau@18372
|
318 |
}
|
tboudreau@18372
|
319 |
}
|
tboudreau@18372
|
320 |
|
tboudreau@18372
|
321 |
boolean hasGradleFile(File fld) {
|
tboudreau@18372
|
322 |
return fld.listFiles((File pathname) -> {
|
tboudreau@18372
|
323 |
return pathname.getName().endsWith(".gradle") && pathname.isFile() && pathname.canRead();
|
tboudreau@18372
|
324 |
}).length > 0;
|
tboudreau@18372
|
325 |
}
|
tboudreau@18372
|
326 |
|
tboudreau@18372
|
327 |
public boolean isGradle() {
|
tboudreau@18372
|
328 |
return gradle;
|
tboudreau@18372
|
329 |
}
|
tboudreau@18372
|
330 |
|
tboudreau@18301
|
331 |
private File srcMainJavaFolder(File projectFolder) {
|
tboudreau@18301
|
332 |
File src = new File(projectFolder, "src");
|
tboudreau@18301
|
333 |
File main = new File(src, "main");
|
tboudreau@18301
|
334 |
File java = new File(main, "java");
|
tboudreau@18301
|
335 |
if (java.exists() && java.isDirectory()) {
|
tboudreau@18301
|
336 |
return java;
|
tboudreau@18301
|
337 |
}
|
tboudreau@18301
|
338 |
return null;
|
tboudreau@18301
|
339 |
}
|
tboudreau@18301
|
340 |
|
tboudreau@18301
|
341 |
public boolean isVerbose() {
|
tboudreau@18301
|
342 |
return verbose;
|
tboudreau@18301
|
343 |
}
|
tboudreau@18301
|
344 |
|
tboudreau@18301
|
345 |
public boolean isDisableEightBitStrings() {
|
tboudreau@18301
|
346 |
return disableEightBitStrings;
|
tboudreau@18301
|
347 |
}
|
tboudreau@18301
|
348 |
|
tboudreau@18301
|
349 |
public boolean isReverse() {
|
tboudreau@18301
|
350 |
return reverse;
|
tboudreau@18301
|
351 |
}
|
tboudreau@18301
|
352 |
|
tboudreau@18301
|
353 |
@Override
|
tboudreau@18301
|
354 |
public File methodGraphFile() {
|
tboudreau@18301
|
355 |
return outfile;
|
tboudreau@18301
|
356 |
}
|
tboudreau@18301
|
357 |
|
tboudreau@18301
|
358 |
@Override
|
tboudreau@18301
|
359 |
public Set<File> folders() {
|
tboudreau@18301
|
360 |
return Collections.unmodifiableSet(folders);
|
tboudreau@18301
|
361 |
}
|
tboudreau@18301
|
362 |
|
tboudreau@18301
|
363 |
@Override
|
tboudreau@18301
|
364 |
public boolean isSelfReferences() {
|
tboudreau@18301
|
365 |
return noSelfReferences == false;
|
tboudreau@18301
|
366 |
}
|
tboudreau@18301
|
367 |
|
tboudreau@18301
|
368 |
@Override
|
tboudreau@18301
|
369 |
public boolean isShortNames() {
|
tboudreau@18301
|
370 |
return shortNames;
|
tboudreau@18301
|
371 |
}
|
tboudreau@18301
|
372 |
|
tboudreau@18301
|
373 |
@Override
|
tboudreau@18301
|
374 |
public boolean isMaven() {
|
tboudreau@18301
|
375 |
return maven;
|
tboudreau@18301
|
376 |
}
|
tboudreau@18301
|
377 |
|
tboudreau@18301
|
378 |
@Override
|
tboudreau@18374
|
379 |
public boolean isAnt() {
|
tboudreau@18374
|
380 |
return ant;
|
tboudreau@18374
|
381 |
}
|
tboudreau@18374
|
382 |
|
tboudreau@18374
|
383 |
@Override
|
tboudreau@18374
|
384 |
public boolean isExtendedProperties() {
|
tboudreau@18374
|
385 |
return xprop;
|
tboudreau@18374
|
386 |
}
|
tboudreau@18374
|
387 |
|
tboudreau@18374
|
388 |
public boolean isAggressive() {
|
tboudreau@18374
|
389 |
return aggressive;
|
tboudreau@18374
|
390 |
}
|
tboudreau@18374
|
391 |
|
tboudreau@18374
|
392 |
@Override
|
tboudreau@18301
|
393 |
public File classGraphFile() {
|
tboudreau@18301
|
394 |
return classGraphFile;
|
tboudreau@18301
|
395 |
}
|
tboudreau@18301
|
396 |
|
tboudreau@18301
|
397 |
@Override
|
tboudreau@18301
|
398 |
public File packageGraphFile() {
|
tboudreau@18301
|
399 |
return packageGraphFile;
|
tboudreau@18301
|
400 |
}
|
tboudreau@18301
|
401 |
|
tboudreau@18301
|
402 |
@Override
|
tboudreau@18301
|
403 |
public Iterator<File> iterator() {
|
tboudreau@18301
|
404 |
return folders().iterator();
|
tboudreau@18301
|
405 |
}
|
tboudreau@18301
|
406 |
|
tboudreau@18301
|
407 |
@Override
|
tboudreau@18301
|
408 |
public Set<String> excludePrefixes() {
|
tboudreau@18301
|
409 |
return Collections.unmodifiableSet(exclude);
|
tboudreau@18301
|
410 |
}
|
tboudreau@18301
|
411 |
|
tboudreau@18301
|
412 |
public boolean isOmitAbstract() {
|
tboudreau@18301
|
413 |
return omitAbstract;
|
tboudreau@18301
|
414 |
}
|
tboudreau@18301
|
415 |
|
tboudreau@18301
|
416 |
public boolean isExcluded(String qname) {
|
tboudreau@18301
|
417 |
for (String ex : exclude) {
|
tboudreau@18301
|
418 |
if (qname.startsWith(ex)) {
|
tboudreau@18301
|
419 |
return true;
|
tboudreau@18301
|
420 |
}
|
tboudreau@18301
|
421 |
}
|
tboudreau@18301
|
422 |
return false;
|
tboudreau@18301
|
423 |
}
|
tboudreau@18301
|
424 |
|
tboudreau@18301
|
425 |
@Override
|
tboudreau@18301
|
426 |
public boolean isQuiet() {
|
tboudreau@18301
|
427 |
return quiet;
|
tboudreau@18301
|
428 |
}
|
tboudreau@18301
|
429 |
|
tboudreau@18301
|
430 |
private String help(List<String> errors) {
|
tboudreau@18301
|
431 |
StringBuilder sb = new StringBuilder("Callgraph prints a graph of things that call each other in a tree of Java sources,\n"
|
tboudreau@18301
|
432 |
+ "and can output graphs of what methods / classes / packages (or all of the above) call each other\nwithin that"
|
tboudreau@18301
|
433 |
+ "source tree."
|
tboudreau@18301
|
434 |
+ "\n\nUsage:\njava -jar callgraph.jar ");
|
tboudreau@18301
|
435 |
for (Command c : commands) {
|
tboudreau@18301
|
436 |
if (c.optional) {
|
tboudreau@18301
|
437 |
sb.append('[');
|
tboudreau@18301
|
438 |
}
|
tboudreau@18301
|
439 |
sb.append("--").append(c.name).append(" | -").append(c.shortcut);
|
tboudreau@18301
|
440 |
if (c.takesArgument) {
|
tboudreau@18301
|
441 |
sb.append(" ").append(c.name);
|
tboudreau@18301
|
442 |
}
|
tboudreau@18301
|
443 |
if (c.optional) {
|
tboudreau@18301
|
444 |
sb.append(']');
|
tboudreau@18301
|
445 |
}
|
tboudreau@18301
|
446 |
sb.append(' ');
|
tboudreau@18301
|
447 |
}
|
tboudreau@18301
|
448 |
sb.append("dir1 [dir2 dir3 ...]");
|
tboudreau@18301
|
449 |
sb.append('\n');
|
tboudreau@18301
|
450 |
for (Command c : commands) {
|
tboudreau@18301
|
451 |
sb.append("\n\t");
|
tboudreau@18301
|
452 |
sb.append("--").append(c.name).append(" / -").append(c.shortcut).append(" :\t").append(c.help());
|
tboudreau@18301
|
453 |
}
|
tboudreau@18301
|
454 |
if (!errors.isEmpty()) {
|
tboudreau@18301
|
455 |
sb.append("\nErrors:\n");
|
tboudreau@18301
|
456 |
for (String err : errors) {
|
tboudreau@18301
|
457 |
sb.append('\t').append(err).append('\n');
|
tboudreau@18301
|
458 |
}
|
tboudreau@18301
|
459 |
}
|
tboudreau@18301
|
460 |
return sb.toString();
|
tboudreau@18301
|
461 |
}
|
tboudreau@18301
|
462 |
|
tboudreau@18301
|
463 |
private static abstract class Command {
|
tboudreau@18301
|
464 |
|
tboudreau@18301
|
465 |
protected final String name;
|
tboudreau@18301
|
466 |
protected final String shortcut;
|
tboudreau@18301
|
467 |
protected final boolean optional;
|
tboudreau@18301
|
468 |
private final boolean takesArgument;
|
tboudreau@18301
|
469 |
|
tboudreau@18301
|
470 |
Command(String name, String shortcut, boolean optional, boolean takesArgument) {
|
tboudreau@18301
|
471 |
this.name = name;
|
tboudreau@18301
|
472 |
this.shortcut = shortcut;
|
tboudreau@18301
|
473 |
this.optional = optional;
|
tboudreau@18301
|
474 |
this.takesArgument = takesArgument;
|
tboudreau@18301
|
475 |
}
|
tboudreau@18301
|
476 |
|
tboudreau@18301
|
477 |
public int parse(int position, String[] args, Arguments toSet) {
|
tboudreau@18301
|
478 |
boolean match = ("-" + shortcut).equals(args[position])
|
tboudreau@18301
|
479 |
|| ("--" + name).equals(args[position]);
|
tboudreau@18301
|
480 |
if (!match) {
|
tboudreau@18301
|
481 |
return 0;
|
tboudreau@18301
|
482 |
}
|
tboudreau@18301
|
483 |
return doParse(position, args, toSet);
|
tboudreau@18301
|
484 |
}
|
tboudreau@18301
|
485 |
|
tboudreau@18301
|
486 |
protected abstract int doParse(int i, String[] args, Arguments toSet);
|
tboudreau@18301
|
487 |
|
tboudreau@18301
|
488 |
protected abstract String help();
|
tboudreau@18301
|
489 |
|
tboudreau@18301
|
490 |
public String toString() {
|
tboudreau@18301
|
491 |
return name;
|
tboudreau@18301
|
492 |
}
|
tboudreau@18301
|
493 |
}
|
tboudreau@18301
|
494 |
|
tboudreau@18301
|
495 |
private static final class NoSelfReferencesCommand extends Command {
|
tboudreau@18301
|
496 |
|
tboudreau@18301
|
497 |
NoSelfReferencesCommand() {
|
tboudreau@18301
|
498 |
super(CMD_NOSELF, "n", true, false);
|
tboudreau@18301
|
499 |
}
|
tboudreau@18301
|
500 |
|
tboudreau@18301
|
501 |
@Override
|
tboudreau@18301
|
502 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
503 |
toSet.noSelfReferences = true;
|
tboudreau@18301
|
504 |
return 1;
|
tboudreau@18301
|
505 |
}
|
tboudreau@18301
|
506 |
|
tboudreau@18301
|
507 |
@Override
|
tboudreau@18301
|
508 |
protected String help() {
|
tboudreau@18301
|
509 |
return "Hide intra-class calls (i.e. if Foo.bar() calls Foo.baz(), don't include it)";
|
tboudreau@18301
|
510 |
}
|
tboudreau@18301
|
511 |
}
|
tboudreau@18301
|
512 |
|
tboudreau@18301
|
513 |
private static final class DisableEightBitStringsCommand extends Command {
|
tboudreau@18301
|
514 |
|
tboudreau@18301
|
515 |
DisableEightBitStringsCommand() {
|
tboudreau@18301
|
516 |
super(CMD_DISABLE_EIGHT_BIT_STRINGS, "u", true, false);
|
tboudreau@18301
|
517 |
}
|
tboudreau@18301
|
518 |
|
tboudreau@18301
|
519 |
@Override
|
tboudreau@18301
|
520 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
521 |
toSet.noSelfReferences = true;
|
tboudreau@18301
|
522 |
return 1;
|
tboudreau@18301
|
523 |
}
|
tboudreau@18301
|
524 |
|
tboudreau@18301
|
525 |
@Override
|
tboudreau@18301
|
526 |
protected String help() {
|
tboudreau@18374
|
527 |
return "Disable string memory optimizations - runs faster and supports unicode class names, but may run out of memory";
|
tboudreau@18301
|
528 |
}
|
tboudreau@18301
|
529 |
}
|
tboudreau@18301
|
530 |
|
tboudreau@18301
|
531 |
private static final class ReverseCommand extends Command {
|
tboudreau@18301
|
532 |
|
tboudreau@18301
|
533 |
ReverseCommand() {
|
tboudreau@18301
|
534 |
super(CMD_REVERSE, "r", true, false);
|
tboudreau@18301
|
535 |
}
|
tboudreau@18301
|
536 |
|
tboudreau@18301
|
537 |
@Override
|
tboudreau@18301
|
538 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
539 |
toSet.reverse = true;
|
tboudreau@18301
|
540 |
return 1;
|
tboudreau@18301
|
541 |
}
|
tboudreau@18301
|
542 |
|
tboudreau@18301
|
543 |
@Override
|
tboudreau@18301
|
544 |
protected String help() {
|
tboudreau@18301
|
545 |
return "Reverse the edges of graph nodes";
|
tboudreau@18301
|
546 |
}
|
tboudreau@18301
|
547 |
}
|
tboudreau@18301
|
548 |
|
tboudreau@18374
|
549 |
private static final class AggressiveCommand extends Command {
|
tboudreau@18374
|
550 |
|
tboudreau@18374
|
551 |
AggressiveCommand() {
|
tboudreau@18374
|
552 |
super(CMD_AGGRESSIVE_MEMORY, "z", true, false);
|
tboudreau@18374
|
553 |
}
|
tboudreau@18374
|
554 |
|
tboudreau@18374
|
555 |
@Override
|
tboudreau@18374
|
556 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18374
|
557 |
toSet.aggressive = true;
|
tboudreau@18374
|
558 |
return 1;
|
tboudreau@18374
|
559 |
}
|
tboudreau@18374
|
560 |
|
tboudreau@18374
|
561 |
@Override
|
tboudreau@18374
|
562 |
protected String help() {
|
tboudreau@18374
|
563 |
return "Aggressively optimize the 8-bit string intern table "
|
tboudreau@18374
|
564 |
+ "for large graphs, sacrificing performace for space";
|
tboudreau@18374
|
565 |
}
|
tboudreau@18374
|
566 |
}
|
tboudreau@18374
|
567 |
|
tboudreau@18301
|
568 |
private static final class ShortNamesCommand extends Command {
|
tboudreau@18301
|
569 |
|
tboudreau@18301
|
570 |
ShortNamesCommand() {
|
tboudreau@18301
|
571 |
super(CMD_SIMPLE, "s", true, false);
|
tboudreau@18301
|
572 |
}
|
tboudreau@18301
|
573 |
|
tboudreau@18301
|
574 |
@Override
|
tboudreau@18301
|
575 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
576 |
toSet.shortNames = true;
|
tboudreau@18301
|
577 |
return 1;
|
tboudreau@18301
|
578 |
}
|
tboudreau@18301
|
579 |
|
tboudreau@18301
|
580 |
@Override
|
tboudreau@18301
|
581 |
protected String help() {
|
tboudreau@18301
|
582 |
return "Use simple class names without the package (may confuse results if two classes have the same name)";
|
tboudreau@18301
|
583 |
}
|
tboudreau@18301
|
584 |
}
|
tboudreau@18301
|
585 |
|
tboudreau@18374
|
586 |
private static final class ExtendedPropertiesCommand extends Command {
|
tboudreau@18374
|
587 |
|
tboudreau@18374
|
588 |
ExtendedPropertiesCommand() {
|
tboudreau@18374
|
589 |
super(CMD_EXTENDED_PROPERTIES, "x", true, false);
|
tboudreau@18374
|
590 |
}
|
tboudreau@18374
|
591 |
|
tboudreau@18374
|
592 |
@Override
|
tboudreau@18374
|
593 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18374
|
594 |
toSet.xprop = true;
|
tboudreau@18374
|
595 |
return 1;
|
tboudreau@18374
|
596 |
}
|
tboudreau@18374
|
597 |
|
tboudreau@18374
|
598 |
@Override
|
tboudreau@18374
|
599 |
protected String help() {
|
tboudreau@18374
|
600 |
return "Find all maven projects that are children of the passed folders, and scan their src/main/java subfolders";
|
tboudreau@18374
|
601 |
}
|
tboudreau@18374
|
602 |
}
|
tboudreau@18374
|
603 |
|
tboudreau@18374
|
604 |
private static final class AntCommand extends Command {
|
tboudreau@18374
|
605 |
|
tboudreau@18374
|
606 |
AntCommand() {
|
tboudreau@18374
|
607 |
super(CMD_ANT, "a", true, false);
|
tboudreau@18374
|
608 |
}
|
tboudreau@18374
|
609 |
|
tboudreau@18374
|
610 |
@Override
|
tboudreau@18374
|
611 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18374
|
612 |
toSet.ant = true;
|
tboudreau@18374
|
613 |
return 1;
|
tboudreau@18374
|
614 |
}
|
tboudreau@18374
|
615 |
|
tboudreau@18374
|
616 |
@Override
|
tboudreau@18374
|
617 |
protected String help() {
|
tboudreau@18374
|
618 |
return "Find all ant projects that are children of the passed folders, and scan their src/ subfolders";
|
tboudreau@18374
|
619 |
}
|
tboudreau@18374
|
620 |
}
|
tboudreau@18374
|
621 |
|
tboudreau@18301
|
622 |
private static final class MavenCommand extends Command {
|
tboudreau@18301
|
623 |
|
tboudreau@18301
|
624 |
MavenCommand() {
|
tboudreau@18301
|
625 |
super(CMD_MAVEN, "m", true, false);
|
tboudreau@18301
|
626 |
}
|
tboudreau@18301
|
627 |
|
tboudreau@18301
|
628 |
@Override
|
tboudreau@18301
|
629 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
630 |
toSet.maven = true;
|
tboudreau@18301
|
631 |
return 1;
|
tboudreau@18301
|
632 |
}
|
tboudreau@18301
|
633 |
|
tboudreau@18301
|
634 |
@Override
|
tboudreau@18301
|
635 |
protected String help() {
|
tboudreau@18301
|
636 |
return "Find all maven projects that are children of the passed folders, and scan their src/main/java subfolders";
|
tboudreau@18301
|
637 |
}
|
tboudreau@18301
|
638 |
}
|
tboudreau@18301
|
639 |
|
tboudreau@18372
|
640 |
private static final class GradleCommand extends Command {
|
tboudreau@18372
|
641 |
|
tboudreau@18372
|
642 |
GradleCommand() {
|
tboudreau@18372
|
643 |
super(CMD_GRADLE, "g", true, false);
|
tboudreau@18372
|
644 |
}
|
tboudreau@18372
|
645 |
|
tboudreau@18372
|
646 |
@Override
|
tboudreau@18372
|
647 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18372
|
648 |
toSet.gradle = true;
|
tboudreau@18372
|
649 |
return 1;
|
tboudreau@18372
|
650 |
}
|
tboudreau@18372
|
651 |
|
tboudreau@18372
|
652 |
@Override
|
tboudreau@18372
|
653 |
protected String help() {
|
tboudreau@18372
|
654 |
return "Find all gradle projects that are children of the passed folders, and scan their src/main/java subfolders";
|
tboudreau@18372
|
655 |
}
|
tboudreau@18372
|
656 |
}
|
tboudreau@18372
|
657 |
|
tboudreau@18301
|
658 |
private static final class OmitAbstractCommand extends Command {
|
tboudreau@18301
|
659 |
|
tboudreau@18301
|
660 |
OmitAbstractCommand() {
|
tboudreau@18301
|
661 |
super(CMD_OMIT_ABSTRACT, "a", true, false);
|
tboudreau@18301
|
662 |
}
|
tboudreau@18301
|
663 |
|
tboudreau@18301
|
664 |
@Override
|
tboudreau@18301
|
665 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
666 |
toSet.omitAbstract = true;
|
tboudreau@18301
|
667 |
return 1;
|
tboudreau@18301
|
668 |
}
|
tboudreau@18301
|
669 |
|
tboudreau@18301
|
670 |
@Override
|
tboudreau@18301
|
671 |
protected String help() {
|
tboudreau@18301
|
672 |
return "Don't emit calls to abstract methods";
|
tboudreau@18301
|
673 |
}
|
tboudreau@18301
|
674 |
}
|
tboudreau@18301
|
675 |
|
tboudreau@18301
|
676 |
private static final class VerboseCommand extends Command {
|
tboudreau@18301
|
677 |
|
tboudreau@18301
|
678 |
VerboseCommand() {
|
tboudreau@18301
|
679 |
super(CMD_VERBOSE, "v", true, false);
|
tboudreau@18301
|
680 |
}
|
tboudreau@18301
|
681 |
|
tboudreau@18301
|
682 |
@Override
|
tboudreau@18301
|
683 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
684 |
toSet.verbose = true;
|
tboudreau@18301
|
685 |
return 1;
|
tboudreau@18301
|
686 |
}
|
tboudreau@18301
|
687 |
|
tboudreau@18301
|
688 |
@Override
|
tboudreau@18301
|
689 |
protected String help() {
|
tboudreau@18301
|
690 |
return "Print output about what is being processed";
|
tboudreau@18301
|
691 |
}
|
tboudreau@18301
|
692 |
}
|
tboudreau@18301
|
693 |
|
tboudreau@18301
|
694 |
private static final class QuietCommand extends Command {
|
tboudreau@18301
|
695 |
|
tboudreau@18301
|
696 |
QuietCommand() {
|
tboudreau@18301
|
697 |
super(CMD_QUIET, "q", true, false);
|
tboudreau@18301
|
698 |
}
|
tboudreau@18301
|
699 |
|
tboudreau@18301
|
700 |
@Override
|
tboudreau@18301
|
701 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
702 |
toSet.quiet = true;
|
tboudreau@18301
|
703 |
return 1;
|
tboudreau@18301
|
704 |
}
|
tboudreau@18301
|
705 |
|
tboudreau@18301
|
706 |
@Override
|
tboudreau@18301
|
707 |
protected String help() {
|
tboudreau@18301
|
708 |
return "Supress writing the graph to the standard output";
|
tboudreau@18301
|
709 |
}
|
tboudreau@18301
|
710 |
}
|
tboudreau@18301
|
711 |
|
tboudreau@18301
|
712 |
private static final class OutfileCommand extends Command {
|
tboudreau@18301
|
713 |
|
tboudreau@18301
|
714 |
OutfileCommand() {
|
tboudreau@18372
|
715 |
super(CMD_METHODGRAPH, "o", true, true);
|
tboudreau@18301
|
716 |
}
|
tboudreau@18301
|
717 |
|
tboudreau@18301
|
718 |
@Override
|
tboudreau@18301
|
719 |
protected int doParse(int index, String[] args, Arguments toSet) {
|
tboudreau@18301
|
720 |
if (args.length == index + 1) {
|
tboudreau@18301
|
721 |
throw new IllegalArgumentException("--outfile or -o present but no output file specified");
|
tboudreau@18301
|
722 |
}
|
tboudreau@18301
|
723 |
toSet.outfile = new File(args[index + 1]);
|
tboudreau@18301
|
724 |
return 2;
|
tboudreau@18301
|
725 |
}
|
tboudreau@18301
|
726 |
|
tboudreau@18301
|
727 |
@Override
|
tboudreau@18301
|
728 |
protected String help() {
|
tboudreau@18301
|
729 |
return "Set the output file for the method call graph";
|
tboudreau@18301
|
730 |
}
|
tboudreau@18301
|
731 |
}
|
tboudreau@18301
|
732 |
|
tboudreau@18301
|
733 |
private static final class ClassGraphFileCommand extends Command {
|
tboudreau@18301
|
734 |
|
tboudreau@18301
|
735 |
ClassGraphFileCommand() {
|
tboudreau@18301
|
736 |
super(CMD_CLASSGRAPH, "c", true, true);
|
tboudreau@18301
|
737 |
}
|
tboudreau@18301
|
738 |
|
tboudreau@18301
|
739 |
@Override
|
tboudreau@18301
|
740 |
protected int doParse(int index, String[] args, Arguments toSet) {
|
tboudreau@18301
|
741 |
if (args.length == index + 1) {
|
tboudreau@18301
|
742 |
throw new IllegalArgumentException("--outfile or -o present but no output file specified");
|
tboudreau@18301
|
743 |
}
|
tboudreau@18301
|
744 |
toSet.classGraphFile = new File(args[index + 1]);
|
tboudreau@18301
|
745 |
return 2;
|
tboudreau@18301
|
746 |
}
|
tboudreau@18301
|
747 |
|
tboudreau@18301
|
748 |
@Override
|
tboudreau@18301
|
749 |
protected String help() {
|
tboudreau@18301
|
750 |
return "Set the output file for the class call graph";
|
tboudreau@18301
|
751 |
}
|
tboudreau@18301
|
752 |
}
|
tboudreau@18301
|
753 |
|
tboudreau@18301
|
754 |
private static final class PackageGraphFileCommand extends Command {
|
tboudreau@18301
|
755 |
|
tboudreau@18301
|
756 |
PackageGraphFileCommand() {
|
tboudreau@18301
|
757 |
super(CMD_PACKAGEGRAPH, "p", true, true);
|
tboudreau@18301
|
758 |
}
|
tboudreau@18301
|
759 |
|
tboudreau@18301
|
760 |
@Override
|
tboudreau@18301
|
761 |
protected int doParse(int index, String[] args, Arguments toSet) {
|
tboudreau@18301
|
762 |
if (args.length == index + 1) {
|
tboudreau@18301
|
763 |
throw new IllegalArgumentException("--outfile or -o present but no output file specified");
|
tboudreau@18301
|
764 |
}
|
tboudreau@18301
|
765 |
toSet.packageGraphFile = new File(args[index + 1]);
|
tboudreau@18301
|
766 |
return 2;
|
tboudreau@18301
|
767 |
}
|
tboudreau@18301
|
768 |
|
tboudreau@18301
|
769 |
@Override
|
tboudreau@18301
|
770 |
protected String help() {
|
tboudreau@18301
|
771 |
return "Set the output file for the package call graph";
|
tboudreau@18301
|
772 |
}
|
tboudreau@18301
|
773 |
}
|
tboudreau@18301
|
774 |
|
tboudreau@18301
|
775 |
private static final class ExcludeCommand extends Command {
|
tboudreau@18301
|
776 |
|
tboudreau@18301
|
777 |
ExcludeCommand() {
|
tboudreau@18301
|
778 |
super("exclude", "e", true, true);
|
tboudreau@18301
|
779 |
}
|
tboudreau@18301
|
780 |
|
tboudreau@18301
|
781 |
@Override
|
tboudreau@18301
|
782 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18301
|
783 |
if (args.length == i + 1) {
|
tboudreau@18301
|
784 |
throw new IllegalArgumentException("--exclude or -e present but no exclusion list present");
|
tboudreau@18301
|
785 |
}
|
tboudreau@18301
|
786 |
for (String s : args[i + 1].split(",")) {
|
tboudreau@18301
|
787 |
toSet.exclude.add(s);
|
tboudreau@18301
|
788 |
}
|
tboudreau@18301
|
789 |
return 2;
|
tboudreau@18301
|
790 |
}
|
tboudreau@18301
|
791 |
|
tboudreau@18301
|
792 |
@Override
|
tboudreau@18301
|
793 |
protected String help() {
|
tboudreau@18301
|
794 |
return "Exclude any relationships where the fully qualified class name starts with any pattern in this comma-delimited list of strings, e.g. -e foo.bar,foo.baz";
|
tboudreau@18301
|
795 |
}
|
tboudreau@18301
|
796 |
}
|
tboudreau@18301
|
797 |
|
tboudreau@18372
|
798 |
private static final class IgnoreCommand extends Command {
|
tboudreau@18372
|
799 |
|
tboudreau@18372
|
800 |
IgnoreCommand() {
|
tboudreau@18372
|
801 |
super(CMD_IGNORE, "i", true, true);
|
tboudreau@18372
|
802 |
}
|
tboudreau@18372
|
803 |
|
tboudreau@18372
|
804 |
@Override
|
tboudreau@18372
|
805 |
protected int doParse(int i, String[] args, Arguments toSet) {
|
tboudreau@18372
|
806 |
if (args.length == i + 1) {
|
tboudreau@18372
|
807 |
throw new IllegalArgumentException("--exclude or -e present but no exclusion list present");
|
tboudreau@18372
|
808 |
}
|
tboudreau@18372
|
809 |
for (String s : args[i + 1].split(",")) {
|
tboudreau@18372
|
810 |
toSet.ignore.add(s);
|
tboudreau@18372
|
811 |
}
|
tboudreau@18372
|
812 |
return 2;
|
tboudreau@18372
|
813 |
}
|
tboudreau@18372
|
814 |
|
tboudreau@18372
|
815 |
@Override
|
tboudreau@18372
|
816 |
protected String help() {
|
tboudreau@18372
|
817 |
return "Comma delimited list of folders or subfolders to ignore, absolute or relative to the base directory.";
|
tboudreau@18372
|
818 |
}
|
tboudreau@18372
|
819 |
}
|
tboudreau@18372
|
820 |
|
tboudreau@18301
|
821 |
static final class InvalidArgumentsException extends IllegalArgumentException {
|
tboudreau@18301
|
822 |
|
tboudreau@18301
|
823 |
private final List<String> errors;
|
tboudreau@18301
|
824 |
|
tboudreau@18301
|
825 |
InvalidArgumentsException(String msg, List<String> errors) {
|
tboudreau@18301
|
826 |
super(msg);
|
tboudreau@18301
|
827 |
this.errors = errors;
|
tboudreau@18301
|
828 |
}
|
tboudreau@18301
|
829 |
|
tboudreau@18301
|
830 |
public List<String> errors() {
|
tboudreau@18301
|
831 |
return errors;
|
tboudreau@18301
|
832 |
}
|
tboudreau@18301
|
833 |
|
tboudreau@18301
|
834 |
public boolean errorContains(String test) { //for tests
|
tboudreau@18301
|
835 |
for (String err : errors) {
|
tboudreau@18301
|
836 |
if (err.contains(test)) {
|
tboudreau@18301
|
837 |
return true;
|
tboudreau@18301
|
838 |
}
|
tboudreau@18301
|
839 |
}
|
tboudreau@18301
|
840 |
return false;
|
tboudreau@18301
|
841 |
}
|
tboudreau@18301
|
842 |
}
|
tboudreau@18301
|
843 |
}
|