Repository: incubator-juneau
Updated Branches:
  refs/heads/master d94d89db6 -> 3551f4c9c


Fix issue where annotations were not being found on parent classes.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/3551f4c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/3551f4c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/3551f4c9

Branch: refs/heads/master
Commit: 3551f4c9ca19a72186385c55f9e93f79148a18e8
Parents: d94d89d
Author: JamesBognar <[email protected]>
Authored: Fri Jun 2 17:16:57 2017 -0400
Committer: JamesBognar <[email protected]>
Committed: Fri Jun 2 17:16:57 2017 -0400

----------------------------------------------------------------------
 .../org/apache/juneau/utils/ClassUtilsTest.java | 50 ++++++++++++++++
 .../main/java/org/apache/juneau/BeanMeta.java   | 12 ++--
 .../org/apache/juneau/internal/ClassUtils.java  | 61 +++++++++++++-------
 .../main/javadoc/resources/icons/LICENSE.txt    | 14 +++++
 .../juneau/rest/test/RequestBeanProxyTest.java  | 45 ++++++++++++---
 5 files changed, 147 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/3551f4c9/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
index 688c2bc..8b5ad42 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
@@ -12,9 +12,14 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.utils;
 
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
 import static org.apache.juneau.internal.ClassUtils.*;
 import static org.junit.Assert.*;
 
+import java.lang.annotation.*;
+
+import org.apache.juneau.internal.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")
@@ -148,4 +153,49 @@ public class ClassUtilsTest {
 
                public void m5(int f1, CharSequence f2) {}
        }
+       
+       
+       
//====================================================================================================
+       // getMethodAnnotation
+       
//====================================================================================================
+       @Test
+       public void getMethodAnnotation() throws Exception {
+               assertEquals("a1", 
ClassUtils.getMethodAnnotation(TestAnnotation.class, 
CI3.class.getMethod("a1")).value());
+               assertEquals("a2b", 
ClassUtils.getMethodAnnotation(TestAnnotation.class, 
CI3.class.getMethod("a2")).value());
+               assertEquals("a3", 
ClassUtils.getMethodAnnotation(TestAnnotation.class, CI3.class.getMethod("a3", 
CharSequence.class)).value());
+               assertEquals("a4", 
ClassUtils.getMethodAnnotation(TestAnnotation.class, 
CI3.class.getMethod("a4")).value());
+       }
+       
+       public static interface CI1 {
+               @TestAnnotation("a1")
+               void a1();
+               @TestAnnotation("a2a")
+               void a2();
+               @TestAnnotation("a3")
+               void a3(CharSequence foo);
+               
+               void a4();
+       }
+       
+       public static class CI2 implements CI1 {
+               public void a1() {}
+               @TestAnnotation("a2b")
+               public void a2() {}
+               public void a3(CharSequence s) {}
+               public void a4() {}
+       }
+
+       public static class CI3 extends CI2 {
+               @Override
+               public void a1() {}
+               @Override public void a2() {}
+               @TestAnnotation("a4")
+               public void a4() {}
+       }
+       
+       @Target(METHOD)
+       @Retention(RUNTIME)
+       public @interface TestAnnotation {
+               String value() default "";
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/3551f4c9/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java 
b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
index cb51ed5..be80772 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -547,17 +547,21 @@ public class BeanMeta<T> {
                                int mod = m.getModifiers();
                                if (Modifier.isStatic(mod))
                                        continue;
-                               if (m.isAnnotationPresent(BeanIgnore.class))
-                                       continue;
                                if (m.isBridge())   // This eliminates methods 
with covariant return types from parent classes on child classes.
                                        continue;
-                               if (! (v.isVisible(m) || 
m.isAnnotationPresent(BeanProperty.class)))
+
+                               BeanIgnore bi = 
getMethodAnnotation(BeanIgnore.class, c, m);
+                               if (bi != null)
                                        continue;
+
+                               BeanProperty bp = 
getMethodAnnotation(BeanProperty.class, c, m);
+                               if (! (v.isVisible(m) || bp != null))
+                                       continue;
+
                                String n = m.getName();
                                Class<?>[] pt = m.getParameterTypes();
                                Class<?> rt = m.getReturnType();
                                boolean isGetter = false, isSetter = false;
-                               BeanProperty bp = 
getMethodAnnotation(BeanProperty.class, m);
                                String bpName = bpName(bp);
                                if (pt.length == 0) {
                                        if (n.startsWith("get") && (! 
rt.equals(Void.TYPE))) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/3551f4c9/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java 
b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
index d176b92..3b31bfc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -336,36 +336,53 @@ public final class ClassUtils {
         * Similar to {@link Method#getAnnotation(Class)}, but searches up the 
parent hierarchy for the annotation
         * defined on parent classes and interfaces.
         * <p>
-        * Normally, annotations defined on methods of parent classes and 
interfaces are not inherited by the child
-        * methods.
-        * This utility method gets around that limitation by searching the 
class hierarchy for the "same" method.
+        * Normally, annotations defined on methods of parent classes and 
interfaces are not inherited by the child methods.
+        * This utility method gets around that limitation by searching the 
class hierarchy for the "same" method
+        *      (i.e. the same name and arguments).
         *
         * @param a The annotation to search for.
         * @param m The method to search.
         * @return The annotation, or <jk>null</jk> if it wasn't found.
         */
        public static <T extends Annotation> T getMethodAnnotation(Class<T> a, 
Method m) {
-               T t = m.getAnnotation(a);
-               if (t != null)
-                       return t;
-               Class<?> pc = m.getDeclaringClass().getSuperclass();
-               if (pc != null) {
-                       for (Method m2 : pc.getDeclaredMethods()) {
-                               if (isSameMethod(m, m2)) {
-                                       t = getMethodAnnotation(a, m2);
-                                       if (t != null)
-                                               return t;
-                               }
+               return getMethodAnnotation(a, m.getDeclaringClass(), m);
+       }
+
+       /**
+        * Returns the specified annotation on the specified method.
+        * <p>
+        * Similar to {@link Method#getAnnotation(Class)}, but searches up the 
parent hierarchy for the annotation defined
+        *      on parent classes and interfaces.
+        * <p>
+        * Normally, annotations defined on methods of parent classes and 
interfaces are not inherited by the child methods.
+        * This utility method gets around that limitation by searching the 
class hierarchy for the "same" method
+        *      (i.e. the same name and arguments).
+        *
+        * @param a The annotation to search for.
+        * @param c The child class to start searching from.
+        *      Note that it can be a descendant class of the actual declaring 
class of the method passed in.
+        *      This allows you to find annotations on methods overridden by 
the method passed in.
+        * @param method The method to search.
+        * @return The annotation, or <jk>null</jk> if it wasn't found.
+        */
+       public static <T extends Annotation> T getMethodAnnotation(Class<T> a, 
Class<?> c, Method method) {
+               for (Method m : c.getDeclaredMethods()) {
+                       if (isSameMethod(method, m)) {
+                               T t = m.getAnnotation(a);
+                               if (t != null)
+                                       return t;
                        }
                }
-               for (Class<?> ic : m.getDeclaringClass().getInterfaces()) {
-                       for (Method m2 : ic.getDeclaredMethods()) {
-                               if (isSameMethod(m, m2)) {
-                                       t = getMethodAnnotation(a, m2);
-                                       if (t != null)
-                                               return t;
-                               }
-                       }
+               Class<?> pc = c.getSuperclass();
+               if (pc != null) {
+                       T t = getMethodAnnotation(a, pc, method);
+                       if (t != null)
+                               return t;
+               }
+               for (Class<?> ic : c.getInterfaces()) {
+                       T t = getMethodAnnotation(a, ic, method);
+                       if (t != null)
+                               return t;
                }
                return null;
        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/3551f4c9/juneau-core/src/main/javadoc/resources/icons/LICENSE.txt
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/resources/icons/LICENSE.txt 
b/juneau-core/src/main/javadoc/resources/icons/LICENSE.txt
new file mode 100644
index 0000000..bba1297
--- /dev/null
+++ b/juneau-core/src/main/javadoc/resources/icons/LICENSE.txt
@@ -0,0 +1,14 @@
+***************************************************************************************************************************
+* Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+* distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+* to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+* with the License.  You may obtain a copy of the License at                   
                                           *
+*                                                                              
                                           *
+*  http://www.apache.org/licenses/LICENSE-2.0                                  
                                           *
+*                                                                              
                                           *
+* Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 
or implied.  See the License for the        *
+* specific language governing permissions and limitations under the License.   
                                           *
+***************************************************************************************************************************
+
+This license covers the png files located in this directory.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/3551f4c9/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
index 93403fb..5f587b5 100644
--- 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
+++ 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
@@ -176,45 +176,72 @@ public class RequestBeanProxyTest extends RestTestcase {
                String 
queryCollectionsX(@RequestBean(serializer=XSerializer.class) 
RequestBean_QueryCollections rb);
        }
 
-       public static class RequestBean_QuerySimpleVals {
+       public static interface RequestBean_QuerySimpleVals_Interface {
 
                @Query
+               String getA();
+
+               @Query("b")
+               String getX1();
+
+               @Query(name="c")
+               String getX2();
+
+               @Query
+               @BeanProperty("d")
+               String getX3();
+
+               @Query("e")
+               String getX4();
+
+               @Query("f")
+               String getX5();
+
+               @Query("g")
+               String getX6();
+
+               @Query("h")
+               String getX7();
+       }
+
+       public static class RequestBean_QuerySimpleVals implements 
RequestBean_QuerySimpleVals_Interface {
+
+               @Override
                public String getA() {
                        return "a1";
                }
 
-               @Query("b")
+               @Override
                public String getX1() {
                        return "b1";
                }
 
-               @Query(name="c")
+               @Override
                public String getX2() {
                        return "c1";
                }
 
-               @Query
-               @BeanProperty("d")
+               @Override
                public String getX3() {
                        return "d1";
                }
 
-               @Query("e")
+               @Override
                public String getX4() {
                        return "";
                }
 
-               @Query("f")
+               @Override
                public String getX5() {
                        return null;
                }
 
-               @Query("g")
+               @Override
                public String getX6() {
                        return "true";
                }
 
-               @Query("h")
+               @Override
                public String getX7() {
                        return "123";
                }

Reply via email to