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

org.perfectable.introspection.proxy.JdkProxyService Maven / Gradle / Ivy

There is a newer version: 5.1.0
Show newest version
package org.perfectable.introspection.proxy;

import org.perfectable.introspection.ObjectMethods;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

import com.google.auto.service.AutoService;
import com.google.errorprone.annotations.Immutable;

import static java.util.Objects.requireNonNull;

// THIS IS NOT A PUBLIC API: class must be public because of ServiceLoader
@SuppressWarnings("javadoc")
@Immutable
@AutoService(ProxyService.class)
public final class JdkProxyService implements ProxyService {

	private static final Set SUPPORTED_FEATURES = EnumSet.noneOf(Feature.class);
	private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];

	@Override
	public boolean supportsFeature(Feature feature) {
		return SUPPORTED_FEATURES.contains(feature);
	}

	@Override
	public  I instantiate(ClassLoader classLoader, Class baseClass, List> interfaces,
							 InvocationHandler> handler)
		throws UnsupportedFeatureException {
		if (!baseClass.getName().equals(Object.class.getName())) {
			throw new UnsupportedFeatureException("JDK proxy cannot be created with superclass other than Object");
		}
		java.lang.reflect.InvocationHandler adapterHandler = JdkInvocationHandlerAdapter.adapt(handler);
		Class[] interfacesArray = interfaces.toArray(EMPTY_CLASS_ARRAY);
		try {
			@SuppressWarnings("unchecked")
			I instance = (I) Proxy.newProxyInstance(classLoader, interfacesArray, adapterHandler);
			return instance;
		}
		catch (IllegalArgumentException e) {
			throw new AssertionError("Proxy construction failed", e);
		}
	}

	private static final class JdkInvocationHandlerAdapter implements java.lang.reflect.InvocationHandler {
		private final InvocationHandler> handler;

		static  JdkInvocationHandlerAdapter adapt(InvocationHandler> handler) {
			return new JdkInvocationHandlerAdapter<>(handler);
		}

		private JdkInvocationHandlerAdapter(InvocationHandler> handler) {
			this.handler = handler;
		}

		@Nullable
		@Override
		public Object invoke(@Nullable Object proxy, Method method,
							 @Nullable Object[] args)
			throws Throwable {
			requireNonNull(method);
			if (method.equals(ObjectMethods.FINALIZE)) {
				return null; // ignore proxy finalization
			}
			@SuppressWarnings("unchecked")
			T castedProxy = (T) proxy;
			@SuppressWarnings("unchecked")
			MethodInvocation invocation = MethodInvocation.intercepted(method, castedProxy, args);
			return this.handler.handle(invocation);
		}

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy