Skip to content

Instantly share code, notes, and snippets.

@elevenetc
Created May 4, 2020 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elevenetc/a44be08d52f626a34939824810e3b021 to your computer and use it in GitHub Desktop.
Save elevenetc/a44be08d52f626a34939824810e3b021 to your computer and use it in GitHub Desktop.
Utils to get implementation classes of an interface
/**
* Kotlin version of https://dzone.com/articles/get-all-classes-within-package
* Mentioned here as well: https://stackoverflow.com/a/520344/798165
*/
object ReflectionUtils {
/**
* Returns list of classes if interface is located in the same package with implementations
*/
@Suppress("UNCHECKED_CAST")
fun <T> getImplementationsOfThePackage(requiredInterface: Class<T>): List<Class<T>> {
val name = requiredInterface.`package`!!.name
val result = mutableListOf<Class<T>>()
val classes = getClasses(name)
classes.forEach { clazz ->
val interfaces = clazz.interfaces
interfaces.forEach {
if (requiredInterface == it) {
result.add(clazz as Class<T>)
}
}
}
return result
}
fun getClasses(packageName: String): List<Class<*>> {
val classLoader = Thread.currentThread().contextClassLoader!!
val path = packageName.replace('.', '/')
val resources = classLoader.getResources(path)
val dirs = mutableListOf<File>()
while (resources.hasMoreElements()) {
val resource = resources.nextElement()
dirs.add(File(resource.file))
}
val classes = mutableListOf<Class<*>>()
for (directory in dirs) {
classes.addAll(findClasses(directory, packageName))
}
return classes
}
fun findClasses(
directory: File,
packageName: String
): List<Class<*>> {
val classes = mutableListOf<Class<*>>()
if (!directory.exists()) {
return classes
}
val files = directory.listFiles()
for (file in files) {
if (file.isDirectory) {
assert(!file.name.contains("."))
classes.addAll(findClasses(file, packageName + "." + file.name))
} else if (file.name.endsWith(".class")) {
classes.add(
Class.forName(
packageName + '.' + file.name.substring(0, file.name.length - 6)
)
)
}
}
return classes
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment