org.unlaxer.compiler.PackageInternalsFinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tinyExpression Show documentation
Show all versions of tinyExpression Show documentation
TinyExpression implemented with Unlaxer
The newest version!
package org.unlaxer.compiler;
import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.function.Function;
import java.util.jar.JarEntry;
import javax.tools.JavaFileObject;
/*
* modified and repackage below sources for java9 and j2ee container
* https://atamur.blogspot.com/2009/10/using-built-in-javacompiler-with-custom.html
*
* @author atamur
* @author opa
* @since 15-Oct-2009
*/
class PackageInternalsFinder {
private ClassLoader classLoader;
private final Function jarURLStringFromURL;
private static final String CLASS_FILE_EXTENSION = ".class";
public PackageInternalsFinder(ClassLoader classLoader, Function jarURLStringFromURL) {
this.classLoader = classLoader;
this.jarURLStringFromURL = jarURLStringFromURL;
}
public List find(String packageName) throws IOException {
String javaPackageName = packageName.replaceAll("\\.", "/");
List result = new ArrayList();
Enumeration urlEnumeration = classLoader.getResources(javaPackageName);
while (urlEnumeration.hasMoreElements()) { // one URL for each jar on the classpath that has the given package
URL packageFolderURL = urlEnumeration.nextElement();
result.addAll(listUnder(packageName, packageFolderURL));
}
return result;
}
private Collection listUnder(String packageName, URL packageFolderURL) {
File directory = new File(packageFolderURL.getFile());
if (directory.isDirectory()) { // browse local .class files - useful for local execution
return processDir(packageName, directory);
} else { // browse a jar file
return processJar(packageFolderURL);
} // maybe there can be something else for more involved class loaders
}
private List processJar(URL packageFolderURL) {
List result = new ArrayList();
try {
String jarUri = jarURLStringFromURL.apply(packageFolderURL);
packageFolderURL = new URL(jarUri + "!/");
JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection();
String rootEntryName = jarConn.getEntryName();
rootEntryName = rootEntryName == null ? "" : rootEntryName;
// int rootEnd = rootEntryName.length() + 1;
Enumeration entryEnum = jarConn.getJarFile().entries();
while (entryEnum.hasMoreElements()) {
JarEntry jarEntry = entryEnum.nextElement();
String name = jarEntry.getName();
if (/* name.startsWith(rootEntryName) && */ /*
* name.indexOf('/', rootEnd) == -1 &&
*/ name.endsWith(CLASS_FILE_EXTENSION)) {
URI uri = URI.create(jarUri + "!/" + name);
String binaryName = name.replaceAll("/", ".");
binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
result.add(new CustomJavaFileObject(binaryName, uri));
}
}
} catch (Exception e) {
throw new RuntimeException("Wasn't able to open " + packageFolderURL + " as a jar file", e);
}
return result;
}
private List processDir(String packageName, File directory) {
List result = new ArrayList();
File[] childFiles = directory.listFiles();
for (File childFile : childFiles) {
if (childFile.isFile()) {
// We only want the .class files.
if (childFile.getName().endsWith(CLASS_FILE_EXTENSION)) {
String binaryName = packageName + "." + childFile.getName();
binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
result.add(new CustomJavaFileObject(binaryName, childFile.toURI()));
}
}
}
return result;
}
}