com.jtransc.reflection.JTranscReflection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jtransc-rt-core Show documentation
Show all versions of jtransc-rt-core Show documentation
JVM AOT compiler currently generating JavaScript, C++, Haxe, with initial focus on Kotlin and games.
package com.jtransc.reflection;
import com.jtransc.JTranscSystem;
import j.ClassInfo;
import j.MemberInfo;
import j.ProgramReflection;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@SuppressWarnings({"EmptyCatchBlock", "WeakerAccess"})
public class JTranscReflection {
static public String[] getAllClasses() {
if (JTranscSystem.isJTransc()) {
ArrayList out = new ArrayList();
for (ClassInfo classInfo : ProgramReflection.getAllClasses()) {
if (classInfo != null && classInfo.name != null) {
out.add(classInfo.name);
}
}
return out.toArray(new String[out.size()]);
} else {
return new ClasspathScanner().getAllClasses();
}
}
static public Class> getClassByName(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null;
}
}
static private class ClasspathScanner {
private static final String CLASS_FILE_EXTENSION = ".class";
private static final String JAR_FILE_EXTENSION = ".jar";
public String[] getAllClasses() {
final ClassLoader classLoader = getClass().getClassLoader();
try {
final Enumeration resources = classLoader.getResources("");
final Queue filesWithDepthsToProcess = new LinkedList();
while (resources.hasMoreElements()) {
try {
filesWithDepthsToProcess.add(new DepthFile(0, toFile(resources.nextElement())));
} catch (final Exception uriSyntaxException) {
// Will throw an exception for non-hierarchical files. Ignored.
}
}
final Set classNames = new HashSet();
if (filesWithDepthsToProcess.isEmpty()) {
extractFromJar(classLoader, classNames);
}
extractFromBinaries(filesWithDepthsToProcess, classNames);
return classNames.toArray(new String[classNames.size()]);
} catch (final Exception exception) {
throw new RuntimeException("Unable to scan classpath.", exception);
}
}
private static void extractFromBinaries(final Queue filesWithDepthsToProcess,
final Set classNames) throws Exception {
while (!filesWithDepthsToProcess.isEmpty()) {
final DepthFile classPathFileWithDepth = filesWithDepthsToProcess.poll();
final File classPathFile = classPathFileWithDepth.file;
final int depth = classPathFileWithDepth.depth;
if (classPathFile.isDirectory()) {
addAllChildren(filesWithDepthsToProcess, classPathFile, depth);
} else {
final String className = getBinaryClassName(classPathFile, depth);
if (isNotPackageInfo(className)) {
classNames.add(className);
}
}
}
}
private static boolean isNotPackageInfo(final String className) {
return className.indexOf('-') < 0;
}
private static File toFile(final URL url) throws URISyntaxException {
return new File(url.toURI()).getAbsoluteFile();
}
private static void addAllChildren(final Queue rootFiles, final File classPathFile, int depth) {
depth++;
for (final File file : classPathFile.listFiles()) {
if (file.isDirectory() || file.getName().endsWith(CLASS_FILE_EXTENSION)) {
rootFiles.add(new DepthFile(depth, file));
}
}
}
private static String getBinaryClassName(final File classPathFile, final int depth) {
final String[] classFolders = classPathFile.getPath().split(File.separator);
final StringBuilder builder = new StringBuilder();
for (int folderIndex = classFolders.length - depth; folderIndex < classFolders.length - 1; folderIndex++) {
if (builder.length() > 0) {
builder.append('.');
}
builder.append(classFolders[folderIndex]);
}
final String classFileName = classFolders[classFolders.length - 1];
builder.append('.').append(classFileName.substring(0, classFileName.length() - CLASS_FILE_EXTENSION.length()));
return builder.toString();
}
private static void extractFromJar(final ClassLoader classLoader, final Set classNames) throws Exception {
final List filesToProcess = getJarFilesToProcess();
for (final JarFile jarFile : filesToProcess) {
final Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
processEntry(entry, classNames);
}
}
}
private static List getJarFilesToProcess() throws URISyntaxException, IOException {
final List filesToProcess = new ArrayList();
final File jarDirectory = new File(ClassLoader.getSystemClassLoader().getResource(".").toURI());
for (final File file : jarDirectory.listFiles()) {
if (file.getName().endsWith(JAR_FILE_EXTENSION)) {
filesToProcess.add(new JarFile(file));
}
}
return filesToProcess;
}
private static void processEntry(final JarEntry entry, final Set classNames) throws Exception {
if (!entry.isDirectory()) {
final String entryName = entry.getName();
if (entryName.endsWith(CLASS_FILE_EXTENSION) && !isNotPackageInfo(entryName)) {
classNames.add(jarEntryToClassName(entryName));
}
}
}
private static String jarEntryToClassName(final String entryName) {
return entryName.substring(0, entryName.length() - CLASS_FILE_EXTENSION.length()).replace(File.separatorChar, '.');
}
private static class DepthFile {
private final int depth;
private final File file;
public DepthFile(final int depth, final File file) {
this.depth = depth;
this.file = file;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy