From 97b0b27a19d4f12a2f06347ed991e6b44e8207a5 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Fri, 14 Jan 2022 13:25:23 +0100 Subject: [PATCH] Improve Index.of to also accept class files and JAR files --- .../src/main/java/org/jboss/jandex/Index.java | 58 +++++++++++++------ .../main/java/org/jboss/jandex/Indexer.java | 7 ++- .../org/jboss/jandex/test/BasicTestCase.java | 55 ++++++++++++++---- 3 files changed, 89 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/org/jboss/jandex/Index.java b/core/src/main/java/org/jboss/jandex/Index.java index 3c4fc75c..b652e15e 100644 --- a/core/src/main/java/org/jboss/jandex/Index.java +++ b/core/src/main/java/org/jboss/jandex/Index.java @@ -22,16 +22,20 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; /** * An index useful for quickly processing annotations. The index is read-only and supports @@ -137,30 +141,50 @@ public static Index of(Class... classes) throws IOException { } /** - * Constructs an Index of class files found in the passed directories. - * The directories are not scanned recursively. + * Constructs an Index of the passed files and directories. Files may be class files or JAR files. + * Directories are scanned for class files, but not recursively. * - * @param directories Directories containing class files to index + * @param files class files, JAR files or directories containing class files to index * @return the index - * @throws IllegalArgumentException if any passed {@code File} is null or not a directory + * @throws IllegalArgumentException if any passed {@code File} is null or not a class file, JAR file or directory */ - public static Index of(File... directories) throws IOException { + public static Index of(File... files) throws IOException { Indexer indexer = new Indexer(); - for (File directory : directories) { - if (directory == null || !directory.isDirectory()) { - throw new IllegalArgumentException("not a directory: " + directory); - } + for (File file : files) { + if (file == null) { + throw new IllegalArgumentException("File must not be null"); + } else if (file.isDirectory()) { + File[] classFiles = file.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isFile() && pathname.getName().endsWith(".class"); + } + }); - File[] sources = directory.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.isFile() && pathname.getName().endsWith(".class"); + for (File classFile : classFiles) { + try (InputStream in = new FileInputStream(classFile)) { + indexer.index(in); + } } - }); - - for (File source : sources) { - indexer.index(new FileInputStream(source)); + } else if (file.isFile() && file.getName().endsWith(".class")) { + try (InputStream in = new FileInputStream(file)) { + indexer.index(in); + } + } else if (file.isFile() && file.getName().endsWith(".jar")) { + try (JarFile jarFile = new JarFile(file)) { + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.getName().endsWith(".class")) { + try (InputStream in = jarFile.getInputStream(entry)) { + indexer.index(in); + } + } + } + } + } else { + throw new IllegalArgumentException("Not a class file, JAR file or directory: " + file); } } diff --git a/core/src/main/java/org/jboss/jandex/Indexer.java b/core/src/main/java/org/jboss/jandex/Indexer.java index b5e9d64a..7a661b11 100644 --- a/core/src/main/java/org/jboss/jandex/Indexer.java +++ b/core/src/main/java/org/jboss/jandex/Indexer.java @@ -2030,8 +2030,9 @@ public ClassInfo indexClass(Class clazz) throws IOException { throw new IllegalArgumentException("clazz cannot be null"); } String resourceName = '/' + clazz.getName().replace('.', '/') + ".class"; - InputStream resource = clazz.getResourceAsStream(resourceName); - return index(resource); + try (InputStream resource = clazz.getResourceAsStream(resourceName)) { + return index(resource); + } } /** @@ -2054,7 +2055,7 @@ public ClassInfo index(InputStream stream) throws IOException { // Retroweaved classes may contain annotations // Also, hierarchy info is needed regardless - if (!isJDK11OrNewer(data)) + if (!isJDK11OrNewer(data)) // refers to JDK 1.1, not JDK 11 return null; initIndexMaps(); diff --git a/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java b/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java index f5b75197..35fac03d 100644 --- a/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java +++ b/core/src/test/java/org/jboss/jandex/test/BasicTestCase.java @@ -277,10 +277,19 @@ public boolean accept(File pathname) { @Test public void testIndexOfEmptyDirectory() throws IOException, URISyntaxException { - URL testLocation = getClass().getResource(getClass().getSimpleName() + ".class"); - File testDirectory = new File(testLocation.toURI().resolve("../../../../")); - Index index = Index.of(testDirectory); - assertEquals(0, index.getKnownClasses().size()); + File tempDir = null; + + try { + tempDir = File.createTempFile("temp", ".dir"); + tempDir.delete(); + tempDir.mkdir(); + Index index = Index.of(tempDir); + assertEquals(0, index.getKnownClasses().size()); + } finally { + if (tempDir != null) { + tempDir.delete(); + } + } } @Test @@ -306,19 +315,43 @@ public void testIndexOfDirectoryNonClassFile() throws IOException, URISyntaxExce } @Test - public void testIndexOfNonDirectory() throws IOException, URISyntaxException { + public void testIndexOfClassFile() throws IOException, URISyntaxException { final URL testLocation = getClass().getResource(getClass().getSimpleName() + ".class"); final File thisClassFile = new File(testLocation.toURI()); - assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { - @Override - public void run() throws Throwable { - Index.of(thisClassFile); + Index index = Index.of(thisClassFile); + assertEquals(1, index.getKnownClasses().size()); + } + + @Test + public void testIndexOfNonClassFile() throws IOException { + File tempDir = null; + File tempFile = null; + + try { + tempDir = File.createTempFile("temp", ".dir"); + tempDir.delete(); + tempDir.mkdir(); + tempFile = File.createTempFile("dummy", ".tmp", tempDir); + + File temp = tempFile; + assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { + @Override + public void run() throws Throwable { + Index.of(temp); + } + }); + } finally { + if (tempFile != null) { + tempFile.delete(); } - }); + if (tempDir != null) { + tempDir.delete(); + } + } } @Test - public void testIndexOfNullDirectory() throws IOException, URISyntaxException { + public void testIndexOfNullDirectory() { assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { @Override public void run() throws Throwable {