use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirrorVisitor in project CommandHelper by EngineHub.
the class ClassDiscovery method discover.
/**
* Does the class discovery for this particular URL. This should only be called by doDiscovery. Other internal
* methods should call doDiscovery, which handles looking through the dirtyURLs.
*/
private synchronized void discover(URL rootLocation) {
long start = System.currentTimeMillis();
if (debug) {
StreamUtils.GetSystemOut().println("Beginning discovery of " + rootLocation);
}
try {
// If the ClassDiscoveryCache is set, just use this.
if (classDiscoveryCache != null) {
ClassDiscoveryURLCache cduc = classDiscoveryCache.getURLCache(rootLocation);
preCaches.put(rootLocation, cduc);
}
String url;
try {
url = URLDecoder.decode(rootLocation.toString(), "UTF-8");
} catch (UnsupportedEncodingException ex) {
// apparently this should never happen, but we have to catch it anyway
url = null;
}
if (url == null) {
url = GetClassContainer(ClassDiscovery.class).toString();
}
final File rootLocationFile;
if (!classCache.containsKey(rootLocation)) {
classCache.put(rootLocation, Collections.synchronizedSet(new HashSet<>()));
} else {
classCache.get(rootLocation).clear();
}
final Set<ClassMirror<?>> mirrors = classCache.get(rootLocation);
if (preCaches.containsKey(rootLocation)) {
if (debug) {
StreamUtils.GetSystemOut().println("Precache already contains this URL, so using it");
}
// No need, already got a cache for this url
mirrors.addAll(preCaches.get(rootLocation).getClasses());
return;
}
if (debug) {
StreamUtils.GetSystemOut().println("Precache does not contain data for this URL, so scanning now.");
}
url = url.replaceFirst("^jar:", "");
if (url.endsWith("!/")) {
url = StringUtils.replaceLast(url, "!/", "");
}
if (url.startsWith("file:") && !url.endsWith(".jar")) {
final AtomicInteger id = new AtomicInteger(0);
// ExecutorService service = Executors.newFixedThreadPool(10, new ThreadFactory() {
// @Override
// public Thread newThread(Runnable r) {
// return new Thread(r, "ClassDiscovery-Async-" + id.incrementAndGet());
// }
// });
// Remove file: from the front
String root = url.substring(5);
rootLocationFile = new File(root);
List<File> fileList = new ArrayList<>();
descend(new File(root), fileList);
// to all of them. We have to first remove the "front" part
for (File f : fileList) {
String file = f.toString();
if (!file.matches(".*\\$(?:\\d)*\\.class") && file.endsWith(".class")) {
InputStream stream = null;
try {
stream = FileUtil.readAsStream(new File(rootLocationFile, f.getAbsolutePath().replaceFirst(Pattern.quote(new File(root).getAbsolutePath() + File.separator), "")));
ClassReader reader = new ClassReader(stream);
ClassMirrorVisitor mirrorVisitor = new ClassMirrorVisitor();
reader.accept(mirrorVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
mirrors.add(mirrorVisitor.getMirror(new URL(url)));
} catch (IOException ex) {
Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ex) {
Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
// service.shutdown();
// try {
// //Doesn't look like 0 is an option, so we'll just wait a day.
// service.awaitTermination(1, TimeUnit.DAYS);
// } catch (InterruptedException ex) {
// Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
// }
} else if (url.startsWith("file:") && url.endsWith(".jar")) {
// We are running from a jar
url = url.replaceFirst("file:", "");
rootLocationFile = new File(url);
ZipIterator zi = new ZipIterator(rootLocationFile);
try {
zi.iterate(new ZipIterator.ZipIteratorCallback() {
@Override
public void handle(String filename, InputStream in) {
if (!filename.matches(".*\\$(?:\\d)*\\.class") && filename.endsWith(".class")) {
try {
ClassReader reader = new ClassReader(in);
ClassMirrorVisitor mirrorVisitor = new ClassMirrorVisitor();
reader.accept(mirrorVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
mirrors.add(mirrorVisitor.getMirror(rootLocationFile.toURI().toURL()));
} catch (IOException ex) {
Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}, progressIterator);
} catch (IOException ex) {
Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
throw new RuntimeException("Unknown url type: " + rootLocation);
}
} catch (RuntimeException e) {
e.printStackTrace(System.err);
} finally {
if (debug) {
StreamUtils.GetSystemOut().println("Scans finished for " + rootLocation + ", taking " + (System.currentTimeMillis() - start) + " ms.");
}
}
}
Aggregations