All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.firefly.utils.classproxy.MethodProxyFactoryUsingJavaCompiler Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.firefly.utils.classproxy;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;

import com.firefly.utils.CompilerUtils;
import com.firefly.utils.ReflectUtils.MethodProxy;
import com.firefly.utils.collection.ConcurrentReferenceHashMap;
import com.firefly.utils.StringUtils;

public class MethodProxyFactoryUsingJavaCompiler extends AbstractMethodProxyFactory {

	private static final Map methodCache = new ConcurrentReferenceHashMap<>(256);
	public static final MethodProxyFactoryUsingJavaCompiler INSTANCE = new MethodProxyFactoryUsingJavaCompiler();
	
	private MethodProxyFactoryUsingJavaCompiler() {
		
	}
	
	@Override
	public MethodProxy getMethodProxy(Method method) throws Throwable {
		MethodProxy ret = methodCache.get(method);
		if(ret != null)
			return ret;
		
		synchronized(methodCache) {
			ret = methodCache.get(method);
			if(ret != null)
				return ret;
		
			ret = _getMethodProxy(method);
			methodCache.put(method, ret);
			return ret;
		}
	}
	
	private MethodProxy _getMethodProxy(Method method) throws Throwable {
//		long start = System.currentTimeMillis();
		String packageName = "com.firefly.utils";
		String className = "MethodReflectionProxy" + UUID.randomUUID().toString().replace("-", "");
		String completeClassName = packageName + "." + className;
		
		Class[] paramClazz = method.getParameterTypes();
		String returnCode = "";		
		if(!method.getReturnType().equals(Void.TYPE)) {
			returnCode += "return ";
		}
		
		returnCode += "((" + method.getDeclaringClass().getCanonicalName() + ")obj)." + method.getName() + "(";
		if(paramClazz.length > 0) {
			int max = paramClazz.length - 1;
			for (int i = 0; ;i++) {
				Class param = paramClazz[i];
				if(param.isPrimitive()) {
					returnCode += StringUtils.replace("(({})args[{}]).{}Value()", primitiveWrapMap.get(param), i, param.getCanonicalName());
				} else {
					returnCode += "(" + param.getCanonicalName() + ")args[" + i + "]";
				}
				
				if(i == max)
					break;
				
				returnCode += ",";
			}
		}
		returnCode += ");";
		
		if(method.getReturnType().equals(Void.TYPE)) {
			returnCode += "\n\treturn null;";
		}
		
		String source = "package " + packageName + ";\n"
				+ "import " + Method.class.getCanonicalName() + ";\n"
				+"public class " + className + " implements " + MethodProxy.class.getCanonicalName() + " {\n"
					+"private Method method;\n"
					+"public " + className + "(Method method){\n"
						+"\tthis.method = method;\n"
					+"}\n\n"
					+"public Method method(){return method;}\n\n"
					+"public Object invoke(Object obj, Object[] args){\n"
						+"\tif(args == null || args.length != " + paramClazz.length +")\n"
							+"\t\tthrow new IllegalArgumentException(\"arguments error\");\n\n"
						+"\t" + returnCode + "\n"
					+"}\n"
				+"}"
				;
		
//		System.out.println(source);
		Class methodProxyClass = CompilerUtils.compileSource(completeClassName, source);
		if(methodProxyClass == null)
			return null;
		
		MethodProxy obj = (MethodProxy)methodProxyClass.getConstructor(Method.class).newInstance(method);
//		long end = System.currentTimeMillis();
//		System.out.println("Java compiler generates class proxy time -> " + (end - start));
		return obj;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy