aboutsummaryrefslogtreecommitdiff
path: root/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt
blob: 7bdf2f9d111f15545d657133cc5ae0d7ff0be857 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package org.jetbrains.dokka

import java.lang.reflect.InvocationHandler
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.lang.reflect.Proxy


/**
 * Warning! Hard reflection magic used here.
 *
 * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
 * to create access proxy for [delegate] into [targetClassLoader].
 */
@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T =
        automagicProxy(targetClassLoader, T::class.java, delegate) as T


/**
 * Warning! Hard reflection magic used here.
 *
 * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
 * to create access proxy for [delegate] into [targetClassLoader].
 *
 */
fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any =
        Proxy.newProxyInstance(
                targetClassLoader,
                arrayOf(targetType),
                DelegatedInvocationHandler(delegate)
        )

class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler {

    @Throws(Throwable::class)
    override fun invoke(proxy: Any, method: Method, args: Array<Any?>?): Any? {
        val delegateMethod = delegate.javaClass.getMethod(method.name, *method.parameterTypes)
        try {
            delegateMethod.isAccessible = true
            return delegateMethod.invoke(delegate, *(args ?: emptyArray()))
        } catch (ex: InvocationTargetException) {
            throw ex.targetException
        }
    }
}