Class Searcher - removed dead code

This commit is contained in:
dragonmacher 2019-05-21 16:33:32 -04:00
parent 146a83f953
commit c3182ab191
5 changed files with 45 additions and 225 deletions

View file

@ -16,8 +16,7 @@
package ghidra.util.classfinder;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.Set;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@ -26,35 +25,16 @@ class ClassDir {
private String dirPath;
private File dir;
private List<ClassPackage> children = new ArrayList<>();
private ClassPackage classPackage;
ClassDir(String dirPath, TaskMonitor monitor) throws CancelledException {
this.dirPath = dirPath;
this.dir = new File(dirPath);
children.add(new ClassPackage(dir, "", monitor));
}
void rescan(TaskMonitor monitor) throws CancelledException {
Iterator<ClassPackage> classPackageIterator = children.iterator();
while (classPackageIterator.hasNext()) {
ClassPackage pkg = classPackageIterator.next();
try {
pkg.rescan(monitor);
}
catch (FileNotFoundException e) {
classPackageIterator.remove();
}
}
classPackage = new ClassPackage(dir, "", monitor);
}
void getClasses(Set<Class<?>> set, TaskMonitor monitor) throws CancelledException {
Iterator<ClassPackage> classPackageIterator = children.iterator();
while (classPackageIterator.hasNext()) {
monitor.checkCanceled();
ClassPackage pkg = classPackageIterator.next();
pkg.getClasses(set, monitor);
}
classPackage.getClasses(set, monitor);
}
String getDirPath() {

View file

@ -29,7 +29,7 @@ import ghidra.util.task.TaskMonitor;
import utility.module.ModuleUtilities;
/**
* Finds classes in the classPath that match one of the filter classes.
* Finds extension classes in the classpath
*/
public class ClassFinder {
static final Logger log = LogManager.getLogger(ClassFinder.class);
@ -37,10 +37,8 @@ public class ClassFinder {
private static List<Class<?>> FILTER_CLASSES =
Collections.unmodifiableList(Arrays.asList(ExtensionPoint.class));
private List<ClassDir> classDirs = new ArrayList<>();
private List<ClassJar> classJars = new ArrayList<>();
private Map<String, List<Class<?>>> classesByName;
private Set<ClassDir> classDirs = new HashSet<>();
private Set<ClassJar> classJars = new HashSet<>();
public ClassFinder(List<String> searchPaths, TaskMonitor monitor) throws CancelledException {
initialize(searchPaths, monitor);
@ -48,46 +46,9 @@ public class ClassFinder {
private void initialize(List<String> searchPaths, TaskMonitor monitor)
throws CancelledException {
classDirs.clear();
classJars.clear();
reconcileClasses(searchPaths, monitor);
}
private void reconcileClasses(List<String> searchPaths, TaskMonitor monitor)
throws CancelledException {
Set<String> pathSet = new LinkedHashSet<>(searchPaths);
Iterator<ClassDir> dirs = classDirs.iterator();
while (dirs.hasNext()) {
monitor.checkCanceled();
ClassDir classDir = dirs.next();
String dirPath = classDir.getDirPath();
if (!pathSet.contains(dirPath)) {
log.trace(dirPath + " dropped from previous classpath");
dirs.remove();
}
else {
classDir.rescan(monitor);
pathSet.remove(dirPath);
}
}
Iterator<ClassJar> jars = classJars.iterator();
while (jars.hasNext()) {
monitor.checkCanceled();
ClassJar classJar = jars.next();
String jarPath = classJar.getJarPath();
if (!pathSet.contains(jarPath)) {
log.trace(jarPath + " dropped from previous classpath");
jars.remove();
}
else {
classJar.rescan(monitor);
pathSet.remove(jarPath);
}
}
Iterator<String> pathIterator = pathSet.iterator();
while (pathIterator.hasNext()) {
monitor.checkCanceled();
@ -109,47 +70,23 @@ public class ClassFinder {
classDirs.add(new ClassDir(path, monitor));
}
}
}
public List<Class<?>> getClasses(Class<?> filterClass, TaskMonitor monitor)
throws CancelledException {
if (classesByName == null) {
Map<String, List<Class<?>>> map = new HashMap<>();
Set<Class<?>> getClasses(TaskMonitor monitor) throws CancelledException {
Set<Class<?>> classSet = new HashSet<>();
Iterator<ClassDir> classDirIterator = classDirs.iterator();
while (classDirIterator.hasNext()) {
monitor.checkCanceled();
ClassDir classDir = classDirIterator.next();
classDir.getClasses(classSet, monitor);
}
Iterator<ClassJar> classJarsIterator = classJars.iterator();
while (classJarsIterator.hasNext()) {
monitor.checkCanceled();
ClassJar classJar = classJarsIterator.next();
classJar.getClasses(classSet, monitor);
}
Set<Class<?>> classes = new HashSet<>();
for (Class<?> filterClasse : FILTER_CLASSES) {
monitor.checkCanceled();
List<Class<?>> list = new ArrayList<>();
Iterator<Class<?>> classSetIterator = classSet.iterator();
while (classSetIterator.hasNext()) {
Class<?> c = classSetIterator.next();
if (filterClasse.isAssignableFrom(c)) {
list.add(c);
}
}
map.put(filterClasse.getName(), list);
}
classesByName = map;
for (ClassDir dir : classDirs) {
monitor.checkCanceled();
dir.getClasses(classes, monitor);
}
List<Class<?>> classes = classesByName.get(filterClass.getName());
return classes != null ? classes : Collections.emptyList();
for (ClassJar jar : classJars) {
monitor.checkCanceled();
jar.getClasses(classes, monitor);
}
return classes;
}
/*package*/ static Class<?> loadExtensionPoint(String path, String fullName) {

View file

@ -40,9 +40,8 @@ class ClassJar {
Pattern.compile(".*/(.*)/(?:lib|build/libs)/(.+).jar");
private String path;
private long time;
private Set<String> classNameList = new HashSet<>();
private Set<Class<?>> classes = null;
private Set<Class<?>> classes = new HashSet<>();
ClassJar(String path, TaskMonitor monitor) throws CancelledException {
this.path = path;
@ -50,45 +49,13 @@ class ClassJar {
scan(monitor);
}
String getJarPath() {
return path;
}
boolean rescan(TaskMonitor monitor) throws CancelledException {
File file = new File(path);
if (file.lastModified() != time) {
scan(monitor);
return true;
}
return false;
}
void getClasses(Set<Class<?>> list, TaskMonitor monitor) {
if (classes == null) {
ClassLoader classLoader = ClassSearcher.class.getClassLoader();
classes = new HashSet<>();
Iterator<String> iter = classNameList.iterator();
while (iter.hasNext()) {
String name = iter.next();
try {
monitor.setMessage("loading class: " + name);
classes.add(Class.forName(name, true, classLoader));
}
catch (Throwable t) {
Msg.showError(this, null, "Error loading class",
"Error loading class " + name + ":", t);
}
}
}
list.addAll(classes);
void getClasses(Set<Class<?>> set, TaskMonitor monitor) {
set.addAll(classes);
}
private void scan(TaskMonitor monitor) throws CancelledException {
classes = new HashSet<>();
classNameList.clear();
File file = new File(path);
time = file.lastModified();
try (JarFile jarFile = new JarFile(file)) {

View file

@ -15,7 +15,8 @@
*/
package ghidra.util.classfinder;
import java.io.*;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
import ghidra.util.Msg;
@ -27,53 +28,47 @@ class ClassPackage {
private static final FileFilter CLASS_FILTER =
pathname -> pathname.getName().endsWith(".class");
private Set<String> classNames = new HashSet<>();
private Set<Class<?>> classes = null;
private List<ClassPackage> children = new ArrayList<>();
private Set<Class<?>> classes = new HashSet<>();
private Set<ClassPackage> children = new HashSet<>();
private File rootDir;
private File packageDir;
private String packageName;
ClassPackage(File rootDir, String packageName, TaskMonitor monitor) throws CancelledException {
monitor.checkCanceled();
this.rootDir = rootDir;
this.packageName = packageName;
this.packageDir = getPackageDir(rootDir, packageName);
scanClasses();
scanSubPackages(monitor);
}
private void scanClasses() {
classNames.clear();
classes = new HashSet<>();
String path = rootDir.getAbsolutePath();
List<String> allClassNames = getAllClassNames();
Set<String> allClassNames = getAllClassNames();
for (String className : allClassNames) {
Class<?> c = ClassFinder.loadExtensionPoint(path, className);
if (c != null) {
classes.add(c);
classNames.add(c.getName());
}
}
}
private void scanSubPackages(TaskMonitor monitor) throws CancelledException {
children.clear();
File dir = getPackageDir(rootDir, packageName);
File[] subdirs = dir.listFiles();
File[] subdirs = packageDir.listFiles();
if (subdirs == null) {
Msg.debug(this, "Directory does not exist: " + dir);
Msg.debug(this, "Directory does not exist: " + packageDir);
return;
}
for (File subdir : subdirs) {
monitor.checkCanceled();
if (!subdir.isDirectory()) {
continue;
}
monitor.checkCanceled();
String pkg = subdir.getName();
if (pkg.contains(".")) {
// java can't handle dir names with '.'-- it conflicts with the package structure
@ -89,64 +84,6 @@ class ClassPackage {
}
}
void rescan(TaskMonitor monitor) throws CancelledException, FileNotFoundException {
monitor.checkCanceled();
scanClasses();
File dir = getPackageDir(rootDir, packageName);
String rootPath = rootDir.getAbsolutePath();
String dirPath = dir.getAbsolutePath();
dirPath = dirPath.substring(rootPath.length());
monitor.setMessage("scanning directory: " + rootDir.getName() + dirPath);
File[] subdirs = dir.listFiles();
if (subdirs == null) {
Msg.debug(this, "Directory does not exist: " + dir);
return;
}
Set<String> pkgNames = new HashSet<>();
for (File subdir : subdirs) {
monitor.checkCanceled();
if (!subdir.isDirectory()) {
continue;
}
String name = subdir.getName();
if (name.contains(".")) {
// java can't handle dir names with '.'-- it conflicts with the package structure
continue;
}
if (packageName.length() > 0) {
name = packageName + "." + name;
}
pkgNames.add(name);
}
Iterator<ClassPackage> classPackageIterator = children.iterator();
while (classPackageIterator.hasNext()) {
monitor.checkCanceled();
ClassPackage pkg = classPackageIterator.next();
if (!pkgNames.contains(pkg.packageName)) {
classPackageIterator.remove();
}
else {
pkg.rescan(monitor);
pkgNames.remove(pkg.packageName);
}
}
Iterator<String> packageNameIterator = pkgNames.iterator();
while (packageNameIterator.hasNext()) {
monitor.checkCanceled();
String pkgName = packageNameIterator.next();
children.add(new ClassPackage(rootDir, pkgName, monitor));
}
}
private File getPackageDir(File lRootDir, String lPackageName) {
return new File(lRootDir, lPackageName.replace('.', File.separatorChar));
}
@ -154,22 +91,22 @@ class ClassPackage {
void getClasses(Set<Class<?>> set, TaskMonitor monitor) throws CancelledException {
set.addAll(classes);
Iterator<ClassPackage> classPackageIterator = children.iterator();
while (classPackageIterator.hasNext()) {
Iterator<ClassPackage> it = children.iterator();
while (it.hasNext()) {
monitor.checkCanceled();
ClassPackage subPkg = classPackageIterator.next();
ClassPackage subPkg = it.next();
subPkg.getClasses(set, monitor);
}
}
private List<String> getAllClassNames() {
File dir = getPackageDir(rootDir, packageName);
File[] files = dir.listFiles(CLASS_FILTER);
private Set<String> getAllClassNames() {
File[] files = packageDir.listFiles(CLASS_FILTER);
if (files == null) {
return Collections.emptyList();
return Collections.emptySet();
}
List<String> results = new ArrayList<>(files.length);
Set<String> results = new HashSet<>(files.length);
for (File file : files) {
String name = file.getName();
name = name.substring(0, name.length() - 6);

View file

@ -66,7 +66,7 @@ public class ClassSearcher {
static final Logger log = LogManager.getLogger(ClassSearcher.class);
private static ClassFinder searcher;
private static List<Class<?>> extensionPoints;
private static Set<Class<?>> extensionPoints;
private static WeakSet<ChangeListener> listenerList =
WeakDataStructureFactory.createCopyOnReadWeakSet();
@ -225,13 +225,13 @@ public class ClassSearcher {
extensionPoints = null;
long t = (new Date()).getTime();
log.trace("Searching for classes...");
log.trace("Searching for classes...");
List<String> searchPaths = gatherSearchPaths();
searcher = new ClassFinder(searchPaths, monitor);
monitor.setMessage("Loading classes...");
extensionPoints = searcher.getClasses(ExtensionPoint.class, monitor);
extensionPoints = searcher.getClasses(monitor);
log.trace("Found extension classes: " + extensionPoints);
if (extensionPoints.isEmpty()) {
throw new AssertException("Unable to location extension points!");
@ -296,7 +296,7 @@ public class ClassSearcher {
ResourceFile extensionClassesFile = new ResourceFile(appRoot, "EXTENSION_POINT_CLASSES");
try {
List<String> classNames = FileUtilities.getLines(extensionClassesFile);
List<Class<?>> extensionClasses = new ArrayList<>();
Set<Class<?>> extensionClasses = new HashSet<>();
for (String className : classNames) {
try {
Class<?> clazz = Class.forName(className);
@ -306,13 +306,12 @@ public class ClassSearcher {
Msg.warn(ClassSearcher.class, "Can't load extension point: " + className);
}
}
extensionPoints = Collections.unmodifiableList(extensionClasses);
extensionPoints = Collections.unmodifiableSet(extensionClasses);
}
catch (IOException e) {
throw new AssertException("Got unexpected IOException ", e);
}
}
private static void loadExtensionPointSuffixes() {