Repository: incubator-juneau
Updated Branches:
  refs/heads/master 342ed1dcb -> 79d19494a


Simplify the way serializers iterate over bean properties.  With the
introduction of MsgPack, we now need to know the number of non-null bean
properties before we start serializing the entries.  Also, the REST
Samples that serializes HttpRequest objects is broken because it's not
catching exceptions.

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

Branch: refs/heads/master
Commit: 79d19494af7f3d335d2edc693d8f9bfa675a45b0
Parents: 342ed1d
Author: jamesbognar <[email protected]>
Authored: Wed Aug 3 16:58:39 2016 -0400
Committer: jamesbognar <[email protected]>
Committed: Wed Aug 3 16:58:39 2016 -0400

----------------------------------------------------------------------
 .../main/java/org/apache/juneau/BeanMap.java    | 63 ++++++++++-------
 .../main/java/org/apache/juneau/BeanMeta.java   | 14 +++-
 .../org/apache/juneau/BeanPropertyMeta.java     | 10 ++-
 .../org/apache/juneau/BeanPropertyValue.java    | 72 ++++++++++++++++++++
 .../org/apache/juneau/html/HtmlSerializer.java  | 33 ++++-----
 .../apache/juneau/internal/DelegateBeanMap.java | 22 +++++-
 .../org/apache/juneau/jena/RdfSerializer.java   | 22 +++---
 .../org/apache/juneau/json/JsonSerializer.java  | 28 ++------
 .../juneau/msgpack/MsgPackSerializer.java       | 53 +++++++-------
 .../juneau/urlencoding/UonSerializer.java       | 27 ++------
 .../urlencoding/UrlEncodingSerializer.java      | 27 ++------
 .../org/apache/juneau/xml/XmlSerializer.java    | 58 ++++++++--------
 .../test/java/org/apache/juneau/CT_BeanMap.java | 13 +++-
 13 files changed, 255 insertions(+), 187 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/main/java/org/apache/juneau/BeanMap.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/BeanMap.java
index adef3ab..28bee46 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/BeanMap.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/BeanMap.java
@@ -413,20 +413,49 @@ public class BeanMap<T> extends 
AbstractMap<String,Object> implements Delegate<T
        }
 
        /**
-        * Returns all the properties associated with the bean.
+        * Invokes all the getters on this bean and return the values as a list 
of {@link BeanPropertyValue} objects.
+        * <p>
+        * This allows a snapshot of all values to be grabbed from a bean in 
one call.
+        *
+        * @param addClassAttr Add a <jk>"_class"</jk> bean property to the 
returned list.
+        * @param ignoreNulls Don't return properties whose values are null.
+        * @return The list of all bean property values.
         */
-       @Override /* Map */
-       public Set<Entry<String,Object>> entrySet() {
-               return entrySet(false);
+       public List<BeanPropertyValue> getValues(final boolean addClassAttr, 
final boolean ignoreNulls) {
+               Collection<BeanPropertyMeta<T>> properties = getProperties();
+               int capacity = (ignoreNulls && properties.size() > 10) ? 10 : 
properties.size() + (addClassAttr ? 1 : 0);
+               List<BeanPropertyValue> l = new 
ArrayList<BeanPropertyValue>(capacity);
+               if (addClassAttr)
+                       l.add(new BeanPropertyValue(meta.getClassProperty(), 
meta.c.getName(), null));
+               for (BeanPropertyMeta<T> bpm : properties) {
+                       try {
+                               Object val = bpm.get(this);
+                               if (val != null || ! ignoreNulls)
+                                       l.add(new BeanPropertyValue(bpm, val, 
null));
+                       } catch (Error e) {
+                               // Errors should always be uncaught.
+                               throw e;
+                       } catch (Throwable t) {
+                               l.add(new BeanPropertyValue(bpm, null, t));
+                       }
+               }
+               return l;
+       }
+
+       /**
+        * Returns a simple collection of properties for this bean map.
+        * @return A simple collection of properties for this bean map.
+        */
+       protected Collection<BeanPropertyMeta<T>> getProperties() {
+               return meta.properties.values();
        }
 
        /**
         * Returns all the properties associated with the bean.
-        * @param ignoreNulls - Iterator should not return properties with null 
values.
         * @return A new set.
         */
-       public Set<Entry<String,Object>> entrySet(final boolean ignoreNulls) {
-               int todo = 1;  // Create a more efficient method.
+       @Override
+       public Set<Entry<String,Object>> entrySet() {
 
                // Construct our own anonymous set to implement this function.
                Set<Entry<String,Object>> s = new 
AbstractSet<Entry<String,Object>>() {
@@ -435,7 +464,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> 
implements Delegate<T
                        // Note that the HashMap.values() method caches 
results, so this collection
                        // will really only be constructed once per bean type 
since the underlying
                        // map never changes.
-                       final Collection<BeanPropertyMeta<T>> pSet = 
meta.properties.values();
+                       final Collection<BeanPropertyMeta<T>> pSet = 
getProperties();
 
                        @Override /* Set */
                        public Iterator<java.util.Map.Entry<String, Object>> 
iterator() {
@@ -446,29 +475,15 @@ public class BeanMap<T> extends 
AbstractMap<String,Object> implements Delegate<T
                                return new Iterator<Entry<String,Object>>() {
 
                                        final Iterator<BeanPropertyMeta<T>> 
pIterator = pSet.iterator();
-                                       BeanMapEntry<T> nextEntry;
 
                                        @Override /* Iterator */
                                        public boolean hasNext() {
-                                               return nextEntry() != null;
+                                               return pIterator.hasNext();
                                        }
 
                                        @Override /* Iterator */
                                        public Map.Entry<String, Object> next() 
{
-                                               BeanMapEntry<T> e = nextEntry();
-                                               nextEntry = null;
-                                               return e;
-                                       }
-
-                                       private BeanMapEntry<T> nextEntry() {
-                                               if (nextEntry == null) {
-                                                       while 
(pIterator.hasNext() && nextEntry == null) {
-                                                               
BeanPropertyMeta<T> bpm = pIterator.next();
-                                                               if ((! 
ignoreNulls) || bpm.get(BeanMap.this) != null)
-                                                                       
nextEntry = new BeanMapEntry<T>(BeanMap.this, bpm);
-                                                       }
-                                               }
-                                               return nextEntry;
+                                               return new 
BeanMapEntry<T>(BeanMap.this, pIterator.next());
                                        }
 
                                        @Override /* Iterator */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/main/java/org/apache/juneau/BeanMeta.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/BeanMeta.java
index b5f4092..8d4d631 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/BeanMeta.java
@@ -100,6 +100,7 @@ public class BeanMeta<T> {
        BeanPropertyMeta<T> uriProperty;                                 // The 
property identified as the URI for this bean (annotated with 
@BeanProperty.beanUri).
        BeanPropertyMeta<T> subTypeIdProperty;                           // The 
property indentified as the sub type differentiator property (identified by 
@Bean.subTypeProperty annotation).
        PropertyNamer propertyNamer;                                     // 
Class used for calculating bean property names.
+       BeanPropertyMeta<T> classProperty;                               // 
"_class" mock bean property.
 
        BeanMeta() {}
 
@@ -110,10 +111,11 @@ public class BeanMeta<T> {
         * @param ctx The bean context that created this object.
         * @param transform Optional bean transform associated with the target 
class.  Can be <jk>null</jk>.
         */
-       protected BeanMeta(ClassMeta<T> classMeta, BeanContext ctx, 
org.apache.juneau.transform.BeanTransform<? extends T> transform) {
+       protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, 
org.apache.juneau.transform.BeanTransform<? extends T> transform) {
                this.classMeta = classMeta;
                this.ctx = ctx;
                this.transform = transform;
+               this.classProperty = new BeanPropertyMeta<T>(this, "_class", 
ctx.string());
                this.c = classMeta.getInnerClass();
        }
 
@@ -398,6 +400,16 @@ public class BeanMeta<T> {
                return uriProperty;
        }
 
+       /**
+        * Returns a mock bean property that resolves to the name 
<js>"_class"</js> and whose value always resolves
+        *      to the class name of the bean.
+        *
+        * @return The class name property.
+        */
+       public BeanPropertyMeta<T> getClassProperty() {
+               return classProperty;
+       }
+
        /*
         * Temporary getter/setter method struct.
         */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyMeta.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyMeta.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index e72ff21..48332cf 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -69,7 +69,13 @@ public class BeanPropertyMeta<T> {
        /** RDF related metadata on this bean property. */
        protected RdfBeanPropertyMeta<T> rdfMeta;  //
 
-       BeanPropertyMeta(BeanMeta<T> beanMeta, String name) {
+       /**
+        * Constructor.
+        *
+        * @param beanMeta The metadata of the bean containing this property.
+        * @param name This property name.
+        */
+       protected BeanPropertyMeta(BeanMeta<T> beanMeta, String name) {
                this.beanMeta = beanMeta;
                this.name = name;
        }
@@ -142,7 +148,7 @@ public class BeanPropertyMeta<T> {
         */
        public ClassMeta<?> getClassMeta() {
                if (typeMeta == null)
-                       typeMeta = (transform != null ? 
transform.getTransformedClassMeta() : rawTypeMeta.getTransformedClassMeta());
+                       typeMeta = (transform != null ? 
transform.getTransformedClassMeta() : rawTypeMeta == null ? 
beanMeta.ctx.object() : rawTypeMeta.getTransformedClassMeta());
                return typeMeta;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyValue.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyValue.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyValue.java
new file mode 100644
index 0000000..3238474
--- /dev/null
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/BeanPropertyValue.java
@@ -0,0 +1,72 @@
+/***************************************************************************************************************************
+ * 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;
+
+/**
+ * Represents a simple bean property value and the meta-data associated with 
it.
+ * <p>
+ *
+ * @author James Bognar ([email protected])
+ */
+public class BeanPropertyValue {
+
+       private final BeanPropertyMeta<?> pMeta;
+       private final Object value;
+       private final Throwable thrown;
+
+       /**
+        * Constructor.
+        *
+        * @param pMeta The bean property metadata.
+        * @param value The bean property value.
+        * @param thrown The exception thrown by calling the property getter.
+        */
+       protected BeanPropertyValue(BeanPropertyMeta<?> pMeta, Object value, 
Throwable thrown) {
+               this.pMeta = pMeta;
+               this.value = value;
+               this.thrown = thrown;
+       }
+
+       /**
+        * Returns the bean property metadata.
+        * @return The bean property metadata.
+        */
+       public final BeanPropertyMeta<?> getMeta() {
+               return pMeta;
+       }
+
+       /**
+        * Returns the bean property name.
+        * @return The bean property name.
+        */
+       public final String getName() {
+               return pMeta.getName();
+       }
+
+       /**
+        * Returns the bean property value.
+        * @return The bean property value.
+        */
+       public final Object getValue() {
+               return value;
+       }
+
+       /**
+        * Returns the exception thrown by calling the property getter.
+        * @return The exception thrown by calling the property getter.
+        */
+       public final Throwable getThrown() {
+               return thrown;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/html/HtmlSerializer.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 6506b9c..522e06a 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -320,7 +320,7 @@ public class HtmlSerializer extends XmlSerializer {
        }
 
        @SuppressWarnings({ "rawtypes" })
-       private void serializeBeanMap(HtmlSerializerSession session, HtmlWriter 
out, BeanMap m, String classAttr, BeanPropertyMeta<?> ppMeta) throws Exception {
+       private void serializeBeanMap(HtmlSerializerSession session, HtmlWriter 
out, BeanMap<?> m, String classAttr, BeanPropertyMeta<?> ppMeta) throws 
Exception {
                int i = session.getIndent();
 
                Object o = m.getBean();
@@ -345,21 +345,14 @@ public class HtmlSerializer extends XmlSerializer {
                        out.eTag(i+1, "tr").nl();
                }
 
-               Iterator mapEntries = 
m.entrySet(session.isTrimNulls()).iterator();
-
-               while (mapEntries.hasNext()) {
-                       BeanMapEntry p = (BeanMapEntry)mapEntries.next();
+               for (BeanPropertyValue p : m.getValues(false, 
session.isTrimNulls())) {
                        BeanPropertyMeta pMeta = p.getMeta();
 
-                       String key = p.getKey();
-                       Object value = null;
-                       try {
-                               value = p.getValue();
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
+                       String key = p.getName();
+                       Object value = p.getValue();
+                       Throwable t = p.getThrown();
+                       if (t != null)
                                session.addBeanGetterWarning(pMeta, t);
-                       }
 
                        if (session.canIgnoreValue(pMeta.getClassMeta(), key, 
value))
                                continue;
@@ -371,12 +364,12 @@ public class HtmlSerializer extends XmlSerializer {
                        out.sTag(i+2, "td").nl();
                        try {
                                serializeAnything(session, out, value, 
p.getMeta().getClassMeta(), key, 2, pMeta);
-                       } catch (SerializeException t) {
-                               throw t;
-                       } catch (StackOverflowError t) {
-                               throw t;
-                       } catch (Throwable t) {
-                               session.addBeanGetterWarning(pMeta, t);
+                       } catch (SerializeException e) {
+                               throw e;
+                       } catch (Error e) {
+                               throw e;
+                       } catch (Throwable e) {
+                               session.addBeanGetterWarning(pMeta, e);
                        }
                        out.eTag(i+2, "td").nl();
                        out.eTag(i+1, "tr").nl();
@@ -448,7 +441,7 @@ public class HtmlSerializer extends XmlSerializer {
                                        else
                                                m2 = bc.forBean(o);
 
-                                       Iterator mapEntries = 
m2.entrySet(false).iterator();
+                                       Iterator mapEntries = 
m2.entrySet().iterator();
                                        while (mapEntries.hasNext()) {
                                                BeanMapEntry p = 
(BeanMapEntry)mapEntries.next();
                                                BeanPropertyMeta pMeta = 
p.getMeta();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
 
b/org.apache.juneau/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
index 0c67ace..4adf0cd 100644
--- 
a/org.apache.juneau/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
+++ 
b/org.apache.juneau/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
@@ -96,7 +96,7 @@ public class DelegateBeanMap<T> extends BeanMap<T> {
        }
 
        @Override /* Map */
-       public Set<Entry<String,Object>> entrySet(final boolean ignoreNulls) {
+       public Set<Entry<String,Object>> entrySet() {
                Set<Entry<String,Object>> s = Collections.newSetFromMap(new 
LinkedHashMap<Map.Entry<String,Object>,Boolean>());
                for (final String key : keys) {
                        BeanMapEntry<T> bme;
@@ -111,6 +111,26 @@ public class DelegateBeanMap<T> extends BeanMap<T> {
                return s;
        }
 
+       @Override /* BeanMap */
+       public Collection<BeanPropertyMeta<T>> getProperties() {
+               List<BeanPropertyMeta<T>> l = new 
ArrayList<BeanPropertyMeta<T>>(keys.size());
+               for (final String key : keys) {
+                       BeanPropertyMeta<T> p = this.getPropertyMeta(key);
+                       if (overrideValues.containsKey(key)) {
+                               p = new BeanPropertyMeta<T>(this.meta, key) {
+                                       @Override /* BeanPropertyMeta */
+                                       public Object get(BeanMap<T> m) {
+                                               return overrideValues.get(key);
+                                       }
+                               };
+                       }
+                       if (p == null)
+                               throw new 
BeanRuntimeException(super.getClassMeta().getInnerClass(), "Property ''{0}'' 
not found on class.", key);
+                       l.add(p);
+               }
+               return l;
+       }
+
        private class BeanMapEntryOverride<T2> extends BeanMapEntry<T2> {
                Object value;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/jena/RdfSerializer.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 27620af..d5d97ee 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -315,30 +315,26 @@ public class RdfSerializer extends WriterSerializer {
                }
        }
 
-       private void serializeBeanMap(RdfSerializerSession session, BeanMap m, 
Resource r) throws SerializeException {
-               ArrayList<BeanMapEntry> l = new 
ArrayList<BeanMapEntry>(m.entrySet(session.isTrimNulls()));
+       private void serializeBeanMap(RdfSerializerSession session, BeanMap<?> 
m, Resource r) throws SerializeException {
+               List<BeanPropertyValue> l = m.getValues(false, 
session.isTrimNulls());
                Collections.reverse(l);
-               for (BeanMapEntry bme : l) {
-                       BeanPropertyMeta pMeta = bme.getMeta();
+               for (BeanPropertyValue bpv : l) {
+                       BeanPropertyMeta pMeta = bpv.getMeta();
                        ClassMeta<?> cm = pMeta.getClassMeta();
 
                        if (pMeta.isBeanUri())
                                continue;
 
-                       String key = bme.getKey();
-                       Object value = null;
-                       try {
-                               value = bme.getValue();
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
+                       String key = bpv.getName();
+                       Object value = bpv.getValue();
+                       Throwable t = bpv.getThrown();
+                       if (t != null)
                                session.addBeanGetterWarning(pMeta, t);
-                       }
 
                        if (session.canIgnoreValue(cm, key, value))
                                continue;
 
-                       BeanPropertyMeta bpm = bme.getMeta();
+                       BeanPropertyMeta bpm = bpv.getMeta();
                        Namespace ns = bpm.getRdfMeta().getNamespace();
                        if (ns == null && session.isUseXmlNamespaces())
                                ns = bpm.getXmlMeta().getNamespace();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/json/JsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/json/JsonSerializer.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 8b89e87..7d431b2 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -291,35 +291,19 @@ public class JsonSerializer extends WriterSerializer {
        }
 
        @SuppressWarnings({ "rawtypes" })
-       private SerializerWriter serializeBeanMap(JsonSerializerSession 
session, JsonWriter out, BeanMap m, boolean addClassAttr) throws Exception {
+       private SerializerWriter serializeBeanMap(JsonSerializerSession 
session, JsonWriter out, BeanMap<?> m, boolean addClassAttr) throws Exception {
                int depth = session.getIndent();
                out.append('{');
 
-               Iterator mapEntries = 
m.entrySet(session.isTrimNulls()).iterator();
-
-               // Print out "_class" attribute on this bean if required.
-               if (addClassAttr) {
-                       String attr = "_class";
-                       
out.cr(depth).attr(attr).append(':').s().q().append(m.getClassMeta().getInnerClass().getName()).q();
-                       if (mapEntries.hasNext())
-                               out.append(',').s();
-               }
-
                boolean addComma = false;
 
-               while (mapEntries.hasNext()) {
-                       BeanMapEntry p = (BeanMapEntry)mapEntries.next();
+               for (BeanPropertyValue p : m.getValues(addClassAttr, 
session.isTrimNulls())) {
                        BeanPropertyMeta pMeta = p.getMeta();
-
-                       String key = p.getKey();
-                       Object value = null;
-                       try {
-                               value = p.getValue();
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
+                       String key = p.getName();
+                       Object value = p.getValue();
+                       Throwable t = p.getThrown();
+                       if (t != null)
                                session.addBeanGetterWarning(pMeta, t);
-                       }
 
                        if (session.canIgnoreValue(pMeta.getClassMeta(), key, 
value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
 
b/org.apache.juneau/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 1779d59..76aa138 100644
--- 
a/org.apache.juneau/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ 
b/org.apache.juneau/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -132,9 +132,12 @@ public class MsgPackSerializer extends 
OutputStreamSerializer {
                ClassMeta<?> keyType = type.getKeyType(), valueType = 
type.getValueType();
 
                m = session.sort(m);
+               
+               // The map size may change as we're iterating over it, so
+               // grab a snapshot of the entries in a separate list.
                List<SimpleMapEntry> entries = new 
ArrayList<SimpleMapEntry>(m.size());
                for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                       entries.add(new SimpleMapEntry(e.getKey(), 
e.getValue(), null));
+                       entries.add(new SimpleMapEntry(e.getKey(), 
e.getValue()));
 
                out.startMap(entries.size());
 
@@ -157,46 +160,38 @@ public class MsgPackSerializer extends 
OutputStreamSerializer {
                serializeCollection(session, out, o, type);
        }
 
-       @SuppressWarnings({ "rawtypes", "unchecked" })
-       private void serializeBeanMap(MsgPackSerializerSession session, 
MsgPackOutputStream out, final BeanMap m, boolean addClassAttr) throws 
Exception {
-
-               List<SimpleMapEntry> entries = new 
ArrayList<SimpleMapEntry>(m.getMeta().getPropertyMetas().size() + (addClassAttr 
? 1 : 0));
-               // Print out "_class" attribute on this bean if required.
-               if (addClassAttr)
-                       entries.add(new SimpleMapEntry("_class", 
m.getClassMeta().getInnerClass().getName(), null));
-
-               for (BeanMapEntry p : 
(Set<BeanMapEntry>)m.entrySet(session.isTrimNulls())) {
-                       try {
-                               BeanPropertyMeta pMeta = p.getMeta();
-                               String key = p.getKey();
-                               Object value = p.getValue();
-                               if (! 
session.canIgnoreValue(pMeta.getClassMeta(), p.getKey(), p.getValue()))
-                                       entries.add(new SimpleMapEntry(key, 
value, pMeta));
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
-                               session.addBeanGetterWarning(p.getMeta(), t);
-                       }
+       @SuppressWarnings({ "rawtypes" })
+       private void serializeBeanMap(MsgPackSerializerSession session, 
MsgPackOutputStream out, final BeanMap<?> m, boolean addClassAttr) throws 
Exception {
 
-               }
-               int size = entries.size();
+               List<BeanPropertyValue> values = m.getValues(addClassAttr, 
session.isTrimNulls());
+
+               int size = values.size();
+               for (BeanPropertyValue p : values)
+                       if (p.getThrown() != null)
+                               size--;
                out.startMap(size);
 
-               for (SimpleMapEntry p : entries) {
-                       serializeAnything(session, out, p.key, null, null, 
null);
-                       serializeAnything(session, out, p.value, p.pMeta == 
null ? session.getBeanContext().string() : p.pMeta.getClassMeta(), 
session.toString(p.key), p.pMeta);
+               for (BeanPropertyValue p : values) {
+                       BeanPropertyMeta pMeta = p.getMeta();
+                       String key = p.getName();
+                       Object value = p.getValue();
+                       Throwable t = p.getThrown();
+                       if (t != null)
+                               session.addBeanGetterWarning(pMeta, t);
+                       else {
+                               serializeAnything(session, out, key, null, 
null, null);
+                               serializeAnything(session, out, value, pMeta == 
null ? session.getBeanContext().string() : pMeta.getClassMeta(), key, pMeta);
+                       }
                }
        }
 
        private static class SimpleMapEntry {
                final Object key;
                final Object value;
-               final BeanPropertyMeta<?> pMeta;
 
-               private SimpleMapEntry(Object key, Object value, 
BeanPropertyMeta<?> pMeta) {
+               private SimpleMapEntry(Object key, Object value) {
                        this.key = key;
                        this.value = value;
-                       this.pMeta = pMeta;
                }
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
 
b/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
index 61dd1d1..df94810 100644
--- 
a/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
+++ 
b/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
@@ -367,36 +367,21 @@ public class UonSerializer extends WriterSerializer {
        }
 
        @SuppressWarnings({ "rawtypes" })
-       private SerializerWriter serializeBeanMap(UonSerializerSession session, 
UonWriter out, BeanMap m, boolean addClassAttr) throws Exception {
+       private SerializerWriter serializeBeanMap(UonSerializerSession session, 
UonWriter out, BeanMap<?> m, boolean addClassAttr) throws Exception {
                int depth = session.getIndent();
 
                out.startFlag('o');
 
-               Iterator mapEntries = 
m.entrySet(session.isTrimNulls()).iterator();
-
-               // Print out "_class" attribute on this bean if required.
-               if (addClassAttr) {
-                       String attr = "_class";
-                       out.cr(depth).appendObject(attr, false, false, 
false).append('=').append(m.getClassMeta().getInnerClass().getName());
-                       if (mapEntries.hasNext())
-                               out.append(',');
-               }
-
                boolean addComma = false;
 
-               while (mapEntries.hasNext()) {
-                       BeanMapEntry p = (BeanMapEntry)mapEntries.next();
+               for (BeanPropertyValue p : m.getValues(addClassAttr, 
session.isTrimNulls())) {
                        BeanPropertyMeta pMeta = p.getMeta();
 
-                       String key = p.getKey();
-                       Object value = null;
-                       try {
-                               value = p.getValue();
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
+                       String key = p.getName();
+                       Object value = p.getValue();
+                       Throwable t = p.getThrown();
+                       if (t != null)
                                session.addBeanGetterWarning(pMeta, t);
-                       }
 
                        if (session.canIgnoreValue(pMeta.getClassMeta(), key, 
value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
 
b/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 8f68709..fd04afb 100644
--- 
a/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ 
b/org.apache.juneau/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -321,34 +321,19 @@ public class UrlEncodingSerializer extends UonSerializer {
        }
 
        @SuppressWarnings({ "rawtypes" })
-       private SerializerWriter serializeBeanMap(UrlEncodingSerializerSession 
session, UonWriter out, BeanMap m, boolean addClassAttr) throws Exception {
+       private SerializerWriter serializeBeanMap(UrlEncodingSerializerSession 
session, UonWriter out, BeanMap<?> m, boolean addClassAttr) throws Exception {
                int depth = session.getIndent();
 
-               Iterator mapEntries = 
m.entrySet(session.isTrimNulls()).iterator();
-
-               // Print out "_class" attribute on this bean if required.
-               if (addClassAttr) {
-                       String attr = "_class";
-                       out.appendObject(attr, false, false, 
true).append('=').append(m.getClassMeta().getInnerClass().getName());
-                       if (mapEntries.hasNext())
-                               out.cr(depth).append('&');
-               }
-
                boolean addAmp = false;
 
-               while (mapEntries.hasNext()) {
-                       BeanMapEntry p = (BeanMapEntry)mapEntries.next();
+               for (BeanPropertyValue p : m.getValues(addClassAttr, 
session.isTrimNulls())) {
                        BeanPropertyMeta pMeta = p.getMeta();
 
-                       String key = p.getKey();
-                       Object value = null;
-                       try {
-                               value = p.getValue();
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable t) {
+                       String key = p.getName();
+                       Object value = p.getValue();
+                       Throwable t = p.getThrown();
+                       if (t != null)
                                session.addBeanGetterWarning(pMeta, t);
-                       }
 
                        if (session.canIgnoreValue(pMeta.getClassMeta(), key, 
value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/main/java/org/apache/juneau/xml/XmlSerializer.java 
b/org.apache.juneau/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 11ff7aa..a686412 100644
--- a/org.apache.juneau/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/org.apache.juneau/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -221,7 +221,7 @@ public class XmlSerializer extends WriterSerializer {
                // Handle recursion
                if (aType != null && ! aType.isPrimitive()) {
 
-                       BeanMap bm = null;
+                       BeanMap<?> bm = null;
                        if (aType.isBeanMap()) {
                                bm = (BeanMap)o;
                        } else if (aType.isBean()) {
@@ -262,7 +262,7 @@ public class XmlSerializer extends WriterSerializer {
                                        findNsfMappings(session, o2);
                        }
                        if (bm != null) {
-                               for (BeanMapEntry p : 
(Set<BeanMapEntry>)bm.entrySet(session.isTrimNulls())) {
+                               for (BeanPropertyValue p : bm.getValues(false, 
session.isTrimNulls())) {
 
                                        Namespace ns = 
p.getMeta().getXmlMeta().getNamespace();
                                        if (ns != null && ns.uri != null)
@@ -526,38 +526,38 @@ public class XmlSerializer extends WriterSerializer {
                return hasChildren;
        }
 
-       private boolean serializeBeanMap(XmlSerializerSession session, 
XmlWriter out, BeanMap m, Namespace elementNs, boolean isCollapsed) throws 
Exception {
+       private boolean serializeBeanMap(XmlSerializerSession session, 
XmlWriter out, BeanMap<?> m, Namespace elementNs, boolean isCollapsed) throws 
Exception {
                boolean hasChildren = false;
                BeanMeta bm = m.getMeta();
 
+               List<BeanPropertyValue> lp = m.getValues(false, 
session.isTrimNulls());
+
                Map<String,BeanPropertyMeta> xmlAttrs = 
bm.getXmlMeta().getXmlAttrProperties();
                Object content = null;
-               for (BeanPropertyMeta p : xmlAttrs.values()) {
-
-                       String key = p.getName();
-                       Object value = null;
-                       try {
-                               value = p.get(m);
-                       } catch (StackOverflowError e) {
-                               throw e;
-                       } catch (Throwable x) {
-                               session.addBeanGetterWarning(p, x);
-                       }
+               for (BeanPropertyValue p : lp) {
+                       if (xmlAttrs.containsKey(p.getName())) {
+                               BeanPropertyMeta pMeta = p.getMeta();
+                               String key = p.getName();
+                               Object value = p.getValue();
+                               Throwable t = p.getThrown();
+                               if (t != null)
+                                       session.addBeanGetterWarning(pMeta, t);
 
-                       if (session.canIgnoreValue(p.getClassMeta(), key, 
value))
-                               continue;
+                               if 
(session.canIgnoreValue(pMeta.getClassMeta(), key, value))
+                                       continue;
 
-                       Namespace ns = (session.isEnableNamespaces() && 
p.getXmlMeta().getNamespace() != elementNs ? p.getXmlMeta().getNamespace() : 
null);
+                               Namespace ns = (session.isEnableNamespaces() && 
pMeta.getXmlMeta().getNamespace() != elementNs ? 
pMeta.getXmlMeta().getNamespace() : null);
 
-                       if (p.isBeanUri() || p.isUri())
-                               out.attrUri(ns, key, value);
-                       else
-                               out.attr(ns, key, value);
+                               if (pMeta.isBeanUri() || pMeta.isUri())
+                                       out.attrUri(ns, key, value);
+                               else
+                                       out.attr(ns, key, value);
+                       }
                }
 
                boolean hasContent = false;
 
-               for (BeanMapEntry p : 
(Set<BeanMapEntry>)m.entrySet(session.isTrimNulls())) {
+               for (BeanPropertyValue p : lp) {
                        BeanPropertyMeta pMeta = p.getMeta();
                        XmlFormat xf = pMeta.getXmlMeta().getXmlFormat();
 
@@ -567,15 +567,11 @@ public class XmlSerializer extends WriterSerializer {
                        } else if (xf == ATTR) {
                                // Do nothing
                        } else {
-                               String key = p.getKey();
-                               Object value = null;
-                               try {
-                                       value = p.getValue();
-                               } catch (StackOverflowError e) {
-                                       throw e;
-                               } catch (Throwable x) {
-                                       session.addWarning("Could not call 
getValue() on property ''{0}'', {1}", key, x.getLocalizedMessage());
-                               }
+                               String key = p.getName();
+                               Object value = p.getValue();
+                               Throwable t = p.getThrown();
+                               if (t != null)
+                                       session.addBeanGetterWarning(pMeta, t);
 
                                if 
(session.canIgnoreValue(pMeta.getClassMeta(), key, value))
                                        continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/79d19494/org.apache.juneau/src/test/java/org/apache/juneau/CT_BeanMap.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/CT_BeanMap.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/CT_BeanMap.java
index 2050b4d..838e05b 100755
--- a/org.apache.juneau/src/test/java/org/apache/juneau/CT_BeanMap.java
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/CT_BeanMap.java
@@ -1895,11 +1895,20 @@ public class CT_BeanMap {
                Z z = new Z();
                BeanMap<Z> bm = BeanContext.DEFAULT.forBean(z);
 
-               Iterator i = bm.entrySet(true).iterator();
+               Iterator i = bm.getValues(false, true).iterator();
                assertFalse(i.hasNext());
 
                z.b = "";
-               i = bm.entrySet(true).iterator();
+               i = bm.getValues(false, true).iterator();
+               assertTrue(i.hasNext());
+               i.next();
+               assertFalse(i.hasNext());
+
+               i = bm.getValues(false, false).iterator();
+               assertTrue(i.hasNext());
+               i.next();
+               assertTrue(i.hasNext());
+               i.next();
                assertTrue(i.hasNext());
                i.next();
                assertFalse(i.hasNext());

Reply via email to