1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.core;
18
19 import java.io.Serializable;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.ParameterizedType;
22 import java.lang.reflect.Type;
23 import java.lang.reflect.TypeVariable;
24 import java.util.Collection;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Map;
31 import java.util.concurrent.DelayQueue;
32 import java.util.concurrent.Delayed;
33
34 import org.junit.Test;
35
36 import org.springframework.util.ReflectionUtils;
37
38 import static org.junit.Assert.*;
39
40
41
42
43
44
45 public class BridgeMethodResolverTests {
46
47 private static TypeVariable<?> findTypeVariable(Class<?> clazz, String name) {
48 TypeVariable<?>[] variables = clazz.getTypeParameters();
49 for (TypeVariable<?> variable : variables) {
50 if (variable.getName().equals(name)) {
51 return variable;
52 }
53 }
54 return null;
55 }
56
57 private static Method findMethodWithReturnType(String name, Class<?> returnType, Class<SettingsDaoImpl> targetType) {
58 Method[] methods = targetType.getMethods();
59 for (Method m : methods) {
60 if (m.getName().equals(name) && m.getReturnType().equals(returnType)) {
61 return m;
62 }
63 }
64 return null;
65 }
66
67
68 @Test
69 public void testFindBridgedMethod() throws Exception {
70 Method unbridged = MyFoo.class.getDeclaredMethod("someMethod", String.class, Object.class);
71 Method bridged = MyFoo.class.getDeclaredMethod("someMethod", Serializable.class, Object.class);
72 assertFalse(unbridged.isBridge());
73 assertTrue(bridged.isBridge());
74
75 assertEquals("Unbridged method not returned directly", unbridged, BridgeMethodResolver.findBridgedMethod(unbridged));
76 assertEquals("Incorrect bridged method returned", unbridged, BridgeMethodResolver.findBridgedMethod(bridged));
77 }
78
79 @Test
80 public void testFindBridgedVarargMethod() throws Exception {
81 Method unbridged = MyFoo.class.getDeclaredMethod("someVarargMethod", String.class, Object[].class);
82 Method bridged = MyFoo.class.getDeclaredMethod("someVarargMethod", Serializable.class, Object[].class);
83 assertFalse(unbridged.isBridge());
84 assertTrue(bridged.isBridge());
85
86 assertEquals("Unbridged method not returned directly", unbridged, BridgeMethodResolver.findBridgedMethod(unbridged));
87 assertEquals("Incorrect bridged method returned", unbridged, BridgeMethodResolver.findBridgedMethod(bridged));
88 }
89
90 @Test
91 public void testFindBridgedMethodInHierarchy() throws Exception {
92 Method bridgeMethod = DateAdder.class.getMethod("add", Object.class);
93 assertTrue(bridgeMethod.isBridge());
94 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod);
95 assertFalse(bridgedMethod.isBridge());
96 assertEquals("add", bridgedMethod.getName());
97 assertEquals(1, bridgedMethod.getParameterTypes().length);
98 assertEquals(Date.class, bridgedMethod.getParameterTypes()[0]);
99 }
100
101 @Test
102 public void testIsBridgeMethodFor() throws Exception {
103 Method bridged = MyBar.class.getDeclaredMethod("someMethod", String.class, Object.class);
104 Method other = MyBar.class.getDeclaredMethod("someMethod", Integer.class, Object.class);
105 Method bridge = MyBar.class.getDeclaredMethod("someMethod", Object.class, Object.class);
106
107 assertTrue("Should be bridge method", BridgeMethodResolver.isBridgeMethodFor(bridge, bridged, MyBar.class));
108 assertFalse("Should not be bridge method", BridgeMethodResolver.isBridgeMethodFor(bridge, other, MyBar.class));
109 }
110
111 @Test
112 @Deprecated
113 public void testCreateTypeVariableMap() throws Exception {
114 Map<TypeVariable, Type> typeVariableMap = GenericTypeResolver.getTypeVariableMap(MyBar.class);
115 TypeVariable<?> barT = findTypeVariable(InterBar.class, "T");
116 assertEquals(String.class, typeVariableMap.get(barT));
117
118 typeVariableMap = GenericTypeResolver.getTypeVariableMap(MyFoo.class);
119 TypeVariable<?> fooT = findTypeVariable(Foo.class, "T");
120 assertEquals(String.class, typeVariableMap.get(fooT));
121
122 typeVariableMap = GenericTypeResolver.getTypeVariableMap(ExtendsEnclosing.ExtendsEnclosed.ExtendsReallyDeepNow.class);
123 TypeVariable<?> r = findTypeVariable(Enclosing.Enclosed.ReallyDeepNow.class, "R");
124 TypeVariable<?> s = findTypeVariable(Enclosing.Enclosed.class, "S");
125 TypeVariable<?> t = findTypeVariable(Enclosing.class, "T");
126 assertEquals(Long.class, typeVariableMap.get(r));
127 assertEquals(Integer.class, typeVariableMap.get(s));
128 assertEquals(String.class, typeVariableMap.get(t));
129 }
130
131 @Test
132 public void testDoubleParameterization() throws Exception {
133 Method objectBridge = MyBoo.class.getDeclaredMethod("foo", Object.class);
134 Method serializableBridge = MyBoo.class.getDeclaredMethod("foo", Serializable.class);
135
136 Method stringFoo = MyBoo.class.getDeclaredMethod("foo", String.class);
137 Method integerFoo = MyBoo.class.getDeclaredMethod("foo", Integer.class);
138
139 assertEquals("foo(String) not resolved.", stringFoo, BridgeMethodResolver.findBridgedMethod(objectBridge));
140 assertEquals("foo(Integer) not resolved.", integerFoo, BridgeMethodResolver.findBridgedMethod(serializableBridge));
141 }
142
143 @Test
144 public void testFindBridgedMethodFromMultipleBridges() throws Exception {
145 Method loadWithObjectReturn = findMethodWithReturnType("load", Object.class, SettingsDaoImpl.class);
146 assertNotNull(loadWithObjectReturn);
147
148 Method loadWithSettingsReturn = findMethodWithReturnType("load", Settings.class, SettingsDaoImpl.class);
149 assertNotNull(loadWithSettingsReturn);
150 assertNotSame(loadWithObjectReturn, loadWithSettingsReturn);
151
152 Method method = SettingsDaoImpl.class.getMethod("load");
153 assertEquals(method, BridgeMethodResolver.findBridgedMethod(loadWithObjectReturn));
154 assertEquals(method, BridgeMethodResolver.findBridgedMethod(loadWithSettingsReturn));
155 }
156
157 @Test
158 public void testFindBridgedMethodFromParent() throws Exception {
159 Method loadFromParentBridge = SettingsDaoImpl.class.getMethod("loadFromParent");
160 assertTrue(loadFromParentBridge.isBridge());
161
162 Method loadFromParent = AbstractDaoImpl.class.getMethod("loadFromParent");
163 assertFalse(loadFromParent.isBridge());
164
165 assertEquals(loadFromParent, BridgeMethodResolver.findBridgedMethod(loadFromParentBridge));
166 }
167
168 @Test
169 public void testWithSingleBoundParameterizedOnInstantiate() throws Exception {
170 Method bridgeMethod = DelayQueue.class.getMethod("add", Object.class);
171 assertTrue(bridgeMethod.isBridge());
172 Method actualMethod = DelayQueue.class.getMethod("add", Delayed.class);
173 assertFalse(actualMethod.isBridge());
174 assertEquals(actualMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
175 }
176
177 @Test
178 public void testWithDoubleBoundParameterizedOnInstantiate() throws Exception {
179 Method bridgeMethod = SerializableBounded.class.getMethod("boundedOperation", Object.class);
180 assertTrue(bridgeMethod.isBridge());
181 Method actualMethod = SerializableBounded.class.getMethod("boundedOperation", HashMap.class);
182 assertFalse(actualMethod.isBridge());
183 assertEquals(actualMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
184 }
185
186 @Test
187 public void testWithGenericParameter() throws Exception {
188 Method[] methods = StringGenericParameter.class.getMethods();
189 Method bridgeMethod = null;
190 Method bridgedMethod = null;
191 for (Method method : methods) {
192 if ("getFor".equals(method.getName()) && !method.getParameterTypes()[0].equals(Integer.class)) {
193 if (method.getReturnType().equals(Object.class)) {
194 bridgeMethod = method;
195 }
196 else {
197 bridgedMethod = method;
198 }
199 }
200 }
201 assertTrue(bridgeMethod != null && bridgeMethod.isBridge());
202 assertTrue(bridgedMethod != null && !bridgedMethod.isBridge());
203 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
204 }
205
206 @Test
207 public void testOnAllMethods() throws Exception {
208 Method[] methods = StringList.class.getMethods();
209 for (Method method : methods) {
210 assertNotNull(BridgeMethodResolver.findBridgedMethod(method));
211 }
212 }
213
214 @Test
215 public void testSPR2583() throws Exception {
216 Method bridgedMethod = MessageBroadcasterImpl.class.getMethod("receive", MessageEvent.class);
217 assertFalse(bridgedMethod.isBridge());
218 Method bridgeMethod = MessageBroadcasterImpl.class.getMethod("receive", Event.class);
219 assertTrue(bridgeMethod.isBridge());
220
221 Method otherMethod = MessageBroadcasterImpl.class.getMethod("receive", NewMessageEvent.class);
222 assertFalse(otherMethod.isBridge());
223
224 assertFalse("Match identified incorrectly", BridgeMethodResolver.isBridgeMethodFor(bridgeMethod, otherMethod, MessageBroadcasterImpl.class));
225 assertTrue("Match not found correctly", BridgeMethodResolver.isBridgeMethodFor(bridgeMethod, bridgedMethod, MessageBroadcasterImpl.class));
226
227 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
228 }
229
230 @Test
231 @Deprecated
232 public void testSPR2454() throws Exception {
233 Map<TypeVariable, Type> typeVariableMap = GenericTypeResolver.getTypeVariableMap(YourHomer.class);
234 TypeVariable<?> variable = findTypeVariable(MyHomer.class, "L");
235 assertEquals(AbstractBounded.class, ((ParameterizedType) typeVariableMap.get(variable)).getRawType());
236 }
237
238 @Test
239 public void testSPR2603() throws Exception {
240 Method objectBridge = YourHomer.class.getDeclaredMethod("foo", Bounded.class);
241 Method abstractBoundedFoo = YourHomer.class.getDeclaredMethod("foo", AbstractBounded.class);
242
243 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(objectBridge);
244 assertEquals("foo(AbstractBounded) not resolved.", abstractBoundedFoo, bridgedMethod);
245 }
246
247 @Test
248 public void testSPR2648() throws Exception {
249 Method bridgeMethod = ReflectionUtils.findMethod(GenericSqlMapIntegerDao.class, "saveOrUpdate", Object.class);
250 assertTrue(bridgeMethod != null && bridgeMethod.isBridge());
251 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod);
252 assertFalse(bridgedMethod.isBridge());
253 assertEquals("saveOrUpdate", bridgedMethod.getName());
254 }
255
256 @Test
257 public void testSPR2763() throws Exception {
258 Method bridgedMethod = AbstractDao.class.getDeclaredMethod("save", Object.class);
259 assertFalse(bridgedMethod.isBridge());
260
261 Method bridgeMethod = UserDaoImpl.class.getDeclaredMethod("save", User.class);
262 assertTrue(bridgeMethod.isBridge());
263
264 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
265 }
266
267 @Test
268 public void testSPR3041() throws Exception {
269 Method bridgedMethod = BusinessDao.class.getDeclaredMethod("save", Business.class);
270 assertFalse(bridgedMethod.isBridge());
271
272 Method bridgeMethod = BusinessDao.class.getDeclaredMethod("save", Object.class);
273 assertTrue(bridgeMethod.isBridge());
274
275 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
276 }
277
278 @Test
279 public void testSPR3173() throws Exception {
280 Method bridgedMethod = UserDaoImpl.class.getDeclaredMethod("saveVararg", User.class, Object[].class);
281 assertFalse(bridgedMethod.isBridge());
282
283 Method bridgeMethod = UserDaoImpl.class.getDeclaredMethod("saveVararg", Object.class, Object[].class);
284 assertTrue(bridgeMethod.isBridge());
285
286 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
287 }
288
289 @Test
290 public void testSPR3304() throws Exception {
291 Method bridgedMethod = MegaMessageProducerImpl.class.getDeclaredMethod("receive", MegaMessageEvent.class);
292 assertFalse(bridgedMethod.isBridge());
293
294 Method bridgeMethod = MegaMessageProducerImpl.class.getDeclaredMethod("receive", MegaEvent.class);
295 assertTrue(bridgeMethod.isBridge());
296
297 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
298 }
299
300 @Test
301 public void testSPR3324() throws Exception {
302 Method bridgedMethod = BusinessDao.class.getDeclaredMethod("get", Long.class);
303 assertFalse(bridgedMethod.isBridge());
304
305 Method bridgeMethod = BusinessDao.class.getDeclaredMethod("get", Object.class);
306 assertTrue(bridgeMethod.isBridge());
307
308 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
309 }
310
311 @Test
312 public void testSPR3357() throws Exception {
313 Method bridgedMethod = ExtendsAbstractImplementsInterface.class.getDeclaredMethod(
314 "doSomething", DomainObjectExtendsSuper.class, Object.class);
315 assertFalse(bridgedMethod.isBridge());
316
317 Method bridgeMethod = ExtendsAbstractImplementsInterface.class.getDeclaredMethod(
318 "doSomething", DomainObjectSuper.class, Object.class);
319 assertTrue(bridgeMethod.isBridge());
320
321 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
322 }
323
324 @Test
325 public void testSPR3485() throws Exception {
326 Method bridgedMethod = DomainObject.class.getDeclaredMethod(
327 "method2", ParameterType.class, byte[].class);
328 assertFalse(bridgedMethod.isBridge());
329
330 Method bridgeMethod = DomainObject.class.getDeclaredMethod(
331 "method2", Serializable.class, Object.class);
332 assertTrue(bridgeMethod.isBridge());
333
334 assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod));
335 }
336
337 @Test
338 public void testSPR3534() throws Exception {
339 Method bridgeMethod = ReflectionUtils.findMethod(TestEmailProvider.class, "findBy", Object.class);
340 assertTrue(bridgeMethod != null && bridgeMethod.isBridge());
341 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod);
342 assertFalse(bridgedMethod.isBridge());
343 assertEquals("findBy", bridgedMethod.getName());
344 }
345
346
347 public static interface Foo<T extends Serializable> {
348
349 void someMethod(T theArg, Object otherArg);
350
351 void someVarargMethod(T theArg, Object... otherArg);
352 }
353
354
355 public static class MyFoo implements Foo<String> {
356
357 public void someMethod(Integer theArg, Object otherArg) {
358 }
359
360 @Override
361 public void someMethod(String theArg, Object otherArg) {
362 }
363
364 @Override
365 public void someVarargMethod(String theArg, Object... otherArgs) {
366 }
367 }
368
369
370 public static abstract class Bar<T> {
371
372 void someMethod(Map<?, ?> m, Object otherArg) {
373 }
374
375 void someMethod(T theArg, Map<?, ?> m) {
376 }
377
378 abstract void someMethod(T theArg, Object otherArg);
379 }
380
381
382 public static abstract class InterBar<T> extends Bar<T> {
383
384 }
385
386
387 public static class MyBar extends InterBar<String> {
388
389 @Override
390 public void someMethod(String theArg, Object otherArg) {
391 }
392
393 public void someMethod(Integer theArg, Object otherArg) {
394 }
395 }
396
397
398 public static interface Adder<T> {
399
400 void add(T item);
401 }
402
403
404 public static abstract class AbstractDateAdder implements Adder<Date> {
405
406 @Override
407 public abstract void add(Date date);
408 }
409
410
411 public static class DateAdder extends AbstractDateAdder {
412
413 @Override
414 public void add(Date date) {
415 }
416 }
417
418
419 public static class Enclosing<T> {
420
421 public class Enclosed<S> {
422
423 public class ReallyDeepNow<R> {
424
425 void someMethod(S s, T t, R r) {
426 }
427 }
428 }
429 }
430
431
432 public static class ExtendsEnclosing extends Enclosing<String> {
433
434 public class ExtendsEnclosed extends Enclosed<Integer> {
435
436 public class ExtendsReallyDeepNow extends ReallyDeepNow<Long> {
437
438 @Override
439 void someMethod(Integer s, String t, Long r) {
440 throw new UnsupportedOperationException();
441 }
442 }
443 }
444 }
445
446
447 public static interface Boo<E, T extends Serializable> {
448
449 void foo(E e);
450
451 void foo(T t);
452 }
453
454
455 public static class MyBoo implements Boo<String, Integer> {
456
457 @Override
458 public void foo(String e) {
459 throw new UnsupportedOperationException();
460 }
461
462 @Override
463 public void foo(Integer t) {
464 throw new UnsupportedOperationException();
465 }
466 }
467
468
469 public static interface Settings {
470
471 }
472
473
474 public static interface ConcreteSettings extends Settings {
475
476 }
477
478
479 public static interface Dao<T, S> {
480
481 T load();
482
483 S loadFromParent();
484 }
485
486
487 public static interface SettingsDao<T extends Settings, S> extends Dao<T, S> {
488
489 @Override
490 T load();
491 }
492
493
494 public static interface ConcreteSettingsDao extends
495 SettingsDao<ConcreteSettings, String> {
496
497 @Override
498 String loadFromParent();
499 }
500
501
502 static abstract class AbstractDaoImpl<T, S> implements Dao<T, S> {
503
504 protected T object;
505
506 protected S otherObject;
507
508 protected AbstractDaoImpl(T object, S otherObject) {
509 this.object = object;
510 this.otherObject = otherObject;
511 }
512
513
514 @Override
515 public S loadFromParent() {
516 return otherObject;
517 }
518 }
519
520
521 static class SettingsDaoImpl extends AbstractDaoImpl<ConcreteSettings, String>
522 implements ConcreteSettingsDao {
523
524 protected SettingsDaoImpl(ConcreteSettings object) {
525 super(object, "From Parent");
526 }
527
528
529 @Override
530 public ConcreteSettings load() {
531 return super.object;
532 }
533 }
534
535
536 public static interface Bounded<E> {
537
538 boolean boundedOperation(E e);
539 }
540
541
542 private static class AbstractBounded<E> implements Bounded<E> {
543
544 @Override
545 public boolean boundedOperation(E myE) {
546 return true;
547 }
548 }
549
550
551 private static class SerializableBounded<E extends HashMap & Delayed> extends AbstractBounded<E> {
552
553 @Override
554 public boolean boundedOperation(E myE) {
555 return false;
556 }
557 }
558
559
560 public static interface GenericParameter<T> {
561
562 T getFor(Class<T> cls);
563 }
564
565
566 @SuppressWarnings("unused")
567 private static class StringGenericParameter implements GenericParameter<String> {
568
569 @Override
570 public String getFor(Class<String> cls) {
571 return "foo";
572 }
573
574 public String getFor(Integer integer) {
575 return "foo";
576 }
577 }
578
579
580 private static class StringList implements List<String> {
581
582 @Override
583 public int size() {
584 throw new UnsupportedOperationException();
585 }
586
587 @Override
588 public boolean isEmpty() {
589 throw new UnsupportedOperationException();
590 }
591
592 @Override
593 public boolean contains(Object o) {
594 throw new UnsupportedOperationException();
595 }
596
597 @Override
598 public Iterator<String> iterator() {
599 throw new UnsupportedOperationException();
600 }
601
602 @Override
603 public Object[] toArray() {
604 throw new UnsupportedOperationException();
605 }
606
607 @Override
608 public <T> T[] toArray(T[] a) {
609 throw new UnsupportedOperationException();
610 }
611
612 @Override
613 public boolean add(String o) {
614 throw new UnsupportedOperationException();
615 }
616
617 @Override
618 public boolean remove(Object o) {
619 throw new UnsupportedOperationException();
620 }
621
622 @Override
623 public boolean containsAll(Collection<?> c) {
624 throw new UnsupportedOperationException();
625 }
626
627 @Override
628 public boolean addAll(Collection<? extends String> c) {
629 throw new UnsupportedOperationException();
630 }
631
632 @Override
633 public boolean addAll(int index, Collection<? extends String> c) {
634 throw new UnsupportedOperationException();
635 }
636
637 @Override
638 public boolean removeAll(Collection<?> c) {
639 throw new UnsupportedOperationException();
640 }
641
642 @Override
643 public boolean retainAll(Collection<?> c) {
644 throw new UnsupportedOperationException();
645 }
646
647 @Override
648 public void clear() {
649 throw new UnsupportedOperationException();
650 }
651
652 @Override
653 public String get(int index) {
654 throw new UnsupportedOperationException();
655 }
656
657 @Override
658 public String set(int index, String element) {
659 throw new UnsupportedOperationException();
660 }
661
662 @Override
663 public void add(int index, String element) {
664 throw new UnsupportedOperationException();
665 }
666
667 @Override
668 public String remove(int index) {
669 throw new UnsupportedOperationException();
670 }
671
672 @Override
673 public int indexOf(Object o) {
674 throw new UnsupportedOperationException();
675 }
676
677 @Override
678 public int lastIndexOf(Object o) {
679 throw new UnsupportedOperationException();
680 }
681
682 @Override
683 public ListIterator<String> listIterator() {
684 throw new UnsupportedOperationException();
685 }
686
687 @Override
688 public ListIterator<String> listIterator(int index) {
689 throw new UnsupportedOperationException();
690 }
691
692 @Override
693 public List<String> subList(int fromIndex, int toIndex) {
694 throw new UnsupportedOperationException();
695 }
696 }
697
698
699 public static interface Event {
700
701 int getPriority();
702 }
703
704
705 public static class GenericEvent implements Event {
706
707 private int priority;
708
709 @Override
710 public int getPriority() {
711 return priority;
712 }
713
714
715
716
717 public GenericEvent(int priority) {
718 this.priority = priority;
719 }
720
721
722
723
724 public GenericEvent() {
725 }
726 }
727
728
729 public static interface UserInitiatedEvent {
730
731
732 }
733
734
735 public static abstract class BaseUserInitiatedEvent extends GenericEvent implements
736 UserInitiatedEvent {
737
738 }
739
740
741 public static class MessageEvent extends BaseUserInitiatedEvent {
742
743 }
744
745
746 public static interface Channel<E extends Event> {
747
748 void send(E event);
749
750 void subscribe(final Receiver<E> receiver, Class<E> event);
751
752 void unsubscribe(final Receiver<E> receiver, Class<E> event);
753 }
754
755
756 public static interface Broadcaster {
757 }
758
759
760 public static interface EventBroadcaster extends Broadcaster {
761
762 public void subscribe();
763
764 public void unsubscribe();
765
766 public void setChannel(Channel<?> channel);
767 }
768
769
770 public static class GenericBroadcasterImpl implements Broadcaster {
771
772 }
773
774
775 @SuppressWarnings({ "unused", "unchecked" })
776 public static abstract class GenericEventBroadcasterImpl<T extends Event> extends
777 GenericBroadcasterImpl
778 implements EventBroadcaster {
779
780 private Class<T>[] subscribingEvents;
781
782 private Channel<T> channel;
783
784
785
786
787
788
789 public abstract Receiver<T> getInstance();
790
791 @Override
792 public void setChannel(Channel channel) {
793 this.channel = channel;
794 }
795
796 private String beanName;
797
798 public void setBeanName(String name) {
799 this.beanName = name;
800 }
801
802 @Override
803 public void subscribe() {
804
805 }
806
807 @Override
808 public void unsubscribe() {
809
810 }
811
812 public GenericEventBroadcasterImpl(Class<? extends T>... events) {
813
814 }
815 }
816
817
818 public static interface Receiver<E extends Event> {
819
820 void receive(E event);
821 }
822
823
824 public static interface MessageBroadcaster extends Receiver<MessageEvent> {
825
826 }
827
828
829 public static class RemovedMessageEvent extends MessageEvent {
830
831 }
832
833
834 public static class NewMessageEvent extends MessageEvent {
835
836 }
837
838
839 public static class ModifiedMessageEvent extends MessageEvent {
840
841 }
842
843
844 @SuppressWarnings("unchecked")
845 public static class MessageBroadcasterImpl extends
846 GenericEventBroadcasterImpl<MessageEvent>
847 implements MessageBroadcaster {
848
849 public MessageBroadcasterImpl() {
850 super(NewMessageEvent.class);
851 }
852
853 @Override
854 public void receive(MessageEvent event) {
855 throw new UnsupportedOperationException("should not be called, use subclassed events");
856 }
857
858 public void receive(NewMessageEvent event) {
859 }
860
861 @Override
862 public Receiver<MessageEvent> getInstance() {
863 return null;
864 }
865
866 public void receive(RemovedMessageEvent event) {
867 }
868
869 public void receive(ModifiedMessageEvent event) {
870 }
871 }
872
873
874
875
876
877
878 public static interface SimpleGenericRepository<T> {
879
880 public Class<T> getPersistentClass();
881
882 List<T> findByQuery();
883
884 List<T> findAll();
885
886 T refresh(T entity);
887
888 T saveOrUpdate(T entity);
889
890 void delete(Collection<T> entities);
891 }
892
893
894 public static interface RepositoryRegistry {
895
896 <T> SimpleGenericRepository<T> getFor(Class<T> entityType);
897 }
898
899
900 @SuppressWarnings("unchecked")
901 public static class SettableRepositoryRegistry<R extends SimpleGenericRepository<?>>
902 implements RepositoryRegistry {
903
904 protected void injectInto(R rep) {
905 }
906
907 public void register(R rep) {
908 }
909
910 public void register(R... reps) {
911 }
912
913 public void setRepos(R... reps) {
914 }
915
916 @Override
917 public <T> SimpleGenericRepository<T> getFor(Class<T> entityType) {
918 return null;
919 }
920
921 public void afterPropertiesSet() throws Exception {
922 }
923 }
924
925
926 public static interface ConvenientGenericRepository<T, ID extends Serializable>
927 extends SimpleGenericRepository<T> {
928
929 T findById(ID id, boolean lock);
930
931 List<T> findByExample(T exampleInstance);
932
933 void delete(ID id);
934
935 void delete(T entity);
936 }
937
938
939 public static class GenericHibernateRepository<T, ID extends Serializable>
940 implements ConvenientGenericRepository<T, ID> {
941
942
943
944
945
946
947
948
949
950 public void setPersistentClass(Class<T> c) {
951 }
952
953 @Override
954 public Class<T> getPersistentClass() {
955 return null;
956 }
957
958 @Override
959 public T findById(ID id, boolean lock) {
960 return null;
961 }
962
963 @Override
964 public List<T> findAll() {
965 return null;
966 }
967
968 @Override
969 public List<T> findByExample(T exampleInstance) {
970 return null;
971 }
972
973 @Override
974 public List<T> findByQuery() {
975 return null;
976 }
977
978 @Override
979 public T saveOrUpdate(T entity) {
980 return null;
981 }
982
983 @Override
984 public void delete(T entity) {
985 }
986
987 @Override
988 public T refresh(T entity) {
989 return null;
990 }
991
992 @Override
993 public void delete(ID id) {
994 }
995
996 @Override
997 public void delete(Collection<T> entities) {
998 }
999 }
1000
1001
1002 public static class HibernateRepositoryRegistry extends
1003 SettableRepositoryRegistry<GenericHibernateRepository<?, ?>> {
1004
1005 @Override
1006 public void injectInto(GenericHibernateRepository<?, ?> rep) {
1007 }
1008
1009 @Override
1010 public <T> GenericHibernateRepository<T, ?> getFor(Class<T> entityType) {
1011 return null;
1012 }
1013 }
1014
1015
1016
1017
1018
1019
1020 public static interface Homer<E> {
1021
1022 void foo(E e);
1023 }
1024
1025
1026 public static class MyHomer<T extends Bounded<T>, L extends T> implements Homer<L> {
1027
1028 @Override
1029 public void foo(L t) {
1030 throw new UnsupportedOperationException();
1031 }
1032 }
1033
1034
1035 public static class YourHomer<T extends AbstractBounded<T>, L extends T> extends
1036 MyHomer<T, L> {
1037
1038 @Override
1039 public void foo(L t) {
1040 throw new UnsupportedOperationException();
1041 }
1042 }
1043
1044
1045 public static interface GenericDao<T> {
1046
1047 public void saveOrUpdate(T t);
1048 }
1049
1050
1051 public static interface ConvenienceGenericDao<T> extends GenericDao<T> {
1052 }
1053
1054
1055 public static class GenericSqlMapDao<T extends Serializable> implements
1056 ConvenienceGenericDao<T> {
1057
1058 @Override
1059 public void saveOrUpdate(T t) {
1060 throw new UnsupportedOperationException();
1061 }
1062 }
1063
1064
1065 public static class GenericSqlMapIntegerDao<T extends Number> extends
1066 GenericSqlMapDao<T> {
1067
1068 @Override
1069 public void saveOrUpdate(T t) {
1070 }
1071 }
1072
1073
1074 public static class Permission {
1075 }
1076
1077
1078 public static class User {
1079 }
1080
1081
1082 public static interface UserDao {
1083
1084
1085 void save(User user);
1086
1087
1088 void save(Permission perm);
1089 }
1090
1091
1092 public static abstract class AbstractDao<T> {
1093
1094 public void save(T t) {
1095 }
1096
1097 public void saveVararg(T t, Object... args) {
1098 }
1099 }
1100
1101
1102 public static class UserDaoImpl extends AbstractDao<User> implements UserDao {
1103
1104 @Override
1105 public void save(Permission perm) {
1106 }
1107
1108 @Override
1109 public void saveVararg(User user, Object... args) {
1110 }
1111 }
1112
1113
1114 public static interface DaoInterface<T, P> {
1115 T get(P id);
1116 }
1117
1118
1119 public static abstract class BusinessGenericDao<T, PK extends Serializable>
1120 implements DaoInterface<T, PK> {
1121
1122 public void save(T object) {
1123 }
1124 }
1125
1126
1127 public static class Business<T> {
1128 }
1129
1130
1131 public static class BusinessDao extends BusinessGenericDao<Business<?>, Long> {
1132
1133 @Override
1134 public void save(Business<?> business) {
1135 }
1136
1137 @Override
1138 public Business<?> get(Long id) {
1139 return null;
1140 }
1141
1142 public Business<?> get(String code) {
1143 return null;
1144 }
1145 }
1146
1147
1148
1149
1150
1151
1152 private static class MegaEvent {
1153 }
1154
1155
1156 private static class MegaMessageEvent extends MegaEvent {
1157 }
1158
1159
1160 private static class NewMegaMessageEvent extends MegaEvent {
1161 }
1162
1163
1164 private static class ModifiedMegaMessageEvent extends MegaEvent {
1165 }
1166
1167
1168 public static interface MegaReceiver<E extends MegaEvent> {
1169
1170 void receive(E event);
1171 }
1172
1173
1174 public static interface MegaMessageProducer extends MegaReceiver<MegaMessageEvent> {
1175 }
1176
1177
1178 private static class Other<S,E> {
1179 }
1180
1181
1182 @SuppressWarnings("unused")
1183 private static class MegaMessageProducerImpl extends Other<Long, String> implements MegaMessageProducer {
1184
1185 public void receive(NewMegaMessageEvent event) {
1186 throw new UnsupportedOperationException();
1187 }
1188
1189 public void receive(ModifiedMegaMessageEvent event) {
1190 throw new UnsupportedOperationException();
1191 }
1192
1193 @Override
1194 public void receive(MegaMessageEvent event) {
1195 throw new UnsupportedOperationException();
1196 }
1197 }
1198
1199
1200
1201
1202
1203
1204 private static class DomainObjectSuper {
1205 }
1206
1207
1208 private static class DomainObjectExtendsSuper extends DomainObjectSuper {
1209 }
1210
1211
1212 public static interface IGenericInterface<D extends DomainObjectSuper> {
1213
1214 <T> void doSomething(final D domainObject, final T value);
1215 }
1216
1217
1218 @SuppressWarnings("unused")
1219 private static abstract class AbstractImplementsInterface<D extends DomainObjectSuper> implements IGenericInterface<D> {
1220
1221 @Override
1222 public <T> void doSomething(D domainObject, T value) {
1223 }
1224
1225 public void anotherBaseMethod() {
1226 }
1227 }
1228
1229
1230 private static class ExtendsAbstractImplementsInterface extends AbstractImplementsInterface<DomainObjectExtendsSuper> {
1231
1232 @Override
1233 public <T> void doSomething(DomainObjectExtendsSuper domainObject, T value) {
1234 super.doSomething(domainObject, value);
1235 }
1236 }
1237
1238
1239
1240
1241
1242
1243 @SuppressWarnings("serial")
1244 private static class ParameterType implements Serializable {
1245 }
1246
1247
1248 private static class AbstractDomainObject<P extends Serializable, R> {
1249
1250 public R method1(P p) {
1251 return null;
1252 }
1253
1254 public void method2(P p, R r) {
1255 }
1256 }
1257
1258
1259 private static class DomainObject extends AbstractDomainObject<ParameterType, byte[]> {
1260
1261 @Override
1262 public byte[] method1(ParameterType p) {
1263 return super.method1(p);
1264 }
1265
1266 @Override
1267 public void method2(ParameterType p, byte[] r) {
1268 super.method2(p, r);
1269 }
1270 }
1271
1272
1273
1274
1275
1276
1277 public static interface SearchProvider<RETURN_TYPE, CONDITIONS_TYPE> {
1278
1279 Collection<RETURN_TYPE> findBy(CONDITIONS_TYPE conditions);
1280 }
1281
1282
1283 public static class SearchConditions {
1284 }
1285
1286
1287 public static interface IExternalMessageProvider<S extends ExternalMessage, T extends ExternalMessageSearchConditions<?>>
1288 extends SearchProvider<S, T> {
1289 }
1290
1291
1292 public static class ExternalMessage {
1293 }
1294
1295
1296 public static class ExternalMessageSearchConditions<T extends ExternalMessage> extends SearchConditions {
1297 }
1298
1299
1300 public static class ExternalMessageProvider<S extends ExternalMessage, T extends ExternalMessageSearchConditions<S>>
1301 implements IExternalMessageProvider<S, T> {
1302
1303 @Override
1304 public Collection<S> findBy(T conditions) {
1305 return null;
1306 }
1307 }
1308
1309
1310 public static class EmailMessage extends ExternalMessage {
1311 }
1312
1313
1314 public static class EmailSearchConditions extends ExternalMessageSearchConditions<EmailMessage> {
1315 }
1316
1317
1318 public static class EmailMessageProvider extends ExternalMessageProvider<EmailMessage, EmailSearchConditions> {
1319 }
1320
1321
1322 public static class TestEmailProvider extends EmailMessageProvider {
1323
1324 @Override
1325 public Collection<EmailMessage> findBy(EmailSearchConditions conditions) {
1326 return null;
1327 }
1328 }
1329
1330 }