package org.freeplane.securegroovy;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.pool.TypePool;

public class GroovyPatcher {
	private static final String CACHED_FIELD_CLASS = "org.codehaus.groovy.reflection.CachedField";
	private static final String CACHED_METHOD_CLASS = "org.codehaus.groovy.reflection.CachedMethod";
	
	public static void apply(final ClassLoader pachedClassLoader){
		final ByteBuddy byteBuddy = new ByteBuddy();
		TypePool typePool = TypePool.Default.of(pachedClassLoader);
		final ClassFileLocator classFileLocator = ClassFileLocator.ForClassLoader.of(pachedClassLoader);

		final MethodDelegation cachedFieldInterceptor = MethodDelegation.to(CachedFieldInterceptor.class);
		byteBuddy.rebase(typePool.describe(CACHED_FIELD_CLASS).resolve(), //
				classFileLocator)
		.method(ElementMatchers.named("getProperty")).intercept(cachedFieldInterceptor)
		.method(ElementMatchers.named("setProperty")).intercept(cachedFieldInterceptor)
		.make()
		.load(pachedClassLoader);

		final MethodDelegation cachedMethodInterceptor = MethodDelegation.to(CachedMethodInterceptor.class);
		final MethodDelegation cachedMethodInvocationInterceptor = MethodDelegation.to(CachedMethodInvocationInterceptor.class);

		byteBuddy.rebase(typePool.describe(CACHED_METHOD_CLASS).resolve(), //
				classFileLocator)
		.method(ElementMatchers.named("setAccessible")).intercept(cachedMethodInterceptor)
		.method(ElementMatchers.named("getCachedMethod")).intercept(cachedMethodInterceptor)
		.method(ElementMatchers.named("invoke")).intercept(cachedMethodInvocationInterceptor)
		.make()
		.load(pachedClassLoader);
	}
}

@@ -30,16 +30,49 @@
 roovy;%0A%0A
+import groovy.lang.GroovyObject;%0A
 import n
@@ -142,16 +142,147 @@
 ocator;%0A
+import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;%0Aimport net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Configurable;%0A
 import n
@@ -1009,16 +1009,148 @@
 class);%0A
+%09%09final Configurable%3CClassLoader%3E strategy = ClassLoadingStrategy.Default.INJECTION.with(GroovyObject.class.getProtectionDomain());%0A
 %09%09byteBu
@@ -1425,32 +1425,42 @@
 achedClassLoader
+, strategy
 );%0A%0A%09%09final Meth
@@ -2059,20 +2059,30 @@
 dClassLoader
+, strategy
 );%0A%09%7D%0A%7D%0A

Fix protection domain and