1 package org.jetbrains.dokka
2
3 import java.lang.reflect.InvocationHandler
4 import java.lang.reflect.InvocationTargetException
5 import java.lang.reflect.Method
6 import java.lang.reflect.Proxy
7
8
9 /**
10 * Warning! Hard reflection magic used here.
11 *
12 * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
13 * to create access proxy for [delegate] into [targetClassLoader].
14 */
15 @Suppress("UNCHECKED_CAST")
automagicTypedProxynull16 inline fun <reified T : Any> automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T =
17 automagicProxy(targetClassLoader, T::class.java, delegate) as T
18
19
20 /**
21 * Warning! Hard reflection magic used here.
22 *
23 * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
24 * to create access proxy for [delegate] into [targetClassLoader].
25 *
26 */
27 fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any =
28 Proxy.newProxyInstance(
29 targetClassLoader,
30 arrayOf(targetType),
31 DelegatedInvocationHandler(delegate)
32 )
33
34 class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler {
35
36 @Throws(Throwable::class)
37 override fun invoke(proxy: Any, method: Method, args: Array<Any?>?): Any? {
38 val delegateMethod = delegate.javaClass.getMethod(method.name, *method.parameterTypes)
39 try {
40 delegateMethod.isAccessible = true
41 return delegateMethod.invoke(delegate, *(args ?: emptyArray()))
42 } catch (ex: InvocationTargetException) {
43 throw ex.targetException
44 }
45 }
46 }
47