Parameterize VirtualField field type (#5165)

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
Anuraag Agrawal 2022-01-19 06:42:44 +09:00 committed by GitHub
parent dd72e9e5f4
commit bdd82a899e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 9 deletions

View File

@ -36,7 +36,8 @@ public abstract class VirtualField<T, F> {
* @param type The type that will contain the new virtual field. * @param type The type that will contain the new virtual field.
* @param fieldType The field type that will be added to {@code type}. * @param fieldType The field type that will be added to {@code type}.
*/ */
public static <U extends T, T, F> VirtualField<U, F> find(Class<T> type, Class<F> fieldType) { public static <U extends T, V extends F, T, F> VirtualField<U, V> find(
Class<T> type, Class<F> fieldType) {
return RuntimeVirtualFieldSupplier.get().find(type, fieldType); return RuntimeVirtualFieldSupplier.get().find(type, fieldType);
} }

View File

@ -16,7 +16,7 @@ public final class RuntimeVirtualFieldSupplier {
private static final Logger logger = LoggerFactory.getLogger(RuntimeVirtualFieldSupplier.class); private static final Logger logger = LoggerFactory.getLogger(RuntimeVirtualFieldSupplier.class);
public interface VirtualFieldSupplier { public interface VirtualFieldSupplier {
<U extends T, T, F> VirtualField<U, F> find(Class<T> type, Class<F> fieldType); <U extends T, V extends F, T, F> VirtualField<U, V> find(Class<T> type, Class<F> fieldType);
} }
private static final VirtualFieldSupplier DEFAULT = new CacheBasedVirtualFieldSupplier(); private static final VirtualFieldSupplier DEFAULT = new CacheBasedVirtualFieldSupplier();
@ -44,8 +44,9 @@ public final class RuntimeVirtualFieldSupplier {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U extends T, T, F> VirtualField<U, F> find(Class<T> type, Class<F> fieldType) { public <U extends T, V extends F, T, F> VirtualField<U, V> find(
return (VirtualField<U, F>) Class<T> type, Class<F> fieldType) {
return (VirtualField<U, V>)
ownerToFieldToImplementationMap ownerToFieldToImplementationMap
.computeIfAbsent(type, c -> Cache.weak()) .computeIfAbsent(type, c -> Cache.weak())
.computeIfAbsent(fieldType, c -> new CacheBasedVirtualField<>()); .computeIfAbsent(fieldType, c -> new CacheBasedVirtualField<>());

View File

@ -41,11 +41,13 @@ public class AbstractMessageListenerContainerInstrumentation implements TypeInst
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static class GetBatchInterceptorAdvice { public static class GetBatchInterceptorAdvice {
@Advice.OnMethodExit(suppress = Throwable.class) @Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit(@Advice.Return(readOnly = false) BatchInterceptor<?, ?> interceptor) { public static <K, V> void onExit(
@Advice.Return(readOnly = false) BatchInterceptor<K, V> interceptor) {
if (!(interceptor instanceof InstrumentedBatchInterceptor)) { if (!(interceptor instanceof InstrumentedBatchInterceptor)) {
VirtualField receiveContextVirtualField = VirtualField<ConsumerRecords<K, V>, Context> receiveContextVirtualField =
VirtualField.find(ConsumerRecords.class, Context.class); VirtualField.find(ConsumerRecords.class, Context.class);
VirtualField stateStore = VirtualField.find(ConsumerRecords.class, State.class); VirtualField<ConsumerRecords<K, V>, State<K, V>> stateStore =
VirtualField.find(ConsumerRecords.class, State.class);
interceptor = interceptor =
new InstrumentedBatchInterceptor<>(receiveContextVirtualField, stateStore, interceptor); new InstrumentedBatchInterceptor<>(receiveContextVirtualField, stateStore, interceptor);
} }

View File

@ -16,14 +16,15 @@ final class RuntimeFieldBasedImplementationSupplier
implements RuntimeVirtualFieldSupplier.VirtualFieldSupplier { implements RuntimeVirtualFieldSupplier.VirtualFieldSupplier {
@Override @Override
public <U extends T, T, F> VirtualField<U, F> find(Class<T> type, Class<F> fieldType) { public <U extends T, V extends F, T, F> VirtualField<U, V> find(
Class<T> type, Class<F> fieldType) {
try { try {
String virtualFieldImplClassName = String virtualFieldImplClassName =
getVirtualFieldImplementationClassName(type.getName(), fieldType.getName()); getVirtualFieldImplementationClassName(type.getName(), fieldType.getName());
Class<?> contextStoreClass = Class.forName(virtualFieldImplClassName, false, null); Class<?> contextStoreClass = Class.forName(virtualFieldImplClassName, false, null);
Method method = contextStoreClass.getMethod("getVirtualField", Class.class, Class.class); Method method = contextStoreClass.getMethod("getVirtualField", Class.class, Class.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
VirtualField<U, F> field = (VirtualField<U, F>) method.invoke(null, type, fieldType); VirtualField<U, V> field = (VirtualField<U, V>) method.invoke(null, type, fieldType);
return field; return field;
} catch (ClassNotFoundException exception) { } catch (ClassNotFoundException exception) {
throw new IllegalStateException("VirtualField not found", exception); throw new IllegalStateException("VirtualField not found", exception);