Github user zmacomber commented on a diff in the pull request:
https://github.com/apache/commons-lang/pull/358#discussion_r228140306
--- Diff: src/main/java/org/apache/commons/lang3/ClassUtils.java ---
@@ -1059,6 +1067,62 @@ public static boolean isInnerClass(final Class<?>
cls) {
return getClass(loader, className, initialize);
}
+ /**
+ * Returns a list of base classes/interfaces underneath the supplied
package
+ * This method only retrieves base classes/interfaces that have
children that can be instantiated
+ * via a no-args constructor
+ * The class loader is retrieved via
Thread.currentThread().getContextClassLoader()
+ * This only retrieves base classes/interfaces directly underneath the
supplied package
+ *
+ * @param desiredBase the desired base class/interface to retrieve
+ * @param packageName the package name in the standard import format
(i.e. "java.lang.String")
+ * @param <T> The desired base class or interface type to retrieve
+ * @return a list of base classes/interfaces that match the supplied
type underneath the supplied package
+ * @throws IllegalArgumentException if the desiredBase or packageName
are invalid
+ * @throws IOException if an I/O error occurs in getting a new
directory stream
+ * @throws NullPointerException if desiredBase or url are null
+ * @throws URISyntaxException if the generated url can't be converted
to a URI
+ */
+ public static <T> List<T> getBaseClasses(final Class<T> desiredBase,
final String packageName)
+ throws IllegalArgumentException, IOException,
NullPointerException, URISyntaxException {
+
+ Objects.requireNonNull(desiredBase, "desiredBase must not be
null");
+
+ if (StringUtils.isBlank(packageName)) {
+ throw new IllegalArgumentException("packageName must not be
blank");
+ }
+
+ ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
+ URL url = classLoader.getResource(packageName.replaceAll("[.]",
"/"));
+ Objects.requireNonNull(url, "supplied package not found");
+
+ Path classesPath = Paths.get(url.toURI());
+
+ List<T> classes = new ArrayList<>();
+
+ try (DirectoryStream<Path> stream =
Files.newDirectoryStream(classesPath)) {
+ for (Path file: stream) {
+ Path pathFileName = file.getFileName();
+ if (( ! Files.isDirectory(file)) && (pathFileName !=
null)) {
+ String fullClassName = packageName + "." +
+
pathFileName.toString().replace(".class", "");
+
+ // Only add classes that can be instantiated via
newInstance()
+ try {
+ Object obj =
Class.forName(fullClassName).newInstance();
--- End diff --
To confirm that the class can actually be instantiated via the default
constructor. Notice the Exception comment and the comment above "try {"
---