You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/06/02 21:17:00 UTC

incubator-juneau git commit: Fix issue where annotations were not being found on parent classes.

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 <ja...@apache.org>
Authored: Fri Jun 2 17:16:57 2017 -0400
Committer: JamesBognar <ja...@apache.org>
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";
 		}