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 58225b7  New option for dyna-property.
58225b7 is described below

commit 58225b702ae59fc11a741d6fac0e09fc4f47b3b8
Author: JamesBognar <[email protected]>
AuthorDate: Thu Apr 5 14:19:48 2018 -0400

    New option for dyna-property.
---
 .../java/org/apache/juneau/DynaBeanComboTest.java  | 79 ++++++++++++++++++++++
 .../src/main/java/org/apache/juneau/BeanMeta.java  | 35 ++++++----
 .../java/org/apache/juneau/BeanPropertyMeta.java   | 11 +--
 .../org/apache/juneau/annotation/BeanProperty.java | 20 ++++++
 juneau-doc/src/main/javadoc/overview.html          |  3 +
 5 files changed, 132 insertions(+), 16 deletions(-)

diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/DynaBeanComboTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/DynaBeanComboTest.java
index 6711527..9fbd80a 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/DynaBeanComboTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/DynaBeanComboTest.java
@@ -206,6 +206,41 @@ public class DynaBeanComboTest extends ComboRoundTripTest {
                                        }
                                }
                        },
+                       {       /* 5 */
+                               new ComboInput<BeanWithDynaMethodsAndExtraKeys>(
+                                       "BeanWithDynaMethodsAndExtraKeys",
+                                       BeanWithDynaMethodsAndExtraKeys.class,
+                                       new 
BeanWithDynaMethodsAndExtraKeys().init(),
+                                       /* Json */              
"{f1:1,f2a:'a',f2b:'b',f3:3}",
+                                       /* JsonT */             
"{f1:1,f2a:'a',f2b:'b',f3:3}",
+                                       /* JsonR */             "{\n\tf1: 
1,\n\tf2a: 'a',\n\tf2b: 'b',\n\tf3: 3\n}",
+                                       /* Xml */               
"<object><f1>1</f1><f2a>a</f2a><f2b>b</f2b><f3>3</f3></object>",
+                                       /* XmlT */              
"<object><f1>1</f1><f2a>a</f2a><f2b>b</f2b><f3>3</f3></object>",
+                                       /* XmlR */              
"<object>\n\t<f1>1</f1>\n\t<f2a>a</f2a>\n\t<f2b>b</f2b>\n\t<f3>3</f3>\n</object>\n",
+                                       /* XmlNs */             
"<object><f1>1</f1><f2a>a</f2a><f2b>b</f2b><f3>3</f3></object>",
+                                       /* Html */              
"<table><tr><td>f1</td><td>1</td></tr><tr><td>f2a</td><td>a</td></tr><tr><td>f2b</td><td>b</td></tr><tr><td>f3</td><td>3</td></tr></table>",
+                                       /* HtmlT */             
"<table><tr><td>f1</td><td>1</td></tr><tr><td>f2a</td><td>a</td></tr><tr><td>f2b</td><td>b</td></tr><tr><td>f3</td><td>3</td></tr></table>",
+                                       /* HtmlR */             
"<table>\n\t<tr>\n\t\t<td>f1</td>\n\t\t<td>1</td>\n\t</tr>\n\t<tr>\n\t\t<td>f2a</td>\n\t\t<td>a</td>\n\t</tr>\n\t<tr>\n\t\t<td>f2b</td>\n\t\t<td>b</td>\n\t</tr>\n\t<tr>\n\t\t<td>f3</td>\n\t\t<td>3</td>\n\t</tr>\n</table>\n",
+                                       /* Uon */               
"(f1=1,f2a=a,f2b=b,f3=3)",
+                                       /* UonT */              
"(f1=1,f2a=a,f2b=b,f3=3)",
+                                       /* UonR */              
"(\n\tf1=1,\n\tf2a=a,\n\tf2b=b,\n\tf3=3\n)",
+                                       /* UrlEnc */    "f1=1&f2a=a&f2b=b&f3=3",
+                                       /* UrlEncT */   "f1=1&f2a=a&f2b=b&f3=3",
+                                       /* UrlEncR */   
"f1=1\n&f2a=a\n&f2b=b\n&f3=3",
+                                       /* MsgPack */   
"84A2663101A3663261A161A3663262A162A2663303",
+                                       /* MsgPackT */  
"84A2663101A3663261A161A3663262A162A2663303",
+                                       /* RdfXml */    
"<rdf:RDF>\n<rdf:Description>\n<jp:f1>1</jp:f1>\n<jp:f2a>a</jp:f2a>\n<jp:f2b>b</jp:f2b>\n<jp:f3>3</jp:f3>\n</rdf:Description>\n</rdf:RDF>\n",
+                                       /* RdfXmlT */   
"<rdf:RDF>\n<rdf:Description>\n<jp:f1>1</jp:f1>\n<jp:f2a>a</jp:f2a>\n<jp:f2b>b</jp:f2b>\n<jp:f3>3</jp:f3>\n</rdf:Description>\n</rdf:RDF>\n",
+                                       /* RdfXmlR */   "<rdf:RDF>\n  
<rdf:Description>\n    <jp:f1>1</jp:f1>\n    <jp:f2a>a</jp:f2a>\n    
<jp:f2b>b</jp:f2b>\n    <jp:f3>3</jp:f3>\n  </rdf:Description>\n</rdf:RDF>\n"
+                               )
+                               {
+                                       @Override
+                                       public void 
verify(BeanWithDynaMethodsAndExtraKeys o) {
+                                               
assertType(BeanWithDynaMethodsAndExtraKeys.class, o);
+                                               
Assert.assertTrue(o.setterCalled);
+                                       }
+                               }
+                       },
                });
        }
 
@@ -278,6 +313,50 @@ public class DynaBeanComboTest extends ComboRoundTripTest {
        }
 
        @Bean(sort=true)
+       public static class BeanWithDynaMethodsAndExtraKeys {
+
+               private int f1, f3;
+               private Map<String,Object> f2 = new 
LinkedHashMap<String,Object>();
+               private boolean setterCalled = false;
+
+               public int getF1() {
+                       return f1;
+               }
+               public void setF1(int f1) {
+                       this.f1 = f1;
+               }
+               public int getF3() {
+                       return f3;
+               }
+               public void setF3(int f3) {
+                       this.f3 = f3;
+               }
+
+               @BeanProperty(name="*")
+               public Object get(String name) {
+                       return f2.get(name);
+               }
+
+               @BeanProperty(name="*")
+               public void set(String name, Object o) {
+                       setterCalled = true;
+                       this.f2.put(name, o);
+               }
+
+               @BeanProperty(name="*")
+               public Collection<String> getExtraKeys() {
+                       return f2.keySet();
+               }
+               
+               public BeanWithDynaMethodsAndExtraKeys init() {
+                       this.f1 = 1;
+                       this.f2 = new ObjectMap().append("f2a", 
"a").append("f2b", "b");
+                       this.f3 = 3;
+                       return this;
+               }
+       }
+
+       @Bean(sort=true)
        public static class BeanWithDynaGetterOnly {
 
                private int f1, f3;
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 0cacb9e..e15aedb 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
@@ -329,6 +329,14 @@ public class BeanMeta<T> {
                                                                
bpm.setSetter(bm.method);
                                                }
                                        }
+                                       
+                                       // Now iterate through all the 
extraKeys.
+                                       for (BeanMethod bm : bms) {
+                                               if (bm.methodType == EXTRAKEYS) 
{
+                                                       
BeanPropertyMeta.Builder bpm = normalProps.get(bm.propertyName);
+                                                       
bpm.setExtraKeys(bm.method);
+                                               }
+                                       }
                                }
 
                                typeVarImpls = new HashMap<>();
@@ -611,19 +619,19 @@ public class BeanMeta<T> {
                                        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))) {
-                                               methodType = GETTER;
-                                               n = n.substring(3);
-                                       } else if (n.startsWith("is") && 
(rt.equals(Boolean.TYPE) || rt.equals(Boolean.class))) {
-                                               methodType = GETTER;
-                                               n = n.substring(2);
-                                       } else if ("*".equals(bpName)) {
+                                       if ("*".equals(bpName)) {
                                                if 
(isParentClass(Collection.class, rt)) {
                                                        methodType = EXTRAKEYS;
                                                } else if 
(isParentClass(Map.class, rt)) {
                                                        methodType = GETTER;
                                                }
                                                n = bpName;
+                                       } else if (n.startsWith("get") && (! 
rt.equals(Void.TYPE))) {
+                                               methodType = GETTER;
+                                               n = n.substring(3);
+                                       } else if (n.startsWith("is") && 
(rt.equals(Boolean.TYPE) || rt.equals(Boolean.class))) {
+                                               methodType = GETTER;
+                                               n = n.substring(2);
                                        } else if (bpName != null) {
                                                methodType = GETTER;
                                                if (bpName.isEmpty()) {
@@ -637,14 +645,17 @@ public class BeanMeta<T> {
                                                }
                                        }
                                } else if (pt.length == 1) {
-                                       if (n.startsWith("set") && 
(isParentClass(rt, c) || rt.equals(Void.TYPE))) {
-                                               methodType = SETTER;
-                                               n = n.substring(3);
-                                       } else if ("*".equals(bpName)) {
+                                       if ("*".equals(bpName)) {
                                                if (isParentClass(Map.class, 
pt[0])) {
                                                        methodType = SETTER;
                                                        n = bpName;
+                                               } else if (pt[0] == 
String.class) {
+                                                       methodType = GETTER;
+                                                       n = bpName;
                                                }
+                                       } else if (n.startsWith("set") && 
(isParentClass(rt, c) || rt.equals(Void.TYPE))) {
+                                               methodType = SETTER;
+                                               n = n.substring(3);
                                        } else if (bpName != null) {
                                                methodType = SETTER;
                                                if (bpName.isEmpty()) {
@@ -670,7 +681,7 @@ public class BeanMeta<T> {
                                n = pn.getPropertyName(n);
                                
                                if ("*".equals(bpName) && methodType == UNKNOWN)
-                                       throw new BeanRuntimeException(c, 
"Found @BeanProperty(\"*\") but could not determine method type.", bpName);
+                                       throw new BeanRuntimeException(c, 
"Found @BeanProperty(\"*\") but could not determine method type on method 
''{0}''.", m.getName());
                                
                                if (methodType != UNKNOWN) {
                                        if (bpName != null && ! 
bpName.isEmpty()) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index 2872385..41cb2a9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -236,7 +236,7 @@ public final class BeanPropertyMeta {
                                if (isDyna) {
                                        if (isParentClass(Map.class, c) && 
pt.length == 0) {
                                                isDynaGetterMap = true;
-                                       } else if (pt.length == 2 && pt[0] == 
String.class) {
+                                       } else if (pt.length == 1 && pt[0] == 
String.class) {
                                                // OK.
                                        } else {
                                                return false;
@@ -271,8 +271,11 @@ public final class BeanPropertyMeta {
                                }
                        }
 
-                       if (isDyna)
+                       if (isDyna) {
                                rawTypeMeta = rawTypeMeta.getValueType();
+                               if (rawTypeMeta == null)
+                                       rawTypeMeta = beanContext.object();
+                       }
                        if (rawTypeMeta == null)
                                return false;
 
@@ -779,7 +782,7 @@ public final class BeanPropertyMeta {
                        Map m = null;
                        if (getter != null) {
                                if (! isDynaGetterMap)
-                                       return getter.invoke(pName);
+                                       return getter.invoke(bean, pName);
                                m = (Map)getter.invoke(bean);
                        }
                        else if (field != null)
@@ -837,7 +840,7 @@ public final class BeanPropertyMeta {
                        if (extraKeys != null && getter != null && ! 
isDynaGetterMap) {
                                Map<String,Object> m = new LinkedHashMap<>();
                                for (String key : 
(Collection<String>)extraKeys.invoke(bean)) 
-                                       m.put(key, getter.invoke(bean));
+                                       m.put(key, getter.invoke(bean, key));
                                return m;
                        }
                        if (getter != null && isDynaGetterMap)
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index 41f5448..eda2437 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -93,6 +93,26 @@ public @interface BeanProperty {
         *                      ...
         *              }
         *      }
+        * 
+        *      <jc>// Option #4 - Getter, setter, and extra-keys method .
+        *      // Define a method that returns a Collection&lt;String&gt; with 
currently-set property names.</jc>
+        *      <jk>public class</jk> BeanWithDynaExtraKeys {
+        * 
+        *              <ja>@BeanProperty</ja>(name=<js>"*"</js>)
+        *              <jk>public</jk> Object get(String name) {
+        *                      ...
+        *              }
+        * 
+        *              <ja>@BeanProperty</ja>(name=<js>"*"</js>)
+        *              <jk>public void</jk> set(String name, Object value) {
+        *                      ...
+        *              }
+        * 
+        *              <ja>@BeanProperty</ja>(name=<js>"*"</js>)
+        *              <jk>public</jk> Collection&lt;String&gt; extraKeys() {
+        *                      ...
+        *              }
+        *      }
         * </p>
         * 
         *<p>
diff --git a/juneau-doc/src/main/javadoc/overview.html 
b/juneau-doc/src/main/javadoc/overview.html
index 087ee05..ea2213e 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -21344,6 +21344,9 @@
                        <li>
                                Fixed <code>NullPointerException</code> when 
serializing beans with a dyna-property (i.e. 
<code><ja>@Bean</ja>(<js>"*"</js>)</code>)
                                which returns a <jk>null</jk> value.
+                       <li>
+                               New option for dyna-property (i.e. 
<code><ja>@Bean</ja>(<js>"*"</js>)</code>) using a method that returns a 
collection of extra keys.
+                               <br>See new options #4 on {@link 
org.apache.juneau.annotation.BeanProperty#name()}
                </ul>
                
                <h5 class='topic w800'>juneau-dto</h5>

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to