BridgeMethodResolver properly resolves interface hierarchies

Issue: SPR-16103

(cherry picked from commit 182da15)
This commit is contained in:
Juergen Hoeller
2017-10-24 01:01:49 +02:00
parent db7d71503d
commit 6446ffd063
2 changed files with 166 additions and 95 deletions

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -344,8 +344,26 @@ public class BridgeMethodResolverTests {
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);
@@ -396,7 +414,7 @@ public class BridgeMethodResolverTests {
}
public static interface Adder<T> {
public interface Adder<T> {
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);
@@ -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();
@@ -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
T load();
}
public static interface ConcreteSettingsDao extends
SettingsDao<ConcreteSettings, String> {
public interface ConcreteSettingsDao extends SettingsDao<ConcreteSettings, String> {
@Override
String loadFromParent();
@@ -511,7 +526,7 @@ public class BridgeMethodResolverTests {
this.otherObject = otherObject;
}
//@Transactional(readOnly = true)
// @Transactional(readOnly = true)
@Override
public S loadFromParent() {
return otherObject;
@@ -526,7 +541,7 @@ public class BridgeMethodResolverTests {
super(object, "From Parent");
}
//@Transactional(readOnly = true)
// @Transactional(readOnly = true)
@Override
public ConcreteSettings load() {
return super.object;
@@ -534,7 +549,7 @@ public class BridgeMethodResolverTests {
}
public static interface Bounded<E> {
public interface Bounded<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);
}
@@ -697,7 +712,7 @@ public class BridgeMethodResolverTests {
}
public static interface Event {
public interface Event {
int getPriority();
}
@@ -727,24 +742,19 @@ public class BridgeMethodResolverTests {
}
public static interface UserInitiatedEvent {
//public Session getInitiatorSession();
public interface UserInitiatedEvent {
}
public static abstract class BaseUserInitiatedEvent extends GenericEvent implements
UserInitiatedEvent {
public static abstract class BaseUserInitiatedEvent extends GenericEvent implements UserInitiatedEvent {
}
public static class MessageEvent extends BaseUserInitiatedEvent {
}
public static interface Channel<E extends Event> {
public interface Channel<E extends 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 {
}
@SuppressWarnings({ "unused", "unchecked" })
public static abstract class GenericEventBroadcasterImpl<T extends Event> extends
GenericBroadcasterImpl
implements EventBroadcaster {
public static abstract class GenericEventBroadcasterImpl<T extends Event>
extends GenericBroadcasterImpl implements EventBroadcaster {
private Class<T>[] subscribingEvents;
@@ -802,27 +810,24 @@ public class BridgeMethodResolverTests {
@Override
public void subscribe() {
}
@Override
public void unsubscribe() {
}
public GenericEventBroadcasterImpl(Class<? extends T>... events) {
}
}
public static interface Receiver<E extends Event> {
public interface Receiver<E extends 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")
public static class MessageBroadcasterImpl extends
GenericEventBroadcasterImpl<MessageEvent>
implements MessageBroadcaster {
implements MessageBroadcaster {
public MessageBroadcasterImpl() {
super(NewMessageEvent.class);
@@ -876,7 +881,7 @@ public class BridgeMethodResolverTests {
// SPR-2454 Test Classes
//-----------------------------
public static interface SimpleGenericRepository<T> {
public interface SimpleGenericRepository<T> {
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);
}
@@ -900,7 +905,7 @@ public class BridgeMethodResolverTests {
@SuppressWarnings("unchecked")
public static class SettableRepositoryRegistry<R extends SimpleGenericRepository<?>>
implements RepositoryRegistry {
implements RepositoryRegistry {
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> {
T findById(ID id, boolean lock);
@@ -938,7 +943,7 @@ public class BridgeMethodResolverTests {
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.
@@ -1018,7 +1023,7 @@ public class BridgeMethodResolverTests {
// SPR-2603 classes
//-------------------
public static interface Homer<E> {
public interface Homer<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
ConvenienceGenericDao<T> {
public static class GenericSqlMapDao<T extends Serializable> implements ConvenienceGenericDao<T> {
@Override
public void saveOrUpdate(T t) {
@@ -1063,8 +1067,7 @@ public class BridgeMethodResolverTests {
}
public static class GenericSqlMapIntegerDao<T extends Number> extends
GenericSqlMapDao<T> {
public static class GenericSqlMapIntegerDao<T extends Number> extends GenericSqlMapDao<T> {
@Override
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);
//@Transactional
// @Transactional
void save(Permission perm);
}
@@ -1112,8 +1115,9 @@ public class BridgeMethodResolverTests {
}
public static interface DaoInterface<T, P> {
T get(P id);
public interface DaoInterface<T, P> {
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);
}
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);
}
@@ -1275,7 +1279,7 @@ public class BridgeMethodResolverTests {
// 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);
}
@@ -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> {
}
@@ -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);
}
}