Enhanced serializer and parser listener API.

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

Branch: refs/heads/master
Commit: 0ccac121d19b55171c1c9910cb088b2b933d20d7
Parents: 3551f4c
Author: JamesBognar <[email protected]>
Authored: Fri Jun 2 19:59:43 2017 -0400
Committer: JamesBognar <[email protected]>
Committed: Fri Jun 2 19:59:43 2017 -0400

----------------------------------------------------------------------
 .../java/org/apache/juneau/jena/RdfParser.java  |  2 +-
 .../apache/juneau/jena/RdfParserBuilder.java    |  6 ++
 .../org/apache/juneau/jena/RdfSerializer.java   |  2 +-
 .../juneau/jena/RdfSerializerBuilder.java       |  6 ++
 .../apache/juneau/html/CommonParserTest.java    | 23 +++--
 .../apache/juneau/jena/CommonParserTest.java    | 24 ++---
 .../apache/juneau/json/CommonParserTest.java    | 24 ++---
 .../urlencoding/CommonParser_UonTest.java       | 24 ++---
 .../CommonParser_UrlEncodingTest.java           | 24 ++---
 .../org/apache/juneau/xml/CommonParserTest.java | 24 ++---
 .../main/java/org/apache/juneau/Session.java    |  8 +-
 .../org/apache/juneau/csv/CsvParserBuilder.java |  6 ++
 .../apache/juneau/csv/CsvSerializerBuilder.java |  6 ++
 .../juneau/encoders/EncoderGroupBuilder.java    |  1 +
 .../java/org/apache/juneau/html/HtmlParser.java |  2 +-
 .../apache/juneau/html/HtmlParserBuilder.java   |  7 ++
 .../org/apache/juneau/html/HtmlSerializer.java  |  6 +-
 .../juneau/html/HtmlSerializerBuilder.java      |  7 ++
 .../apache/juneau/ini/ConfigFileBuilder.java    |  1 +
 .../org/apache/juneau/internal/ClassUtils.java  | 20 ++++
 .../org/apache/juneau/internal/StringUtils.java |  1 -
 .../org/apache/juneau/jso/JsoParserBuilder.java |  6 ++
 .../apache/juneau/jso/JsoSerializerBuilder.java |  6 ++
 .../java/org/apache/juneau/json/JsonParser.java |  2 +-
 .../apache/juneau/json/JsonParserBuilder.java   |  6 ++
 .../json/JsonSchemaSerializerBuilder.java       |  7 ++
 .../org/apache/juneau/json/JsonSerializer.java  |  2 +-
 .../juneau/json/JsonSerializerBuilder.java      |  6 ++
 .../apache/juneau/msgpack/MsgPackParser.java    |  2 +-
 .../juneau/msgpack/MsgPackParserBuilder.java    |  6 ++
 .../juneau/msgpack/MsgPackSerializer.java       |  2 +-
 .../msgpack/MsgPackSerializerBuilder.java       |  6 ++
 .../java/org/apache/juneau/parser/Parser.java   | 44 ---------
 .../org/apache/juneau/parser/ParserBuilder.java | 20 ++++
 .../org/apache/juneau/parser/ParserContext.java | 17 ++++
 .../juneau/parser/ParserGroupBuilder.java       | 11 +++
 .../apache/juneau/parser/ParserListener.java    | 26 +++--
 .../org/apache/juneau/parser/ParserSession.java | 99 +++++++++++++++++---
 .../plaintext/PlainTextParserBuilder.java       |  6 ++
 .../plaintext/PlainTextSerializerBuilder.java   |  6 ++
 .../juneau/remoteable/RemoteableMeta.java       |  2 +-
 .../juneau/serializer/SerializerBuilder.java    | 20 ++++
 .../juneau/serializer/SerializerContext.java    | 20 +++-
 .../serializer/SerializerGroupBuilder.java      | 15 ++-
 .../juneau/serializer/SerializerListener.java   | 46 +++++++++
 .../juneau/serializer/SerializerSession.java    | 27 +++++-
 .../juneau/soap/SoapXmlSerializerBuilder.java   |  7 ++
 .../java/org/apache/juneau/uon/UonParser.java   |  4 +-
 .../org/apache/juneau/uon/UonParserBuilder.java |  6 ++
 .../org/apache/juneau/uon/UonSerializer.java    |  2 +-
 .../apache/juneau/uon/UonSerializerBuilder.java |  6 ++
 .../juneau/urlencoding/UrlEncodingParser.java   |  4 +-
 .../urlencoding/UrlEncodingParserBuilder.java   |  7 ++
 .../urlencoding/UrlEncodingSerializer.java      |  2 +-
 .../UrlEncodingSerializerBuilder.java           |  7 ++
 .../java/org/apache/juneau/xml/XmlParser.java   |  4 +-
 .../org/apache/juneau/xml/XmlParserBuilder.java |  6 ++
 .../juneau/xml/XmlSchemaSerializerBuilder.java  |  7 ++
 .../org/apache/juneau/xml/XmlSerializer.java    |  6 +-
 .../apache/juneau/xml/XmlSerializerBuilder.java |  6 ++
 juneau-core/src/main/javadoc/overview.html      | 15 +++
 .../juneau/rest/client/RestClientBuilder.java   | 15 +++
 .../java/org/apache/juneau/rest/RestConfig.java | 32 +++++++
 .../org/apache/juneau/rest/RestContext.java     |  4 +-
 .../juneau/rest/annotation/RestResource.java    | 10 ++
 65 files changed, 615 insertions(+), 169 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index 60e6b0b..ed9fc34 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -252,7 +252,7 @@ public class RdfParser extends ReaderParser {
                                        pMeta.set(m, key, value);
                                }
                        } else if (! (p.equals(session.getRootProperty()) || 
p.equals(session.getTypeProperty()))) {
-                               onUnknownProperty(session, key, m, -1, -1);
+                               session.onUnknownProperty(key, m, -1, -1);
                        }
                        session.setCurrentProperty(null);
                }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
index 03dbc48..f5ddfdc 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
@@ -349,6 +349,12 @@ public class RdfParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public RdfParserBuilder listener(Class<? extends ParserListener> value) 
{
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public RdfParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 05dc92e..7ac3cde 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -368,7 +368,7 @@ public class RdfSerializer extends WriterSerializer {
                        Object value = bpv.getValue();
                        Throwable t = bpv.getThrown();
                        if (t != null)
-                               session.addBeanGetterWarning(pMeta, t);
+                               session.onBeanGetterException(pMeta, t);
 
                        if (session.canIgnoreValue(cMeta, key, value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
index 91957a3..6bc1a50 100644
--- 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
+++ 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
@@ -524,6 +524,12 @@ public class RdfSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
        
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public RdfSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
index 90f5c5c..8e4a059 100755
--- 
a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
@@ -142,21 +142,20 @@ public class CommonParserTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               HtmlParser p = new 
HtmlParserBuilder().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               HtmlParser p = new 
HtmlParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String in = "<table 
_type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>unknown</string></td><td><string>/foo</string></td></tr><tr><td><string>b</string></td><td><number>2</number></td></tr></table>";
                p.parse(in, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknown,-1,-1", events.get(0));
+               assertEquals(1, MyParserListener.events.size());
+               assertEquals("unknown,-1,-1", MyParserListener.events.get(0));
        }
+       
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
 
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
index dc59199..d7f2c0a 100755
--- 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
@@ -186,20 +186,20 @@ public class CommonParserTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               RdfParser p = new 
RdfParserBuilder().xml().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               RdfParser p = new 
RdfParserBuilder().xml().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a><jp:unknownProperty>foo</jp:unknownProperty><jp:b
 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>2</jp:b></rdf:Description>");
                p.parse(in, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknownProperty,-1,-1", events.get(0));
+               assertEquals(1, MyParserListener.events.size());
+               assertEquals("unknownProperty,-1,-1", 
MyParserListener.events.get(0));
+       }
+       
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
+
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
index c3e4688..c9734a9 100755
--- 
a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
@@ -161,20 +161,20 @@ public class CommonParserTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               JsonParser p = new 
JsonParserBuilder().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               JsonParser p = new 
JsonParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String json = "{a:1,unknownProperty:\"/foo\",b:2}";
                p.parse(json, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknownProperty,1,5", events.get(0));
+               assertEquals(1, MyParserListener.events.size());
+               assertEquals("unknownProperty,1,5", 
MyParserListener.events.get(0));
+       }
+       
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
+
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
 
b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
index 62a5d9d..ddb79f3 100755
--- 
a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
@@ -150,20 +150,20 @@ public class CommonParser_UonTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               UonParser p = new 
UonParserBuilder().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               UonParser p = new 
UonParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String in = "(a=1,unknownProperty=foo,b=2)";
                p.parse(in, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknownProperty,1,5", events.get(0));
+               assertEquals(1, MyParserListener.events.size());
+               assertEquals("unknownProperty,1,5", 
MyParserListener.events.get(0));
+       }
+       
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
+
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
 
b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
index d480a1b..a8f4e1a 100755
--- 
a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
@@ -152,21 +152,21 @@ public class CommonParser_UrlEncodingTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               UonParser p = new 
UrlEncodingParserBuilder().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               UonParser p = new 
UrlEncodingParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String in = "a=1&unknownProperty=foo&b=2";
                p.parse(in, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknownProperty,1,4", events.get(0));
+               assertEquals(1, MyParserListener.events.size());
+               assertEquals("unknownProperty,1,4", 
MyParserListener.events.get(0));
+       }
+
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
+
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
        }
 
        @Test

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
index 6c06dc3..73e1e4e1 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
@@ -158,21 +158,21 @@ public class CommonParserTest {
        
//====================================================================================================
        @Test
        public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               XmlParser p = new 
XmlParserBuilder().ignoreUnknownBeanProperties(true).build();
-               p.addListener(
-                       new ParserListener() {
-                               @Override /* ParserListener */
-                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
-                                       events.add(propertyName + "," + line + 
"," + col);
-                               }
-                       }
-               );
+               XmlParser p = new 
XmlParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build();
 
                String in = "<object><a _type='number'>1</a><unknownProperty 
_type='string'>foo</unknownProperty><b _type='number'>2</b></object>";
                p.parse(in, B.class);
-               assertEquals(1, events.size());
+               assertEquals(1, MyParserListener.events.size());
                // XML parser may or may not support line numbers.
-               assertTrue(events.get(0).startsWith("unknownProperty,"));
+               
assertTrue(MyParserListener.events.get(0).startsWith("unknownProperty,"));
+       }
+       
+       public static class MyParserListener extends ParserListener {
+               final static List<String> events = new LinkedList<String>();
+
+               @Override /* ParserListener */
+               public <T> void onUnknownBeanProperty(ParserSession session, 
String propertyName, Class<T> beanClass, T bean, int line, int col) {
+                       events.add(propertyName + "," + line + "," + col);
+               }
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/Session.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/Session.java 
b/juneau-core/src/main/java/org/apache/juneau/Session.java
index a75d197..d9bbfc8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/src/main/java/org/apache/juneau/Session.java
@@ -59,7 +59,7 @@ public abstract class Session {
         *      <li>Property defined on the context object.
         *      <li>System.property.
         * </ul>
-        * 
+        *
         * @param key The property key.
         * @return The property value, or <jk>null</jk> if it doesn't exist.
         */
@@ -69,7 +69,7 @@ public abstract class Session {
 
        /**
         * Same as {@link #getProperty(String)} but with a default value.
-        * 
+        *
         * @param key The property key.
         * @param def The default value if the property doesn't exist or is 
<jk>null</jk>.
         * @return The property value.
@@ -85,7 +85,7 @@ public abstract class Session {
 
        /**
         * Same as {@link #getProperty(String)} but transforms the value to the 
specified type.
-        * 
+        *
         * @param type The class type of the value.
         * @param key The property key.
         * @return The property value.
@@ -96,7 +96,7 @@ public abstract class Session {
 
        /**
         * Same as {@link #getProperty(Class,String)} but with a default value.
-        * 
+        *
         * @param type The class type of the value.
         * @param key The property key.
         * @param def The default value if the property doesn't exist or is 
<jk>null</jk>.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
index addbbb7..a33f9d6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
@@ -77,6 +77,12 @@ public class CsvParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public CsvParserBuilder listener(Class<? extends ParserListener> value) 
{
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public CsvParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
index eb002b3..e752a82 100644
--- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
@@ -162,6 +162,12 @@ public class CsvSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public CsvSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public CsvSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
index 2180fd1..be4546b 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.encoders;
 
 import static org.apache.juneau.internal.CollectionUtils.*;
+
 import java.util.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java 
b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
index 3d80c7b..5376b0a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -461,7 +461,7 @@ public class HtmlParser extends XmlParser {
                                nextTag(r, TD);
                                BeanPropertyMeta pMeta = m.getPropertyMeta(key);
                                if (pMeta == null) {
-                                       onUnknownProperty(session, key, m, -1, 
-1);
+                                       session.onUnknownProperty(key, m, -1, 
-1);
                                        parseAnything(session, object(), r, 
null, false, null);
                                } else {
                                        ClassMeta<?> cm = pMeta.getClassMeta();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
index 6c9f27c..4c2c283 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
@@ -19,6 +19,7 @@ import javax.xml.stream.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.parser.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -105,6 +106,12 @@ public class HtmlParserBuilder extends XmlParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public HtmlParserBuilder listener(Class<? extends ParserListener> 
value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public HtmlParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 736e8c8..0bb39b8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -381,7 +381,7 @@ public class HtmlSerializer extends XmlSerializer {
                        } catch (StackOverflowError t) {
                                throw t;
                        } catch (Throwable t) {
-                               session.addWarning("Could not call getValue() 
on property ''{0}'', {1}", e.getKey(), t.getLocalizedMessage());
+                               session.onError(t, "Could not call getValue() 
on property ''{0}'', {1}", e.getKey(), t.getLocalizedMessage());
                        }
 
                        out.sTag(i+1, "tr").nl();
@@ -429,7 +429,7 @@ public class HtmlSerializer extends XmlSerializer {
                        Object value = p.getValue();
                        Throwable t = p.getThrown();
                        if (t != null)
-                               session.addBeanGetterWarning(pMeta, t);
+                               session.onBeanGetterException(pMeta, t);
 
                        if (session.canIgnoreValue(cMeta, key, value))
                                continue;
@@ -456,7 +456,7 @@ public class HtmlSerializer extends XmlSerializer {
                                throw e;
                        } catch (Throwable e) {
                                e.printStackTrace();
-                               session.addBeanGetterWarning(pMeta, e);
+                               session.onBeanGetterException(pMeta, e);
                        }
                        out.eTag("td").nl();
                        out.eTag(i+1, "tr").nl();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
index b9a7fad..c2f4112 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.serializer.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -334,6 +335,12 @@ public class HtmlSerializerBuilder extends 
XmlSerializerBuilder {
        }
 
        @Override /* SerializerBuilder */
+       public HtmlSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
        public HtmlSerializerBuilder sortMaps(boolean value) {
                super.sortMaps(value);
                return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileBuilder.java
index 5d44f10..67a1693 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileBuilder.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.ini.ConfigFileFormat.*;
 import java.io.*;
 import java.nio.charset.*;
 import java.util.*;
+
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/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 3b31bfc..f3163d3 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
@@ -739,4 +739,24 @@ public final class ClassUtils {
                        returnType = 
BeanContext.DEFAULT.getClassMeta(m.getGenericReturnType()).toString();
                }
        }
+
+       /**
+        * Creates an instance of the specified class without throwing 
exceptions.
+        *
+        * @param c The class to instantiate.
+        * @param args The arguments to pass to the constructor.
+        * @return The new class instance, or <jk>null</jk> if the class was 
<jk>null</jk>.
+        * @throws RuntimeException if constructor could not be found or called.
+        */
+       public static <T> T newInstance(Class<T> c, Object...args) {
+               if (c == null)
+                       return null;
+               try {
+                       if (args.length == 0)
+                               return c.newInstance();
+                       return 
c.getConstructor(getClasses(args)).newInstance(args);
+               } catch (Exception e) {
+                       throw new RuntimeException(e);
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java 
b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
index d17bc58..c4bf1db 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -26,7 +26,6 @@ import java.util.regex.*;
 import javax.xml.bind.*;
 
 import org.apache.juneau.parser.*;
-import org.apache.juneau.parser.ParseException;
 
 /**
  * Reusable string utility methods.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
index 210460b..aa5e448 100644
--- a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
@@ -78,6 +78,12 @@ public class JsoParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public JsoParserBuilder listener(Class<? extends ParserListener> value) 
{
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public JsoParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
index 3508985..1da92e6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
@@ -162,6 +162,12 @@ public class JsoSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public JsoSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public JsoSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
index 490eed1..8fb7fd2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -498,7 +498,7 @@ public class JsonParser extends ReaderParser {
                                                BeanPropertyMeta pMeta = 
m.getPropertyMeta(currAttr);
                                                
session.setCurrentProperty(pMeta);
                                                if (pMeta == null) {
-                                                       
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+                                                       
session.onUnknownProperty(currAttr, m, currAttrLine, currAttrCol);
                                                        parseAnything(session, 
object(), r.unread(), m.getBean(false), null); // Read content anyway to ignore 
it
                                                } else {
                                                        ClassMeta<?> cm = 
pMeta.getClassMeta();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
index 1d6a3ad..40cfd30 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
@@ -78,6 +78,12 @@ public class JsonParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public JsonParserBuilder listener(Class<? extends ParserListener> 
value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public JsonParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
index 112cbee..d58aca2 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
@@ -16,6 +16,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.serializer.*;
 
 /**
  * Builder class for building instances of JSON Schema serializers.
@@ -179,6 +180,12 @@ public class JsonSchemaSerializerBuilder extends 
JsonSerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public JsonSchemaSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public JsonSchemaSerializerBuilder 
beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 1037e60..4ec9298 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -322,7 +322,7 @@ public class JsonSerializer extends WriterSerializer {
                        Object value = p.getValue();
                        Throwable t = p.getThrown();
                        if (t != null)
-                               session.addBeanGetterWarning(pMeta, t);
+                               session.onBeanGetterException(pMeta, t);
 
                        if (session.canIgnoreValue(cMeta, key, value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
index 33be93f..98ed08c 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
@@ -227,6 +227,12 @@ public class JsonSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public JsonSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public JsonSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index 51ec189..b02ee46 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -131,7 +131,7 @@ public class MsgPackParser extends InputStreamParser {
                                                        if 
(pName.equals(session.getBeanTypePropertyName(eType)))
                                                                
parseAnything(session, session.string(), is, null, null);
                                                        else
-                                                               
onUnknownProperty(session, pName, m, 0, is.getPosition());
+                                                               
session.onUnknownProperty(pName, m, 0, is.getPosition());
                                                } else {
                                                        ClassMeta<?> cm = 
bpm.getClassMeta();
                                                        Object value = 
parseAnything(session, cm, is, m.getBean(false), bpm);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
index 26df53b..38d2841 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
@@ -78,6 +78,12 @@ public class MsgPackParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public MsgPackParserBuilder listener(Class<? extends ParserListener> 
value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public MsgPackParserBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index c47b630..0f4949c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -172,7 +172,7 @@ public class MsgPackSerializer extends 
OutputStreamSerializer {
                        Object value = p.getValue();
                        Throwable t = p.getThrown();
                        if (t != null)
-                               session.addBeanGetterWarning(pMeta, t);
+                               session.onBeanGetterException(pMeta, t);
                        else {
                                serializeAnything(session, out, key, null, 
null, null);
                                serializeAnything(session, out, value, cMeta, 
key, pMeta);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
index 36ebe9f..fc4935f 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
@@ -162,6 +162,12 @@ public class MsgPackSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public MsgPackSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public MsgPackSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
index a1f00a0..38c6d16 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
@@ -134,7 +134,6 @@ import org.apache.juneau.utils.*;
 public abstract class Parser extends CoreObject {
 
        /** General parser properties currently set on this parser. */
-       private final List<ParserListener> listeners = new 
LinkedList<ParserListener>();
        private final MediaType[] mediaTypes;
        private final ParserContext ctx;
 
@@ -506,26 +505,6 @@ public abstract class Parser extends CoreObject {
        
//--------------------------------------------------------------------------------
 
        /**
-        * Adds a {@link ParserListener} to this parser to listen for parse 
events.
-        *
-        * @param listener The listener to associate with this parser.
-        * @return This object (for method chaining).
-        */
-       public Parser addListener(ParserListener listener) {
-               this.listeners.add(listener);
-               return this;
-       }
-
-       /**
-        * Returns the current parser listeners associated with this parser.
-        *
-        * @return The current list of parser listeners.
-        */
-       public List<ParserListener> getListeners() {
-               return listeners;
-       }
-
-       /**
         * Converts the specified string to the specified type.
         *
         * @param session The session object.
@@ -602,29 +581,6 @@ public abstract class Parser extends CoreObject {
        }
 
        /**
-        * Method that gets called when an unknown bean property name is 
encountered.
-        *
-        * @param session The parser session.
-        * @param propertyName The unknown bean property name.
-        * @param beanMap The bean that doesn't have the expected property.
-        * @param line The line number where the property was found.  
<code>-1</code> if line numbers are not available.
-        * @param col The column number where the property was found.  
<code>-1</code> if column numbers are not available.
-        * @throws ParseException Automatically thrown if {@link 
BeanContext#BEAN_ignoreUnknownBeanProperties} setting
-        *      on this parser is <jk>false</jk>
-        * @param <T> The class type of the bean map that doesn't have the 
expected property.
-        */
-       protected <T> void onUnknownProperty(ParserSession session, String 
propertyName, BeanMap<T> beanMap, int line, int col) throws ParseException {
-               if 
(propertyName.equals(session.getBeanTypePropertyName(beanMap.getClassMeta())))
-                       return;
-               if (! session.isIgnoreUnknownBeanProperties())
-                       throw new ParseException(session, "Unknown property 
''{0}'' encountered while trying to parse into class ''{1}''", propertyName, 
beanMap.getClassMeta());
-               if (listeners.size() > 0)
-                       for (ParserListener listener : listeners)
-                               listener.onUnknownProperty(propertyName, 
beanMap.getClassMeta().getInnerClass(), beanMap.getBean(), line, col);
-       }
-
-
-       /**
         * Returns the media types handled based on the value of the {@link 
Consumes} annotation on the parser class.
         * <p>
         * This method can be overridden by subclasses to determine the media 
types programatically.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
index bdf3cf3..dbc9d86 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
@@ -192,6 +192,26 @@ public class ParserBuilder extends CoreObjectBuilder {
                return property(PARSER_fileCharset, value);
        }
 
+       /**
+        * <b>Configuration property:</b>  Parser listener.
+        * <p>
+        * <ul>
+        *      <li><b>Name:</b> <js>"Parser.listener"</js>
+        *      <li><b>Data type:</b> <code>Class&lt;? extends 
ParserListener&gt;</code>
+        *      <li><b>Default:</b> <jk>null</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * <p>
+        * Class used to listen for errors and warnings that occur during 
parsing.
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see ParserContext#PARSER_listener
+        */
+       public ParserBuilder listener(Class<? extends ParserListener> value) {
+               return property(PARSER_listener, value);
+       }
+
        @Override /* CoreObjectBuilder */
        public ParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
index e0ee73c..bff9dec 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
@@ -110,21 +110,37 @@ public class ParserContext extends BeanContext {
         */
        public static final String PARSER_fileCharset = "Parser.fileCharset";
 
+       /**
+        * <b>Configuration property:</b>  Parser listener.
+        * <p>
+        * <ul>
+        *      <li><b>Name:</b> <js>"Parser.listener"</js>
+        *      <li><b>Data type:</b> <code>Class&lt;? extends 
ParserListener&gt;</code>
+        *      <li><b>Default:</b> <jk>null</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * <p>
+        * Class used to listen for errors and warnings that occur during 
parsing.
+        */
+       public static final String PARSER_listener = "PARSER.listener";
 
        final boolean trimStrings, strict;
        final String inputStreamCharset, fileCharset;
+       final Class<? extends ParserListener> listener;
 
        /**
         * Constructor.
         *
         * @param ps The property store that created this context.
         */
+       @SuppressWarnings("unchecked")
        public ParserContext(PropertyStore ps) {
                super(ps);
                this.trimStrings = ps.getProperty(PARSER_trimStrings, 
boolean.class, false);
                this.strict = ps.getProperty(PARSER_strict, boolean.class, 
false);
                this.inputStreamCharset = 
ps.getProperty(PARSER_inputStreamCharset, String.class, "UTF-8");
                this.fileCharset = ps.getProperty(PARSER_fileCharset, 
String.class, "default");
+               this.listener = ps.getProperty(PARSER_listener, Class.class, 
null);
        }
 
        @Override /* Context */
@@ -135,6 +151,7 @@ public class ParserContext extends BeanContext {
                                .append("strict", strict)
                                .append("inputStreamCharset", 
inputStreamCharset)
                                .append("fileCharset", fileCharset)
+                               .append("listener", listener)
                        );
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
index 06383a9..f9dc3f3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
@@ -252,6 +252,17 @@ public class ParserGroupBuilder {
        }
 
        /**
+        * Sets the {@link ParserContext#PARSER_listener} property on all 
parsers in this group.
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see ParserContext#PARSER_listener
+        */
+       public ParserGroupBuilder listener(Class<? extends ParserListener> 
value) {
+               return property(PARSER_listener, value);
+       }
+
+       /**
         * Sets the {@link BeanContext#BEAN_beansRequireDefaultConstructor} 
property on all parsers in this group.
         *
         * @param value The new value for this property.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
index 9c01704..dd1989d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
@@ -12,14 +12,12 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.parser;
 
+import java.text.*;
+
 import org.apache.juneau.*;
 
 /**
  * Class for listening for certain parse events during a document parse.
- * <p>
- * Listeners can be registered with parsers through the {@link 
Parser#addListener(ParserListener)} method.
- * <p>
- * It should be noted that listeners are not automatically copied over to new 
parsers when a parser is cloned using the {@link Parser#builder()} method.
  */
 public class ParserListener {
 
@@ -30,13 +28,29 @@ public class ParserListener {
         * Otherwise, the parser will throw a {@link ParseException}.
         *
         * @param <T> The class type of the bean.
+        * @param session The parser session.
+        *      Note that if {@link BeanContext#BEAN_debug} is enabled on the 
parser, you can get the input as a string through
+        *      {@link ParserSession#getInputAsString()}.
         * @param propertyName The property name encountered in the document.
         * @param beanClass The bean class.
         * @param bean The bean.
         * @param line The line number where the unknown property was found (-1 
if parser doesn't support line/column indicators).
         * @param col The column number where the unknown property was found 
(-1 if parser doesn't support line/column indicators).
         */
-       public <T> void onUnknownProperty(String propertyName, Class<T> 
beanClass, T bean, int line, int col) {
-               // Do something with information
+       public <T> void onUnknownBeanProperty(ParserSession session, String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
+               onError(session, null, MessageFormat.format("Unknown property 
''{0}'' encountered while trying to parse into class ''{1}'' at line {2} column 
{3}", propertyName, beanClass, line, col));
+       }
+
+       /**
+        * Called when an error occurs during parsing but is ignored.
+        *
+        * @param session The parsers session.
+        *      Note that if {@link BeanContext#BEAN_debug} is enabled on the 
parser, you can get the input as a string through
+        *      {@link ParserSession#getInputAsString()}.
+        * @param t The throwable that was thrown by the getter method.
+        * @param msg The error message.
+        */
+       public void onError(ParserSession session, Throwable t, String msg) {
+               // Do something with this information.
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
index 5704dce..0b28ce6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -36,10 +36,12 @@ public class ParserSession extends BeanSession {
        private final Method javaMethod;
        private final Object outer;
        private final Object input;
+       private String inputString;
        private InputStream inputStream;
        private Reader reader, noCloseReader;
        private BeanPropertyMeta currentProperty;
        private ClassMeta<?> currentClass;
+       private final ParserListener listener;
 
        /**
         * Create a new session using properties specified in the context.
@@ -73,22 +75,31 @@ public class ParserSession extends BeanSession {
         * If <jk>null</jk>, then the timezone defined on the context is used.
         * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
+       @SuppressWarnings("unchecked")
        public ParserSession(ParserContext ctx, ObjectMap op, Object input, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
                super(ctx, op, locale, timeZone, mediaType);
+               Class<? extends ParserListener> listenerClass;
                if (op == null || op.isEmpty()) {
                        trimStrings = ctx.trimStrings;
                        strict = ctx.strict;
                        inputStreamCharset = ctx.inputStreamCharset;
                        fileCharset = ctx.fileCharset;
+                       listenerClass = ctx.listener;
                } else {
                        trimStrings = op.getBoolean(PARSER_trimStrings, 
ctx.trimStrings);
                        strict = op.getBoolean(PARSER_strict, ctx.strict);
                        inputStreamCharset = 
op.getString(PARSER_inputStreamCharset, ctx.inputStreamCharset);
                        fileCharset = op.getString(PARSER_fileCharset, 
ctx.fileCharset);
+                       listenerClass = op.get(Class.class, PARSER_listener, 
ctx.listener);
                }
                this.input = input;
                this.javaMethod = javaMethod;
                this.outer = outer;
+               try {
+                       this.listener = listenerClass == null ? null : 
listenerClass.newInstance();
+               } catch (Exception e) {
+                       throw new RuntimeException(e);
+               }
        }
 
        /**
@@ -99,21 +110,38 @@ public class ParserSession extends BeanSession {
         * @throws ParseException If object could not be converted to an input 
stream.
         */
        public InputStream getInputStream() throws ParseException {
-               if (input == null)
-                       return null;
-               if (input instanceof InputStream)
-                       return (InputStream)input;
-               if (input instanceof byte[])
-                       return new ByteArrayInputStream((byte[])input);
-               if (input instanceof String)
-                       return new 
ByteArrayInputStream(StringUtils.fromHex((String)input));
-               if (input instanceof File)
-                       try {
+               try {
+                       if (input == null)
+                               return null;
+                       if (input instanceof InputStream) {
+                               if (isDebug()) {
+                                       byte[] b = 
IOUtils.readBytes((InputStream)input, 1024);
+                                       inputString = StringUtils.toHex(b);
+                                       return new ByteArrayInputStream(b);
+                               }
+                               return (InputStream)input;
+                       }
+                       if (input instanceof byte[]) {
+                               if (isDebug())
+                                       inputString = 
StringUtils.toHex((byte[])input);
+                               return new ByteArrayInputStream((byte[])input);
+                       }
+                       if (input instanceof String) {
+                               inputString = (String)input;
+                               return new 
ByteArrayInputStream(StringUtils.fromHex((String)input));
+                       }
+                       if (input instanceof File) {
+                               if (isDebug()) {
+                                       byte[] b = 
IOUtils.readBytes((File)input);
+                                       inputString = StringUtils.toHex(b);
+                                       return new ByteArrayInputStream(b);
+                               }
                                inputStream = new FileInputStream((File)input);
                                return inputStream;
-                       } catch (FileNotFoundException e) {
-                               throw new ParseException(e);
                        }
+               } catch (IOException e) {
+                       throw new ParseException(e);
+               }
                throw new ParseException("Cannot convert object of type {0} to 
an InputStream.", input.getClass().getName());
        }
 
@@ -128,9 +156,15 @@ public class ParserSession extends BeanSession {
        public Reader getReader() throws Exception {
                if (input == null)
                        return null;
-               if (input instanceof Reader)
+               if (input instanceof Reader) {
+                       if (isDebug()) {
+                               inputString = IOUtils.read((Reader)input);
+                               return new StringReader(inputString);
+                       }
                        return (Reader)input;
+               }
                if (input instanceof CharSequence) {
+                       inputString = input.toString();
                        if (reader == null)
                                reader = new ParserReader((CharSequence)input);
                        return reader;
@@ -148,6 +182,10 @@ public class ParserSession extends BeanSession {
                                }
                                noCloseReader = new InputStreamReader(is, cd);
                        }
+                       if (isDebug()) {
+                               inputString = IOUtils.read(noCloseReader);
+                               return new StringReader(inputString);
+                       }
                        return noCloseReader;
                }
                if (input instanceof File) {
@@ -162,6 +200,10 @@ public class ParserSession extends BeanSession {
                                }
                                reader = new InputStreamReader(new 
FileInputStream((File)input), cd);
                        }
+                       if (isDebug()) {
+                               inputString = IOUtils.read(reader);
+                               return new StringReader(inputString);
+                       }
                        return reader;
                }
                throw new ParseException("Cannot convert object of type {0} to 
a Reader.", input.getClass().getName());
@@ -344,6 +386,37 @@ public class ParserSession extends BeanSession {
        }
 
        /**
+        * Method that gets called when an unknown bean property name is 
encountered.
+        *
+        * @param propertyName The unknown bean property name.
+        * @param beanMap The bean that doesn't have the expected property.
+        * @param line The line number where the property was found.  
<code>-1</code> if line numbers are not available.
+        * @param col The column number where the property was found.  
<code>-1</code> if column numbers are not available.
+        * @throws ParseException Automatically thrown if {@link 
BeanContext#BEAN_ignoreUnknownBeanProperties} setting
+        *      on this parser is <jk>false</jk>
+        * @param <T> The class type of the bean map that doesn't have the 
expected property.
+        */
+       public <T> void onUnknownProperty(String propertyName, BeanMap<T> 
beanMap, int line, int col) throws ParseException {
+               if 
(propertyName.equals(getBeanTypePropertyName(beanMap.getClassMeta())))
+                       return;
+               if (! isIgnoreUnknownBeanProperties())
+                       throw new ParseException(this, "Unknown property 
''{0}'' encountered while trying to parse into class ''{1}''", propertyName, 
beanMap.getClassMeta());
+               if (listener != null)
+                       listener.onUnknownBeanProperty(this, propertyName, 
beanMap.getClassMeta().getInnerClass(), beanMap.getBean(), line, col);
+       }
+
+       /**
+        * Returns the input to this parser as a plain string.
+        * <p>
+        * This method only returns a value if {@link BeanContext#BEAN_debug} 
is enabled.
+        *
+        * @return The input as a string, or <jk>null</jk> if debug mode not 
enabled.
+        */
+       public String getInputAsString() {
+               return inputString;
+       }
+
+       /**
         * Perform cleanup on this context object if necessary.
         */
        @Override

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
index bb60f4c..9f9177d 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
@@ -78,6 +78,12 @@ public class PlainTextParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public PlainTextParserBuilder listener(Class<? extends ParserListener> 
value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public PlainTextParserBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
index 596fed2..883053a 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
@@ -162,6 +162,12 @@ public class PlainTextSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public PlainTextSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public PlainTextSerializerBuilder 
beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMeta.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMeta.java 
b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMeta.java
index 98ea600..0fb31b2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMeta.java
@@ -12,8 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.remoteable;
 
-import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ClassUtils.*;
+import static org.apache.juneau.internal.StringUtils.*;
 
 import java.lang.reflect.*;
 import java.util.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
index 79d6a29..3716d23 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
@@ -557,6 +557,26 @@ public class SerializerBuilder extends CoreObjectBuilder {
                return property(SERIALIZER_abridged, value);
        }
 
+       /**
+        * <b>Configuration property:</b>  Serializer listener.
+        * <p>
+        * <ul>
+        *      <li><b>Name:</b> <js>"Serializer.listener"</js>
+        *      <li><b>Data type:</b> <code>Class&lt;? extends 
SerializerListener&gt;</code>
+        *      <li><b>Default:</b> <jk>null</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * <p>
+        * Class used to listen for errors and warnings that occur during 
serialization.
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see SerializerContext#SERIALIZER_listener
+        */
+       public SerializerBuilder listener(Class<? extends SerializerListener> 
value) {
+               return property(SERIALIZER_listener, value);
+       }
+
        @Override /* CoreObjectBuilder */
        public SerializerBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
index 372e8e0..1381972 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
@@ -320,7 +320,7 @@ public class SerializerContext extends BeanContext {
         * <b>Configuration property:</b>  Abridged output.
         * <p>
         * <ul>
-        *      <li><b>Name:</b> <js>"Serializer.parserKnowsRootType"</js>
+        *      <li><b>Name:</b> <js>"Serializer.abridged"</js>
         *      <li><b>Data type:</b> <code>Boolean</code>
         *      <li><b>Default:</b> <jk>false</jk>
         *      <li><b>Session-overridable:</b> <jk>true</jk>
@@ -335,6 +335,20 @@ public class SerializerContext extends BeanContext {
         */
        public static final String SERIALIZER_abridged = "Serializer.abridged";
 
+       /**
+        * <b>Configuration property:</b>  Serializer listener.
+        * <p>
+        * <ul>
+        *      <li><b>Name:</b> <js>"Serializer.listener"</js>
+        *      <li><b>Data type:</b> <code>Class&lt;? extends 
SerializerListener&gt;</code>
+        *      <li><b>Default:</b> <jk>null</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * <p>
+        * Class used to listen for errors and warnings that occur during 
serialization.
+        */
+       public static final String SERIALIZER_listener = "Serializer.listener";
+
 
        final int maxDepth, initialDepth;
        final boolean
@@ -353,12 +367,14 @@ public class SerializerContext extends BeanContext {
        final UriContext uriContext;
        final UriResolution uriResolution;
        final UriRelativity uriRelativity;
+       final Class<? extends SerializerListener> listener;
 
        /**
         * Constructor.
         *
         * @param ps The property store that created this context.
         */
+       @SuppressWarnings("unchecked")
        public SerializerContext(PropertyStore ps) {
                super(ps);
                maxDepth = ps.getProperty(SERIALIZER_maxDepth, int.class, 100);
@@ -378,6 +394,7 @@ public class SerializerContext extends BeanContext {
                uriContext = ps.getProperty(SERIALIZER_uriContext, 
UriContext.class, UriContext.DEFAULT);
                uriResolution = ps.getProperty(SERIALIZER_uriResolution, 
UriResolution.class, UriResolution.ROOT_RELATIVE);
                uriRelativity = ps.getProperty(SERIALIZER_uriRelativity, 
UriRelativity.class, UriRelativity.RESOURCE);
+               listener = ps.getProperty(SERIALIZER_listener, Class.class, 
null);
        }
 
        @Override /* Context */
@@ -401,6 +418,7 @@ public class SerializerContext extends BeanContext {
                                .append("uriContext", uriContext)
                                .append("uriResolution", uriResolution)
                                .append("uriRelativity", uriRelativity)
+                               .append("listener", listener)
                        );
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
index bbe7577..d34b07f 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.serializer;
 
 import static org.apache.juneau.BeanContext.*;
-import static org.apache.juneau.serializer.SerializerContext.*;
 import static org.apache.juneau.internal.CollectionUtils.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
 
 import java.util.*;
 
@@ -408,11 +408,22 @@ public class SerializerGroupBuilder {
         * @return This object (for method chaining).
         * @see SerializerContext#SERIALIZER_abridged
         */
-       public SerializerGroupBuilder parserKnowsRootType(boolean value) {
+       public SerializerGroupBuilder abridged(boolean value) {
                return property(SERIALIZER_abridged, value);
        }
 
        /**
+        * Sets the {@link SerializerContext#SERIALIZER_listener} property on 
all serializers in this group.
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see SerializerContext#SERIALIZER_listener
+        */
+       public SerializerGroupBuilder listener(Class<? extends 
SerializerListener> value) {
+               return property(SERIALIZER_listener, value);
+       }
+
+       /**
         * Sets the {@link BeanContext#BEAN_beansRequireDefaultConstructor} 
property on all serializers in this group.
         *
         * @param value The new value for this property.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerListener.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerListener.java
 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerListener.java
new file mode 100644
index 0000000..9125063
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerListener.java
@@ -0,0 +1,46 @@
+// 
***************************************************************************************************************************
+// * 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.serializer;
+
+import java.text.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Class for listening for serialize events during a serialization.
+ */
+public class SerializerListener {
+
+       /**
+        * Called when an exception is thrown when trying to call a bean getter 
method.
+        *
+        * @param session The serializer session.
+        *      Note that if
+        * @param t The throwable that was thrown by the getter method.
+        * @param p The bean property we had an issue on.
+        */
+       public void onBeanGetterException(SerializerSession session, Throwable 
t, BeanPropertyMeta p) {
+               onError(session, t, MessageFormat.format("Could not call 
getValue() on property ''{1}'' of class ''{2}'', exception = {3}", p.getName(), 
p.getBeanMeta().getClassMeta(), t.getLocalizedMessage()));
+       }
+
+       /**
+        * Called when an error occurs during serialization but is ignored.
+        *
+        * @param session The serializer session.
+        * @param t The throwable that was thrown by the getter method.
+        * @param msg The error message.
+        */
+       public void onError(SerializerSession session, Throwable t, String msg) 
{
+               // Do something with this information.
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 9a96a30..a52314a 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -17,6 +17,7 @@ import static 
org.apache.juneau.serializer.SerializerContext.*;
 
 import java.io.*;
 import java.lang.reflect.*;
+import java.text.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -67,6 +68,7 @@ public class SerializerSession extends BeanSession {
        private Writer writer, flushOnlyWriter;
        private BeanPropertyMeta currentProperty;
        private ClassMeta<?> currentClass;
+       private final SerializerListener listener;
 
 
        /**
@@ -97,12 +99,14 @@ public class SerializerSession extends BeanSession {
         * @param uriContext The URI context.
         *      Identifies the current request URI used for resolution of URIs 
to absolute or root-relative form.
         */
+       @SuppressWarnings("unchecked")
        public SerializerSession(SerializerContext ctx, ObjectMap op, Object 
output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType 
mediaType, UriContext uriContext) {
                super(ctx, op, locale, timeZone, mediaType);
                this.javaMethod = javaMethod;
                this.output = output;
                UriResolution uriResolution;
                UriRelativity uriRelativity;
+               Class<? extends SerializerListener> listenerClass;
                if (op == null || op.isEmpty()) {
                        maxDepth = ctx.maxDepth;
                        initialDepth = ctx.initialDepth;
@@ -120,6 +124,7 @@ public class SerializerSession extends BeanSession {
                        abridged = ctx.abridged;
                        uriResolution = ctx.uriResolution;
                        uriRelativity = ctx.uriRelativity;
+                       listenerClass = ctx.listener;
                } else {
                        maxDepth = op.getInt(SERIALIZER_maxDepth, ctx.maxDepth);
                        initialDepth = op.getInt(SERIALIZER_initialDepth, 
ctx.initialDepth);
@@ -137,10 +142,13 @@ public class SerializerSession extends BeanSession {
                        abridged = op.getBoolean(SERIALIZER_abridged, 
ctx.abridged);
                        uriResolution = op.get(UriResolution.class, 
SERIALIZER_uriResolution, UriResolution.ROOT_RELATIVE);
                        uriRelativity = op.get(UriRelativity.class, 
SERIALIZER_uriRelativity, UriRelativity.RESOURCE);
+                       listenerClass = op.get(Class.class, 
SERIALIZER_listener, ctx.listener);
                }
 
                uriResolver = new UriResolver(uriResolution, uriRelativity, 
uriContext == null ? ctx.uriContext : uriContext);
 
+               listener = ClassUtils.newInstance(listenerClass);
+
                this.indent = initialDepth;
                if (detectRecursions || isDebug()) {
                        set = new IdentityHashMap<Object,Object>();
@@ -435,7 +443,7 @@ public class SerializerSession extends BeanSession {
                        Object o = stack.removeLast().o;
                        Object o2 = set.remove(o);
                        if (o2 == null)
-                               addWarning("Couldn't remove object of type 
''{0}'' on attribute ''{1}'' from object stack.", o.getClass().getName(), 
stack);
+                               onError(null, "Couldn't remove object of type 
''{0}'' on attribute ''{1}'' from object stack.", o.getClass().getName(), 
stack);
                }
                isBottom = false;
        }
@@ -455,12 +463,27 @@ public class SerializerSession extends BeanSession {
         * @param p The bean map entry representing the bean property.
         * @param t The throwable that the bean getter threw.
         */
-       public void addBeanGetterWarning(BeanPropertyMeta p, Throwable t) {
+       public void onBeanGetterException(BeanPropertyMeta p, Throwable t) {
+               if (listener != null)
+                       listener.onBeanGetterException(this, t, p);
                String prefix = (isDebug() ? getStack(false) + ": " : "");
                addWarning("{0}Could not call getValue() on property ''{1}'' of 
class ''{2}'', exception = {3}", prefix, p.getName(), 
p.getBeanMeta().getClassMeta(), t.getLocalizedMessage());
        }
 
        /**
+        * Logs a warning message.
+        *
+        * @param t The throwable that was thrown (if there was one).
+        * @param msg The warning message.
+        * @param args Optional {@link MessageFormat}-style arguments.
+        */
+       public final void onError(Throwable t, String msg, Object... args) {
+               if (listener != null)
+                       listener.onError(this, t, MessageFormat.format(msg, 
args));
+               super.addWarning(msg, args);
+       }
+
+       /**
         * Trims the specified string if {@link 
SerializerSession#isTrimStrings()} returns <jk>true</jk>.
         *
         * @param o The input string to trim.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
index 015e662..ad67be4 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.serializer.*;
 import org.apache.juneau.xml.*;
 
 /**
@@ -223,6 +224,12 @@ public class SoapXmlSerializerBuilder extends 
XmlSerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public SoapXmlSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public SoapXmlSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java 
b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
index 020a2f4..32ea7b4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -458,7 +458,7 @@ public class UonParser extends ReaderParser {
                                                if (! 
currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
                                                        BeanPropertyMeta pMeta 
= m.getPropertyMeta(currAttr);
                                                        if (pMeta == null) {
-                                                               
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+                                                               
session.onUnknownProperty(currAttr, m, currAttrLine, currAttrCol);
                                                        } else {
                                                                Object value = 
session.convertToType("", pMeta.getClassMeta());
                                                                pMeta.set(m, 
currAttr, value);
@@ -471,7 +471,7 @@ public class UonParser extends ReaderParser {
                                                if (! 
currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
                                                        BeanPropertyMeta pMeta 
= m.getPropertyMeta(currAttr);
                                                        if (pMeta == null) {
-                                                               
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+                                                               
session.onUnknownProperty(currAttr, m, currAttrLine, currAttrCol);
                                                                
parseAnything(session, object(), r.unread(), m.getBean(false), false, null); // 
Read content anyway to ignore it
                                                        } else {
                                                                
session.setCurrentProperty(pMeta);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
index ef29a73..4d1f576 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
@@ -116,6 +116,12 @@ public class UonParserBuilder extends ParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public UonParserBuilder listener(Class<? extends ParserListener> value) 
{
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public UonParserBuilder beansRequireDefaultConstructor(boolean value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
index 8eed75b..96901d2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -327,7 +327,7 @@ public class UonSerializer extends WriterSerializer {
                        Object value = p.getValue();
                        Throwable t = p.getThrown();
                        if (t != null)
-                               session.addBeanGetterWarning(pMeta, t);
+                               session.onBeanGetterException(pMeta, t);
 
                        if (session.canIgnoreValue(cMeta, key, value))
                                continue;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
index 3d0ee3d..b64350e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
@@ -204,6 +204,12 @@ public class UonSerializerBuilder extends 
SerializerBuilder {
                return this;
        }
 
+       @Override /* SerializerBuilder */
+       public UonSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public UonSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index cb9f19c..800129f 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -269,7 +269,7 @@ public class UrlEncodingParser extends UonParser {
                                                if (! 
currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
                                                        BeanPropertyMeta pMeta 
= m.getPropertyMeta(currAttr);
                                                        if (pMeta == null) {
-                                                               
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+                                                               
session.onUnknownProperty(currAttr, m, currAttrLine, currAttrCol);
                                                        } else {
                                                                
session.setCurrentProperty(pMeta);
                                                                // In cases of 
"&foo=", create an empty instance of the value if createable.
@@ -287,7 +287,7 @@ public class UrlEncodingParser extends UonParser {
                                                if (! 
currAttr.equals(session.getBeanTypePropertyName(m.getClassMeta()))) {
                                                        BeanPropertyMeta pMeta 
= m.getPropertyMeta(currAttr);
                                                        if (pMeta == null) {
-                                                               
onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+                                                               
session.onUnknownProperty(currAttr, m, currAttrLine, currAttrCol);
                                                                
parseAnything(session, object(), r.unread(), m.getBean(false), true, null); // 
Read content anyway to ignore it
                                                        } else {
                                                                
session.setCurrentProperty(pMeta);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/0ccac121/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
index 07c4a71..56b8448 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.parser.*;
 import org.apache.juneau.uon.*;
 
 /**
@@ -134,6 +135,12 @@ public class UrlEncodingParserBuilder extends 
UonParserBuilder {
                return this;
        }
 
+       @Override /* ParserBuilder */
+       public UrlEncodingParserBuilder listener(Class<? extends 
ParserListener> value) {
+               super.listener(value);
+               return this;
+       }
+
        @Override /* CoreObjectBuilder */
        public UrlEncodingParserBuilder beansRequireDefaultConstructor(boolean 
value) {
                super.beansRequireDefaultConstructor(value);


Reply via email to