Skip to content

Commit

Permalink
refactor(WrapperAdapterUtils): use Clazz.class.getMethod(...) ins…
Browse files Browse the repository at this point in the history
…tead of lonely method name constants; the former is IDE aware, so safer and refactor friendly 🤖
  • Loading branch information
oldratlee committed Mar 31, 2024
1 parent 599e7e8 commit 978d0b6
Showing 1 changed file with 50 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@
import io.foldright.inspectablewrappers.Wrapper;
import io.foldright.inspectablewrappers.WrapperAdapter;

import javax.annotation.ParametersAreNonnullByDefault;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.concurrent.Callable;

import static io.foldright.inspectablewrappers.utils.WrapperAdapterProxyRelatedMethods.*;
import static java.util.Objects.requireNonNull;


/**
* Utility class for creating {@link WrapperAdapter} instances
* Utility class for creating {@link io.foldright.inspectablewrappers.WrapperAdapter} instances
* without writing boilerplate code of creating a new adapter class.
*
* @author Jerry Lee (oldratlee at gmail dot com)
*/
@ParametersAreNonnullByDefault
public final class WrapperAdapterUtils {
/**
* Creates a {@link WrapperAdapter} instance of the given biz interface type
Expand Down Expand Up @@ -69,12 +73,12 @@ public static <T> T createWrapperAdapter(Class<T> bizInterface, T underlying, T
@SuppressWarnings({"unchecked", "rawtypes"})
private static <T> T createWrapperAdapter0(Class<T> bizInterface, T underlying, T adaptee, @Nullable Attachable<?, ?> attachable) {
final InvocationHandler handler = (proxy, method, args) -> {
if (isMethodUnwrap(method)) return underlying;
if (isMethodAdaptee(method)) return adaptee;
if (UNWRAP.sameSignatureAs(method)) return underlying;
if (ADAPTEE.sameSignatureAs(method)) return adaptee;

if (attachable != null && isMethodGetAttachment(method))
if (attachable != null && GET_ATTACHMENT.sameSignatureAs(method))
return ((Attachable) attachable).getAttachment(args[0]);
if (attachable != null && isMethodSetAttachment(method)) {
if (attachable != null && SET_ATTACHMENT.sameSignatureAs(method)) {
((Attachable) attachable).setAttachment(args[0], args[1]);
return null;
}
Expand All @@ -90,31 +94,50 @@ private static <T> T createWrapperAdapter0(Class<T> bizInterface, T underlying,
handler);
}

private static boolean isMethodAdaptee(Method method) {
return checkMethod(method, "adaptee");
}

private static boolean isMethodUnwrap(Method method) {
return checkMethod(method, "unwrap");
}

private static boolean isMethodGetAttachment(Method method) {
return checkMethod(method, "getAttachment", Object.class);
}

private static boolean isMethodSetAttachment(Method method) {
return checkMethod(method, "setAttachment", Object.class, Object.class);
}

private static boolean checkMethod(Method method, String methodName, Class<?>... parameterTypes) {
return method.getName().equals(methodName)
&& method.getParameterCount() == parameterTypes.length
&& Arrays.equals(method.getParameterTypes(), parameterTypes);
}

/**
* NO need to create instance at all
*/
private WrapperAdapterUtils() {
}
}

/**
* Use {@code Clazz.class.getMethod(...)} rather than lonely method name constants;
* The former is IDE aware, so safer and refactor friendly.
*/
enum WrapperAdapterProxyRelatedMethods {
/**
* {@link WrapperAdapter#adaptee()}
*/
UNWRAP(() -> Wrapper.class.getMethod("unwrap")),
/**
* {@link Wrapper#unwrap()}
*/
ADAPTEE(() -> WrapperAdapter.class.getMethod("adaptee")),
/**
* {@link Attachable#getAttachment(Object)}
*/
GET_ATTACHMENT(() -> Attachable.class.getMethod("getAttachment", Object.class)),
/**
* {@link Attachable#setAttachment(Object, Object)}
*/
SET_ATTACHMENT(() -> Attachable.class.getMethod("setAttachment", Object.class, Object.class)),
;

private final String methodName;
private final Class<?>[] parameterTypes;

WrapperAdapterProxyRelatedMethods(Callable<Method> method) {
try {
Method m = method.call();
this.methodName = m.getName();
this.parameterTypes = m.getParameterTypes();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}

boolean sameSignatureAs(Method method) {
return methodName.equals(method.getName()) && Arrays.equals(parameterTypes, method.getParameterTypes());
}
}

0 comments on commit 978d0b6

Please sign in to comment.