BridgeMethodResolver properly resolves interface hierarchies
Issue: SPR-16103
(cherry picked from commit 182da15)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -59,6 +59,7 @@ public abstract class BridgeMethodResolver {
|
|||||||
if (bridgeMethod == null || !bridgeMethod.isBridge()) {
|
if (bridgeMethod == null || !bridgeMethod.isBridge()) {
|
||||||
return bridgeMethod;
|
return bridgeMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather all methods with matching name and parameter size.
|
// Gather all methods with matching name and parameter size.
|
||||||
List<Method> candidateMethods = new ArrayList<Method>();
|
List<Method> candidateMethods = new ArrayList<Method>();
|
||||||
Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass());
|
Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass());
|
||||||
@@ -67,10 +68,12 @@ public abstract class BridgeMethodResolver {
|
|||||||
candidateMethods.add(candidateMethod);
|
candidateMethods.add(candidateMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now perform simple quick check.
|
// Now perform simple quick check.
|
||||||
if (candidateMethods.size() == 1) {
|
if (candidateMethods.size() == 1) {
|
||||||
return candidateMethods.get(0);
|
return candidateMethods.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for candidate match.
|
// Search for candidate match.
|
||||||
Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod);
|
Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod);
|
||||||
if (bridgedMethod != null) {
|
if (bridgedMethod != null) {
|
||||||
@@ -133,42 +136,13 @@ public abstract class BridgeMethodResolver {
|
|||||||
return (method != null && isResolvedTypeMatch(method, candidateMethod, declaringClass));
|
return (method != null && isResolvedTypeMatch(method, candidateMethod, declaringClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches for the generic {@link Method} declaration whose erased signature
|
|
||||||
* matches that of the supplied bridge method.
|
|
||||||
* @throws IllegalStateException if the generic declaration cannot be found
|
|
||||||
*/
|
|
||||||
private static Method findGenericDeclaration(Method bridgeMethod) {
|
|
||||||
// Search parent types for method that has same signature as bridge.
|
|
||||||
Class<?> superclass = bridgeMethod.getDeclaringClass().getSuperclass();
|
|
||||||
while (superclass != null && Object.class != superclass) {
|
|
||||||
Method method = searchForMatch(superclass, bridgeMethod);
|
|
||||||
if (method != null && !method.isBridge()) {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
superclass = superclass.getSuperclass();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search interfaces.
|
|
||||||
Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(bridgeMethod.getDeclaringClass());
|
|
||||||
for (Class<?> ifc : interfaces) {
|
|
||||||
Method method = searchForMatch(ifc, bridgeMethod);
|
|
||||||
if (method != null && !method.isBridge()) {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the {@link Type} signature of both the supplied
|
* Returns {@code true} if the {@link Type} signature of both the supplied
|
||||||
* {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method}
|
* {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method}
|
||||||
* are equal after resolving all types against the declaringType, otherwise
|
* are equal after resolving all types against the declaringType, otherwise
|
||||||
* returns {@code false}.
|
* returns {@code false}.
|
||||||
*/
|
*/
|
||||||
private static boolean isResolvedTypeMatch(
|
private static boolean isResolvedTypeMatch(Method genericMethod, Method candidateMethod, Class<?> declaringClass) {
|
||||||
Method genericMethod, Method candidateMethod, Class<?> declaringClass) {
|
|
||||||
Type[] genericParameters = genericMethod.getGenericParameterTypes();
|
Type[] genericParameters = genericMethod.getGenericParameterTypes();
|
||||||
Class<?>[] candidateParameters = candidateMethod.getParameterTypes();
|
Class<?>[] candidateParameters = candidateMethod.getParameterTypes();
|
||||||
if (genericParameters.length != candidateParameters.length) {
|
if (genericParameters.length != candidateParameters.length) {
|
||||||
@@ -191,13 +165,51 @@ public abstract class BridgeMethodResolver {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for the generic {@link Method} declaration whose erased signature
|
||||||
|
* matches that of the supplied bridge method.
|
||||||
|
* @throws IllegalStateException if the generic declaration cannot be found
|
||||||
|
*/
|
||||||
|
private static Method findGenericDeclaration(Method bridgeMethod) {
|
||||||
|
// Search parent types for method that has same signature as bridge.
|
||||||
|
Class<?> superclass = bridgeMethod.getDeclaringClass().getSuperclass();
|
||||||
|
while (superclass != null && Object.class != superclass) {
|
||||||
|
Method method = searchForMatch(superclass, bridgeMethod);
|
||||||
|
if (method != null && !method.isBridge()) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
superclass = superclass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(bridgeMethod.getDeclaringClass());
|
||||||
|
return searchInterfaces(interfaces, bridgeMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method searchInterfaces(Class<?>[] interfaces, Method bridgeMethod) {
|
||||||
|
for (Class<?> ifc : interfaces) {
|
||||||
|
Method method = searchForMatch(ifc, bridgeMethod);
|
||||||
|
if (method != null && !method.isBridge()) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return searchInterfaces(ifc.getInterfaces(), bridgeMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the supplied {@link Class} has a declared {@link Method} whose signature matches
|
* If the supplied {@link Class} has a declared {@link Method} whose signature matches
|
||||||
* that of the supplied {@link Method}, then this matching {@link Method} is returned,
|
* that of the supplied {@link Method}, then this matching {@link Method} is returned,
|
||||||
* otherwise {@code null} is returned.
|
* otherwise {@code null} is returned.
|
||||||
*/
|
*/
|
||||||
private static Method searchForMatch(Class<?> type, Method bridgeMethod) {
|
private static Method searchForMatch(Class<?> type, Method bridgeMethod) {
|
||||||
return ReflectionUtils.findMethod(type, bridgeMethod.getName(), bridgeMethod.getParameterTypes());
|
try {
|
||||||
|
return type.getDeclaredMethod(bridgeMethod.getName(), bridgeMethod.getParameterTypes());
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -344,8 +344,26 @@ public class BridgeMethodResolverTests {
|
|||||||
assertEquals("findBy", bridgedMethod.getName());
|
assertEquals("findBy", bridgedMethod.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // SPR-16103
|
||||||
|
public void testClassHierarchy() throws Exception {
|
||||||
|
doTestHierarchyResolution(FooClass.class);
|
||||||
|
}
|
||||||
|
|
||||||
public static interface Foo<T extends Serializable> {
|
@Test // SPR-16103
|
||||||
|
public void testInterfaceHierarchy() throws Exception {
|
||||||
|
doTestHierarchyResolution(FooInterface.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTestHierarchyResolution(Class<?> clazz) throws Exception {
|
||||||
|
for (Method method : clazz.getDeclaredMethods()){
|
||||||
|
Method bridged = BridgeMethodResolver.findBridgedMethod(method);
|
||||||
|
Method expected = clazz.getMethod("test", FooEntity.class);
|
||||||
|
assertEquals(expected, bridged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface Foo<T extends Serializable> {
|
||||||
|
|
||||||
void someMethod(T theArg, Object otherArg);
|
void someMethod(T theArg, Object otherArg);
|
||||||
|
|
||||||
@@ -396,7 +414,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Adder<T> {
|
public interface Adder<T> {
|
||||||
|
|
||||||
void add(T item);
|
void add(T item);
|
||||||
}
|
}
|
||||||
@@ -445,7 +463,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Boo<E, T extends Serializable> {
|
public interface Boo<E, T extends Serializable> {
|
||||||
|
|
||||||
void foo(E e);
|
void foo(E e);
|
||||||
|
|
||||||
@@ -467,17 +485,15 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Settings {
|
public interface Settings {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface ConcreteSettings extends Settings {
|
public interface ConcreteSettings extends Settings {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Dao<T, S> {
|
public interface Dao<T, S> {
|
||||||
|
|
||||||
T load();
|
T load();
|
||||||
|
|
||||||
@@ -485,15 +501,14 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface SettingsDao<T extends Settings, S> extends Dao<T, S> {
|
public interface SettingsDao<T extends Settings, S> extends Dao<T, S> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
T load();
|
T load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface ConcreteSettingsDao extends
|
public interface ConcreteSettingsDao extends SettingsDao<ConcreteSettings, String> {
|
||||||
SettingsDao<ConcreteSettings, String> {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String loadFromParent();
|
String loadFromParent();
|
||||||
@@ -511,7 +526,7 @@ public class BridgeMethodResolverTests {
|
|||||||
this.otherObject = otherObject;
|
this.otherObject = otherObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Transactional(readOnly = true)
|
// @Transactional(readOnly = true)
|
||||||
@Override
|
@Override
|
||||||
public S loadFromParent() {
|
public S loadFromParent() {
|
||||||
return otherObject;
|
return otherObject;
|
||||||
@@ -526,7 +541,7 @@ public class BridgeMethodResolverTests {
|
|||||||
super(object, "From Parent");
|
super(object, "From Parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Transactional(readOnly = true)
|
// @Transactional(readOnly = true)
|
||||||
@Override
|
@Override
|
||||||
public ConcreteSettings load() {
|
public ConcreteSettings load() {
|
||||||
return super.object;
|
return super.object;
|
||||||
@@ -534,7 +549,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Bounded<E> {
|
public interface Bounded<E> {
|
||||||
|
|
||||||
boolean boundedOperation(E e);
|
boolean boundedOperation(E e);
|
||||||
}
|
}
|
||||||
@@ -558,7 +573,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface GenericParameter<T> {
|
public interface GenericParameter<T> {
|
||||||
|
|
||||||
T getFor(Class<T> cls);
|
T getFor(Class<T> cls);
|
||||||
}
|
}
|
||||||
@@ -697,7 +712,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Event {
|
public interface Event {
|
||||||
|
|
||||||
int getPriority();
|
int getPriority();
|
||||||
}
|
}
|
||||||
@@ -727,24 +742,19 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface UserInitiatedEvent {
|
public interface UserInitiatedEvent {
|
||||||
|
|
||||||
//public Session getInitiatorSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static abstract class BaseUserInitiatedEvent extends GenericEvent implements
|
public static abstract class BaseUserInitiatedEvent extends GenericEvent implements UserInitiatedEvent {
|
||||||
UserInitiatedEvent {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class MessageEvent extends BaseUserInitiatedEvent {
|
public static class MessageEvent extends BaseUserInitiatedEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Channel<E extends Event> {
|
public interface Channel<E extends Event> {
|
||||||
|
|
||||||
void send(E event);
|
void send(E event);
|
||||||
|
|
||||||
@@ -754,29 +764,27 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Broadcaster {
|
public interface Broadcaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface EventBroadcaster extends Broadcaster {
|
public interface EventBroadcaster extends Broadcaster {
|
||||||
|
|
||||||
public void subscribe();
|
void subscribe();
|
||||||
|
|
||||||
public void unsubscribe();
|
void unsubscribe();
|
||||||
|
|
||||||
public void setChannel(Channel<?> channel);
|
void setChannel(Channel<?> channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class GenericBroadcasterImpl implements Broadcaster {
|
public static class GenericBroadcasterImpl implements Broadcaster {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unused", "unchecked" })
|
@SuppressWarnings({ "unused", "unchecked" })
|
||||||
public static abstract class GenericEventBroadcasterImpl<T extends Event> extends
|
public static abstract class GenericEventBroadcasterImpl<T extends Event>
|
||||||
GenericBroadcasterImpl
|
extends GenericBroadcasterImpl implements EventBroadcaster {
|
||||||
implements EventBroadcaster {
|
|
||||||
|
|
||||||
private Class<T>[] subscribingEvents;
|
private Class<T>[] subscribingEvents;
|
||||||
|
|
||||||
@@ -802,27 +810,24 @@ public class BridgeMethodResolverTests {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void subscribe() {
|
public void subscribe() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsubscribe() {
|
public void unsubscribe() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericEventBroadcasterImpl(Class<? extends T>... events) {
|
public GenericEventBroadcasterImpl(Class<? extends T>... events) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface Receiver<E extends Event> {
|
public interface Receiver<E extends Event> {
|
||||||
|
|
||||||
void receive(E event);
|
void receive(E event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface MessageBroadcaster extends Receiver<MessageEvent> {
|
public interface MessageBroadcaster extends Receiver<MessageEvent> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,7 +850,7 @@ public class BridgeMethodResolverTests {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static class MessageBroadcasterImpl extends
|
public static class MessageBroadcasterImpl extends
|
||||||
GenericEventBroadcasterImpl<MessageEvent>
|
GenericEventBroadcasterImpl<MessageEvent>
|
||||||
implements MessageBroadcaster {
|
implements MessageBroadcaster {
|
||||||
|
|
||||||
public MessageBroadcasterImpl() {
|
public MessageBroadcasterImpl() {
|
||||||
super(NewMessageEvent.class);
|
super(NewMessageEvent.class);
|
||||||
@@ -876,7 +881,7 @@ public class BridgeMethodResolverTests {
|
|||||||
// SPR-2454 Test Classes
|
// SPR-2454 Test Classes
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
|
|
||||||
public static interface SimpleGenericRepository<T> {
|
public interface SimpleGenericRepository<T> {
|
||||||
|
|
||||||
public Class<T> getPersistentClass();
|
public Class<T> getPersistentClass();
|
||||||
|
|
||||||
@@ -892,7 +897,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface RepositoryRegistry {
|
public interface RepositoryRegistry {
|
||||||
|
|
||||||
<T> SimpleGenericRepository<T> getFor(Class<T> entityType);
|
<T> SimpleGenericRepository<T> getFor(Class<T> entityType);
|
||||||
}
|
}
|
||||||
@@ -900,7 +905,7 @@ public class BridgeMethodResolverTests {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static class SettableRepositoryRegistry<R extends SimpleGenericRepository<?>>
|
public static class SettableRepositoryRegistry<R extends SimpleGenericRepository<?>>
|
||||||
implements RepositoryRegistry {
|
implements RepositoryRegistry {
|
||||||
|
|
||||||
protected void injectInto(R rep) {
|
protected void injectInto(R rep) {
|
||||||
}
|
}
|
||||||
@@ -924,7 +929,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface ConvenientGenericRepository<T, ID extends Serializable>
|
public interface ConvenientGenericRepository<T, ID extends Serializable>
|
||||||
extends SimpleGenericRepository<T> {
|
extends SimpleGenericRepository<T> {
|
||||||
|
|
||||||
T findById(ID id, boolean lock);
|
T findById(ID id, boolean lock);
|
||||||
@@ -938,7 +943,7 @@ public class BridgeMethodResolverTests {
|
|||||||
|
|
||||||
|
|
||||||
public static class GenericHibernateRepository<T, ID extends Serializable>
|
public static class GenericHibernateRepository<T, ID extends Serializable>
|
||||||
implements ConvenientGenericRepository<T, ID> {
|
implements ConvenientGenericRepository<T, ID> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param c Mandatory. The domain class this repository is responsible for.
|
* @param c Mandatory. The domain class this repository is responsible for.
|
||||||
@@ -1018,7 +1023,7 @@ public class BridgeMethodResolverTests {
|
|||||||
// SPR-2603 classes
|
// SPR-2603 classes
|
||||||
//-------------------
|
//-------------------
|
||||||
|
|
||||||
public static interface Homer<E> {
|
public interface Homer<E> {
|
||||||
|
|
||||||
void foo(E e);
|
void foo(E e);
|
||||||
}
|
}
|
||||||
@@ -1043,18 +1048,17 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface GenericDao<T> {
|
public interface GenericDao<T> {
|
||||||
|
|
||||||
public void saveOrUpdate(T t);
|
void saveOrUpdate(T t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface ConvenienceGenericDao<T> extends GenericDao<T> {
|
public interface ConvenienceGenericDao<T> extends GenericDao<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class GenericSqlMapDao<T extends Serializable> implements
|
public static class GenericSqlMapDao<T extends Serializable> implements ConvenienceGenericDao<T> {
|
||||||
ConvenienceGenericDao<T> {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveOrUpdate(T t) {
|
public void saveOrUpdate(T t) {
|
||||||
@@ -1063,8 +1067,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class GenericSqlMapIntegerDao<T extends Number> extends
|
public static class GenericSqlMapIntegerDao<T extends Number> extends GenericSqlMapDao<T> {
|
||||||
GenericSqlMapDao<T> {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveOrUpdate(T t) {
|
public void saveOrUpdate(T t) {
|
||||||
@@ -1080,12 +1083,12 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface UserDao {
|
public interface UserDao {
|
||||||
|
|
||||||
//@Transactional
|
// @Transactional
|
||||||
void save(User user);
|
void save(User user);
|
||||||
|
|
||||||
//@Transactional
|
// @Transactional
|
||||||
void save(Permission perm);
|
void save(Permission perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1112,8 +1115,9 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface DaoInterface<T, P> {
|
public interface DaoInterface<T, P> {
|
||||||
T get(P id);
|
|
||||||
|
T get(P id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1166,13 +1170,13 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface MegaReceiver<E extends MegaEvent> {
|
public interface MegaReceiver<E extends MegaEvent> {
|
||||||
|
|
||||||
void receive(E event);
|
void receive(E event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface MegaMessageProducer extends MegaReceiver<MegaMessageEvent> {
|
public interface MegaMessageProducer extends MegaReceiver<MegaMessageEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1210,7 +1214,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface IGenericInterface<D extends DomainObjectSuper> {
|
public interface IGenericInterface<D extends DomainObjectSuper> {
|
||||||
|
|
||||||
<T> void doSomething(final D domainObject, final T value);
|
<T> void doSomething(final D domainObject, final T value);
|
||||||
}
|
}
|
||||||
@@ -1275,7 +1279,7 @@ public class BridgeMethodResolverTests {
|
|||||||
// SPR-3534 classes
|
// SPR-3534 classes
|
||||||
//-------------------
|
//-------------------
|
||||||
|
|
||||||
public static interface SearchProvider<RETURN_TYPE, CONDITIONS_TYPE> {
|
public interface SearchProvider<RETURN_TYPE, CONDITIONS_TYPE> {
|
||||||
|
|
||||||
Collection<RETURN_TYPE> findBy(CONDITIONS_TYPE conditions);
|
Collection<RETURN_TYPE> findBy(CONDITIONS_TYPE conditions);
|
||||||
}
|
}
|
||||||
@@ -1285,7 +1289,7 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface IExternalMessageProvider<S extends ExternalMessage, T extends ExternalMessageSearchConditions<?>>
|
public interface IExternalMessageProvider<S extends ExternalMessage, T extends ExternalMessageSearchConditions<?>>
|
||||||
extends SearchProvider<S, T> {
|
extends SearchProvider<S, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1328,4 +1332,59 @@ public class BridgeMethodResolverTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------
|
||||||
|
// SPR-16103 classes
|
||||||
|
//-------------------
|
||||||
|
|
||||||
|
public static abstract class BaseEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FooEntity extends BaseEntity {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BaseClass<T> {
|
||||||
|
|
||||||
|
public <S extends T> S test(S T) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EntityClass<T extends BaseEntity> extends BaseClass<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <S extends T> S test(S T) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FooClass extends EntityClass<FooEntity> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <S extends FooEntity> S test(S T) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface BaseInterface<T> {
|
||||||
|
|
||||||
|
<S extends T> S test(S T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface EntityInterface<T extends BaseEntity> extends BaseInterface<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
<S extends T> S test(S T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface FooInterface extends EntityInterface<FooEntity> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
<S extends FooEntity> S test(S T);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user