/** * Return class methods ordered with non-bridge methods appearing higher. */ private Method[] getSortedMethods(Class<?> clazz) { return this.sortedMethodsCache.computeIfAbsent(clazz, key -> { Method[] methods = key.getMethods(); Arrays.sort(methods, (o1, o2) -> (o1.isBridge() == o2.isBridge() ? 0 : (o1.isBridge() ? 1 : -1))); return methods; }); }
/** * Returns {@code true} if the supplied '{@code candidateMethod}' can be * consider a validate candidate for the {@link Method} that is {@link Method#isBridge() bridged} * by the supplied {@link Method bridge Method}. This method performs inexpensive * checks and can be used quickly filter for a set of possible matches. */ private static boolean isBridgedCandidateFor(Method candidateMethod, Method bridgeMethod) { return (!candidateMethod.isBridge() && !candidateMethod.equals(bridgeMethod) && candidateMethod.getName().equals(bridgeMethod.getName()) && candidateMethod.getParameterCount() == bridgeMethod.getParameterCount()); }
/** * Determine whether the given method is declared by the user or at least pointing to * a user-declared method. * <p>Checks {@link Method#isSynthetic()} (for implementation methods) as well as the * {@code GroovyObject} interface (for interface methods; on an implementation class, * implementations of the {@code GroovyObject} methods will be marked as synthetic anyway). * Note that, despite being synthetic, bridge methods ({@link Method#isBridge()}) are considered * as user-level methods since they are eventually pointing to a user-declared generic method. * @param method the method to check * @return {@code true} if the method can be considered as user-declared; [@code false} otherwise */ public static boolean isUserLevelMethod(Method method) { Assert.notNull(method, "Method must not be null"); return (method.isBridge() || (!method.isSynthetic() && !isGroovyObjectMethod(method))); }
@Test public void testWithSingleBoundParameterizedOnInstantiate() throws Exception { Method bridgeMethod = DelayQueue.class.getMethod("add", Object.class); assertTrue(bridgeMethod.isBridge()); Method actualMethod = DelayQueue.class.getMethod("add", Delayed.class); assertFalse(actualMethod.isBridge()); assertEquals(actualMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR2763() throws Exception { Method bridgedMethod = AbstractDao.class.getDeclaredMethod("save", Object.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = UserDaoImpl.class.getDeclaredMethod("save", User.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR3041() throws Exception { Method bridgedMethod = BusinessDao.class.getDeclaredMethod("save", Business.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = BusinessDao.class.getDeclaredMethod("save", Object.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR3324() throws Exception { Method bridgedMethod = BusinessDao.class.getDeclaredMethod("get", Long.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = BusinessDao.class.getDeclaredMethod("get", Object.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR3485() throws Exception { Method bridgedMethod = DomainObject.class.getDeclaredMethod( "method2", ParameterType.class, byte[].class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = DomainObject.class.getDeclaredMethod( "method2", Serializable.class, Object.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR3534() throws Exception { Method bridgeMethod = ReflectionUtils.findMethod(TestEmailProvider.class, "findBy", Object.class); assertTrue(bridgeMethod != null && bridgeMethod.isBridge()); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod); assertFalse(bridgedMethod.isBridge()); assertEquals("findBy", bridgedMethod.getName()); }
@Test public void testSPR3173() throws Exception { Method bridgedMethod = UserDaoImpl.class.getDeclaredMethod("saveVararg", User.class, Object[].class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = UserDaoImpl.class.getDeclaredMethod("saveVararg", Object.class, Object[].class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR3357() throws Exception { Method bridgedMethod = ExtendsAbstractImplementsInterface.class.getDeclaredMethod( "doSomething", DomainObjectExtendsSuper.class, Object.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = ExtendsAbstractImplementsInterface.class.getDeclaredMethod( "doSomething", DomainObjectSuper.class, Object.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testFindBridgedMethodFromParent() throws Exception { Method loadFromParentBridge = SettingsDaoImpl.class.getMethod("loadFromParent"); assertTrue(loadFromParentBridge.isBridge()); Method loadFromParent = AbstractDaoImpl.class.getMethod("loadFromParent"); assertFalse(loadFromParent.isBridge()); assertEquals(loadFromParent, BridgeMethodResolver.findBridgedMethod(loadFromParentBridge)); }
@Test public void testWithDoubleBoundParameterizedOnInstantiate() throws Exception { Method bridgeMethod = SerializableBounded.class.getMethod("boundedOperation", Object.class); assertTrue(bridgeMethod.isBridge()); Method actualMethod = SerializableBounded.class.getMethod("boundedOperation", HashMap.class); assertFalse(actualMethod.isBridge()); assertEquals(actualMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testSPR2648() throws Exception { Method bridgeMethod = ReflectionUtils.findMethod(GenericSqlMapIntegerDao.class, "saveOrUpdate", Object.class); assertTrue(bridgeMethod != null && bridgeMethod.isBridge()); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod); assertFalse(bridgedMethod.isBridge()); assertEquals("saveOrUpdate", bridgedMethod.getName()); }
@Test public void testSPR3304() throws Exception { Method bridgedMethod = MegaMessageProducerImpl.class.getDeclaredMethod("receive", MegaMessageEvent.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = MegaMessageProducerImpl.class.getDeclaredMethod("receive", MegaEvent.class); assertTrue(bridgeMethod.isBridge()); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testFindBridgedMethodInHierarchy() throws Exception { Method bridgeMethod = DateAdder.class.getMethod("add", Object.class); assertTrue(bridgeMethod.isBridge()); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(bridgeMethod); assertFalse(bridgedMethod.isBridge()); assertEquals("add", bridgedMethod.getName()); assertEquals(1, bridgedMethod.getParameterCount()); assertEquals(Date.class, bridgedMethod.getParameterTypes()[0]); }
@Test public void testSPR2583() throws Exception { Method bridgedMethod = MessageBroadcasterImpl.class.getMethod("receive", MessageEvent.class); assertFalse(bridgedMethod.isBridge()); Method bridgeMethod = MessageBroadcasterImpl.class.getMethod("receive", Event.class); assertTrue(bridgeMethod.isBridge()); Method otherMethod = MessageBroadcasterImpl.class.getMethod("receive", NewMessageEvent.class); assertFalse(otherMethod.isBridge()); assertFalse("Match identified incorrectly", BridgeMethodResolver.isBridgeMethodFor(bridgeMethod, otherMethod, MessageBroadcasterImpl.class)); assertTrue("Match not found correctly", BridgeMethodResolver.isBridgeMethodFor(bridgeMethod, bridgedMethod, MessageBroadcasterImpl.class)); assertEquals(bridgedMethod, BridgeMethodResolver.findBridgedMethod(bridgeMethod)); }
@Test public void testFindBridgedMethod() throws Exception { Method unbridged = MyFoo.class.getDeclaredMethod("someMethod", String.class, Object.class); Method bridged = MyFoo.class.getDeclaredMethod("someMethod", Serializable.class, Object.class); assertFalse(unbridged.isBridge()); assertTrue(bridged.isBridge()); assertEquals("Unbridged method not returned directly", unbridged, BridgeMethodResolver.findBridgedMethod(unbridged)); assertEquals("Incorrect bridged method returned", unbridged, BridgeMethodResolver.findBridgedMethod(bridged)); }
@Test public void testFindBridgedVarargMethod() throws Exception { Method unbridged = MyFoo.class.getDeclaredMethod("someVarargMethod", String.class, Object[].class); Method bridged = MyFoo.class.getDeclaredMethod("someVarargMethod", Serializable.class, Object[].class); assertFalse(unbridged.isBridge()); assertTrue(bridged.isBridge()); assertEquals("Unbridged method not returned directly", unbridged, BridgeMethodResolver.findBridgedMethod(unbridged)); assertEquals("Incorrect bridged method returned", unbridged, BridgeMethodResolver.findBridgedMethod(bridged)); }
@Test public void findMethodAnnotationOnBridgedMethod() throws Exception { Method bridgedMethod = SimpleFoo.class.getMethod("something", String.class); assertFalse(bridgedMethod.isBridge()); assertNull(bridgedMethod.getAnnotation(Order.class)); assertNull(getAnnotation(bridgedMethod, Order.class)); assertNotNull(findAnnotation(bridgedMethod, Order.class)); assertNotNull(bridgedMethod.getAnnotation(Transactional.class)); assertNotNull(getAnnotation(bridgedMethod, Transactional.class)); assertNotNull(findAnnotation(bridgedMethod, Transactional.class)); }