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 <[email protected]>
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
[email protected].

Reply via email to