http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_CommonParser.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_CommonParser.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_CommonParser.java
deleted file mode 100755
index c600867..0000000
--- 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_CommonParser.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/***************************************************************************************************************************
- * 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.json;
-
-import static org.apache.juneau.BeanContext.*;
-import static org.apache.juneau.serializer.SerializerContext.*;
-import static org.junit.Assert.*;
-
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-import org.junit.*;
-
-@SuppressWarnings({"rawtypes","serial"})
-public class CT_CommonParser {
-
-       
//====================================================================================================
-       // testFromSerializer
-       
//====================================================================================================
-       @Test
-       public void testFromSerializer() throws Exception {
-               ReaderParser p = 
JsonParser.DEFAULT.clone().setClassLoader(getClass().getClassLoader());
-
-               Map m = null;
-               m = (Map)p.parse("{a:1}", Object.class);
-               assertEquals(1, m.get("a"));
-               m = (Map)p.parse("{a:1,b:\"foo bar\"}", Object.class);
-               assertEquals(1, m.get("a"));
-               assertEquals("foo bar", m.get("b"));
-               m = (Map)p.parse("{a:1,b:\"foo bar\",c:false}", Object.class);
-               assertEquals(1, m.get("a"));
-               assertEquals(false, m.get("c"));
-               m = (Map)p.parse(" { a : 1 , b : 'foo' , c : false } ", 
Object.class);
-               assertEquals(1, m.get("a"));
-               assertEquals("foo", m.get("b"));
-               assertEquals(false, m.get("c"));
-
-               m = 
(Map)p.parse("{x:\"org.apache.juneau.test.Person\",addresses:[{x:\"org.apache.juneau.test.Address\",city:\"city
 A\",state:\"state A\",street:\"street A\",zip:12345}]}", Object.class);
-               assertEquals("org.apache.juneau.test.Person", m.get("x"));
-               List l = (List)m.get("addresses");
-               assertNotNull(l);
-               m = (Map)l.get(0);
-               assertNotNull(m);
-               assertEquals("org.apache.juneau.test.Address", m.get("x"));
-               assertEquals("city A", m.get("city"));
-               assertEquals("state A", m.get("state"));
-               assertEquals("street A", m.get("street"));
-               assertEquals(12345, m.get("zip"));
-
-               ObjectList jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
-               assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
-               assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
-
-               // Verify that all the following return null.
-               assertNull(p.parse((CharSequence)null, Object.class));
-               assertNull(p.parse("", Object.class));
-               assertNull(p.parse("   ", Object.class));
-               assertNull(p.parse("   \t", Object.class));
-               assertNull(p.parse("   /*foo*/", Object.class));
-               assertNull(p.parse("   /*foo*/   ", Object.class));
-               assertNull(p.parse("   //foo   ", Object.class));
-
-               try {
-                       jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
-                       assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
-                       assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
-               } catch (Exception e) {
-                       fail(e.getLocalizedMessage());
-               }
-
-               A1 b = new A1();
-               A2 tl = new A2();
-               tl.add(new A3("name0","value0"));
-               tl.add(new A3("name1","value1"));
-               b.list = tl;
-               String json = new 
JsonSerializer().setProperty(SERIALIZER_addClassAttrs, true).serialize(b);
-               b = (A1)p.parse(json, Object.class);
-               assertEquals("value1", b.list.get(1).value);
-
-               json = JsonSerializer.DEFAULT.serialize(b);
-               b = p.parse(json, A1.class);
-               assertEquals("value1", b.list.get(1).value);
-       }
-
-       public static class A1 {
-               public A2 list;
-       }
-
-       public static class A2 extends LinkedList<A3> {
-       }
-
-       public static class A3 {
-               public String name, value;
-               public A3(){}
-               public A3(String name, String value) {
-                       this.name = name;
-                       this.value = value;
-               }
-       }
-
-       
//====================================================================================================
-       // Correct handling of unknown properties.
-       
//====================================================================================================
-       @Test
-       public void testCorrectHandlingOfUnknownProperties() throws Exception {
-               ReaderParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
-               B b;
-
-               String in =  "{a:1,unknown:3,b:2}";
-               b = p.parse(in, B.class);
-               assertEquals(b.a, 1);
-               assertEquals(b.b, 2);
-
-               try {
-                       p = new JsonParser();
-                       p.parse(in, B.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {}
-       }
-
-       public static class B {
-               public int a, b;
-       }
-
-       
//====================================================================================================
-       // Writing to Collection properties with no setters.
-       
//====================================================================================================
-       @Test
-       public void testCollectionPropertiesWithNoSetters() throws Exception {
-               JsonParser p = JsonParser.DEFAULT;
-               String json = "{ints:[1,2,3],beans:[{a:1,b:2}]}";
-               C t = p.parse(json, C.class);
-               assertEquals(t.getInts().size(), 3);
-               assertEquals(t.getBeans().get(0).b, 2);
-       }
-
-       public static class C {
-               private Collection<Integer> ints = new LinkedList<Integer>();
-               private List<B> beans = new LinkedList<B>();
-               public Collection<Integer> getInts() {
-                       return ints;
-               }
-               public List<B> getBeans() {
-                       return beans;
-               }
-       }
-
-       
//====================================================================================================
-       // Parser listeners.
-       
//====================================================================================================
-       @Test
-       public void testParserListeners() throws Exception {
-               final List<String> events = new LinkedList<String>();
-               JsonParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
-               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);
-                               }
-                       }
-               );
-
-               String json = "{a:1,unknownProperty:\"/foo\",b:2}";
-               p.parse(json, B.class);
-               assertEquals(1, events.size());
-               assertEquals("unknownProperty,1,5", events.get(0));
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_Json.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_Json.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_Json.java
deleted file mode 100755
index 93e3554..0000000
--- a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_Json.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/***************************************************************************************************************************
- * 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.json;
-
-import static org.apache.juneau.TestUtils.*;
-import static org.apache.juneau.json.JsonSerializerContext.*;
-import static org.apache.juneau.serializer.SerializerContext.*;
-import static org.junit.Assert.*;
-
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.json.annotation.*;
-import org.apache.juneau.serializer.*;
-import org.junit.*;
-
-@SuppressWarnings("serial")
-public class CT_Json {
-
-       
//====================================================================================================
-       // testBasic
-       
//====================================================================================================
-       @Test
-       public void testBasic() throws Exception {
-               Map<String,Object> m = new LinkedHashMap<String,Object>();
-               List<Object> l = new LinkedList<Object>();
-
-               WriterSerializer s1 = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, false);
-               WriterSerializer s2 = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(SERIALIZER_quoteChar, '"');
-               String r;
-
-               // Null keys and values
-               m.clear();
-               m.put(null, null);
-               m.put("aaa", "bbb");
-               assertEquals("A1", "{null:null,aaa:'bbb'}", s1.serialize(m));
-
-               // Escapes.
-               // String = ["]
-               m.clear();
-               m.put("x", "[\"]");
-               assertEquals("{x:\"[\\\"]\"}", s2.serialize(m));
-               // String = [\"]
-               // JSON = {x:"\\\""}
-               m.clear();
-               m.put("x", "[\\\"]");
-               assertEquals("{x:\"[\\\\\\\"]\"}", s2.serialize(m));
-
-               // String = [\w[\w\-\.]{3,}\w]
-               // JSON = {x:"\\w[\\w\\-\\.]{3,}\\w"}
-               m.clear();
-               r = "\\w[\\w\\-\\.]{3,}\\w";
-               m.put("x", r);
-               assertEquals("{x:\"\\\\w[\\\\w\\\\-\\\\.]{3,}\\\\w\"}", 
s2.serialize(m));
-               assertEquals(r, new ObjectMap(s2.serialize(m)).getString("x"));
-
-               // String = [foo\bar]
-               // JSON = {x:"foo\\bar"}
-               m.clear();
-               m.put("x", "foo\\bar");
-               assertEquals("{x:\"foo\\\\bar\"}", s2.serialize(m));
-
-               m.clear();
-               m.put("null", null);
-               m.put("aaa", "bbb");
-               assertEquals("A2", "{'null':null,aaa:'bbb'}", s1.serialize(m));
-
-               m.clear();
-               m.put(null, "null");
-               m.put("aaa", "bbb");
-               assertEquals("A3", "{null:'null',aaa:'bbb'}", s1.serialize(m));
-
-               // Arrays
-               m.clear();
-               l.clear();
-               m.put("J", "f1");
-               m.put("B", "b");
-               m.put("C", "c");
-               l.add("1");
-               l.add("2");
-               l.add("3");
-               Object o = new Object[] { m, l };
-               Object o2 = new Object[] { o, "foo", "bar", new Integer(1), new 
Boolean(false), new Float(1.2), null };
-               assertEquals("K1", 
"[[{J:'f1',B:'b',C:'c'},['1','2','3']],'foo','bar',1,false,1.2,null]", 
s1.serialize(o2));
-       }
-
-       @Test
-       public void testReservedKeywordAttributes() throws Exception {
-               Map<String,Object> m = new LinkedHashMap<String,Object>();
-
-               // Keys with reserved names.
-               for (String attr : new 
String[]{"","true","false","null","try","123","1x","-123",".123"}) {
-                       m.clear();
-                       m.put(attr,1);
-                       assertObjectEquals("{'"+attr+"':1}", m);
-               }
-       }
-
-       
//====================================================================================================
-       // Validate various backslashes in strings.
-       
//====================================================================================================
-       @Test
-       public void testBackslashesInStrings() throws Exception {
-               JsonSerializer s = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(SERIALIZER_quoteChar, '"');
-               String r, r2;
-
-               // [\\]
-               r = "\\";
-               r2 = s.serialize(r);
-               assertEquals(r2, "\"\\\\\"");
-               assertEquals(JsonParser.DEFAULT.parse(r2, Object.class), r);
-
-               // [\b\f\n\t]
-               r = "\b\f\n\t";
-               r2 = s.serialize(r);
-               assertEquals("\"\\b\\f\\n\\t\"", r2);
-               assertEquals(r, JsonParser.DEFAULT.parse(r2, Object.class));
-
-               // Special JSON case:  Forward slashes can OPTIONALLY be 
escaped.
-               // [\/]
-               assertEquals(JsonParser.DEFAULT.parse("\"\\/\"", Object.class), 
"/");
-
-               // Unicode
-               r = "\u1234\u1ABC\u1abc";
-               r2 = s.serialize(r);
-               assertEquals("\"\u1234\u1ABC\u1abc\"", r2);
-
-               assertEquals("\u1234", JsonParser.DEFAULT.parse("\"\\u1234\"", 
Object.class));
-       }
-
-       
//====================================================================================================
-       // Indentation
-       
//====================================================================================================
-       @Test
-       public void testIndentation() throws Exception {
-               ObjectMap m = new 
ObjectMap("{J:{B:['c',{D:'e'},['f',{G:'h'},1,false]]},I:'j'}");
-               String e = ""
-                       + "{"
-                       + "\n   J: {"
-                       + "\n           B: ["
-                       + "\n                   'c', "
-                       + "\n                   {"
-                       + "\n                           D: 'e'"
-                       + "\n                   }, "
-                       + "\n                   ["
-                       + "\n                           'f', "
-                       + "\n                           {"
-                       + "\n                                   G: 'h'"
-                       + "\n                           }, "
-                       + "\n                           1, "
-                       + "\n                           false"
-                       + "\n                   ]"
-                       + "\n           ]"
-                       + "\n   }, "
-                       + "\n   I: 'j'"
-                       + "\n}";
-               assertEquals(e, 
JsonSerializer.DEFAULT_LAX_READABLE.serialize(m));
-       }
-
-       
//====================================================================================================
-       // Escaping double quotes
-       
//====================================================================================================
-       @Test
-       public void testEscapingDoubleQuotes() throws Exception {
-               JsonSerializer s = JsonSerializer.DEFAULT;
-               String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
-               assertEquals("{\"f1\":\"x'x\\\"x\"}", r);
-               JsonParser p = JsonParser.DEFAULT;
-               assertEquals("x'x\"x", p.parse(r, 
ObjectMap.class).getString("f1"));
-       }
-
-       
//====================================================================================================
-       // Escaping single quotes
-       
//====================================================================================================
-       @Test
-       public void testEscapingSingleQuotes() throws Exception {
-               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
-               String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
-               assertEquals("{f1:'x\\'x\"x'}", r);
-               JsonParser p = JsonParser.DEFAULT;
-               assertEquals("x'x\"x", p.parse(r, 
ObjectMap.class).getString("f1"));
-       }
-
-       
//====================================================================================================
-       // testWrapperAttrAnnotationOnBean
-       
//====================================================================================================
-       @Test
-       @SuppressWarnings("unchecked")
-       public void testWrapperAttrAnnotationOnBean() throws Exception {
-               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
-               JsonParser p = JsonParser.DEFAULT;
-               String r;
-
-               A t = A.create();
-               r = s.serialize(t);
-               assertEquals("{foo:{f1:1}}", r);
-               t = p.parse(r, A.class);
-               assertEquals(1, t.f1);
-
-               Map<String,A> m = new LinkedHashMap<String,A>();
-               m.put("bar", A.create());
-               r = s.serialize(m);
-               assertEquals("{bar:{foo:{f1:1}}}", r);
-
-               m = p.parseMap(r, LinkedHashMap.class, String.class, A.class);
-               assertEquals(1, m.get("bar").f1);
-       }
-
-       @Json(wrapperAttr="foo")
-       public static class A {
-               public int f1;
-
-               static A create() {
-                       A a = new A();
-                       a.f1 = 1;
-                       return a;
-               }
-       }
-
-       
//====================================================================================================
-       // testWrapperAttrAnnotationOnNonBean
-       
//====================================================================================================
-       @Test
-       @SuppressWarnings("unchecked")
-       public void testWrapperAttrAnnotationOnNonBean() throws Exception {
-               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
-               JsonParser p = JsonParser.DEFAULT;
-               String r;
-
-               B t = B.create();
-               r = s.serialize(t);
-               assertEquals("{foo:'1'}", r);
-               t = p.parse(r, B.class);
-               assertEquals(1, t.f1);
-
-               Map<String,B> m = new LinkedHashMap<String,B>();
-               m.put("bar", B.create());
-               r = s.serialize(m);
-               assertEquals("{bar:{foo:'1'}}", r);
-
-               m = p.parseMap(r, LinkedHashMap.class, String.class, B.class);
-               assertEquals(1, m.get("bar").f1);
-       }
-
-       @Json(wrapperAttr="foo")
-       public static class B {
-               int f1;
-
-               static B create() {
-                       B b = new B();
-                       b.f1 = 1;
-                       return b;
-               }
-
-               @Override /* Object */
-               public String toString() {
-                       return String.valueOf(f1);
-               }
-
-               public static B valueOf(String s) {
-                       B b = new B();
-                       b.f1 = Integer.parseInt(s);
-                       return b;
-               }
-       }
-
-       
//====================================================================================================
-       // testAddClassAttrs
-       
//====================================================================================================
-       @Test
-       public void testAddClassAttrs() throws Exception {
-               JsonSerializer s = new 
JsonSerializer().setProperty(SERIALIZER_addClassAttrs, true);
-               Map<String,Object> o = new HashMap<String,Object>();
-               o.put("c", new C());
-               
assertEquals("{\"c\":{\"_class\":\"org.apache.juneau.json.CT_Json$C\",\"items\":[]}}",
 s.serialize(o));
-       }
-
-       public static class C extends LinkedList<String> {
-       }
-
-       
//====================================================================================================
-       // testEscapeSolidus
-       
//====================================================================================================
-       @Test
-       public void testEscapeSolidus() throws Exception {
-               JsonSerializer s = new 
JsonSerializer().setProperty(JSON_escapeSolidus, false);
-               String r = s.serialize("foo/bar");
-               assertEquals("\"foo/bar\"", r);
-               r = JsonParser.DEFAULT.parse(r, String.class);
-               assertEquals("foo/bar", r);
-
-               s = new JsonSerializer().setProperty(JSON_escapeSolidus, true);
-               r = s.serialize("foo/bar");
-               assertEquals("\"foo\\/bar\"", r);
-               r = JsonParser.DEFAULT.parse(r, String.class);
-               assertEquals("foo/bar", r);
-       }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonParser.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonParser.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonParser.java
deleted file mode 100755
index e00aa77..0000000
--- a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonParser.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/***************************************************************************************************************************
- * 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.json;
-
-import static org.junit.Assert.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.serializer.*;
-import org.junit.*;
-
-@SuppressWarnings("hiding")
-public class CT_JsonParser {
-
-       private static final JsonParser p = JsonParser.DEFAULT;
-       private static final JsonParser sp = JsonParser.DEFAULT_STRICT;
-
-
-       
//====================================================================================================
-       // Test invalid input
-       
//====================================================================================================
-       @Test
-       public void testInvalidJson() {
-               try {
-                       p.parse("{\na:1,\nb:xxx\n}", Object.class);
-                       fail("Exception expected.");
-               } catch (ParseException e) {}
-       }
-
-       @Test
-       public void testNonExistentAttribute() throws Exception {
-               String json = "{foo:,bar:}";
-               ObjectMap m = p.parse(json, ObjectMap.class);
-               assertEquals("{foo:null,bar:null}", m.toString());
-       }
-
-       @Test
-       public void testNonStringAsString() throws Exception {
-               String json = "123";
-               String s;
-
-               // Strict mode does not allow unquoted values.
-               try {
-                       sp.parse(json, String.class);
-                       fail("Exception expected");
-               } catch (Exception e) {
-                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
-               }
-
-               s = p.parse(json, String.class);
-               assertEquals("123", s);
-
-               json = " 123 ";
-               // Strict mode does not allow unquoted values.
-               try {
-                       sp.parse(json, String.class);
-                       fail("Exception expected");
-               } catch (Exception e) {
-                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
-               }
-
-               s = p.parse(json, String.class);
-               assertEquals("123", s);
-
-               json = "{\"fa\":123}";
-               try {
-                       sp.parse(json, A.class);
-                       fail("Exception expected");
-               } catch (Exception e) {
-                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
-               }
-
-               A a = p.parse(json, A.class);
-               assertEquals("123", a.fa);
-
-               json = " { \"fa\" : 123 } ";
-               try {
-                       sp.parse(json, A.class);
-                       fail("Exception expected");
-               } catch (Exception e) {
-                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
-               }
-
-               a = p.parse(json, A.class);
-               assertEquals("123", a.fa);
-
-               json = "'123'";
-               try {
-                       sp.parse(json, String.class);
-                       fail("Exception expected");
-               } catch (Exception e) {
-                       assertTrue(e.getMessage().contains("Invalid quote 
character"));
-               }
-       }
-
-       public static class A {
-               public String fa;
-       }
-
-       @Test
-       public void testCognosJson() throws Exception {
-               String json = 
TestUtils.readFile(getClass().getResource("/json/BrokenCognosOutput.txt").getPath());
-               p.parse(json, ObjectMap.class);
-       }
-
-       @Test
-       public void testStrictMode() throws Exception {
-               JsonParser p = sp;
-
-               // Missing attribute values.
-               String json = "{\"foo\":,\"bar\":}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:7}.  Missing value detected.", 
e.getRootCause().getMessage());
-               }
-
-               // Single quoted values.
-               json = "{\"foo\":'bar'}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:8}.  Invalid quote character \"'\" being 
used.", e.getRootCause().getMessage());
-               }
-
-               // Single quoted attribute name.
-               json = "{'foo':\"bar\"}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:2}.  Invalid quote 
character \"'\" being used.", e.getRootCause().getMessage());
-               }
-
-               // Unquoted attribute name.
-               json = "{foo:\"bar\"}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:1}.  Unquoted attribute 
detected.", e.getRootCause().getMessage());
-               }
-
-               // Concatenated string
-               json = "{\"foo\":\"bar\"+\"baz\"}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:12}.  String concatenation detected.", 
e.getRootCause().getMessage());
-               }
-
-               // Concatenated string 2
-               json = "{\"foo\":\"bar\" + \"baz\"}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:13}.  String concatenation detected.", 
e.getRootCause().getMessage());
-               }
-
-               json = "{\"foo\":/*comment*/\"bar\"}";
-               try {
-                       p.parse(json, ObjectMap.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:8}.  Javascript comment 
detected.", e.getRootCause().getMessage());
-               }
-       }
-
-       /**
-        * JSON numbers and booleans should be representable as strings and 
converted accordingly.
-        */
-       @Test
-       public void testPrimitivesAsStrings() throws Exception {
-               String json;
-               ReaderParser p = JsonParser.DEFAULT;
-               WriterSerializer s = JsonSerializer.DEFAULT_LAX;
-
-               json = 
"{f1:'1',f2:'1',f3:'true',f4:'true',f5:'1',f6:'1',f7:'1',f8:'1',f9:'1',f10:'1'}";
-               B b = p.parse(json, B.class);
-               
assertEquals("{f1:1,f2:1,f3:true,f4:true,f5:1.0,f6:1.0,f7:1,f8:1,f9:1,f10:1}", 
s.toString(b));
-
-               json = 
"{f1:'',f2:'',f3:'',f4:'',f5:'',f6:'',f7:'',f8:'',f9:'',f10:''}";
-               b = p.parse(json, B.class);
-               
assertEquals("{f1:0,f2:0,f3:false,f4:false,f5:0.0,f6:0.0,f7:0,f8:0,f9:0,f10:0}",
 s.toString(b));
-       }
-
-       public static class B {
-               public int f1;
-               public Integer f2;
-               public boolean f3;
-               public Boolean f4;
-               public float f5;
-               public Float f6;
-               public long f7;
-               public Long f8;
-               public byte f9;
-               public Byte f10;
-       }
-
-       
//====================================================================================================
-       // testInvalidJsonNumbers
-       // Lax parser allows octal and hexadecimal numbers.  Strict parser does 
not.
-       
//====================================================================================================
-       @Test
-       public void testInvalidJsonNumbers() throws Exception {
-               JsonParser p1 = JsonParser.DEFAULT;
-               JsonParser p2 = JsonParser.DEFAULT_STRICT;
-               Number r;
-
-               // Lax allows blank strings interpreted as 0, strict does not.
-               String s = "\"\"";
-               r = p1.parse(s, Number.class);
-               assertEquals(0, r.intValue());
-               assertTrue(r instanceof Integer);
-               try {
-                       r = p2.parse(s, Number.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
''"));
-               }
-
-               // Either should allow 0 or -0.
-               s = "0";
-               r = p1.parse(s, Number.class);
-               assertEquals(0, r.intValue());
-               assertTrue(r instanceof Integer);
-               r = p2.parse(s, Number.class);
-               assertEquals(0, r.intValue());
-               assertTrue(r instanceof Integer);
-
-               s = "-0";
-               r = p1.parse(s, Number.class);
-               assertEquals(0, r.intValue());
-               assertTrue(r instanceof Integer);
-               r = p2.parse(s, Number.class);
-               assertEquals(0, r.intValue());
-               assertTrue(r instanceof Integer);
-
-               // Lax allows 0123 and -0123, strict does not.
-               s = "0123";
-               r = p1.parse(s, Number.class);
-               assertEquals(0123, r.intValue());
-               assertTrue(r instanceof Integer);
-               try {
-                       r = p2.parse(s, Number.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'0123'"));
-               }
-               s = "-0123";
-               r = p1.parse(s, Number.class);
-               assertEquals(-0123, r.intValue());
-               assertTrue(r instanceof Integer);
-               try {
-                       r = p2.parse(s, Number.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'-0123'"));
-               }
-
-               // Lax allows 0x123 and -0x123, strict does not.
-               s = "0x123";
-               r = p1.parse(s, Number.class);
-               assertEquals(0x123, r.intValue());
-               assertTrue(r instanceof Integer);
-               try {
-                       r = p2.parse(s, Number.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'0x123'"));
-               }
-               s = "-0x123";
-               r = p1.parse(s, Number.class);
-               assertEquals(-0x123, r.intValue());
-               assertTrue(r instanceof Integer);
-               try {
-                       r = p2.parse(s, Number.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'-0x123'"));
-               }
-       }
-
-       
//====================================================================================================
-       // testUnquotedStrings
-       // Lax parser allows unquoted strings if POJO can be converted from a 
string.
-       
//====================================================================================================
-       @Test
-       public void testUnquotedStrings() throws Exception {
-               JsonParser p1 = JsonParser.DEFAULT;
-               JsonParser p2 = JsonParser.DEFAULT_STRICT;
-
-               String s = "foobar";
-               C c = p1.parse(s, C.class);
-               assertEquals("f=foobar", c.toString());
-
-               try {
-                       p2.parse(s, C.class);
-                       fail("Exception expected");
-               } catch (ParseException e) {
-                       // OK
-               }
-       }
-
-       public static class C {
-               String f;
-               public static C valueOf(String s) {
-                       C c = new C();
-                       c.f = s;
-                       return c;
-               }
-               @Override /* Object */
-               public String toString() {
-                       return "f="+f;
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonSchema.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonSchema.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonSchema.java
deleted file mode 100755
index a22412c..0000000
--- a/org.apache.juneau/src/test/java/org/apache/juneau/json/CT_JsonSchema.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/***************************************************************************************************************************
- * 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.json;
-
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-public class CT_JsonSchema {
-
-       
//====================================================================================================
-       // Primitive objects
-       
//====================================================================================================
-       @Test
-       public void testBasic() throws Exception {
-
-               JsonSchemaSerializer s = 
JsonSerializer.DEFAULT_LAX.getSchemaSerializer();
-
-               Object o = new String();
-               assertEquals("{type:'string',description:'java.lang.String'}", 
s.serialize(o));
-
-               o = new Integer(123);
-               assertEquals("{type:'number',description:'java.lang.Integer'}", 
s.serialize(o));
-
-               o = new Float(123);
-               assertEquals("{type:'number',description:'java.lang.Float'}", 
s.serialize(o));
-
-               o = new Double(123);
-               assertEquals("{type:'number',description:'java.lang.Double'}", 
s.serialize(o));
-
-               o = Boolean.TRUE;
-               
assertEquals("{type:'boolean',description:'java.lang.Boolean'}", 
s.serialize(o));
-       }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonParserTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonParserTest.java
new file mode 100755
index 0000000..c809254
--- /dev/null
+++ 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonParserTest.java
@@ -0,0 +1,180 @@
+/***************************************************************************************************************************
+ * 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.json;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.junit.*;
+
+@SuppressWarnings({"rawtypes","serial"})
+public class CommonParserTest {
+
+       
//====================================================================================================
+       // testFromSerializer
+       
//====================================================================================================
+       @Test
+       public void testFromSerializer() throws Exception {
+               ReaderParser p = 
JsonParser.DEFAULT.clone().setClassLoader(getClass().getClassLoader());
+
+               Map m = null;
+               m = (Map)p.parse("{a:1}", Object.class);
+               assertEquals(1, m.get("a"));
+               m = (Map)p.parse("{a:1,b:\"foo bar\"}", Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals("foo bar", m.get("b"));
+               m = (Map)p.parse("{a:1,b:\"foo bar\",c:false}", Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals(false, m.get("c"));
+               m = (Map)p.parse(" { a : 1 , b : 'foo' , c : false } ", 
Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals("foo", m.get("b"));
+               assertEquals(false, m.get("c"));
+
+               m = 
(Map)p.parse("{x:\"org.apache.juneau.test.Person\",addresses:[{x:\"org.apache.juneau.test.Address\",city:\"city
 A\",state:\"state A\",street:\"street A\",zip:12345}]}", Object.class);
+               assertEquals("org.apache.juneau.test.Person", m.get("x"));
+               List l = (List)m.get("addresses");
+               assertNotNull(l);
+               m = (Map)l.get(0);
+               assertNotNull(m);
+               assertEquals("org.apache.juneau.test.Address", m.get("x"));
+               assertEquals("city A", m.get("city"));
+               assertEquals("state A", m.get("state"));
+               assertEquals("street A", m.get("street"));
+               assertEquals(12345, m.get("zip"));
+
+               ObjectList jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
+               assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
+               assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
+
+               // Verify that all the following return null.
+               assertNull(p.parse((CharSequence)null, Object.class));
+               assertNull(p.parse("", Object.class));
+               assertNull(p.parse("   ", Object.class));
+               assertNull(p.parse("   \t", Object.class));
+               assertNull(p.parse("   /*foo*/", Object.class));
+               assertNull(p.parse("   /*foo*/   ", Object.class));
+               assertNull(p.parse("   //foo   ", Object.class));
+
+               try {
+                       jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
+                       assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
+                       assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
+               } catch (Exception e) {
+                       fail(e.getLocalizedMessage());
+               }
+
+               A1 b = new A1();
+               A2 tl = new A2();
+               tl.add(new A3("name0","value0"));
+               tl.add(new A3("name1","value1"));
+               b.list = tl;
+               String json = new 
JsonSerializer().setProperty(SERIALIZER_addClassAttrs, true).serialize(b);
+               b = (A1)p.parse(json, Object.class);
+               assertEquals("value1", b.list.get(1).value);
+
+               json = JsonSerializer.DEFAULT.serialize(b);
+               b = p.parse(json, A1.class);
+               assertEquals("value1", b.list.get(1).value);
+       }
+
+       public static class A1 {
+               public A2 list;
+       }
+
+       public static class A2 extends LinkedList<A3> {
+       }
+
+       public static class A3 {
+               public String name, value;
+               public A3(){}
+               public A3(String name, String value) {
+                       this.name = name;
+                       this.value = value;
+               }
+       }
+
+       
//====================================================================================================
+       // Correct handling of unknown properties.
+       
//====================================================================================================
+       @Test
+       public void testCorrectHandlingOfUnknownProperties() throws Exception {
+               ReaderParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               B b;
+
+               String in =  "{a:1,unknown:3,b:2}";
+               b = p.parse(in, B.class);
+               assertEquals(b.a, 1);
+               assertEquals(b.b, 2);
+
+               try {
+                       p = new JsonParser();
+                       p.parse(in, B.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {}
+       }
+
+       public static class B {
+               public int a, b;
+       }
+
+       
//====================================================================================================
+       // Writing to Collection properties with no setters.
+       
//====================================================================================================
+       @Test
+       public void testCollectionPropertiesWithNoSetters() throws Exception {
+               JsonParser p = JsonParser.DEFAULT;
+               String json = "{ints:[1,2,3],beans:[{a:1,b:2}]}";
+               C t = p.parse(json, C.class);
+               assertEquals(t.getInts().size(), 3);
+               assertEquals(t.getBeans().get(0).b, 2);
+       }
+
+       public static class C {
+               private Collection<Integer> ints = new LinkedList<Integer>();
+               private List<B> beans = new LinkedList<B>();
+               public Collection<Integer> getInts() {
+                       return ints;
+               }
+               public List<B> getBeans() {
+                       return beans;
+               }
+       }
+
+       
//====================================================================================================
+       // Parser listeners.
+       
//====================================================================================================
+       @Test
+       public void testParserListeners() throws Exception {
+               final List<String> events = new LinkedList<String>();
+               JsonParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               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);
+                               }
+                       }
+               );
+
+               String json = "{a:1,unknownProperty:\"/foo\",b:2}";
+               p.parse(json, B.class);
+               assertEquals(1, events.size());
+               assertEquals("unknownProperty,1,5", events.get(0));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonTest.java
new file mode 100755
index 0000000..c64fb25
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/json/CommonTest.java
@@ -0,0 +1,501 @@
+/***************************************************************************************************************************
+ * 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.json;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.net.*;
+import java.net.URI;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testbeans.*;
+import org.junit.*;
+
+@SuppressWarnings({"serial"})
+public class CommonTest {
+
+       
//====================================================================================================
+       // Trim nulls from beans
+       
//====================================================================================================
+       @Test
+       public void testTrimNullsFromBeans() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               A t1 = A.create(), t2;
+
+               s.setProperty(SERIALIZER_trimNullProperties, false);
+               String r = s.serialize(t1);
+               assertEquals("{s1:null,s2:'s2'}", r);
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimNullProperties, true);
+               r = s.serialize(t1);
+               assertEquals("{s2:'s2'}", r);
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class A {
+               public String s1, s2;
+
+               public static A create() {
+                       A t = new A();
+                       t.s2 = "s2";
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty maps
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyMaps() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               B t1 = B.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:{},f2:{f2a:null,f2b:{s2:'s2'}}}", r);
+               t2 = p.parse(r, B.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:{f2a:null,f2b:{s2:'s2'}}}", r);
+               t2 = p.parse(r, B.class);
+               assertNull(t2.f1);
+       }
+
+       public static class B {
+               public TreeMap<String,A> f1, f2;
+
+               public static B create() {
+                       B t = new B();
+                       t.f1 = new TreeMap<String,A>();
+                       t.f2 = new 
TreeMap<String,A>(){{put("f2a",null);put("f2b",A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty lists
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyLists() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               C t1 = C.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyLists, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, C.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyLists, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, C.class);
+               assertNull(t2.f1);
+       }
+
+       public static class C {
+               public List<A> f1, f2;
+
+               public static C create() {
+                       C t = new C();
+                       t.f1 = new LinkedList<A>();
+                       t.f2 = new 
LinkedList<A>(){{add(null);add(A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty arrays
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyArrays() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               D t1 = D.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyLists, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, D.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyLists, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, D.class);
+               assertNull(t2.f1);
+       }
+
+       public static class D {
+               public A[] f1, f2;
+
+               public static D create() {
+                       D t = new D();
+                       t.f1 = new A[]{};
+                       t.f2 = new A[]{null, A.create()};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperies() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               E1 t = new E1();
+               String r;
+
+               r = s.serialize(t);
+               
assertEquals("{x1:{f1:1},x2:{f1:1},x3:[{f1:1}],x4:[{f1:1}],x5:[{f1:1}],x6:[{f1:1}]}",
 r);
+               r = s.getSchemaSerializer().serialize(t);
+               assertTrue(r.indexOf("f2") == -1);
+       }
+
+       public static class E1 {
+               @BeanProperty(properties={"f1"}) public E2 x1 = new E2();
+               @BeanProperty(properties={"f1"}) public Map<String,Integer> x2 
= new LinkedHashMap<String,Integer>() {{
+                       put("f1",1); put("f2",2);
+               }};
+               @BeanProperty(properties={"f1"}) public E2[] x3 = {new E2()};
+               @BeanProperty(properties={"f1"}) public List<E2> x4 = new 
LinkedList<E2>() {{
+                       add(new E2());
+               }};
+               @BeanProperty(properties={"f1"}) public ObjectMap[] x5 = {new 
ObjectMap().append("f1",1).append("f2",2)};
+               @BeanProperty(properties={"f1"}) public List<ObjectMap> x6 = 
new LinkedList<ObjectMap>() {{
+                       add(new ObjectMap().append("f1",1).append("f2",2));
+               }};
+       }
+
+       public static class E2 {
+               public int f1 = 1;
+               public int f2 = 2;
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation on list of beans.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperiesOnListOfBeans() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               List<F> l = new LinkedList<F>();
+               F t = new F();
+               t.x1.add(new F());
+               l.add(t);
+               String json = s.serialize(l);
+               assertEquals("[{x1:[{x2:2}],x2:2}]", json);
+       }
+
+       public static class F {
+               @BeanProperty(properties={"x2"}) public List<F> x1 = new 
LinkedList<F>();
+               public int x2 = 2;
+       }
+
+       
//====================================================================================================
+       // Test that URLs and URIs are serialized and parsed correctly.
+       
//====================================================================================================
+       @Test
+       public void testURIAttr() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               JsonParser p = JsonParser.DEFAULT;
+
+               G t = new G();
+               t.uri = new URI("http://uri";);
+               t.f1 = new URI("http://f1";);
+               t.f2 = new URL("http://f2";);
+
+               String json = s.serialize(t);
+               t = p.parse(json, G.class);
+               assertEquals("http://uri";, t.uri.toString());
+               assertEquals("http://f1";, t.f1.toString());
+               assertEquals("http://f2";, t.f2.toString());
+       }
+
+       public static class G {
+               @BeanProperty(beanUri=true) public URI uri;
+               public URI f1;
+               public URL f2;
+       }
+
+       
//====================================================================================================
+       // Test URIs with URI_CONTEXT and URI_AUTHORITY
+       
//====================================================================================================
+       @Test
+       public void testUris() throws Exception {
+               WriterSerializer s = new JsonSerializer.Simple();
+               TestURI t = new TestURI();
+               String r;
+               String expected = "";
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.ibm.com/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.ibm.com/f6/x6',"
+                       +"f7:'http://www.ibm.com/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.ibm.com/fa/xa#MY_LABEL',"
+                       +"fb:'http://www.ibm.com/fb/xb?label=MY_LABEL&foo=bar',"
+                       +"fc:'http://www.ibm.com/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.ibm.com/fd/xd?label2=MY_LABEL&foo=bar',"
+                       +"fe:'http://www.ibm.com/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "");  // Same as null.
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr");
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'/cr/f0/x0',"
+                       +"f1:'/cr/f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.ibm.com/f3/x3',"
+                       +"f4:'/cr/f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.ibm.com/f6/x6',"
+                       +"f7:'http://www.ibm.com/f7/x7',"
+                       +"f8:'/cr/f8/x8',"
+                       +"f9:'/cr/f9/x9',"
+                       +"fa:'http://www.ibm.com/fa/xa#MY_LABEL',"
+                       +"fb:'http://www.ibm.com/fb/xb?label=MY_LABEL&foo=bar',"
+                       +"fc:'http://www.ibm.com/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.ibm.com/fd/xd?label2=MY_LABEL&foo=bar',"
+                       +"fe:'http://www.ibm.com/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr/");  // Same as 
above
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/");
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'/f0/x0',"
+                       +"f1:'/f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.ibm.com/f3/x3',"
+                       +"f4:'/f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.ibm.com/f6/x6',"
+                       +"f7:'http://www.ibm.com/f7/x7',"
+                       +"f8:'/f8/x8',"
+                       +"f9:'/f9/x9',"
+                       +"fa:'http://www.ibm.com/fa/xa#MY_LABEL',"
+                       +"fb:'http://www.ibm.com/fb/xb?label=MY_LABEL&foo=bar',"
+                       +"fc:'http://www.ibm.com/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.ibm.com/fd/xd?label2=MY_LABEL&foo=bar',"
+                       +"fe:'http://www.ibm.com/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo";);
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'http://foo/f2/x2',"
+                       +"f3:'http://www.ibm.com/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'http://foo/f5/x5',"
+                       +"f6:'http://www.ibm.com/f6/x6',"
+                       +"f7:'http://www.ibm.com/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.ibm.com/fa/xa#MY_LABEL',"
+                       +"fb:'http://www.ibm.com/fb/xb?label=MY_LABEL&foo=bar',"
+                       +"fc:'http://www.ibm.com/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.ibm.com/fd/xd?label2=MY_LABEL&foo=bar',"
+                       +"fe:'http://www.ibm.com/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo/";);
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "");  // Same as 
null.
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.ibm.com/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.ibm.com/f6/x6',"
+                       +"f7:'http://www.ibm.com/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.ibm.com/fa/xa#MY_LABEL',"
+                       +"fb:'http://www.ibm.com/fb/xb?label=MY_LABEL&foo=bar',"
+                       +"fc:'http://www.ibm.com/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.ibm.com/fd/xd?label2=MY_LABEL&foo=bar',"
+                       +"fe:'http://www.ibm.com/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+       }
+
+       
//====================================================================================================
+       // Validate that you cannot update properties on locked serializer.
+       
//====================================================================================================
+       @Test
+       public void testLockedSerializer() throws Exception {
+               JsonSerializer s = new JsonSerializer().lock();
+               try {
+                       s.setProperty(JsonSerializerContext.JSON_simpleMode, 
true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(SerializerContext.SERIALIZER_addClassAttrs, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(BeanContext.BEAN_beanMapPutReturnsOldValue, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+       }
+
+       
//====================================================================================================
+       // Recursion
+       
//====================================================================================================
+       @Test
+       public void testRecursion() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+
+               R1 r1 = new R1();
+               R2 r2 = new R2();
+               R3 r3 = new R3();
+               r1.r2 = r2;
+               r2.r3 = r3;
+               r3.r1 = r1;
+
+               // No recursion detection
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       assertTrue(msg.contains("It's recommended you use the 
SerializerContext.SERIALIZER_detectRecursions setting to help locate the 
loop."));
+               }
+
+               // Recursion detection, no ignore
+               s.setProperty(SERIALIZER_detectRecursions, true);
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       
assertTrue(msg.contains("[0]root:org.apache.juneau.json.CommonTest$R1"));
+                       
assertTrue(msg.contains("->[1]r2:org.apache.juneau.json.CommonTest$R2"));
+                       
assertTrue(msg.contains("->[2]r3:org.apache.juneau.json.CommonTest$R3"));
+                       
assertTrue(msg.contains("->[3]r1:org.apache.juneau.json.CommonTest$R1"));
+               }
+
+               s.setProperty(SERIALIZER_ignoreRecursions, true);
+               assertEquals("{name:'foo',r2:{name:'bar',r3:{name:'baz'}}}", 
s.serialize(r1));
+
+               // Make sure this doesn't blow up.
+               s.getSchemaSerializer().serialize(r1);
+       }
+
+       public static class R1 {
+               public String name = "foo";
+               public R2 r2;
+       }
+       public static class R2 {
+               public String name = "bar";
+               public R3 r3;
+       }
+       public static class R3 {
+               public String name = "baz";
+               public R1 r1;
+       }
+
+       
//====================================================================================================
+       // Basic bean
+       
//====================================================================================================
+       @Test
+       public void testBasicBean() throws Exception {
+               JsonSerializer s = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(BEAN_sortProperties, true);
+
+               J a = new J();
+               a.setF1("J");
+               a.setF2(100);
+               a.setF3(true);
+               assertEquals("C1", "{f1:'J',f2:100,f3:true}", s.serialize(a));
+       }
+
+       public static class J {
+               private String f1 = null;
+               private int f2 = -1;
+               private boolean f3 = false;
+
+               public String getF1() {
+                       return this.f1;
+               }
+
+               public void setF1(String f1) {
+                       this.f1 = f1;
+               }
+
+               public int getF2() {
+                       return this.f2;
+               }
+
+               public void setF2(int f2) {
+                       this.f2 = f2;
+               }
+
+               public boolean isF3() {
+                       return this.f3;
+               }
+
+               public void setF3(boolean f3) {
+                       this.f3 = f3;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return ("J(f1: " + this.getF1() + ", f2: " + 
this.getF2() + ")");
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonParserTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonParserTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonParserTest.java
new file mode 100755
index 0000000..1f10dee
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonParserTest.java
@@ -0,0 +1,331 @@
+/***************************************************************************************************************************
+ * 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.json;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+@SuppressWarnings("hiding")
+public class JsonParserTest {
+
+       private static final JsonParser p = JsonParser.DEFAULT;
+       private static final JsonParser sp = JsonParser.DEFAULT_STRICT;
+
+
+       
//====================================================================================================
+       // Test invalid input
+       
//====================================================================================================
+       @Test
+       public void testInvalidJson() {
+               try {
+                       p.parse("{\na:1,\nb:xxx\n}", Object.class);
+                       fail("Exception expected.");
+               } catch (ParseException e) {}
+       }
+
+       @Test
+       public void testNonExistentAttribute() throws Exception {
+               String json = "{foo:,bar:}";
+               ObjectMap m = p.parse(json, ObjectMap.class);
+               assertEquals("{foo:null,bar:null}", m.toString());
+       }
+
+       @Test
+       public void testNonStringAsString() throws Exception {
+               String json = "123";
+               String s;
+
+               // Strict mode does not allow unquoted values.
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               s = p.parse(json, String.class);
+               assertEquals("123", s);
+
+               json = " 123 ";
+               // Strict mode does not allow unquoted values.
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               s = p.parse(json, String.class);
+               assertEquals("123", s);
+
+               json = "{\"fa\":123}";
+               try {
+                       sp.parse(json, A.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               A a = p.parse(json, A.class);
+               assertEquals("123", a.fa);
+
+               json = " { \"fa\" : 123 } ";
+               try {
+                       sp.parse(json, A.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               a = p.parse(json, A.class);
+               assertEquals("123", a.fa);
+
+               json = "'123'";
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Invalid quote 
character"));
+               }
+       }
+
+       public static class A {
+               public String fa;
+       }
+
+       @Test
+       public void testCognosJson() throws Exception {
+               String json = 
TestUtils.readFile(getClass().getResource("/json/BrokenCognosOutput.txt").getPath());
+               p.parse(json, ObjectMap.class);
+       }
+
+       @Test
+       public void testStrictMode() throws Exception {
+               JsonParser p = sp;
+
+               // Missing attribute values.
+               String json = "{\"foo\":,\"bar\":}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:7}.  Missing value detected.", 
e.getRootCause().getMessage());
+               }
+
+               // Single quoted values.
+               json = "{\"foo\":'bar'}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:8}.  Invalid quote character \"'\" being 
used.", e.getRootCause().getMessage());
+               }
+
+               // Single quoted attribute name.
+               json = "{'foo':\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:2}.  Invalid quote 
character \"'\" being used.", e.getRootCause().getMessage());
+               }
+
+               // Unquoted attribute name.
+               json = "{foo:\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:1}.  Unquoted attribute 
detected.", e.getRootCause().getMessage());
+               }
+
+               // Concatenated string
+               json = "{\"foo\":\"bar\"+\"baz\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:12}.  String concatenation detected.", 
e.getRootCause().getMessage());
+               }
+
+               // Concatenated string 2
+               json = "{\"foo\":\"bar\" + \"baz\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:13}.  String concatenation detected.", 
e.getRootCause().getMessage());
+               }
+
+               json = "{\"foo\":/*comment*/\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:8}.  Javascript comment 
detected.", e.getRootCause().getMessage());
+               }
+       }
+
+       /**
+        * JSON numbers and booleans should be representable as strings and 
converted accordingly.
+        */
+       @Test
+       public void testPrimitivesAsStrings() throws Exception {
+               String json;
+               ReaderParser p = JsonParser.DEFAULT;
+               WriterSerializer s = JsonSerializer.DEFAULT_LAX;
+
+               json = 
"{f1:'1',f2:'1',f3:'true',f4:'true',f5:'1',f6:'1',f7:'1',f8:'1',f9:'1',f10:'1'}";
+               B b = p.parse(json, B.class);
+               
assertEquals("{f1:1,f2:1,f3:true,f4:true,f5:1.0,f6:1.0,f7:1,f8:1,f9:1,f10:1}", 
s.toString(b));
+
+               json = 
"{f1:'',f2:'',f3:'',f4:'',f5:'',f6:'',f7:'',f8:'',f9:'',f10:''}";
+               b = p.parse(json, B.class);
+               
assertEquals("{f1:0,f2:0,f3:false,f4:false,f5:0.0,f6:0.0,f7:0,f8:0,f9:0,f10:0}",
 s.toString(b));
+       }
+
+       public static class B {
+               public int f1;
+               public Integer f2;
+               public boolean f3;
+               public Boolean f4;
+               public float f5;
+               public Float f6;
+               public long f7;
+               public Long f8;
+               public byte f9;
+               public Byte f10;
+       }
+
+       
//====================================================================================================
+       // testInvalidJsonNumbers
+       // Lax parser allows octal and hexadecimal numbers.  Strict parser does 
not.
+       
//====================================================================================================
+       @Test
+       public void testInvalidJsonNumbers() throws Exception {
+               JsonParser p1 = JsonParser.DEFAULT;
+               JsonParser p2 = JsonParser.DEFAULT_STRICT;
+               Number r;
+
+               // Lax allows blank strings interpreted as 0, strict does not.
+               String s = "\"\"";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
''"));
+               }
+
+               // Either should allow 0 or -0.
+               s = "0";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               r = p2.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+
+               s = "-0";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               r = p2.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+
+               // Lax allows 0123 and -0123, strict does not.
+               s = "0123";
+               r = p1.parse(s, Number.class);
+               assertEquals(0123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'0123'"));
+               }
+               s = "-0123";
+               r = p1.parse(s, Number.class);
+               assertEquals(-0123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'-0123'"));
+               }
+
+               // Lax allows 0x123 and -0x123, strict does not.
+               s = "0x123";
+               r = p1.parse(s, Number.class);
+               assertEquals(0x123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'0x123'"));
+               }
+               s = "-0x123";
+               r = p1.parse(s, Number.class);
+               assertEquals(-0x123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().endsWith("Invalid JSON number 
'-0x123'"));
+               }
+       }
+
+       
//====================================================================================================
+       // testUnquotedStrings
+       // Lax parser allows unquoted strings if POJO can be converted from a 
string.
+       
//====================================================================================================
+       @Test
+       public void testUnquotedStrings() throws Exception {
+               JsonParser p1 = JsonParser.DEFAULT;
+               JsonParser p2 = JsonParser.DEFAULT_STRICT;
+
+               String s = "foobar";
+               C c = p1.parse(s, C.class);
+               assertEquals("f=foobar", c.toString());
+
+               try {
+                       p2.parse(s, C.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       // OK
+               }
+       }
+
+       public static class C {
+               String f;
+               public static C valueOf(String s) {
+                       C c = new C();
+                       c.f = s;
+                       return c;
+               }
+               @Override /* Object */
+               public String toString() {
+                       return "f="+f;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonSchemaTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
new file mode 100755
index 0000000..f484a07
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
@@ -0,0 +1,44 @@
+/***************************************************************************************************************************
+ * 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.json;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+public class JsonSchemaTest {
+
+       
//====================================================================================================
+       // Primitive objects
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+
+               JsonSchemaSerializer s = 
JsonSerializer.DEFAULT_LAX.getSchemaSerializer();
+
+               Object o = new String();
+               assertEquals("{type:'string',description:'java.lang.String'}", 
s.serialize(o));
+
+               o = new Integer(123);
+               assertEquals("{type:'number',description:'java.lang.Integer'}", 
s.serialize(o));
+
+               o = new Float(123);
+               assertEquals("{type:'number',description:'java.lang.Float'}", 
s.serialize(o));
+
+               o = new Double(123);
+               assertEquals("{type:'number',description:'java.lang.Double'}", 
s.serialize(o));
+
+               o = Boolean.TRUE;
+               
assertEquals("{type:'boolean',description:'java.lang.Boolean'}", 
s.serialize(o));
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonTest.java
----------------------------------------------------------------------
diff --git 
a/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonTest.java 
b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonTest.java
new file mode 100755
index 0000000..6f7fd4f
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/json/JsonTest.java
@@ -0,0 +1,308 @@
+/***************************************************************************************************************************
+ * 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.json;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.json.JsonSerializerContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+@SuppressWarnings("serial")
+public class JsonTest {
+
+       
//====================================================================================================
+       // testBasic
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+               Map<String,Object> m = new LinkedHashMap<String,Object>();
+               List<Object> l = new LinkedList<Object>();
+
+               WriterSerializer s1 = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, false);
+               WriterSerializer s2 = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(SERIALIZER_quoteChar, '"');
+               String r;
+
+               // Null keys and values
+               m.clear();
+               m.put(null, null);
+               m.put("aaa", "bbb");
+               assertEquals("A1", "{null:null,aaa:'bbb'}", s1.serialize(m));
+
+               // Escapes.
+               // String = ["]
+               m.clear();
+               m.put("x", "[\"]");
+               assertEquals("{x:\"[\\\"]\"}", s2.serialize(m));
+               // String = [\"]
+               // JSON = {x:"\\\""}
+               m.clear();
+               m.put("x", "[\\\"]");
+               assertEquals("{x:\"[\\\\\\\"]\"}", s2.serialize(m));
+
+               // String = [\w[\w\-\.]{3,}\w]
+               // JSON = {x:"\\w[\\w\\-\\.]{3,}\\w"}
+               m.clear();
+               r = "\\w[\\w\\-\\.]{3,}\\w";
+               m.put("x", r);
+               assertEquals("{x:\"\\\\w[\\\\w\\\\-\\\\.]{3,}\\\\w\"}", 
s2.serialize(m));
+               assertEquals(r, new ObjectMap(s2.serialize(m)).getString("x"));
+
+               // String = [foo\bar]
+               // JSON = {x:"foo\\bar"}
+               m.clear();
+               m.put("x", "foo\\bar");
+               assertEquals("{x:\"foo\\\\bar\"}", s2.serialize(m));
+
+               m.clear();
+               m.put("null", null);
+               m.put("aaa", "bbb");
+               assertEquals("A2", "{'null':null,aaa:'bbb'}", s1.serialize(m));
+
+               m.clear();
+               m.put(null, "null");
+               m.put("aaa", "bbb");
+               assertEquals("A3", "{null:'null',aaa:'bbb'}", s1.serialize(m));
+
+               // Arrays
+               m.clear();
+               l.clear();
+               m.put("J", "f1");
+               m.put("B", "b");
+               m.put("C", "c");
+               l.add("1");
+               l.add("2");
+               l.add("3");
+               Object o = new Object[] { m, l };
+               Object o2 = new Object[] { o, "foo", "bar", new Integer(1), new 
Boolean(false), new Float(1.2), null };
+               assertEquals("K1", 
"[[{J:'f1',B:'b',C:'c'},['1','2','3']],'foo','bar',1,false,1.2,null]", 
s1.serialize(o2));
+       }
+
+       @Test
+       public void testReservedKeywordAttributes() throws Exception {
+               Map<String,Object> m = new LinkedHashMap<String,Object>();
+
+               // Keys with reserved names.
+               for (String attr : new 
String[]{"","true","false","null","try","123","1x","-123",".123"}) {
+                       m.clear();
+                       m.put(attr,1);
+                       assertObjectEquals("{'"+attr+"':1}", m);
+               }
+       }
+
+       
//====================================================================================================
+       // Validate various backslashes in strings.
+       
//====================================================================================================
+       @Test
+       public void testBackslashesInStrings() throws Exception {
+               JsonSerializer s = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(SERIALIZER_quoteChar, '"');
+               String r, r2;
+
+               // [\\]
+               r = "\\";
+               r2 = s.serialize(r);
+               assertEquals(r2, "\"\\\\\"");
+               assertEquals(JsonParser.DEFAULT.parse(r2, Object.class), r);
+
+               // [\b\f\n\t]
+               r = "\b\f\n\t";
+               r2 = s.serialize(r);
+               assertEquals("\"\\b\\f\\n\\t\"", r2);
+               assertEquals(r, JsonParser.DEFAULT.parse(r2, Object.class));
+
+               // Special JSON case:  Forward slashes can OPTIONALLY be 
escaped.
+               // [\/]
+               assertEquals(JsonParser.DEFAULT.parse("\"\\/\"", Object.class), 
"/");
+
+               // Unicode
+               r = "\u1234\u1ABC\u1abc";
+               r2 = s.serialize(r);
+               assertEquals("\"\u1234\u1ABC\u1abc\"", r2);
+
+               assertEquals("\u1234", JsonParser.DEFAULT.parse("\"\\u1234\"", 
Object.class));
+       }
+
+       
//====================================================================================================
+       // Indentation
+       
//====================================================================================================
+       @Test
+       public void testIndentation() throws Exception {
+               ObjectMap m = new 
ObjectMap("{J:{B:['c',{D:'e'},['f',{G:'h'},1,false]]},I:'j'}");
+               String e = ""
+                       + "{"
+                       + "\n   J: {"
+                       + "\n           B: ["
+                       + "\n                   'c', "
+                       + "\n                   {"
+                       + "\n                           D: 'e'"
+                       + "\n                   }, "
+                       + "\n                   ["
+                       + "\n                           'f', "
+                       + "\n                           {"
+                       + "\n                                   G: 'h'"
+                       + "\n                           }, "
+                       + "\n                           1, "
+                       + "\n                           false"
+                       + "\n                   ]"
+                       + "\n           ]"
+                       + "\n   }, "
+                       + "\n   I: 'j'"
+                       + "\n}";
+               assertEquals(e, 
JsonSerializer.DEFAULT_LAX_READABLE.serialize(m));
+       }
+
+       
//====================================================================================================
+       // Escaping double quotes
+       
//====================================================================================================
+       @Test
+       public void testEscapingDoubleQuotes() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT;
+               String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
+               assertEquals("{\"f1\":\"x'x\\\"x\"}", r);
+               JsonParser p = JsonParser.DEFAULT;
+               assertEquals("x'x\"x", p.parse(r, 
ObjectMap.class).getString("f1"));
+       }
+
+       
//====================================================================================================
+       // Escaping single quotes
+       
//====================================================================================================
+       @Test
+       public void testEscapingSingleQuotes() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
+               assertEquals("{f1:'x\\'x\"x'}", r);
+               JsonParser p = JsonParser.DEFAULT;
+               assertEquals("x'x\"x", p.parse(r, 
ObjectMap.class).getString("f1"));
+       }
+
+       
//====================================================================================================
+       // testWrapperAttrAnnotationOnBean
+       
//====================================================================================================
+       @Test
+       @SuppressWarnings("unchecked")
+       public void testWrapperAttrAnnotationOnBean() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               JsonParser p = JsonParser.DEFAULT;
+               String r;
+
+               A t = A.create();
+               r = s.serialize(t);
+               assertEquals("{foo:{f1:1}}", r);
+               t = p.parse(r, A.class);
+               assertEquals(1, t.f1);
+
+               Map<String,A> m = new LinkedHashMap<String,A>();
+               m.put("bar", A.create());
+               r = s.serialize(m);
+               assertEquals("{bar:{foo:{f1:1}}}", r);
+
+               m = p.parseMap(r, LinkedHashMap.class, String.class, A.class);
+               assertEquals(1, m.get("bar").f1);
+       }
+
+       @Json(wrapperAttr="foo")
+       public static class A {
+               public int f1;
+
+               static A create() {
+                       A a = new A();
+                       a.f1 = 1;
+                       return a;
+               }
+       }
+
+       
//====================================================================================================
+       // testWrapperAttrAnnotationOnNonBean
+       
//====================================================================================================
+       @Test
+       @SuppressWarnings("unchecked")
+       public void testWrapperAttrAnnotationOnNonBean() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               JsonParser p = JsonParser.DEFAULT;
+               String r;
+
+               B t = B.create();
+               r = s.serialize(t);
+               assertEquals("{foo:'1'}", r);
+               t = p.parse(r, B.class);
+               assertEquals(1, t.f1);
+
+               Map<String,B> m = new LinkedHashMap<String,B>();
+               m.put("bar", B.create());
+               r = s.serialize(m);
+               assertEquals("{bar:{foo:'1'}}", r);
+
+               m = p.parseMap(r, LinkedHashMap.class, String.class, B.class);
+               assertEquals(1, m.get("bar").f1);
+       }
+
+       @Json(wrapperAttr="foo")
+       public static class B {
+               int f1;
+
+               static B create() {
+                       B b = new B();
+                       b.f1 = 1;
+                       return b;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return String.valueOf(f1);
+               }
+
+               public static B valueOf(String s) {
+                       B b = new B();
+                       b.f1 = Integer.parseInt(s);
+                       return b;
+               }
+       }
+
+       
//====================================================================================================
+       // testAddClassAttrs
+       
//====================================================================================================
+       @Test
+       public void testAddClassAttrs() throws Exception {
+               JsonSerializer s = new 
JsonSerializer().setProperty(SERIALIZER_addClassAttrs, true);
+               Map<String,Object> o = new HashMap<String,Object>();
+               o.put("c", new C());
+               
assertEquals("{\"c\":{\"_class\":\"org.apache.juneau.json.JsonTest$C\",\"items\":[]}}",
 s.serialize(o));
+       }
+
+       public static class C extends LinkedList<String> {
+       }
+
+       
//====================================================================================================
+       // testEscapeSolidus
+       
//====================================================================================================
+       @Test
+       public void testEscapeSolidus() throws Exception {
+               JsonSerializer s = new 
JsonSerializer().setProperty(JSON_escapeSolidus, false);
+               String r = s.serialize("foo/bar");
+               assertEquals("\"foo/bar\"", r);
+               r = JsonParser.DEFAULT.parse(r, String.class);
+               assertEquals("foo/bar", r);
+
+               s = new JsonSerializer().setProperty(JSON_escapeSolidus, true);
+               r = s.serialize("foo/bar");
+               assertEquals("\"foo\\/bar\"", r);
+               r = JsonParser.DEFAULT.parse(r, String.class);
+               assertEquals("foo/bar", r);
+       }
+}
\ No newline at end of file

Reply via email to