1   /*
2    * Copyright 2002-2009 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.sf.json;
18  
19  import java.io.Serializable;
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import junit.framework.TestCase;
31  import net.sf.ezmorph.MorphUtils;
32  import net.sf.ezmorph.bean.MorphDynaBean;
33  import net.sf.ezmorph.bean.MorphDynaClass;
34  import net.sf.ezmorph.test.ArrayAssertions;
35  import net.sf.json.processors.DefaultValueProcessor;
36  import net.sf.json.processors.DefaultValueProcessorMatcher;
37  import net.sf.json.processors.PropertyNameProcessor;
38  import net.sf.json.sample.BeanA;
39  import net.sf.json.sample.BeanB;
40  import net.sf.json.sample.BeanC;
41  import net.sf.json.sample.BeanFoo;
42  import net.sf.json.sample.BeanWithFunc;
43  import net.sf.json.sample.ChildBean;
44  import net.sf.json.sample.ClassBean;
45  import net.sf.json.sample.EmptyBean;
46  import net.sf.json.sample.JavaIdentifierBean;
47  import net.sf.json.sample.ListingBean;
48  import net.sf.json.sample.MappingBean;
49  import net.sf.json.sample.NumberBean;
50  import net.sf.json.sample.ObjectBean;
51  import net.sf.json.sample.ObjectJSONStringBean;
52  import net.sf.json.sample.ParentBean;
53  import net.sf.json.sample.PrimitiveBean;
54  import net.sf.json.sample.PropertyBean;
55  import net.sf.json.sample.SetBean;
56  import net.sf.json.sample.TransientBean;
57  import net.sf.json.sample.ValueBean;
58  import net.sf.json.util.CycleDetectionStrategy;
59  import net.sf.json.util.JSONTokener;
60  import net.sf.json.util.JSONUtils;
61  import net.sf.json.util.JavaIdentifierTransformer;
62  import net.sf.json.util.PropertyExclusionClassMatcher;
63  import net.sf.json.util.PropertyFilter;
64  import net.sf.json.util.PropertySetStrategy;
65  
66  import org.apache.commons.beanutils.PropertyUtils;
67  
68  /**
69   * @author Andres Almiray <aalmiray@users.sourceforge.net>
70   */
71  public class TestJSONObject extends TestCase {
72     public static void main( String[] args ) {
73        junit.textui.TestRunner.run( TestJSONObject.class );
74     }
75  
76     private JsonConfig jsonConfig;
77  
78     public TestJSONObject( String testName ) {
79        super( testName );
80     }
81  
82     public void testAccumulate() {
83        JSONObject json = new JSONObject();
84        json.accumulate( "key", "1" );
85        Assertions.assertEquals( 1, json.getInt( "key" ) );
86        json.accumulate( "key", "2" );
87        Assertions.assertEquals( JSONArray.fromObject( "['1','2']" ), json.getJSONArray( "key" ) );
88        json.accumulate( "key", "3" );
89        Assertions.assertEquals( JSONArray.fromObject( "['1','2','3']" ), json.getJSONArray( "key" ) );
90     }
91  
92     public void testAccumulate__nullObject() {
93        try{
94           new JSONObject( true ).accumulate( "key", "value" );
95           fail( "Expected a JSONException" );
96        }catch( JSONException expected ){
97           // ok
98        }
99     }
100 
101    public void testConstructor_Object__nullJSONObject() {
102       JSONObject jsonObject = JSONObject.fromObject( (JSONObject) null );
103       assertTrue( jsonObject.isNullObject() );
104    }
105 
106    public void testConstructor_Object_String_Array__nullObject() {
107       jsonConfig.setExcludes( new String[] { "bool", "integer" } );
108       JSONObject jsonObject = JSONObject.fromObject( (Object) null, jsonConfig );
109       assertTrue( jsonObject.isNullObject() );
110    }
111 
112    public void testCycleDetection_beans_noprop() {
113       jsonConfig.setCycleDetectionStrategy( CycleDetectionStrategy.NOPROP );
114       ParentBean parent = new ParentBean();
115       parent.setChild( new ChildBean() );
116 
117       JSONObject actual = JSONObject.fromObject( parent, jsonConfig );
118       JSONObject expected = new JSONObject().element( "value", 0 )
119             .element( "child", new JSONObject().element( "value", 0 ) );
120       Assertions.assertEquals( expected, actual );
121    }
122 
123    public void testCycleDetection_beans_null() {
124       jsonConfig.setCycleDetectionStrategy( CycleDetectionStrategy.LENIENT );
125       ParentBean parent = new ParentBean();
126       parent.setChild( new ChildBean() );
127 
128       JSONObject actual = JSONObject.fromObject( parent, jsonConfig );
129       JSONObject expected = new JSONObject().element( "value", 0 )
130             .element( "child", new JSONObject().element( "value", 0 )
131                   .element( "parent", new JSONObject( true ) ) );
132       Assertions.assertEquals( expected, actual );
133    }
134 
135    public void testCycleDetection_beans_strict() {
136       ParentBean parent = new ParentBean();
137       parent.setChild( new ChildBean() );
138       try{
139          JSONObject.fromObject( parent );
140          fail( "A JSONException was expected" );
141       }catch( JSONException expected ){
142          assertTrue( expected.getMessage()
143                .endsWith( "There is a cycle in the hierarchy!" ) );
144       }
145    }
146 
147    public void testDiscard() {
148       JSONObject jsonObject = new JSONObject().element( "int", "1" )
149             .element( "long", "1" )
150             .element( "boolean", "true" )
151             .element( "string", "string" )
152             .element( "func", "function(){ return this; }" )
153             .element( "array", "[1,2,3]" );
154       assertEquals( 6, jsonObject.size() );
155       jsonObject.discard( "int" )
156             .discard( "func" );
157       assertEquals( 4, jsonObject.size() );
158       assertFalse( jsonObject.has( "int" ) );
159       assertFalse( jsonObject.has( "func" ) );
160    }
161 
162    public void testElement__duplicateProperty() {
163       JSONObject jsonObject = new JSONObject();
164       jsonObject.element( "duplicated", "json1" );
165       jsonObject.element( "duplicated", "json2" );
166       Object o = jsonObject.get( "duplicated" );
167       assertFalse( o instanceof JSONArray );
168       assertEquals( "json2", o );
169    }
170 
171    public void testElement__duplicateProperty_2() {
172       JSONObject jsonObject = JSONObject.fromObject( "{'duplicated':'json1','duplicated':'json2'}" );
173       Object o = jsonObject.get( "duplicated" );
174       assertTrue( o instanceof JSONArray );
175       assertEquals( new JSONArray().element( "json1" )
176             .element( "json2" ), o );
177    }
178 
179    public void testElement_Bean() {
180       JSONObject jsonObject = new JSONObject();
181       jsonObject.element( "bean", new ObjectBean() );
182       JSONObject actual = jsonObject.getJSONObject( "bean" );
183       Assertions.assertTrue( !actual.has( "class" ) );
184    }
185 
186    public void testElement_Bean_exclusions() {
187       JSONObject jsonObject = new JSONObject();
188       jsonConfig.setExcludes( new String[] { "pexcluded" } );
189       jsonObject.element( "bean", new ObjectBean(), jsonConfig );
190       JSONObject actual = jsonObject.getJSONObject( "bean" );
191       Assertions.assertTrue( !actual.has( "class" ) );
192       Assertions.assertTrue( !actual.has( "pexcluded" ) );
193    }
194 
195    public void testElement_Bean_exclusions_ignoreDefault() {
196       JSONObject jsonObject = new JSONObject();
197       jsonConfig.setExcludes( new String[] { "pexcluded" } );
198       jsonConfig.setIgnoreDefaultExcludes( true );
199       jsonObject.element( "bean", new ObjectBean(), jsonConfig );
200       JSONObject actual = jsonObject.getJSONObject( "bean" );
201       Assertions.assertTrue( actual.has( "class" ) );
202       Assertions.assertTrue( !actual.has( "pexcluded" ) );
203    }
204 
205    public void testElement_boolean() {
206       JSONObject jsonObject = new JSONObject();
207       jsonObject.element( "bool", true );
208       assertTrue( jsonObject.getBoolean( "bool" ) );
209    }
210 
211    public void testElement_Boolean() {
212       JSONObject jsonObject = new JSONObject();
213       jsonObject.element( "bool", Boolean.TRUE );
214       Assertions.assertTrue( jsonObject.getBoolean( "bool" ) );
215    }
216 
217    public void testElement_Class() {
218       JSONObject jsonObject = new JSONObject();
219       jsonObject.element( "class", Object.class );
220       assertEquals( "java.lang.Object", jsonObject.get( "class" ) );
221    }
222 
223    public void testElement_Collection() {
224       JSONObject jsonObject = new JSONObject();
225       jsonObject.element( "list", Collections.EMPTY_LIST );
226       Assertions.assertEquals( new JSONArray(), jsonObject.getJSONArray( "list" ) );
227    }
228 
229    public void testElement_Collection2() {
230       List list = new ArrayList();
231       list.add( new ObjectBean() );
232       JSONObject jsonObject = new JSONObject();
233       jsonObject.element( "list", list );
234       JSONObject actual = jsonObject.getJSONArray( "list" )
235             .getJSONObject( 0 );
236       Assertions.assertTrue( !actual.has( "class" ) );
237    }
238 
239    public void testElement_Collection2_exclusions() {
240       List list = new ArrayList();
241       list.add( new ObjectBean() );
242       JSONObject jsonObject = new JSONObject();
243       jsonConfig.setExcludes( new String[] { "pexcluded" } );
244       jsonObject.element( "list", list, jsonConfig );
245       JSONObject actual = jsonObject.getJSONArray( "list" )
246             .getJSONObject( 0 );
247       Assertions.assertTrue( !actual.has( "class" ) );
248       Assertions.assertTrue( !actual.has( "pexcluded" ) );
249    }
250 
251    public void testElement_Collection2_exclusions_ignoreDefault() {
252       List list = new ArrayList();
253       list.add( new ObjectBean() );
254       jsonConfig.setExcludes( new String[] { "pexcluded" } );
255       jsonConfig.setIgnoreDefaultExcludes( true );
256       JSONObject jsonObject = new JSONObject();
257       jsonObject.element( "list", list, jsonConfig );
258       JSONObject actual = jsonObject.getJSONArray( "list" )
259             .getJSONObject( 0 );
260       Assertions.assertTrue( actual.has( "class" ) );
261       Assertions.assertTrue( !actual.has( "pexcluded" ) );
262    }
263 
264    public void testElement_double() {
265       JSONObject jsonObject = new JSONObject();
266       jsonObject.element( "double", 1d );
267       assertEquals( 1d, jsonObject.getDouble( "double" ), 0d );
268    }
269 
270    public void testElement_int() {
271       JSONObject jsonObject = new JSONObject();
272       jsonObject.element( "int", 1 );
273       assertEquals( 1, jsonObject.getInt( "int" ) );
274    }
275 
276    public void testElement_JSON() {
277       JSONObject jsonObject = new JSONObject();
278       jsonObject.element( "null", JSONNull.getInstance() );
279       Assertions.assertEquals( JSONNull.getInstance(), jsonObject.get( "null" ) );
280    }
281 
282    public void testElement_JSONFunction() {
283       JSONObject jsonObject = new JSONObject();
284       JSONFunction f = new JSONFunction( "return this;" );
285       jsonObject.element( "func", f );
286       Assertions.assertEquals( f, (JSONFunction) jsonObject.get( "func" ) );
287    }
288 
289    public void testElement_JSONString() {
290       JSONObject jsonObject = new JSONObject();
291       ObjectJSONStringBean bean = new ObjectJSONStringBean();
292       bean.setName( "json" );
293       jsonObject.element( "bean", bean );
294       Assertions.assertEquals( JSONObject.fromObject( bean ), jsonObject.getJSONObject( "bean" ) );
295    }
296 
297    public void testElement_JSONTokener() {
298       JSONObject jsonObject = new JSONObject();
299       JSONTokener tok = new JSONTokener( "{'name':'json'}" );
300       jsonObject.element( "obj", tok );
301       tok.reset();
302       Assertions.assertEquals( JSONObject.fromObject( tok ), jsonObject.getJSONObject( "obj" ) );
303    }
304 
305    public void testElement_long() {
306       JSONObject jsonObject = new JSONObject();
307       jsonObject.element( "long", 1L );
308       assertEquals( 1L, jsonObject.getLong( "long" ) );
309    }
310 
311    public void testElement_Map() {
312       Map map = new HashMap();
313       map.put( "name", "json" );
314       JSONObject jsonObject = new JSONObject();
315       jsonObject.element( "map", map );
316       Assertions.assertEquals( JSONObject.fromObject( map ), jsonObject.getJSONObject( "map" ) );
317    }
318 
319    public void testElement_Map2() {
320       Map map = new HashMap();
321       map.put( "name", "json" );
322       map.put( "class", "java.lang.Object" );
323       map.put( "excluded", "excluded" );
324       JSONObject jsonObject = new JSONObject();
325       jsonObject.element( "map", map );
326       JSONObject actual = jsonObject.getJSONObject( "map" );
327       Assertions.assertTrue( !actual.has( "class" ) );
328    }
329 
330    public void testElement_Map2_exclusions() {
331       Map map = new HashMap();
332       map.put( "name", "json" );
333       map.put( "class", "java.lang.Object" );
334       map.put( "pexcluded", "excluded" );
335       jsonConfig.setExcludes( new String[] { "pexcluded" } );
336       JSONObject jsonObject = new JSONObject();
337       jsonObject.element( "map", map, jsonConfig );
338       JSONObject actual = jsonObject.getJSONObject( "map" );
339       Assertions.assertTrue( !actual.has( "class" ) );
340       Assertions.assertTrue( !actual.has( "pexcluded" ) );
341    }
342 
343    public void testElement_Map2_exclusions_ignoreDefault() {
344       Map map = new HashMap();
345       map.put( "name", "json" );
346       map.put( "class", "java.lang.Object" );
347       map.put( "pexcluded", "excluded" );
348       jsonConfig.setExcludes( new String[] { "pexcluded" } );
349       jsonConfig.setIgnoreDefaultExcludes( true );
350       JSONObject jsonObject = new JSONObject();
351       jsonObject.element( "map", map, jsonConfig );
352       JSONObject actual = jsonObject.getJSONObject( "map" );
353       Assertions.assertTrue( actual.has( "class" ) );
354       Assertions.assertTrue( !actual.has( "pexcluded" ) );
355    }
356 
357    public void testElement_null_key() {
358       try{
359          new JSONObject().element( null, "value" );
360          fail( "Expected a JSONException" );
361       }catch( JSONException expected ){
362          // ok
363       }
364    }
365 
366    public void testElement_Number() {
367       JSONObject jsonObject = new JSONObject();
368       jsonObject.element( "num", new Double( 2 ) );
369       Assertions.assertEquals( new Double( 2 ).doubleValue(), jsonObject.getDouble( "num" ), 0d );
370    }
371 
372    public void testElement_Object() {
373       JSONObject jsonObject = new JSONObject();
374       jsonObject.element( "bean", new BeanA() );
375       Assertions.assertEquals( JSONObject.fromObject( new BeanA() ),
376             jsonObject.getJSONObject( "bean" ) );
377    }
378 
379    public void testElement_String() {
380       JSONObject jsonObject = new JSONObject();
381       jsonObject.element( "str", "json" );
382       Assertions.assertEquals( "json", jsonObject.getString( "str" ) );
383    }
384 
385    public void testElement_String_JSON() {
386       JSONObject jsonObject = new JSONObject();
387       jsonObject.element( "str", "[]" );
388       Assertions.assertEquals( new JSONArray().toString(), jsonObject.getString( "str" ) );
389    }
390 
391    public void testElement_String_null() {
392       JSONObject jsonObject = new JSONObject();
393       jsonObject.element( "str", (String) null );
394       // special case, if value null, there is no value associated to key
395       try{
396          jsonObject.getString( "str" );
397          fail( "Should have thrown a JSONException" );
398       }catch( JSONException expected ){
399          // ok
400       }
401    }
402 
403    public void testFromBean_array() {
404       try{
405          JSONObject.fromObject( new ArrayList() );
406          fail( "Expected a JSONException" );
407       }catch( JSONException expected ){
408          // OK
409       }
410 
411       try{
412          JSONObject.fromObject( new String[] { "json" } );
413          fail( "Expected a JSONException" );
414       }catch( JSONException expected ){
415          // OK
416       }
417    }
418 
419    public void testFromBean_ClassBean() {
420       ClassBean classBean = new ClassBean();
421       classBean.setKlass( Object.class );
422       JSONObject json = JSONObject.fromObject( classBean );
423       assertEquals( "java.lang.Object", json.get( "klass" ) );
424    }
425 
426    public void testFromBean_DynaBean() throws Exception {
427       JSONObject json = JSONObject.fromObject( createDynaBean() );
428       assertEquals( "json", json.getString( "name" ) );
429       Assertions.assertEquals( "[1,2]", json.getString( "str" ) );
430       Assertions.assertEquals( JSONObject.fromObject( "{'id':'1'}" ), json.getJSONObject( "json" ) );
431       Assertions.assertEquals( JSONObject.fromObject( "{'name':''}" ),
432             json.getJSONObject( "jsonstr" ) );
433       Assertions.assertEquals( "function(){ return this; }", (JSONFunction) json.get( "func" ) );
434    }
435 
436    public void testFromBean_JSONObject() {
437       JSONObject json = new JSONObject();
438       json.element( "name", "json" );
439       Assertions.assertEquals( json, JSONObject.fromObject( json ) );
440    }
441 
442    public void testFromBean_JSONString() {
443       ObjectJSONStringBean bean = new ObjectJSONStringBean();
444       bean.setId( 1 );
445       bean.setName( "json" );
446       JSONObject json = JSONObject.fromObject( bean );
447       assertEquals( "json", json.getString( "name" ) );
448       assertTrue( !json.has( "id" ) );
449    }
450 
451    public void testFromBean_JSONTokener() {
452       JSONTokener jsonTokener = new JSONTokener( "{\"string\":\"json\"}" );
453       JSONObject json = JSONObject.fromObject( jsonTokener );
454       assertEquals( "json", json.getString( "string" ) );
455    }
456 
457    public void testFromBean_Map() {
458       Map map = new HashMap();
459       map.put( "bool", Boolean.TRUE );
460       map.put( "integer", new Integer( 42 ) );
461       map.put( "string", "json" );
462 
463       JSONObject json = JSONObject.fromObject( map );
464       assertEquals( true, json.getBoolean( "bool" ) );
465       assertEquals( 42, json.getInt( "integer" ) );
466       assertEquals( "json", json.getString( "string" ) );
467    }
468 
469    public void testFromBean_noReadMethod() {
470       JSONObject json = JSONObject.fromObject( new PropertyBean() );
471       assertTrue( json.has( "propertyWithNoWriteMethod" ) );
472       assertTrue( !json.has( "propertyWithNoReadMethod" ) );
473    }
474 
475    public void testFromBean_null() {
476       JSONObject json = JSONObject.fromObject( null );
477       assertTrue( json.isNullObject() );
478       assertEquals( JSONNull.getInstance()
479             .toString(), json.toString() );
480    }
481 
482    public void testFromBean_String() {
483       JSONObject json = JSONObject.fromObject( "{\"string\":\"json\"}" );
484       assertEquals( "json", json.getString( "string" ) );
485    }
486 
487    public void testFromBean_use_wrappers() {
488       JSONObject json = JSONObject.fromObject( Boolean.TRUE );
489       assertTrue( json.isEmpty() );
490       json = JSONObject.fromObject( new Byte( Byte.MIN_VALUE ) );
491       assertTrue( json.isEmpty() );
492       json = JSONObject.fromObject( new Short( Short.MIN_VALUE ) );
493       assertTrue( json.isEmpty() );
494       json = JSONObject.fromObject( new Integer( Integer.MIN_VALUE ) );
495       assertTrue( json.isEmpty() );
496       json = JSONObject.fromObject( new Long( Long.MIN_VALUE ) );
497       assertTrue( json.isEmpty() );
498       json = JSONObject.fromObject( new Float( Float.MIN_VALUE ) );
499       assertTrue( json.isEmpty() );
500       json = JSONObject.fromObject( new Double( Double.MIN_VALUE ) );
501       assertTrue( json.isEmpty() );
502       json = JSONObject.fromObject( new Character( 'A' ) );
503       assertTrue( json.isEmpty() );
504    }
505 
506    public void testFromBeanWithJsonPropertyNameProcessor(){
507       JsonConfig jsonConfig = new JsonConfig();
508       jsonConfig.registerJsonPropertyNameProcessor( BeanA.class, new PrefixerPropertyNameProcessor("json") );
509       JSONObject jsonObject = JSONObject.fromObject( new BeanA(), jsonConfig );
510       assertNotNull( jsonObject );
511       assertEquals( 3, jsonObject.names().size() );
512       assertTrue( jsonObject.has( "jsonbool" ) );
513       assertTrue( jsonObject.has( "jsonstring" ) );
514       assertTrue( jsonObject.has( "jsoninteger" ) );
515    }
516 
517    public void testFromDynaBean_full() throws Exception {
518       Map properties = new HashMap();
519       properties.put( "string", String.class );
520       properties.put( "number", Integer.class );
521       properties.put( "array", Object[].class );
522       properties.put( "list", List.class );
523       properties.put( "func", JSONFunction.class );
524       properties.put( "boolean", Boolean.class );
525       properties.put( "bean", BeanA.class );
526       MorphDynaClass dynaClass = new MorphDynaClass( "JSON", MorphDynaBean.class, properties );
527       MorphDynaBean dynaBean = (MorphDynaBean) dynaClass.newInstance();
528       dynaBean.setDynaBeanClass( dynaClass );
529       dynaBean.set( "string", "json" );
530       dynaBean.set( "number", new Double( 2 ) );
531       dynaBean.set( "array", new Integer[] { new Integer( 1 ), new Integer( 2 ) } );
532       dynaBean.set( "list", new ArrayList() );
533       dynaBean.set( "func", new JSONFunction( new String[] { "a" }, "return a;" ) );
534       dynaBean.set( "boolean", Boolean.TRUE );
535       dynaBean.set( "bean", new BeanA() );
536 
537       JSONObject jsonObject = JSONObject.fromObject( dynaBean );
538       assertEquals( "json", jsonObject.get( "string" ) );
539       assertEquals( new Double( 2 ), jsonObject.get( "number" ) );
540       assertEquals( Boolean.TRUE, jsonObject.get( "boolean" ) );
541       Assertions.assertEquals( "function(a){ return a; }", (JSONFunction) jsonObject.get( "func" ) );
542    }
543 
544    public void testFromDynaBean_null() {
545       JSONObject jsonObject = JSONObject.fromObject( null );
546       assertTrue( jsonObject.isNullObject() );
547    }
548 
549    public void testFromJSONTokener() {
550       JSONTokener jsonTokener = new JSONTokener( "{\"string\":\"json\"}" );
551       JSONObject json = JSONObject.fromObject( jsonTokener );
552       assertEquals( "json", json.getString( "string" ) );
553    }
554 
555    public void testFromMap_nested_null_object() {
556       Map map = new HashMap();
557       map.put( "nested", null );
558       map.put( "string", "json" );
559 
560       JSONObject json = JSONObject.fromObject( map );
561       assertEquals( "json", json.getString( "string" ) );
562       Object nested = json.get( "nested" );
563       assertTrue( JSONUtils.isNull( nested ) );
564    }
565 
566    public void testFromMap_null_Map() {
567       JSONObject json = JSONObject.fromObject( null );
568       assertTrue( json.isNullObject() );
569       assertEquals( JSONNull.getInstance()
570             .toString(), json.toString() );
571    }
572 
573    public void testFromObject_array() {
574       try{
575          JSONObject.fromObject( new ArrayList() );
576          fail( "Expected a JSONException" );
577       }catch( JSONException expected ){
578          // OK
579       }
580 
581       try{
582          JSONObject.fromObject( new String[] { "json" } );
583          fail( "Expected a JSONException" );
584       }catch( JSONException expected ){
585          // OK
586       }
587    }
588 
589    public void testFromObject_Bean() {
590       JSONObject json = JSONObject.fromObject( new BeanA() );
591       assertEquals( true, json.getBoolean( "bool" ) );
592       assertEquals( 42, json.getInt( "integer" ) );
593       assertEquals( "json", json.getString( "string" ) );
594    }
595 
596    public void testFromObject_BeanWithFunc() {
597       JSONObject json = JSONObject.fromObject( new BeanWithFunc( "return a;" ) );
598       assertNotNull( json.get( "function" ) );
599       assertTrue( JSONUtils.isFunction( json.get( "function" ) ) );
600       assertEquals( "function(){ return a; }", json.get( "function" )
601             .toString() );
602    }
603 
604    public void testFromObject_DynaBean() throws Exception {
605       JSONObject json = JSONObject.fromObject( createDynaBean() );
606       assertEquals( "json", json.getString( "name" ) );
607    }
608 
609    public void testFromObject_emptyBean() {
610       EmptyBean bean = new EmptyBean();
611       JSONObject json = JSONObject.fromObject( bean );
612       JSONObject expected = new JSONObject();
613       expected.element( "arrayp", new JSONArray() );
614       expected.element( "listp", new JSONArray() );
615       expected.element( "bytep", new Integer( 0 ) );
616       expected.element( "shortp", new Integer( 0 ) );
617       expected.element( "intp", new Integer( 0 ) );
618       expected.element( "longp", new Integer( 0 ) );
619       expected.element( "floatp", new Integer( 0 ) );
620       expected.element( "doublep", new Double( 0 ) );
621       expected.element( "charp", "" );
622       expected.element( "stringp", "" );
623 
624       Assertions.assertEquals( expected, json );
625    }
626 
627    public void testFromObject_ExtendedBean() {
628       JSONObject json = JSONObject.fromObject( new BeanB() );
629       assertEquals( true, json.getBoolean( "bool" ) );
630       assertEquals( 42, json.getInt( "integer" ) );
631       assertEquals( "json", json.getString( "string" ) );
632       assertNotNull( json.get( "intarray" ) );
633    }
634 
635    public void testFromObject_ignoreTransientFields() {
636       jsonConfig.setIgnoreTransientFields( true );
637       TransientBean bean = new TransientBean();
638       bean.setValue( 42 );
639       bean.setTransientValue( 84 );
640       JSONObject jsonObject = JSONObject.fromObject( bean, jsonConfig );
641       assertTrue( jsonObject.has( "value" ) );
642       assertFalse( jsonObject.has( "transientValue" ) );
643    }
644 
645    public void testFromObject_JSONObject() {
646       JSONObject expected = new JSONObject().element( "id", "1" )
647             .element( "name", "json" );
648       JSONObject actual = JSONObject.fromObject( expected );
649       Assertions.assertEquals( expected, actual );
650    }
651 
652    public void testFromObject_JSONString() {
653       ObjectJSONStringBean bean = new ObjectJSONStringBean();
654       bean.setId( 1 );
655       bean.setName( "json" );
656       JSONObject json = JSONObject.fromObject( bean );
657       assertEquals( "json", json.getString( "name" ) );
658       assertTrue( !json.has( "id" ) );
659    }
660 
661    public void testFromObject_JSONTokener() {
662       JSONTokener jsonTokener = new JSONTokener( "{\"string\":\"json\"}" );
663       JSONObject json = JSONObject.fromObject( jsonTokener );
664       assertEquals( "json", json.getString( "string" ) );
665    }
666 
667    public void testFromObject_Map() {
668       Map map = new HashMap();
669       map.put( "bool", Boolean.TRUE );
670       map.put( "integer", new Integer( 42 ) );
671       map.put( "string", "json" );
672       map.put( "array", JSONArray.fromObject( "[1]" ) );
673       map.put( "object", JSONObject.fromObject( "{\"name\":\"json\"}" ) );
674 
675       JSONObject json = JSONObject.fromObject( map );
676       assertEquals( true, json.getBoolean( "bool" ) );
677       assertEquals( 42, json.getInt( "integer" ) );
678       assertEquals( "json", json.getString( "string" ) );
679       Assertions.assertEquals( JSONArray.fromObject( "[1]" ), json.getJSONArray( "array" ) );
680       Assertions.assertEquals( JSONObject.fromObject( "{\"name\":\"json\"}" ),
681             json.getJSONObject( "object" ) );
682    }
683 
684    public void testFromObject_nested_bean() {
685       JSONObject json = JSONObject.fromObject( new BeanC() );
686       assertNotNull( json.get( "beanA" ) );
687       assertNotNull( json.get( "beanB" ) );
688    }
689 
690    public void testFromObject_null() {
691       JSONObject json = JSONObject.fromObject( null );
692       assertTrue( json.isNullObject() );
693       assertEquals( JSONNull.getInstance()
694             .toString(), json.toString() );
695    }
696 
697    public void testFromObject_ObjectBean() {
698       // FR 1611204
699       ObjectBean bean = new ObjectBean();
700       bean.setPbyte( Byte.valueOf( "1" ) );
701       bean.setPshort( Short.valueOf( "1" ) );
702       bean.setPint( Integer.valueOf( "1" ) );
703       bean.setPlong( Long.valueOf( "1" ) );
704       bean.setPfloat( Float.valueOf( "1" ) );
705       bean.setPdouble( Double.valueOf( "1" ) );
706       bean.setPchar( new Character( '1' ) );
707       bean.setPboolean( Boolean.TRUE );
708       bean.setPstring( "json" );
709       bean.setParray( new String[] { "a", "b" } );
710       bean.setPbean( new BeanA() );
711       List list = new ArrayList();
712       list.add( "1" );
713       list.add( "2" );
714       bean.setPlist( list );
715       Map map = new HashMap();
716       map.put( "string", "json" );
717       bean.setPmap( map );
718       bean.setPfunction( new JSONFunction( "this;" ) );
719 
720       JSONObject json = JSONObject.fromObject( bean );
721       assertEquals( 1, json.getInt( "pbyte" ) );
722       assertEquals( 1, json.getInt( "pshort" ) );
723       assertEquals( 1, json.getInt( "pint" ) );
724       assertEquals( 1, json.getInt( "plong" ) );
725       assertEquals( 1d, json.getDouble( "pfloat" ), 0d );
726       assertEquals( 1d, json.getDouble( "pdouble" ), 0d );
727       assertTrue( json.getBoolean( "pboolean" ) );
728       assertEquals( "json", json.get( "pstring" ) );
729       Assertions.assertEquals( JSONArray.fromObject( "['a','b']" ), json.getJSONArray( "parray" ) );
730       Assertions.assertEquals( JSONArray.fromObject( "['1','2']" ), json.getJSONArray( "plist" ) );
731       assertEquals( "1", json.getString( "pchar" ) );
732       JSONObject b = new JSONObject().element( "string", "json" )
733             .element( "integer", "42" )
734             .element( "bool", "true" );
735       Assertions.assertEquals( b, json.getJSONObject( "pbean" ) );
736       b = new JSONObject().element( "string", "json" );
737       Assertions.assertEquals( b, json.getJSONObject( "pmap" ) );
738    }
739 
740    public void testFromObject_ObjectBean_empty() {
741       // FR 1611204
742       ObjectBean bean = new ObjectBean();
743       JSONObject json = JSONObject.fromObject( bean );
744 
745       String[] keys = { "pbyte", "pshort", "pint", "plong", "pfloat", "pdouble", "pboolean",
746             "pchar", "pstring", "parray", "plist", "pmap", "pbean" };
747       for( int i = 0; i < keys.length; i++ ){
748          assertTrue( JSONNull.getInstance()
749                .equals( json.get( keys[i] ) ) );
750       }
751    }
752 
753    public void testFromObject_String() {
754       JSONObject json = JSONObject.fromObject( "{\"string\":\"json\"}" );
755       assertEquals( "json", json.getString( "string" ) );
756    }
757 
758    public void testFromObject_toBean_DynaBean() {
759       // bug report 1540137
760 
761       String jsondata = "{\"person\":{\"phone\":[\"111-222-3333\",\"777-888-9999\"],"
762             + "\"address\":{\"street\":\"123 somewhere place\",\"zip\":\"30005\",\"city\":\"Alpharetta\"},"
763             + "\"email\":[\"allen@work.com\",\"allen@home.net\"],\"name\":\"Allen\"}}";
764 
765       JSONObject jsonobj = JSONObject.fromObject( jsondata );
766       Object bean = JSONObject.toBean( jsonobj );
767       // bean is a DynaBean
768       assertTrue( bean instanceof MorphDynaBean );
769       // convert the DynaBean to a JSONObject again
770       JSONObject jsonobj2 = JSONObject.fromObject( bean );
771 
772       assertNotNull( jsonobj.getJSONObject( "person" ) );
773       assertFalse( JSONUtils.isNull( jsonobj.getJSONObject( "person" ) ) );
774       assertNotNull( jsonobj2.getJSONObject( "person" ) );
775       assertFalse( JSONUtils.isNull( jsonobj2.getJSONObject( "person" ) ) );
776 
777       JSONObject person1 = jsonobj.getJSONObject( "person" );
778       JSONObject person2 = jsonobj2.getJSONObject( "person" );
779       assertEquals( person1.get( "name" ), person2.get( "name" ) );
780       assertEquals( person1.get( "phone" )
781             .toString(), person2.get( "phone" )
782             .toString() );
783       assertEquals( person1.get( "email" )
784             .toString(), person2.get( "email" )
785             .toString() );
786       JSONObject address1 = person1.getJSONObject( "address" );
787       JSONObject address2 = person2.getJSONObject( "address" );
788       assertEquals( address1.get( "street" ), address2.get( "street" ) );
789       assertEquals( address1.get( "zip" ), address2.get( "zip" ) );
790       assertEquals( address1.get( "city" ), address2.get( "city" ) );
791    }
792 
793    public void testFromObject_use_wrappers() {
794       JSONObject json = JSONObject.fromObject( Boolean.TRUE );
795       assertTrue( json.isEmpty() );
796       json = JSONObject.fromObject( new Byte( Byte.MIN_VALUE ) );
797       assertTrue( json.isEmpty() );
798       json = JSONObject.fromObject( new Short( Short.MIN_VALUE ) );
799       assertTrue( json.isEmpty() );
800       json = JSONObject.fromObject( new Integer( Integer.MIN_VALUE ) );
801       assertTrue( json.isEmpty() );
802       json = JSONObject.fromObject( new Long( Long.MIN_VALUE ) );
803       assertTrue( json.isEmpty() );
804       json = JSONObject.fromObject( new Float( Float.MIN_VALUE ) );
805       assertTrue( json.isEmpty() );
806       json = JSONObject.fromObject( new Double( Double.MIN_VALUE ) );
807       assertTrue( json.isEmpty() );
808       json = JSONObject.fromObject( new Character( 'A' ) );
809       assertTrue( json.isEmpty() );
810    }
811 
812    public void testFromObject_withCustomDefaultValueProcessor() {
813       JsonConfig jsonConfig = new JsonConfig();
814       jsonConfig.registerDefaultValueProcessor( Integer.class, new NumberDefaultValueProcessor() );
815       JSONObject jsonObject = JSONObject.fromObject( new NumberBean(), jsonConfig );
816       assertNotNull( jsonObject );
817       assertEquals( new Integer( 0 ), jsonObject.get( "pwbyte" ) );
818       assertEquals( new Integer( 0 ), jsonObject.get( "pwshort" ) );
819       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwint" ) );
820       assertEquals( new Integer( 0 ), jsonObject.get( "pwlong" ) );
821       assertEquals( new Integer( 0 ), jsonObject.get( "pwfloat" ) );
822       assertEquals( new Double( 0 ), jsonObject.get( "pwdouble" ) );
823       assertEquals( new Integer( 0 ), jsonObject.get( "pbigdec" ) );
824       assertEquals( new Integer( 0 ), jsonObject.get( "pbigint" ) );
825       assertEquals( new Integer( 0 ), jsonObject.get( "pbyte" ) );
826       assertEquals( new Integer( 0 ), jsonObject.get( "pshort" ) );
827       assertEquals( new Integer( 0 ), jsonObject.get( "pint" ) );
828       assertEquals( new Integer( 0 ), jsonObject.get( "plong" ) );
829       assertEquals( new Double( 0 ), jsonObject.get( "pfloat" ) );
830       assertEquals( new Double( 0 ), jsonObject.get( "pdouble" ) );
831    }
832 
833    public void testFromObject_withCustomDefaultValueProcessor_andMatcher() {
834       JsonConfig jsonConfig = new JsonConfig();
835       jsonConfig.registerDefaultValueProcessor( Integer.class, new NumberDefaultValueProcessor() );
836       jsonConfig.setDefaultValueProcessorMatcher( new NumberDefaultValueProcessorMatcher() );
837       JSONObject jsonObject = JSONObject.fromObject( new NumberBean(), jsonConfig );
838       assertNotNull( jsonObject );
839       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pbigdec" ) );
840       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pbigint" ) );
841       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwbyte" ) );
842       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwshort" ) );
843       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwint" ) );
844       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwlong" ) );
845       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwfloat" ) );
846       assertEquals( NumberDefaultValueProcessor.NUMBER, jsonObject.get( "pwdouble" ) );
847       assertEquals( new Integer( 0 ), jsonObject.get( "pbyte" ) );
848       assertEquals( new Integer( 0 ), jsonObject.get( "pshort" ) );
849       assertEquals( new Integer( 0 ), jsonObject.get( "pint" ) );
850       assertEquals( new Integer( 0 ), jsonObject.get( "plong" ) );
851       assertEquals( new Double( 0 ), jsonObject.get( "pfloat" ) );
852       assertEquals( new Double( 0 ), jsonObject.get( "pdouble" ) );
853    }
854 
855    public void testFromObject_withExcludesPerClass() {
856       JsonConfig jsonConfig = new JsonConfig();
857       jsonConfig.registerPropertyExclusion( BeanA.class, "bool" );
858       JSONObject jsonA = JSONObject.fromObject( new BeanA(), jsonConfig );
859       JSONObject jsonB = JSONObject.fromObject( new BeanB(), jsonConfig );
860       assertNotNull( jsonA );
861       assertNotNull( jsonB );
862       assertFalse( jsonA.has("bool") );
863       assertTrue( jsonB.has("bool") );
864    }
865 
866    public void testFromObject_withExcludesPerClassAndMatcher() {
867       JsonConfig jsonConfig = new JsonConfig();
868       jsonConfig.registerPropertyExclusion( BeanA.class, "bool" );
869       jsonConfig.setPropertyExclusionClassMatcher( new BeanAPropertyExclusionClassMatcher() );
870       JSONObject jsonA = JSONObject.fromObject( new BeanA(), jsonConfig );
871       JSONObject jsonB = JSONObject.fromObject( new BeanB(), jsonConfig );
872       assertNotNull( jsonA );
873       assertNotNull( jsonB );
874       assertFalse( jsonA.has("bool") );
875       assertFalse( jsonB.has("bool") );
876    }
877    
878    public void testFromObject_withFilters() {
879       PrimitiveBean bean = new PrimitiveBean();
880       JsonConfig jsonConfig = new JsonConfig();
881       jsonConfig.setJsonPropertyFilter( new NumberPropertyFilter() );
882       JSONObject json = JSONObject.fromObject( bean, jsonConfig );
883       assertNotNull( json );
884       assertTrue( json.has( "pbean" ) );
885       assertTrue( json.has( "pclass" ) );
886       assertTrue( json.has( "pexcluded" ) );
887       assertTrue( json.has( "pfunction" ) );
888       assertTrue( json.has( "plist" ) );
889       assertTrue( json.has( "pmap" ) );
890       assertTrue( json.has( "pstring" ) );
891       assertTrue( json.has( "parray" ) );
892 
893       assertTrue( json.has( "pboolean" ) );
894       assertTrue( !json.has( "pbyte" ) );
895       assertTrue( !json.has( "pshort" ) );
896       assertTrue( !json.has( "pint" ) );
897       assertTrue( !json.has( "plong" ) );
898       assertTrue( !json.has( "pfloat" ) );
899       assertTrue( !json.has( "pdouble" ) );
900       assertTrue( json.has( "pchar" ) );
901    }
902    
903    public void testFromObject_withFiltersAndExcludes() {
904       PrimitiveBean bean = new PrimitiveBean();
905       JsonConfig jsonConfig = new JsonConfig();
906       jsonConfig.setJsonPropertyFilter( new NumberPropertyFilter() );
907       jsonConfig.setExcludes( new String[] { "pexcluded" } );
908       JSONObject json = JSONObject.fromObject( bean, jsonConfig );
909       assertNotNull( json );
910       assertTrue( json.has( "pbean" ) );
911       assertTrue( json.has( "pclass" ) );
912       assertTrue( !json.has( "pexcluded" ) );
913       assertTrue( json.has( "pfunction" ) );
914       assertTrue( json.has( "plist" ) );
915       assertTrue( json.has( "pmap" ) );
916       assertTrue( json.has( "pstring" ) );
917       assertTrue( json.has( "parray" ) );
918 
919       assertTrue( json.has( "pboolean" ) );
920       assertTrue( !json.has( "pbyte" ) );
921       assertTrue( !json.has( "pshort" ) );
922       assertTrue( !json.has( "pint" ) );
923       assertTrue( !json.has( "plong" ) );
924       assertTrue( !json.has( "pfloat" ) );
925       assertTrue( !json.has( "pdouble" ) );
926       assertTrue( json.has( "pchar" ) );
927    }
928 
929    public void testFromString_null_String() {
930       JSONObject json = JSONObject.fromObject( null );
931       assertTrue( json.isNullObject() );
932       assertEquals( JSONNull.getInstance()
933             .toString(), json.toString() );
934    }
935 
936    public void testHas() {
937       assertFalse( new JSONObject().has( "any" ) );
938       assertTrue( new JSONObject().element( "any", "value" )
939             .has( "any" ) );
940    }
941 
942    public void testLength() {
943       assertEquals( 0, new JSONObject().size() );
944    }
945 
946    public void testLength_nullObject() {
947       /*
948       try{
949          new JSONObject( true ).size();
950          fail( "Expected a JSONException" );
951       }catch( JSONException expected ){
952          // ok
953       }
954       */
955       assertEquals( 0, new JSONObject(true).size() );
956    }
957 
958    public void testOptBoolean() {
959       assertFalse( new JSONObject().optBoolean( "any" ) );
960    }
961 
962    public void testOptBoolean_defaultValue() {
963       assertTrue( new JSONObject().optBoolean( "any", true ) );
964    }
965 
966    public void testOptDouble() {
967       assertTrue( Double.isNaN( new JSONObject().optDouble( "any" ) ) );
968    }
969 
970    public void testOptDouble_defaultValue() {
971       assertEquals( 2d, new JSONObject().optDouble( "any", 2d ), 0d );
972    }
973 
974    public void testOptInt() {
975       assertEquals( 0, new JSONObject().optInt( "any" ) );
976    }
977 
978    public void testOptInt_defaultValue() {
979       assertEquals( 1, new JSONObject().optInt( "any", 1 ) );
980    }
981 
982    public void testOptJSONArray() {
983       JSONObject json = new JSONObject();
984       assertNull( json.optJSONArray( "a" ) );
985       json.element( "a", "[]" );
986       Assertions.assertEquals( new JSONArray(), json.optJSONArray( "a" ) );
987    }
988 
989    public void testOptJSONObject() {
990       JSONObject json = new JSONObject();
991       assertNull( json.optJSONObject( "a" ) );
992       json.element( "a", "{}" );
993       Assertions.assertEquals( new JSONObject(), json.optJSONObject( "a" ) );
994    }
995 
996    public void testOptLong() {
997       assertEquals( 0L, new JSONObject().optLong( "any" ) );
998    }
999 
1000    public void testOptLong_defaultValue() {
1001       assertEquals( 1L, new JSONObject().optLong( "any", 1L ) );
1002    }
1003 
1004    public void testOptString() {
1005       assertEquals( "", new JSONObject().optString( "any" ) );
1006    }
1007 
1008    public void testOptString_defaultValue() {
1009       assertEquals( "json", new JSONObject().optString( "any", "json" ) );
1010    }
1011 
1012    public void testToBean() throws Exception {
1013       String json = "{name=\"json\",bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2]}";
1014       JSONObject jsonObject = JSONObject.fromObject( json );
1015       Object bean = JSONObject.toBean( jsonObject );
1016       assertEquals( jsonObject.get( "name" ), PropertyUtils.getProperty( bean, "name" ) );
1017       assertEquals( jsonObject.get( "bool" ), PropertyUtils.getProperty( bean, "bool" ) );
1018       assertEquals( jsonObject.get( "int" ), PropertyUtils.getProperty( bean, "int" ) );
1019       assertEquals( jsonObject.get( "double" ), PropertyUtils.getProperty( bean, "double" ) );
1020       assertEquals( jsonObject.get( "func" ), PropertyUtils.getProperty( bean, "func" ) );
1021       List expected = (List) JSONArray.toCollection( jsonObject.getJSONArray( "array" ) );
1022       Assertions.assertEquals( expected, (List) PropertyUtils.getProperty( bean, "array" ) );
1023    }
1024 
1025    public void testToBean_BeanA() {
1026       String json = "{bool:true,integer:1,string:\"json\"}";
1027       JSONObject jsonObject = JSONObject.fromObject( json );
1028       BeanA bean = (BeanA) JSONObject.toBean( jsonObject, BeanA.class );
1029       assertEquals( jsonObject.get( "bool" ), Boolean.valueOf( bean.isBool() ) );
1030       assertEquals( jsonObject.get( "integer" ), new Integer( bean.getInteger() ) );
1031       assertEquals( jsonObject.get( "string" ), bean.getString() );
1032    }
1033 
1034    public void testToBean_BeanB() {
1035       String json = "{bool:true,integer:1,string:\"json\",intarray:[4,5,6]}";
1036       JSONObject jsonObject = JSONObject.fromObject( json );
1037       BeanB bean = (BeanB) JSONObject.toBean( jsonObject, BeanB.class );
1038       assertEquals( jsonObject.get( "bool" ), Boolean.valueOf( bean.isBool() ) );
1039       assertEquals( jsonObject.get( "integer" ), new Integer( bean.getInteger() ) );
1040       assertEquals( jsonObject.get( "string" ), bean.getString() );
1041       Assertions.assertEquals( bean.getIntarray(),
1042             JSONArray.toArray( jsonObject.getJSONArray( "intarray" ) ) );
1043    }
1044 
1045    public void testToBean_ClassBean() {
1046       JSONObject json = new JSONObject();
1047       json.element( "klass", "java.lang.Object" );
1048 
1049       ClassBean bean = (ClassBean) JSONObject.toBean( json, ClassBean.class );
1050       assertEquals( Object.class, bean.getKlass() );
1051    }
1052 
1053    public void testToBean_DynaBean__BigInteger_BigDecimal() {
1054       BigInteger l = new BigDecimal( "1.7976931348623157E308" ).toBigInteger();
1055       BigDecimal m = new BigDecimal( "1.7976931348623157E307" ).add( new BigDecimal( "0.0001" ) );
1056       JSONObject json = new JSONObject().element( "i", BigInteger.ZERO )
1057             .element( "d", MorphUtils.BIGDECIMAL_ONE )
1058             .element( "bi", l )
1059             .element( "bd", m );
1060       Object bean = JSONObject.toBean( json );
1061       Object i = ((MorphDynaBean) bean).get( "i" );
1062       Object d = ((MorphDynaBean) bean).get( "d" );
1063       assertTrue( i instanceof Integer );
1064       assertTrue( d instanceof Integer );
1065 
1066       Object bi = ((MorphDynaBean) bean).get( "bi" );
1067       Object bd = ((MorphDynaBean) bean).get( "bd" );
1068       assertTrue( bi instanceof BigInteger );
1069       assertTrue( bd instanceof BigDecimal );
1070    }
1071 
1072    public void testToBean_emptyBean() {
1073       EmptyBean bean = new EmptyBean();
1074 
1075       JSONObject json = JSONObject.fromObject( bean );
1076       JSONObject expected = new JSONObject();
1077       expected.element( "arrayp", new JSONArray() );
1078       expected.element( "listp", new JSONArray() );
1079       expected.element( "bytep", new Integer( 0 ) );
1080       expected.element( "shortp", new Integer( 0 ) );
1081       expected.element( "intp", new Integer( 0 ) );
1082       expected.element( "longp", new Integer( 0 ) );
1083       expected.element( "floatp", new Integer( 0 ) );
1084       expected.element( "doublep", new Double( 0 ) );
1085       expected.element( "charp", "" );
1086       expected.element( "stringp", "" );
1087 
1088       Assertions.assertEquals( expected, json );
1089 
1090       EmptyBean bean2 = (EmptyBean) JSONObject.toBean( json, EmptyBean.class );
1091 
1092       ArrayAssertions.assertEquals( new Object[0], bean2.getArrayp() );
1093       Assertions.assertEquals( new ArrayList(), bean2.getListp() );
1094       Assertions.assertEquals( new Byte( (byte) 0 ), bean2.getBytep() );
1095       Assertions.assertEquals( new Short( (short) 0 ), bean2.getShortp() );
1096       Assertions.assertEquals( new Integer( 0 ), bean2.getIntp() );
1097       Assertions.assertEquals( new Long( 0 ), bean2.getLongp() );
1098       Assertions.assertEquals( new Float( 0 ), bean2.getFloatp() );
1099       Assertions.assertEquals( new Double( 0 ), bean2.getDoublep() );
1100       Assertions.assertEquals( new Character( '\0' ), bean2.getCharp() );
1101       Assertions.assertEquals( "", bean2.getStringp() );
1102    }
1103 
1104    public void testToBean_interface() {
1105       // BUG 1542104
1106 
1107       try{
1108          JSONObject.toBean( JSONObject.fromObject( "{\"int\":1}" ), Serializable.class );
1109          fail( "Expected a JSONException" );
1110       }catch( JSONException expected ){
1111          // ok
1112       }
1113    }
1114 
1115    public void testToBean_Map() {
1116       // BUG 1542104
1117 
1118       Map map = new HashMap();
1119       map.put( "name", "json" );
1120       Object obj = JSONObject.toBean( JSONObject.fromObject( map ), Map.class );
1121       assertTrue( obj instanceof Map );
1122       assertEquals( map.get( "name" ), ((Map) obj).get( "name" ) );
1123    }
1124 
1125    public void testToBean_nested() throws Exception {
1126       String json = "{name=\"json\",bool:true,int:1,double:2.2,func:function(a){ return a; },nested:{nested:true}}";
1127       JSONObject jsonObject = JSONObject.fromObject( json );
1128       Object bean = JSONObject.toBean( jsonObject );
1129       assertEquals( jsonObject.get( "name" ), PropertyUtils.getProperty( bean, "name" ) );
1130       assertEquals( jsonObject.get( "bool" ), PropertyUtils.getProperty( bean, "bool" ) );
1131       assertEquals( jsonObject.get( "int" ), PropertyUtils.getProperty( bean, "int" ) );
1132       assertEquals( jsonObject.get( "double" ), PropertyUtils.getProperty( bean, "double" ) );
1133       assertEquals( jsonObject.get( "func" ), PropertyUtils.getProperty( bean, "func" ) );
1134       JSONObject nestedJson = jsonObject.getJSONObject( "nested" );
1135       Object nestedBean = PropertyUtils.getProperty( bean, "nested" );
1136       assertEquals( nestedJson.get( "nested" ), PropertyUtils.getProperty( nestedBean, "nested" ) );
1137    }
1138 
1139    public void testToBean_nested_beans__null_object() throws Exception {
1140       // BUG 1553617
1141 
1142       String json = "{\"beanA\":{bool:true,integer:1,string:\"jsonbean\"},\"beanB\":null}";
1143       JSONObject jsonObject = JSONObject.fromObject( json );
1144       BeanC bean = (BeanC) JSONObject.toBean( jsonObject, BeanC.class );
1145       assertNotNull( bean );
1146       BeanA beanA = bean.getBeanA();
1147       assertNotNull( beanA );
1148       assertEquals( true, beanA.isBool() );
1149       assertEquals( 1, beanA.getInteger() );
1150       assertEquals( "jsonbean", beanA.getString() );
1151       BeanB beanB = bean.getBeanB();
1152       assertNull( beanB );
1153    }
1154 
1155    public void testToBean_nested_beans_in_list__beans() {
1156       // BUG 1592799
1157 
1158       ListingBean listingBean = new ListingBean();
1159 
1160       ValueBean beanA1 = new ValueBean();
1161       beanA1.setValue( 90000 );
1162       ValueBean beanA2 = new ValueBean();
1163       beanA2.setValue( 91000 );
1164 
1165       listingBean.addAttribute( beanA1 );
1166       listingBean.addAttribute( beanA2 );
1167 
1168       JSONObject jsonObject = JSONObject.fromObject( listingBean );
1169       Map classMap = new HashMap();
1170       classMap.put( "attributes", ValueBean.class );
1171       ListingBean listingBean2 = (ListingBean) JSONObject.toBean( jsonObject, ListingBean.class,
1172             classMap );
1173       List attributes = listingBean2.getAttributes();
1174       Object ba = attributes.get( 0 );
1175       Object bb = attributes.get( 1 );
1176 
1177       assertTrue( ba instanceof ValueBean );
1178       assertTrue( bb instanceof ValueBean );
1179       assertEquals( beanA1.getValue(), ((ValueBean) ba).getValue() );
1180       assertEquals( beanA2.getValue(), ((ValueBean) bb).getValue() );
1181    }
1182 
1183    public void testToBean_nested_beans_in_list__DynaBean() {
1184       // BUG 1592799
1185 
1186       ListingBean listingBean = new ListingBean();
1187 
1188       ValueBean beanA1 = new ValueBean();
1189       beanA1.setValue( 90000 );
1190       ValueBean beanA2 = new ValueBean();
1191       beanA2.setValue( 91000 );
1192 
1193       listingBean.addAttribute( beanA1 );
1194       listingBean.addAttribute( beanA2 );
1195 
1196       JSONObject jsonObject = JSONObject.fromObject( listingBean );
1197       ListingBean listingBean2 = (ListingBean) JSONObject.toBean( jsonObject, ListingBean.class );
1198       List attributes = listingBean2.getAttributes();
1199       Object ba = attributes.get( 0 );
1200       Object bb = attributes.get( 1 );
1201 
1202       assertTrue( ba instanceof MorphDynaBean );
1203       assertTrue( bb instanceof MorphDynaBean );
1204       assertEquals( new Integer( beanA1.getValue() ), ((MorphDynaBean) ba).get( "value" ) );
1205       assertEquals( new Integer( beanA2.getValue() ), ((MorphDynaBean) bb).get( "value" ) );
1206    }
1207 
1208    public void testToBean_nested_beans_in_map__beans() {
1209       // BUG 1542092
1210 
1211       MappingBean mappingBean = new MappingBean();
1212 
1213       ValueBean beanA = new ValueBean();
1214       beanA.setValue( 90000 );
1215       ValueBean beanB = new ValueBean();
1216       beanB.setValue( 91000 );
1217 
1218       mappingBean.addAttribute( "beanA", beanA );
1219       mappingBean.addAttribute( "beanB", beanB );
1220 
1221       JSONObject jsonObject = JSONObject.fromObject( mappingBean );
1222       Map classMap = new HashMap();
1223       classMap.put( "bean.*", ValueBean.class );
1224       MappingBean mappingBean2 = (MappingBean) JSONObject.toBean( jsonObject, MappingBean.class,
1225             classMap );
1226       Object ba = mappingBean2.getAttributes()
1227             .get( "beanA" );
1228       Object bb = mappingBean2.getAttributes()
1229             .get( "beanB" );
1230       assertTrue( ba instanceof ValueBean );
1231       assertTrue( bb instanceof ValueBean );
1232       assertEquals( beanA.getValue(), ((ValueBean) ba).getValue() );
1233       assertEquals( beanB.getValue(), ((ValueBean) bb).getValue() );
1234    }
1235 
1236    public void testToBean_nested_beans_in_map__DynaBean() {
1237       // BUG 1542092
1238 
1239       MappingBean mappingBean = new MappingBean();
1240 
1241       ValueBean beanA = new ValueBean();
1242       beanA.setValue( 90000 );
1243       ValueBean beanB = new ValueBean();
1244       beanB.setValue( 91000 );
1245 
1246       mappingBean.addAttribute( "beanA", beanA );
1247       mappingBean.addAttribute( "beanB", beanB );
1248 
1249       JSONObject jsonObject = JSONObject.fromObject( mappingBean );
1250       MappingBean mappingBean2 = (MappingBean) JSONObject.toBean( jsonObject, MappingBean.class );
1251       Object ba = mappingBean2.getAttributes()
1252             .get( "beanA" );
1253       Object bb = mappingBean2.getAttributes()
1254             .get( "beanB" );
1255       assertTrue( ba instanceof MorphDynaBean );
1256       assertTrue( bb instanceof MorphDynaBean );
1257       assertEquals( new Integer( beanA.getValue() ), ((MorphDynaBean) ba).get( "value" ) );
1258       assertEquals( new Integer( beanB.getValue() ), ((MorphDynaBean) bb).get( "value" ) );
1259    }
1260 
1261    public void testToBean_nested_beans_in_set__beans() {
1262       // FR 1847116
1263 
1264       SetBean setBean = new SetBean();
1265 
1266       ValueBean beanA1 = new ValueBean();
1267       beanA1.setValue( 90000 );
1268       ValueBean beanA2 = new ValueBean();
1269       beanA2.setValue( 91000 );
1270 
1271       setBean.addAttribute( beanA1 );
1272       setBean.addAttribute( beanA2 );
1273 
1274       JSONObject jsonObject = JSONObject.fromObject( setBean );
1275       Map classMap = new HashMap();
1276       classMap.put( "attributes", ValueBean.class );
1277       SetBean setBean2 = (SetBean) JSONObject.toBean( jsonObject, SetBean.class, classMap );
1278       assertEquals( setBean, setBean2 );
1279    }
1280 
1281    public void testToBean_nested_beans_in_set__DynaBean() {
1282       // FR 1847116
1283 
1284       SetBean setBean = new SetBean();
1285 
1286       ValueBean beanA1 = new ValueBean();
1287       beanA1.setValue( 90000 );
1288       ValueBean beanA2 = new ValueBean();
1289       beanA2.setValue( 91000 );
1290 
1291       setBean.addAttribute( beanA1 );
1292       setBean.addAttribute( beanA2 );
1293 
1294       JSONObject jsonObject = JSONObject.fromObject( setBean );
1295       //SetBean setBean2 = (SetBean) JSONObject.toBean( jsonObject, SetBean.class );
1296       //assertEquals( setBean, setBean2 );
1297    }
1298 
1299    public void testToBean_nested_dynabeans__null_object() throws Exception {
1300       // BUG 1553617
1301 
1302       String json = "{\"beanA\":{bool:true,integer:1,string:\"jsonbean\"},\"beanB\":null}";
1303       JSONObject jsonObject = JSONObject.fromObject( json );
1304       Object bean = JSONObject.toBean( jsonObject );
1305       assertNotNull( bean );
1306       Object beanA = PropertyUtils.getProperty( bean, "beanA" );
1307       assertNotNull( beanA );
1308       assertEquals( Boolean.TRUE, PropertyUtils.getProperty( beanA, "bool" ) );
1309       assertEquals( new Integer( 1 ), PropertyUtils.getProperty( beanA, "integer" ) );
1310       assertEquals( "jsonbean", PropertyUtils.getProperty( beanA, "string" ) );
1311       Object beanB = PropertyUtils.getProperty( bean, "beanB" );
1312       assertNull( beanB );
1313    }
1314 
1315    public void testtoBean_noWriteMethod() {
1316       JSONObject json = new JSONObject();
1317       json.element( "propertyWithNoReadMethod", "json" );
1318       json.element( "propertyWithNoWriteMethod", "value" );
1319       PropertyBean bean = (PropertyBean) JSONObject.toBean( json, PropertyBean.class );
1320       assertNotNull( bean );
1321       assertEquals( "json", bean.valueOfPropertyWithNoReadMethod() );
1322       assertEquals( "json", bean.getPropertyWithNoWriteMethod() );
1323    }
1324 
1325    public void testToBean_null() {
1326       assertNull( JSONObject.toBean( null ) );
1327    }
1328 
1329    public void testToBean_null_2() {
1330       assertNull( JSONObject.toBean( null, BeanA.class ) );
1331    }
1332 
1333    public void testToBean_null_object() {
1334       JSONObject jsonObject = new JSONObject( true );
1335       BeanA bean = (BeanA) JSONObject.toBean( jsonObject, BeanA.class );
1336       assertNull( bean );
1337    }
1338 
1339    public void testToBean_null_values() {
1340       // bug report 1540196
1341 
1342       String json = "{\"items\":[[\"000\"],[\"010\", \"011\"],[\"020\"]]}";
1343       JSONObject jsonObject = JSONObject.fromObject( json );
1344 
1345       BeanFoo foo = (BeanFoo) JSONObject.toBean( jsonObject, BeanFoo.class );
1346       assertNotNull( foo );
1347       assertNotNull( foo.getItems() );
1348       String[][] items = foo.getItems();
1349       assertEquals( 3, items.length );
1350       assertEquals( "000", items[0][0] );
1351       assertEquals( "010", items[1][0] );
1352       assertEquals( "011", items[1][1] );
1353       assertEquals( "020", items[2][0] );
1354    }
1355 
1356    public void testToBean_NumberBean() {
1357       JSONObject json = new JSONObject();
1358       json.element( "pbyte", new Byte( (byte) 2 ) );
1359       json.element( "pshort", new Short( (short) 2 ) );
1360       json.element( "pint", new Integer( 2 ) );
1361       json.element( "plong", new Long( 2 ) );
1362       json.element( "pfloat", new Float( 2 ) );
1363       json.element( "pdouble", new Double( 2 ) );
1364       json.element( "pbigint", new BigInteger( "2" ) );
1365       json.element( "pbigdec", new BigDecimal( "2" ) );
1366 
1367       NumberBean bean = (NumberBean) JSONObject.toBean( json, NumberBean.class );
1368       assertEquals( (byte) 2, bean.getPbyte() );
1369       assertEquals( (short) 2, bean.getPshort() );
1370       assertEquals( 2, bean.getPint() );
1371       assertEquals( 2L, bean.getPlong() );
1372       assertEquals( 2f, bean.getPfloat(), 0f );
1373       assertEquals( 2d, bean.getPdouble(), 0d );
1374       assertEquals( new BigInteger( "2" ), bean.getPbigint() );
1375       assertEquals( new BigDecimal( "2" ), bean.getPbigdec() );
1376    }
1377 
1378    public void testToBean_NumberBean_2() {
1379       JSONObject json = new JSONObject();
1380       json.element( "pbyte", new Integer( 2 ) );
1381       json.element( "pshort", new Integer( 2 ) );
1382       json.element( "pint", new Integer( 2 ) );
1383       json.element( "plong", new Integer( 2 ) );
1384       json.element( "pfloat", new Integer( 2 ) );
1385       json.element( "pdouble", new Integer( 2 ) );
1386       json.element( "pbigint", new Integer( 2 ) );
1387       json.element( "pbigdec", new Integer( 2 ) );
1388 
1389       NumberBean bean = (NumberBean) JSONObject.toBean( json, NumberBean.class );
1390       assertEquals( (byte) 2, bean.getPbyte() );
1391       assertEquals( (short) 2, bean.getPshort() );
1392       assertEquals( 2, bean.getPint() );
1393       assertEquals( 2L, bean.getPlong() );
1394       assertEquals( 2f, bean.getPfloat(), 0f );
1395       assertEquals( 2d, bean.getPdouble(), 0d );
1396       assertEquals( new BigInteger( "2" ), bean.getPbigint() );
1397       assertEquals( new BigDecimal( "2" ), bean.getPbigdec() );
1398    }
1399 
1400    public void testToBean_ObjectBean() {
1401       // FR 1611204
1402       ObjectBean bean = new ObjectBean();
1403       bean.setPbyte( Byte.valueOf( "1" ) );
1404       bean.setPshort( Short.valueOf( "1" ) );
1405       bean.setPint( Integer.valueOf( "1" ) );
1406       bean.setPlong( Long.valueOf( "1" ) );
1407       bean.setPfloat( Float.valueOf( "1" ) );
1408       bean.setPdouble( Double.valueOf( "1" ) );
1409       bean.setPchar( new Character( '1' ) );
1410       bean.setPboolean( Boolean.TRUE );
1411       bean.setPstring( "json" );
1412       bean.setParray( new String[] { "a", "b" } );
1413       bean.setPbean( new BeanA() );
1414       List list = new ArrayList();
1415       list.add( "1" );
1416       list.add( "2" );
1417       bean.setPlist( list );
1418       Map map = new HashMap();
1419       map.put( "string", "json" );
1420       bean.setPmap( map );
1421       bean.setPfunction( new JSONFunction( "this;" ) );
1422       JSONObject json = JSONObject.fromObject( bean );
1423       Map classMap = new HashMap();
1424       classMap.put( "pbean", BeanA.class );
1425       ObjectBean obj = (ObjectBean) JSONObject.toBean( json, ObjectBean.class, classMap );
1426       assertEquals( Integer.valueOf( "1" ), obj.getPbyte() );
1427       assertEquals( Integer.valueOf( "1" ), obj.getPshort() );
1428       assertEquals( Integer.valueOf( "1" ), obj.getPint() );
1429       assertEquals( Integer.valueOf( "1" ), obj.getPlong() );
1430       assertEquals( Double.valueOf( "1" ), obj.getPfloat() );
1431       assertEquals( Double.valueOf( "1" ), obj.getPdouble() );
1432       assertEquals( "1", obj.getPchar() );
1433       assertEquals( "json", obj.getPstring() );
1434       List l = new ArrayList();
1435       l.add( "a" );
1436       l.add( "b" );
1437       ArrayAssertions.assertEquals( l.toArray(), (Object[]) obj.getParray() );
1438       l = new ArrayList();
1439       l.add( "1" );
1440       l.add( "2" );
1441       ArrayAssertions.assertEquals( l.toArray(), (Object[]) obj.getPlist() );
1442       assertEquals( new BeanA(), obj.getPbean() );
1443       assertTrue( obj.getPmap() instanceof MorphDynaBean );
1444    }
1445 
1446    public void testToBean_ObjectBean_empty() throws Exception {
1447       // FR 1611204
1448       ObjectBean bean = new ObjectBean();
1449       JSONObject json = JSONObject.fromObject( bean );
1450       Map classMap = new HashMap();
1451       classMap.put( "bean", BeanA.class );
1452       ObjectBean obj = (ObjectBean) JSONObject.toBean( json, ObjectBean.class, classMap );
1453 
1454       String[] keys = { "pbyte", "pshort", "pint", "plong", "pfloat", "pdouble", "pboolean",
1455             "pchar", "pstring", "parray", "plist", "pmap", "pbean" };
1456       for( int i = 0; i < keys.length; i++ ){
1457          assertNull( PropertyUtils.getProperty( obj, keys[i] ) );
1458       }
1459    }
1460 
1461    public void testToBean_rootObject() {
1462       JSONObject json = new JSONObject().element( "bool", "false" )
1463             .element( "integer", 84 )
1464             .element( "string", "bean" );
1465       BeanA expected = new BeanA();
1466       BeanA actual = (BeanA) JSONObject.toBean( json, expected, new JsonConfig() );
1467       assertNotNull( actual );
1468       assertEquals( expected, actual );
1469       assertFalse( actual.isBool() );
1470       assertEquals( 84, actual.getInteger() );
1471       assertEquals( "bean", actual.getString() );
1472    }
1473 
1474    public void testToBean_withFilters() {
1475       BeanA bean = new BeanA();
1476       bean.setBool( false );
1477       bean.setInteger( 84 );
1478       bean.setString( "filter" );
1479       JSONObject json = JSONObject.fromObject( bean );
1480       JsonConfig jsonConfig = new JsonConfig();
1481       jsonConfig.setRootClass( BeanA.class );
1482       jsonConfig.setJavaPropertyFilter( new BeanAPropertyFilter() );
1483       BeanA actual = (BeanA) JSONObject.toBean( json, jsonConfig );
1484       assertNotNull( actual );
1485       assertTrue( actual.isBool() );
1486       assertEquals( 42, actual.getInteger() );
1487       assertEquals( "filter", actual.getString() );
1488    }
1489 
1490    public void testToBean_withNonJavaIdentifier_camelCase_Strategy() {
1491       JSONObject json = new JSONObject().element( "camel case", "json" );
1492       jsonConfig.setJavaIdentifierTransformer( JavaIdentifierTransformer.CAMEL_CASE );
1493       jsonConfig.setRootClass( JavaIdentifierBean.class );
1494       JavaIdentifierBean bean = (JavaIdentifierBean) JSONObject.toBean( json, jsonConfig );
1495       assertNotNull( bean );
1496       assertEquals( "json", bean.getCamelCase() );
1497    }
1498 
1499    public void testToBean_withNonJavaIdentifier_underScore_Strategy() {
1500       JSONObject json = new JSONObject().element( "under score", "json" );
1501       jsonConfig.setJavaIdentifierTransformer( JavaIdentifierTransformer.UNDERSCORE );
1502       jsonConfig.setRootClass( JavaIdentifierBean.class );
1503       JavaIdentifierBean bean = (JavaIdentifierBean) JSONObject.toBean( json, jsonConfig );
1504       assertNotNull( bean );
1505       assertEquals( "json", bean.getUnder_score() );
1506    }
1507 
1508    public void testToBean_withNonJavaIdentifier_whitespace_Strategy() {
1509       JSONObject json = new JSONObject().element( " white space ", "json" );
1510       jsonConfig.setJavaIdentifierTransformer( JavaIdentifierTransformer.WHITESPACE );
1511       jsonConfig.setRootClass( JavaIdentifierBean.class );
1512       JavaIdentifierBean bean = (JavaIdentifierBean) JSONObject.toBean( json, jsonConfig );
1513       assertNotNull( bean );
1514       assertEquals( "json", bean.getWhitespace() );
1515    }
1516 
1517    public void testToBean_withPropertySetStrategy() {
1518       JSONObject json = new JSONObject().element( "key", "value" );
1519       JsonConfig jsonConfig = new JsonConfig();
1520       jsonConfig.setRootClass( MappingBean.class );
1521       jsonConfig.setPropertySetStrategy( new MappingPropertySetStrategy() );
1522       MappingBean bean = (MappingBean) JSONObject.toBean( json, jsonConfig );
1523       assertNotNull( bean );
1524       assertEquals( "value", bean.getAttributes()
1525             .get( "key" ) );
1526    }
1527    
1528    public void testToBeanWithJavaPropertyNameProcessor(){
1529       String json = "{bool:false}";
1530       JSONObject jsonObject = JSONObject.fromObject( json );
1531       JsonConfig jsonConfig = new JsonConfig();
1532       jsonConfig.registerJavaPropertyNameProcessor( BeanA.class, new SwapPropertyNameProcessor() );
1533       jsonConfig.setRootClass( BeanA.class );
1534       BeanA bean = (BeanA) JSONObject.toBean( jsonObject, jsonConfig );
1535       assertNotNull( bean );
1536       assertTrue( bean.isBool() );
1537       assertEquals( "false", bean.getString() );
1538    }
1539    
1540    public void testToJSONArray() {
1541       String json = "{bool:true,integer:1,string:\"json\"}";
1542       JSONArray names = JSONArray.fromObject( "['string','integer','bool']" );
1543       JSONObject jsonObject = JSONObject.fromObject( json );
1544       JSONArray jsonArray = jsonObject.toJSONArray( names );
1545       assertEquals( "json", jsonArray.getString( 0 ) );
1546       assertEquals( 1, jsonArray.getInt( 1 ) );
1547       assertTrue( jsonArray.getBoolean( 2 ) );
1548    }
1549 
1550    protected void setUp() throws Exception {
1551       jsonConfig = new JsonConfig();
1552    }
1553 
1554    private MorphDynaBean createDynaBean() throws Exception {
1555       Map properties = new HashMap();
1556       properties.put( "name", String.class );
1557       properties.put( "func", JSONFunction.class );
1558       properties.put( "jsonstr", JSONString.class );
1559       properties.put( "json", JSON.class );
1560       properties.put( "str", String.class );
1561       MorphDynaClass dynaClass = new MorphDynaClass( properties );
1562       MorphDynaBean dynaBean = (MorphDynaBean) dynaClass.newInstance();
1563       dynaBean.setDynaBeanClass( dynaClass );
1564       dynaBean.set( "name", "json" );
1565       dynaBean.set( "func", new JSONFunction( "return this;" ) );
1566       dynaBean.set( "jsonstr", new ObjectJSONStringBean() );
1567       dynaBean.set( "json", new JSONObject().element( "id", "1" ) );
1568       dynaBean.set( "str", "[1,2]" );
1569       // JSON Strings can not be null, only empty
1570       return dynaBean;
1571    }
1572 
1573    public static class BeanAPropertyExclusionClassMatcher extends PropertyExclusionClassMatcher {
1574       public Object getMatch( Class target, Set set ) {
1575          for( Iterator i = set.iterator(); i.hasNext(); ){
1576             Class c = (Class) i.next();
1577             if( BeanA.class.isAssignableFrom( c ) ){
1578                return c;
1579             }
1580          }
1581          return null;
1582       }
1583    }
1584 
1585    public static class BeanAPropertyFilter implements PropertyFilter {
1586       public boolean apply( Object source, String name, Object value ) {
1587          if( "bool".equals( name ) || "integer".equals( name ) ){
1588             return true;
1589          }
1590          return false;
1591       }
1592 
1593    }
1594 
1595    public static class MappingPropertySetStrategy extends PropertySetStrategy {
1596       public void setProperty( Object bean, String key, Object value ) throws JSONException {
1597          ((MappingBean) bean).addAttribute( key, value );
1598       }
1599    }
1600 
1601    public static class NumberDefaultValueProcessor implements DefaultValueProcessor {
1602       public static final Integer NUMBER = new Integer( 42 );
1603 
1604       public Object getDefaultValue( Class type ) {
1605          return NUMBER;
1606       }
1607    }
1608 
1609    public static class NumberDefaultValueProcessorMatcher extends DefaultValueProcessorMatcher {
1610       public Object getMatch( Class target, Set set ) {
1611          for( Iterator i = set.iterator(); i.hasNext(); ){
1612             Class c = (Class) i.next();
1613             if( Number.class.isAssignableFrom( c ) ){
1614                return c;
1615             }
1616          }
1617          return null;
1618       }
1619    }
1620    
1621    public static class NumberPropertyFilter implements PropertyFilter {
1622       public boolean apply( Object source, String name, Object value ) {
1623          if( value != null && Number.class.isAssignableFrom( value.getClass() ) ){
1624             return true;
1625          }
1626          return false;
1627       }
1628    }
1629    
1630    public static class PrefixerPropertyNameProcessor implements PropertyNameProcessor {
1631       private final String prefix;
1632 
1633       public PrefixerPropertyNameProcessor( String prefix ) {
1634          this.prefix = prefix;
1635       }
1636 
1637       public String processPropertyName( Class beanClass, String name ) {
1638          return prefix + name;
1639       }
1640    }
1641    
1642    public static class SwapPropertyNameProcessor implements PropertyNameProcessor {
1643       public String processPropertyName( Class beanClass, String name ) {
1644          if( name.equals("bool")){
1645             return "string";
1646          }
1647          return name;
1648       }
1649    }
1650    
1651    public void test_fromJSONObject() {
1652    }
1653 }