diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/autocomplete/AstPackageExplorer.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/autocomplete/AstPackageExplorer.java index 2d760ca884..0a85c4ad70 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/autocomplete/AstPackageExplorer.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/autocomplete/AstPackageExplorer.java @@ -8,13 +8,23 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Modifier; import java.net.URL; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.Enumeration; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.commons.io.FilenameUtils; + import net.sourceforge.pmd.lang.Language; @@ -48,52 +58,56 @@ class AstPackageExplorer implements NodeNameFinder { /** Finds the classes in the given package by looking in the classpath directories. */ private static Stream> getClasses(String packageName) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); assert classLoader != null; - String path = packageName.replace('.', '/'); Enumeration resources; try { + String path = packageName.replace('.', '/'); resources = classLoader.getResources(path); } catch (IOException e) { return Stream.empty(); } - List dirs = new ArrayList<>(); + final List> result = new ArrayList<>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); - dirs.add(new File(resource.getFile())); + try { + Files.walkFileTree(new File(resource.getFile()).toPath(), + EnumSet.noneOf(FileVisitOption.class), + 1, + getClassFileVisitor(packageName, result)); + + } catch (IOException e) { + // continue + e.printStackTrace(); + } } - List> classes = new ArrayList<>(); - - for (File directory : dirs) { - addClasses(classes, directory, packageName); - } - - return classes.stream(); + return result.stream(); } - private static void addClasses(List> classes, File directory, String packageName) { - - if (!directory.exists()) { - return; - } - - File[] files = directory.listFiles(); - for (File file : files) { - if (file.getName().endsWith(".class")) { - try { - classes.add(Class.forName(packageName + "." + file.getName().substring(0, file.getName().length() - ".class".length()))); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + private static FileVisitor getClassFileVisitor(String packageName, List> accumulator) { + return new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) { + final String extension = FilenameUtils.getExtension(file.toString()); + if ("class".equalsIgnoreCase(extension)) { + try { + accumulator.add(Class.forName(packageName + "." + FilenameUtils.getBaseName(file.getFileName().toString()))); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } } + return FileVisitResult.CONTINUE; } - } + }; + }