juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject [juneau] branch master updated: Throw runtime exception if you forget to add to @Bean(properties)
Date Sat, 17 Mar 2018 19:50:24 GMT
This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 49383e7  Throw runtime exception if you forget to add to @Bean(properties)
49383e7 is described below

commit 49383e75238c19ea560e9a336dcac808499c7dfb
Author: JamesBognar <jamesbognar@apache.org>
AuthorDate: Sat Mar 17 15:49:55 2018 -0400

    Throw runtime exception if you forget to add to @Bean(properties)
---
 .../java/org/apache/juneau/BeanMapErrorsTest.java  | 71 ++++++++++++++++++++++
 .../src/main/java/org/apache/juneau/BeanMeta.java  | 30 +++++++--
 juneau-doc/src/main/javadoc/overview.html          |  3 +
 3 files changed, 98 insertions(+), 6 deletions(-)

diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanMapErrorsTest.java
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanMapErrorsTest.java
new file mode 100644
index 0000000..032683e
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanMapErrorsTest.java
@@ -0,0 +1,71 @@
+// ***************************************************************************************************************************
+// * 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.         
                                    *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.annotation.*;
+import org.junit.*;
+
+/**
+ * Tests various error conditions when defining beans.
+ */
+public class BeanMapErrorsTest {
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// @BeanProperty(name) on method not in @Bean(properties)
+	//-----------------------------------------------------------------------------------------------------------------
+	@Test
+	public void beanPropertyMethodNotInBeanProperties() {
+		BeanContext bc = BeanContext.DEFAULT;
+		
+		try {
+			bc.getClassMeta(A1.class);
+			fail();
+		} catch (Exception e) {
+			assertEquals("org.apache.juneau.BeanMapErrorsTest$A1: Found @BeanProperty(\"f2\") but
name was not found in @Bean(properties)", e.getMessage());
+		}
+	}
+	
+	@Bean(properties="f1")
+	public static class A1 {
+		public int f1;
+		
+		@BeanProperty("f2")
+		public int f2() {
+			return -1;
+		};
+	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// @BeanProperty(name) on field not in @Bean(properties)
+	//-----------------------------------------------------------------------------------------------------------------
+	@Test
+	public void beanPropertyFieldNotInBeanProperties() {
+		BeanContext bc = BeanContext.DEFAULT;
+		
+		try {
+			bc.getClassMeta(A2.class);
+			fail();
+		} catch (Exception e) {
+			assertEquals("org.apache.juneau.BeanMapErrorsTest$A2: Found @BeanProperty(\"f2\") but
name was not found in @Bean(properties)", e.getMessage());
+		}
+	}
+	@Bean(properties="f1")
+	public static class A2 {
+		public int f1;
+		
+		@BeanProperty("f2")
+		public int f2;
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index 70e48f3..90268a3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -240,7 +240,12 @@ public class BeanMeta<T> {
 				String[] includeProperties = ctx.getIncludeProperties(c);
 				String[] excludeProperties = ctx.getExcludeProperties(c);
 
+				Set<String> filterProps = new HashSet<>();  // Names of properties defined
in @Bean(properties)
+				
 				if (beanFilter != null) {
+					
+					if (beanFilter.getProperties() != null)
+						filterProps.addAll(Arrays.asList(beanFilter.getProperties()));
 
 					// Get the 'properties' attribute if specified.
 					if (beanFilter.getProperties() != null && includeProperties == null)
@@ -279,7 +284,7 @@ public class BeanMeta<T> {
 
 				} else /* Use 'better' introspection */ {
 
-					for (Field f : findBeanFields(c2, stopClass, fVis)) {
+					for (Field f : findBeanFields(c2, stopClass, fVis, filterProps)) {
 						String name = findPropertyName(f, fixedBeanProps);
 						if (name != null) {
 							if (! normalProps.containsKey(name))
@@ -288,7 +293,7 @@ public class BeanMeta<T> {
 						}
 					}
 
-					List<BeanMethod> bms = findBeanMethods(c2, stopClass, mVis, fixedBeanProps, propertyNamer);
+					List<BeanMethod> bms = findBeanMethods(c2, stopClass, mVis, fixedBeanProps, filterProps,
propertyNamer);
 
 					// Iterate through all the getters.
 					for (BeanMethod bm : bms) {
@@ -441,7 +446,7 @@ public class BeanMeta<T> {
 		private String findPropertyName(Field f, Set<String> fixedBeanProps) {
 			BeanProperty bp = f.getAnnotation(BeanProperty.class);
 			String name = bpName(bp);
-			if (name != null && ! name.isEmpty()) {
+			if (! isEmpty(name)) {
 				if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
 					return name;
 				return null;  // Could happen if filtered via BEAN_includeProperties/BEAN_excludeProperties.
@@ -552,7 +557,7 @@ public class BeanMeta<T> {
 	 * @param fixedBeanProps Only include methods whose properties are in this list.
 	 * @param pn Use this property namer to determine property names from the method names.
 	 */
-	static final List<BeanMethod> findBeanMethods(Class<?> c, Class<?> stopClass,
Visibility v, Set<String> fixedBeanProps, PropertyNamer pn) {
+	static final List<BeanMethod> findBeanMethods(Class<?> c, Class<?> stopClass,
Visibility v, Set<String> fixedBeanProps, Set<String> filterProps, PropertyNamer
pn) {
 		List<BeanMethod> l = new LinkedList<>();
 
 		for (Class<?> c2 : findClasses(c, stopClass)) {
@@ -571,10 +576,15 @@ public class BeanMeta<T> {
 					continue;
 
 				String n = m.getName();
+				
 				Class<?>[] pt = m.getParameterTypes();
 				Class<?> rt = m.getReturnType();
 				boolean isGetter = false, isSetter = false;
 				String bpName = bpName(bp);
+				
+				if (! (isEmpty(bpName) || filterProps.isEmpty() || filterProps.contains(bpName))) 
+					throw new BeanRuntimeException(c, "Found @BeanProperty(\"{0}\") but name was not found
in @Bean(properties)", bpName);
+				
 				if (pt.length == 0) {
 					if (n.startsWith("get") && (! rt.equals(Void.TYPE))) {
 						isGetter = true;
@@ -630,7 +640,7 @@ public class BeanMeta<T> {
 		return l;
 	}
 
-	static final Collection<Field> findBeanFields(Class<?> c, Class<?> stopClass,
Visibility v) {
+	static final Collection<Field> findBeanFields(Class<?> c, Class<?> stopClass,
Visibility v, Set<String> filterProps) {
 		List<Field> l = new LinkedList<>();
 		for (Class<?> c2 : findClasses(c, stopClass)) {
 			for (Field f : c2.getDeclaredFields()) {
@@ -638,8 +648,16 @@ public class BeanMeta<T> {
 					continue;
 				if (f.isAnnotationPresent(BeanIgnore.class))
 					continue;
-				if (! (v.isVisible(f) || f.isAnnotationPresent(BeanProperty.class)))
+				
+				BeanProperty bp = f.getAnnotation(BeanProperty.class);
+				String bpName = bpName(bp);
+				
+				if (! (v.isVisible(f) || bp != null))
 					continue;
+				
+				if (! (isEmpty(bpName) || filterProps.isEmpty() || filterProps.contains(bpName))) 
+					throw new BeanRuntimeException(c, "Found @BeanProperty(\"{0}\") but name was not found
in @Bean(properties)", bpName);
+				
 				l.add(f);
 			}
 		}
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index a4aea2a..dc983ab 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -21247,6 +21247,9 @@
 				</ul>
 			<li>
 				Fixed bug where parsers could report the wrong line number when an error occurred.
+			<li>
+				A runtime exception is now thrown if you define a <code><ja>@BeanProperty</ja>(name)</code>
but forget to
+				add it to your <code><ja>@Bean</ja>(properties)</code> annotation.
 		</ul>
 		
 		<h5 class='topic w800'>juneau-dto</h5>

-- 
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.

Mime
View raw message