26 package com.sun.tools.jdeps; |
26 package com.sun.tools.jdeps; |
27 |
27 |
28 import com.sun.tools.classfile.Dependency.Location; |
28 import com.sun.tools.classfile.Dependency.Location; |
29 import java.io.IOException; |
29 import java.io.IOException; |
30 import java.util.ArrayList; |
30 import java.util.ArrayList; |
|
31 import java.util.Collection; |
31 import java.util.Deque; |
32 import java.util.Deque; |
32 import java.util.LinkedHashSet; |
33 import java.util.LinkedHashSet; |
33 import java.util.LinkedList; |
34 import java.util.LinkedList; |
34 import java.util.List; |
35 import java.util.List; |
35 import java.util.Optional; |
36 import java.util.Optional; |
89 |
90 |
90 // if -include pattern is specified, add the matching archives on |
91 // if -include pattern is specified, add the matching archives on |
91 // classpath to the root archives |
92 // classpath to the root archives |
92 if (filter.hasIncludePattern() || filter.hasTargetFilter()) { |
93 if (filter.hasIncludePattern() || filter.hasTargetFilter()) { |
93 configuration.getModules().values().stream() |
94 configuration.getModules().values().stream() |
94 .filter(source -> filter.include(source) && filter.matches(source)) |
95 .filter(source -> include(source) && filter.matches(source)) |
95 .forEach(this.rootArchives::add); |
96 .forEach(this.rootArchives::add); |
96 } |
97 } |
97 |
98 |
98 // class path archives |
99 // class path archives |
99 configuration.classPathArchives().stream() |
100 configuration.classPathArchives().stream() |
159 * If --require is set, they should be excluded. |
160 * If --require is set, they should be excluded. |
160 */ |
161 */ |
161 Set<Archive> archives() { |
162 Set<Archive> archives() { |
162 if (filter.requiresFilter().isEmpty()) { |
163 if (filter.requiresFilter().isEmpty()) { |
163 return archives.stream() |
164 return archives.stream() |
164 .filter(filter::include) |
165 .filter(this::include) |
165 .filter(Archive::hasDependences) |
166 .filter(Archive::hasDependences) |
166 .collect(Collectors.toSet()); |
167 .collect(Collectors.toSet()); |
167 } else { |
168 } else { |
168 // use the archives that have dependences and not specified in --require |
169 // use the archives that have dependences and not specified in --require |
169 return archives.stream() |
170 return archives.stream() |
170 .filter(filter::include) |
171 .filter(this::include) |
171 .filter(source -> !filter.requiresFilter().contains(source)) |
172 .filter(source -> !filter.requiresFilter().contains(source.getName())) |
172 .filter(source -> |
173 .filter(source -> |
173 source.getDependencies() |
174 source.getDependencies() |
174 .map(finder::locationToArchive) |
175 .map(finder::locationToArchive) |
175 .anyMatch(a -> a != source)) |
176 .anyMatch(a -> a != source)) |
176 .collect(Collectors.toSet()); |
177 .collect(Collectors.toSet()); |
195 private Set<Archive> unresolvedArchives(Stream<Location> locations) { |
196 private Set<Archive> unresolvedArchives(Stream<Location> locations) { |
196 return locations.filter(l -> !finder.isParsed(l)) |
197 return locations.filter(l -> !finder.isParsed(l)) |
197 .distinct() |
198 .distinct() |
198 .map(configuration::findClass) |
199 .map(configuration::findClass) |
199 .flatMap(Optional::stream) |
200 .flatMap(Optional::stream) |
200 .filter(filter::include) |
|
201 .collect(toSet()); |
201 .collect(toSet()); |
202 } |
202 } |
203 |
203 |
204 /* |
204 /* |
205 * Recursively analyzes entire module/archives. |
205 * Recursively analyzes entire module/archives. |
236 while ((target = unresolved.poll()) != null) { |
236 while ((target = unresolved.poll()) != null) { |
237 if (finder.isParsed(target)) |
237 if (finder.isParsed(target)) |
238 continue; |
238 continue; |
239 |
239 |
240 Archive archive = configuration.findClass(target).orElse(null); |
240 Archive archive = configuration.findClass(target).orElse(null); |
241 if (archive != null && filter.include(archive)) { |
241 if (archive != null) { |
242 archives.add(archive); |
242 archives.add(archive); |
243 |
243 |
244 String name = target.getName(); |
244 String name = target.getName(); |
245 Set<Location> targets = apiOnly |
245 Set<Location> targets = apiOnly |
246 ? finder.parseExportedAPIs(archive, name) |
246 ? finder.parseExportedAPIs(archive, name) |
253 } |
253 } |
254 } |
254 } |
255 unresolved = deque; |
255 unresolved = deque; |
256 deque = new ConcurrentLinkedDeque<>(); |
256 deque = new ConcurrentLinkedDeque<>(); |
257 } while (!unresolved.isEmpty() && depth-- > 0); |
257 } while (!unresolved.isEmpty() && depth-- > 0); |
|
258 } |
|
259 |
|
260 /* |
|
261 * Tests if the given archive is requested for analysis. |
|
262 * It includes the root modules specified in --module, --add-modules |
|
263 * or modules specified on the command line |
|
264 * |
|
265 * This filters system module by default unless they are explicitly |
|
266 * requested. |
|
267 */ |
|
268 public boolean include(Archive source) { |
|
269 Module module = source.getModule(); |
|
270 // skip system module by default |
|
271 return !module.isSystem() |
|
272 || configuration.rootModules().contains(source); |
258 } |
273 } |
259 |
274 |
260 // ----- for testing purpose ----- |
275 // ----- for testing purpose ----- |
261 |
276 |
262 public static enum Info { |
277 public static enum Info { |