http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
new file mode 100755
index 0000000..6ec7335
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -0,0 +1,850 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+
+@SuppressWarnings({"unchecked","rawtypes","javadoc"})
+public class BeanConfigTest {
+
+       
//====================================================================================================
+       // testBasic
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+
+               BeanSession session = BeanContext.DEFAULT.createSession();
+
+               Person p1 = new Person();
+               p1.setName("John Doe");
+               p1.setAge(25);
+
+               Address a = new Address("101 Main St.", "Las Vegas", "NV", 
"89101");
+               AddressablePerson p2 = new AddressablePerson();
+               p2.setName("Jane Doe");
+               p2.setAge(21);
+               p2.setAddress(a);
+
+               // setup the reference results
+               Map m1 = new LinkedHashMap();
+               m1.put("name", p1.getName());
+               m1.put("age", new Integer(p1.getAge()));
+
+               Map m2 = new LinkedHashMap();
+               m2.put("street", a.getStreet());
+               m2.put("city", a.getCity());
+               m2.put("state", a.getState());
+               m2.put("zip", a.getZip());
+
+               Map m3 = new LinkedHashMap();
+               m3.put("name", p2.getName());
+               m3.put("age", new Integer(p2.getAge()));
+               m3.put("address", p2.getAddress());
+
+               Map pm1 = session.toBeanMap(p1);
+
+               if (pm1.size() != m1.size())
+                       fail("Bean Map size failed for: " + p1 + " / " + 
pm1.size()+ " / " + m1.size());
+
+               if (!pm1.keySet().equals(m1.keySet()))
+                       fail("Bean Map key set equality failed for: " + p1 + " 
/ " + pm1.keySet() + " / " + m1.keySet());
+
+               if (!m1.keySet().equals(pm1.keySet()))
+                       fail("Bean Map key set reverse equality failed for: " + 
p1 + " / " + pm1.keySet() + " / " + m1.keySet());
+
+               if (!pm1.equals(m1))
+                       fail("Bean Map equality failed for: " + p1 + " / " + 
pm1 + " / " + m1);
+
+               if (!m1.equals(pm1))
+                       fail("Bean Map reverse equality failed for: " + p1 + " 
/ " + pm1 + " / " + m1);
+
+               BeanMap bm1 = null;
+               try {
+                       bm1 = session.newBeanMap(Address.class);
+                       fail("Address returned as a new bean type, but 
shouldn't be since it doesn't have a default constructor.");
+               } catch (BeanRuntimeException e) {
+                       // Good.
+               }
+               bm1 = session.toBeanMap(new Address("street", "city", "state", 
"zip"));
+
+               BeanMap bm2 = session.newBeanMap(java.lang.Integer.class);
+               if (bm2 != null)
+                       fail("java.lang.Integer incorrectly desingated as bean 
type.");
+
+               BeanMap bm3 = session.newBeanMap(java.lang.Class.class);
+               if (bm3 != null)
+                       fail("java.lang.Class incorrectly desingated as bean 
type.");
+
+               Map m4 = bm1;
+               if (m4.keySet().size() != m2.size())
+                       fail("Bean Adapter map's key set has wrong size: " + a 
+ " / " + m4.keySet().size() + " / " + m2.size());
+
+               Iterator iter = m4.keySet().iterator();
+               Set temp = new HashSet();
+               int count = 0;
+               while (iter.hasNext()) {
+                       temp.add(iter.next());
+                       count++;
+               }
+               if (count != m2.size())
+                       fail("Iteration count over bean adpater key set failed: 
" + a + " / " + count + " / " + m2.size());
+
+               if (!m2.keySet().equals(temp))
+                       fail("Iteration over bean adpater key set failed: " + a 
+ " / " + m4.keySet() + " / " + m2.keySet());
+
+               BeanMap bm4 = session.toBeanMap(p2);
+               if (bm4 == null) {
+                       fail("Failed to identify class as bean type: " + 
p2.getClass());
+                       return;
+               }
+
+               Map m5 = bm4;
+               Set es1 = m5.entrySet();
+
+               if (!es1.equals(m3.entrySet()))
+                       fail("Entry set equality failed: " + p2 + " / " + es1 + 
" / " + m3.entrySet());
+
+               if (!m3.entrySet().equals(es1))
+                       fail("Entry set reverse equality failed: " + p2 + " / " 
+ es1 + " / " + m3.entrySet());
+
+               iter = es1.iterator();
+               temp = new HashSet();
+               count = 0;
+               while (iter.hasNext()) {
+                       temp.add(iter.next());
+                       count++;
+               }
+               if (count != m3.size())
+                       fail("Iteration count over bean adpater entry set 
failed: " + a + " / " + count + " / " + m3.size());
+
+               if (!m3.entrySet().equals(temp))
+                       fail("Iteration over bean adpater entry set failed: " + 
a + " / " + es1 + " / " + m3.entrySet());
+       }
+
+       public static class Person {
+               private String name;
+               private int age;
+
+               public Person() {
+                       this.name = null;
+                       this.age = -1;
+               }
+
+               public String getName() {
+                       return this.name;
+               }
+
+               public void setName(String name) {
+                       this.name = name;
+               }
+
+               public int getAge() {
+                       return this.age;
+               }
+
+               public void setAge(int age) {
+                       this.age = age;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return ("Person(name: " + this.getName() + ", age: "
+                                       + this.getAge() + ")");
+               }
+       }
+
+       public static class Address {
+               protected String street;
+               protected String city;
+               protected String state;
+               protected String zip;
+
+               public Address(String street, String city, String state, String 
zip) {
+                       this.street = street;
+                       this.city = city;
+                       this.state = state;
+                       this.zip = zip;
+               }
+
+               public String getStreet() {
+                       return this.street;
+               }
+
+               public String getCity() {
+                       return this.city;
+               }
+
+               public String getState() {
+                       return this.state;
+               }
+
+               public String getZip() {
+                       return this.zip;
+               }
+
+               @Override /* Object */
+               public boolean equals(Object o) {
+                       if (o == null)
+                               return false;
+                       if (this == o)
+                               return true;
+                       if (this.getClass() != o.getClass())
+                               return false;
+                       Address a = (Address) o;
+
+                       String v1 = this.getStreet();
+                       String v2 = a.getStreet();
+                       if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
+                               return false;
+
+                       v1 = this.getCity();
+                       v2 = a.getCity();
+                       if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
+                               return false;
+
+                       v1 = this.getState();
+                       v2 = a.getState();
+                       if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
+                               return false;
+
+                       v1 = this.getZip();
+                       v2 = a.getZip();
+                       return ((v1 == null) ? (v2 == null) : (v1.equals(v2)));
+               }
+
+               @Override /* Object */
+               public int hashCode() {
+                       int code = 0;
+                       if (this.street != null)
+                               code ^= this.street.hashCode();
+                       if (this.city != null)
+                               code ^= this.city.hashCode();
+                       if (this.state != null)
+                               code ^= this.state.hashCode();
+                       if (this.zip != null)
+                               code ^= this.zip.hashCode();
+                       return code;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return ("Address(street: " + this.getStreet() + ", 
city: "
+                                       + this.getCity() + ", state: " + 
this.getState()
+                                       + ", zip: " + this.getZip() + ")");
+               }
+       }
+
+       public static class AddressablePerson extends Person {
+               private Address address;
+
+               public AddressablePerson() {
+                       this.address = null;
+               }
+
+               public Address getAddress() {
+                       return this.address;
+               }
+
+               public void setAddress(Address addr) {
+                       this.address = addr;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return super.toString() + "@" + this.address;
+               }
+       }
+
+       
//====================================================================================================
+       // Exhaustive test of BeanContext.convertToType();
+       
//====================================================================================================
+       @Test
+       public void testBeanContextConvertToType() throws Exception {
+               BeanSession session = BeanContext.DEFAULT.createSession();
+               Object o;
+
+               // Primitive nulls.
+               o = null;
+               assertEquals(new Integer(0), session.convertToType(o, 
Integer.TYPE));
+               assertEquals(new Short((short) 0), session.convertToType(o, 
Short.TYPE));
+               assertEquals(new Long(0), session.convertToType(o, Long.TYPE));
+               assertEquals(new Float(0), session.convertToType(o, 
Float.TYPE));
+               assertEquals(new Double(0), session.convertToType(o, 
Double.TYPE));
+               assertEquals(new Byte((byte) 0), session.convertToType(o, 
Byte.TYPE));
+               assertEquals(new Character((char) 0), session.convertToType(o, 
Character.TYPE));
+               assertEquals(Boolean.FALSE, session.convertToType(o, 
Boolean.TYPE));
+
+               o = "1";
+
+               assertEquals(new Integer(1), session.convertToType(o, 
Integer.class));
+               assertEquals(new Short((short) 1), session.convertToType(o, 
Short.class));
+               assertEquals(new Long(1), session.convertToType(o, Long.class));
+               assertEquals(new Float(1), session.convertToType(o, 
Float.class));
+               assertEquals(new Double(1), session.convertToType(o, 
Double.class));
+               assertEquals(new Byte((byte) 1), session.convertToType(o, 
Byte.class));
+               assertEquals(new Character('1'), session.convertToType(o, 
Character.class));
+               assertEquals(Boolean.FALSE, session.convertToType(o, 
Boolean.class));
+
+               assertEquals(new Integer(1), session.convertToType(o, 
Integer.TYPE));
+               assertEquals(new Short((short) 1), session.convertToType(o, 
Short.TYPE));
+               assertEquals(new Long(1), session.convertToType(o, Long.TYPE));
+               assertEquals(new Float(1), session.convertToType(o, 
Float.TYPE));
+               assertEquals(new Double(1), session.convertToType(o, 
Double.TYPE));
+               assertEquals(new Byte((byte) 1), session.convertToType(o, 
Byte.TYPE));
+               assertEquals(new Character('1'), session.convertToType(o, 
Character.TYPE));
+               assertEquals(Boolean.FALSE, session.convertToType(o, 
Boolean.TYPE));
+
+               o = new Integer(1);
+
+               assertEquals(new Integer(1), session.convertToType(o, 
Integer.TYPE));
+               assertEquals(new Short((short) 1), session.convertToType(o, 
Short.TYPE));
+               assertEquals(new Long(1), session.convertToType(o, Long.TYPE));
+               assertEquals(new Float(1), session.convertToType(o, 
Float.TYPE));
+               assertEquals(new Double(1), session.convertToType(o, 
Double.TYPE));
+               assertEquals(new Byte((byte) 1), session.convertToType(o, 
Byte.TYPE));
+               assertEquals(new Character('1'), session.convertToType(o, 
Character.TYPE));
+               assertEquals(Boolean.TRUE, session.convertToType(o, 
Boolean.TYPE));
+
+               o = new Integer(0);
+               assertEquals(Boolean.FALSE, session.convertToType(o, 
Boolean.TYPE));
+
+               // Bean
+               o = "{name:'x',age:123}";
+               assertEquals("x", session.convertToType(o, 
Person.class).getName());
+               assertEquals(123, session.convertToType(o, 
Person.class).getAge());
+
+               // Read-only bean
+               o = "{name:'x',age:123}";
+               assertEquals("x", session.convertToType(o, 
ReadOnlyPerson.class).getName());
+               assertEquals(123, session.convertToType(o, 
ReadOnlyPerson.class).getAge());
+
+               // Class with forString(String) method.
+               o = UUID.randomUUID();
+               assertEquals(o, session.convertToType(o.toString(), 
UUID.class));
+
+               // Class with Constructor(String).
+               o = "xxx";
+               File file = session.convertToType(o, File.class);
+               assertEquals("xxx", file.getName());
+
+               // List of ints to array
+               o = new ObjectList(1, 2, 3);
+               assertEquals(1, session.convertToType(o, int[].class)[0]);
+
+               // List of beans to array
+               o = new ObjectList(new ReadOnlyPerson("x", 123));
+               assertEquals("x", session.convertToType(o, 
ReadOnlyPerson[].class)[0].getName());
+
+               // Multi-dimensional array of beans.
+               o = new ObjectList().append(new ObjectList(new 
ReadOnlyPerson("x", 123)));
+               assertEquals("x", session.convertToType(o, 
ReadOnlyPerson[][].class)[0][0].getName());
+
+               // Array of strings to array of ints
+               o = new String[] { "1", "2", "3" };
+               assertEquals(new Integer(1), session.convertToType(o, 
Integer[].class)[0]);
+               assertEquals(1, session.convertToType(o, int[].class)[0]);
+
+               // Array to list
+               o = new Integer[] { 1, 2, 3 };
+               assertEquals(new Integer(1), session.convertToType(o, 
LinkedList.class).get(0));
+
+               // HashMap to TreeMap
+               o = new AMap<Integer,String>().append(1, "foo");
+               assertEquals("foo", session.convertToType(o, 
TreeMap.class).firstEntry().getValue());
+
+               // String to TreeMap
+               o = "{1:'foo'}";
+               assertEquals("foo", session.convertToType(o, 
TreeMap.class).firstEntry().getValue());
+
+               // String to generic Map
+               assertEquals("foo", session.convertToType(o, 
Map.class).values().iterator().next());
+
+               // Array to String
+               o = new Object[] { "a", 1, false };
+               assertEquals("['a',1,false]", session.convertToType(o, 
String.class));
+               o = new Object[][] { { "a", 1, false } };
+               assertEquals("[['a',1,false]]", session.convertToType(o, 
String.class));
+
+       }
+
+       
//====================================================================================================
+       // Test properties set through a constructor.
+       
//====================================================================================================
+       @Test
+       public void testReadOnlyProperties() throws Exception {
+               BeanSession session = BeanContext.DEFAULT.createSession();
+               Object o;
+
+               // Bean to String
+               o = new ReadOnlyPerson("x", 123);
+               assertEquals("{name:'x',age:123}", session.convertToType(o, 
String.class));
+
+               // List of Maps to array of beans.
+               o = new ObjectList(new ObjectMap("{name:'x',age:1}"), new 
ObjectMap("{name:'y',age:2}"));
+               assertEquals(1, session.convertToType(o, 
ReadOnlyPerson[].class)[0].getAge());
+       }
+
+
+       @Bean(properties="name,age")
+       public static class ReadOnlyPerson {
+               private final String name;
+               private final int age;
+
+               @BeanConstructor(properties="name,age")
+               public ReadOnlyPerson(String name, int age) {
+                       this.name = name;
+                       this.age = age;
+               }
+
+               public String getName() {
+                       return this.name;
+               }
+
+               public int getAge() {
+                       return this.age;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return "toString():name=" + name + ",age=" + age;
+               }
+       }
+
+       
//====================================================================================================
+       // testEnums
+       
//====================================================================================================
+       @Test
+       public void testEnums() throws Exception {
+               BeanSession session = BeanContext.DEFAULT.createSession();
+               Object o;
+
+               // Enum
+               o = "ENUM2";
+               assertEquals(TestEnum.ENUM2, session.convertToType(o, 
TestEnum.class));
+               assertEquals("ENUM2", session.convertToType(TestEnum.ENUM2, 
String.class));
+
+               // Array of enums
+               o = new String[] { "ENUM2" };
+               assertEquals(TestEnum.ENUM2, session.convertToType(o, 
TestEnum[].class)[0]);
+       }
+
+       public enum TestEnum {
+               ENUM1, ENUM2, ENUM3
+       }
+
+       
//====================================================================================================
+       // testProxyHandler
+       
//====================================================================================================
+       @Test
+       public void testProxyHandler() throws Exception {
+               BeanSession session = 
PropertyStore.create().getBeanContext().createSession();
+
+               A f1 = (A) Proxy.newProxyInstance(this.getClass()
+                               .getClassLoader(), new Class[] { A.class },
+                               new AHandler());
+
+               BeanMap bm1 = session.toBeanMap(f1);
+               if (bm1 == null) {
+                       fail("Failed to obtain bean adapter for proxy: " + f1);
+                       return;
+               }
+
+               BeanMap bm2 = session.newBeanMap(A.class);
+               if (bm2 == null) {
+                       fail("Failed to create dynamic proxy bean for 
interface: " + A.class.getName());
+                       return;
+               }
+               bm2.put("a", "Hello");
+               bm2.put("b", new Integer(50));
+               f1.setA("Hello");
+               f1.setB(50);
+
+               if (!bm2.get("a").equals("Hello"))
+                       fail("Failed to set string property 'a' on dynamic 
proxy bean.  " + bm2);
+
+               if (!bm2.get("b").equals(new Integer(50)))
+                       fail("Failed to set string property 'b' on dynamic 
proxy bean.  " + bm2);
+
+               if (!bm1.equals(bm2))
+                       fail("Failed equality test of dynamic proxies beans: " 
+ bm1 + " / " + bm2);
+
+               if (!bm2.equals(bm1))
+                       fail("Failed reverse equality test of dynamic proxies 
beans: " + bm1 + " / " + bm2);
+       }
+
+       public static interface A {
+               String getA();
+
+               void setA(String a);
+
+               int getB();
+
+               void setB(int b);
+       }
+
+       public static class AHandler implements InvocationHandler {
+               private Map map;
+
+               public AHandler() {
+                       this.map = new HashMap();
+                       this.map.put("a", "");
+                       this.map.put("b", new Integer(0));
+               }
+
+               @Override /* InvocationHandler */
+               public Object invoke(Object proxy, Method method, Object[] args)
+                               throws Throwable {
+                       String methodName = method.getName();
+                       if (methodName.equals("getA")) {
+                               return this.map.get("a");
+                       }
+                       if (methodName.equals("setA")) {
+                               this.map.put("a", args[0]);
+                               return null;
+                       }
+                       if (methodName.equals("getB")) {
+                               return this.map.get("b");
+                       }
+                       if (methodName.equals("setB")) {
+                               this.map.put("b", args[0]);
+                               return null;
+                       }
+                       if (methodName.equals("toString")) {
+                               return this.map.toString();
+                       }
+                       return null;
+               }
+       }
+
+       
//====================================================================================================
+       // testFluentStyleSetters
+       
//====================================================================================================
+       @Test
+       public void testFluentStyleSetters() throws Exception {
+               B2 t = new B2().init();
+               BeanMap m = BeanContext.DEFAULT.createSession().toBeanMap(t);
+               m.put("f1", 2);
+               assertEquals(t.f1, 2);
+       }
+
+       public static class B {
+               int f1;
+               public int getF1() { return f1; }
+               public B setF1(int f1) { this.f1 = f1; return this; }
+       }
+
+       public static class B2 extends B {
+               @Override /* B */
+               public B2 setF1(int f1) { this.f1 = f1; return this; }
+               public B2 init() { this.f1 = 1; return this;}
+       }
+
+       
//====================================================================================================
+       // testClassMetaCaching
+       
//====================================================================================================
+       @Test
+       public void testClassMetaCaching() throws Exception {
+               ParserBuilder p1, p2;
+
+               p1 = new JsonParserBuilder();
+               p2 = new JsonParserBuilder();
+               assertSameCache(p1, p2);
+
+               p1.beansRequireDefaultConstructor(true);
+               assertDifferentCache(p1, p2);
+               p2.beansRequireDefaultConstructor(true);
+               assertSameCache(p1, p2);
+
+               p1.beansRequireSerializable(true);
+               assertDifferentCache(p1, p2);
+               p2.beansRequireSerializable(true);
+               assertSameCache(p1, p2);
+
+               p1.beansRequireSettersForGetters(true);
+               assertDifferentCache(p1, p2);
+               p2.beansRequireSettersForGetters(true);
+               assertSameCache(p1, p2);
+
+               p1.beansRequireSomeProperties(false);
+               assertDifferentCache(p1, p2);
+               p2.beansRequireSomeProperties(false);
+               assertSameCache(p1, p2);
+
+               p1.beanMapPutReturnsOldValue(true);
+               assertDifferentCache(p1, p2);
+               p2.beanMapPutReturnsOldValue(true);
+               assertSameCache(p1, p2);
+
+               p1.beanConstructorVisibility(Visibility.DEFAULT);
+               assertDifferentCache(p1, p2);
+               p2.beanConstructorVisibility(Visibility.DEFAULT);
+               assertSameCache(p1, p2);
+               p1.beanConstructorVisibility(Visibility.NONE);
+               assertDifferentCache(p1, p2);
+               p2.beanConstructorVisibility(Visibility.NONE);
+               assertSameCache(p1, p2);
+               p1.beanConstructorVisibility(Visibility.PRIVATE);
+               assertDifferentCache(p1, p2);
+               p2.beanConstructorVisibility(Visibility.PRIVATE);
+               assertSameCache(p1, p2);
+               p1.beanConstructorVisibility(Visibility.PROTECTED);
+               assertDifferentCache(p1, p2);
+               p2.beanConstructorVisibility(Visibility.PROTECTED);
+               assertSameCache(p1, p2);
+
+               p1.beanClassVisibility(Visibility.DEFAULT);
+               assertDifferentCache(p1, p2);
+               p2.beanClassVisibility(Visibility.DEFAULT);
+               assertSameCache(p1, p2);
+               p1.beanClassVisibility(Visibility.NONE);
+               assertDifferentCache(p1, p2);
+               p2.beanClassVisibility(Visibility.NONE);
+               assertSameCache(p1, p2);
+               p1.beanClassVisibility(Visibility.PRIVATE);
+               assertDifferentCache(p1, p2);
+               p2.beanClassVisibility(Visibility.PRIVATE);
+               assertSameCache(p1, p2);
+               p1.beanClassVisibility(Visibility.PROTECTED);
+               assertDifferentCache(p1, p2);
+               p2.beanClassVisibility(Visibility.PROTECTED);
+               assertSameCache(p1, p2);
+
+               p1.beanFieldVisibility(Visibility.DEFAULT);
+               assertDifferentCache(p1, p2);
+               p2.beanFieldVisibility(Visibility.DEFAULT);
+               assertSameCache(p1, p2);
+               p1.beanFieldVisibility(Visibility.NONE);
+               assertDifferentCache(p1, p2);
+               p2.beanFieldVisibility(Visibility.NONE);
+               assertSameCache(p1, p2);
+               p1.beanFieldVisibility(Visibility.PRIVATE);
+               assertDifferentCache(p1, p2);
+               p2.beanFieldVisibility(Visibility.PRIVATE);
+               assertSameCache(p1, p2);
+               p1.beanFieldVisibility(Visibility.PROTECTED);
+               assertDifferentCache(p1, p2);
+               p2.beanFieldVisibility(Visibility.PROTECTED);
+               assertSameCache(p1, p2);
+
+               p1.methodVisibility(Visibility.DEFAULT);
+               assertDifferentCache(p1, p2);
+               p2.methodVisibility(Visibility.DEFAULT);
+               assertSameCache(p1, p2);
+               p1.methodVisibility(Visibility.NONE);
+               assertDifferentCache(p1, p2);
+               p2.methodVisibility(Visibility.NONE);
+               assertSameCache(p1, p2);
+               p1.methodVisibility(Visibility.PRIVATE);
+               assertDifferentCache(p1, p2);
+               p2.methodVisibility(Visibility.PRIVATE);
+               assertSameCache(p1, p2);
+               p1.methodVisibility(Visibility.PROTECTED);
+               assertDifferentCache(p1, p2);
+               p2.methodVisibility(Visibility.PROTECTED);
+               assertSameCache(p1, p2);
+
+               p1.useJavaBeanIntrospector(true);
+               assertDifferentCache(p1, p2);
+               p2.useJavaBeanIntrospector(true);
+               assertSameCache(p1, p2);
+
+               p1.useInterfaceProxies(false);
+               assertDifferentCache(p1, p2);
+               p2.useInterfaceProxies(false);
+               assertSameCache(p1, p2);
+
+               p1.ignoreUnknownBeanProperties(true);
+               assertDifferentCache(p1, p2);
+               p2.ignoreUnknownBeanProperties(true);
+               assertSameCache(p1, p2);
+
+               p1.ignoreUnknownNullBeanProperties(false);
+               assertDifferentCache(p1, p2);
+               p2.ignoreUnknownNullBeanProperties(false);
+               assertSameCache(p1, p2);
+
+               p1.ignorePropertiesWithoutSetters(false);
+               assertDifferentCache(p1, p2);
+               p2.ignorePropertiesWithoutSetters(false);
+               assertSameCache(p1, p2);
+
+               p1.ignoreInvocationExceptionsOnGetters(true);
+               assertDifferentCache(p1, p2);
+               p2.ignoreInvocationExceptionsOnGetters(true);
+               assertSameCache(p1, p2);
+
+               p1.ignoreInvocationExceptionsOnSetters(true);
+               assertDifferentCache(p1, p2);
+               p2.ignoreInvocationExceptionsOnSetters(true);
+               assertSameCache(p1, p2);
+
+               p1.notBeanPackages("foo");
+               assertDifferentCache(p1, p2);
+               p2.notBeanPackages("foo");
+               assertSameCache(p1, p2);
+               p1.notBeanPackages("bar");
+               assertDifferentCache(p1, p2);
+               p2.notBeanPackages("bar");
+               assertSameCache(p1, p2);
+               p1.notBeanPackages("baz");
+               p1.notBeanPackages("bing");
+               assertDifferentCache(p1, p2);
+               p2.notBeanPackages("bing");
+               p2.notBeanPackages("baz");
+               assertSameCache(p1, p2);
+
+               p1.removeNotBeanPackages("bar");
+               assertDifferentCache(p1, p2);
+               p2.removeNotBeanPackages("bar");
+               assertSameCache(p1, p2);
+
+               p1.pojoSwaps(DummyPojoSwapA.class);
+               assertDifferentCache(p1, p2);
+               p2.pojoSwaps(DummyPojoSwapA.class);
+               assertSameCache(p1, p2);
+               p1.pojoSwaps(DummyPojoSwapB.class,DummyPojoSwapC.class);  // 
Order of filters is important!
+               p2.pojoSwaps(DummyPojoSwapC.class,DummyPojoSwapB.class);
+               assertDifferentCache(p1, p2);
+
+               p1 = new JsonParserBuilder();
+               p2 = new JsonParserBuilder();
+               p1.beanFilters(DummyBeanFilterA.class);
+               assertDifferentCache(p1, p2);
+               p2.beanFilters(DummyBeanFilterA.class);
+               assertSameCache(p1, p2);
+               p1.beanFilters(DummyBeanFilterB.class,DummyBeanFilterC.class);  
// Order of filters is important!
+               p2.beanFilters(DummyBeanFilterC.class,DummyBeanFilterB.class);
+               assertDifferentCache(p1, p2);
+       }
+
+       public static class DummyPojoSwapA extends MapSwap<A> {}
+       public static class DummyPojoSwapB extends MapSwap<B> {}
+       public static class DummyPojoSwapC extends MapSwap<C> {}
+       public static class DummyBeanFilterA extends BeanFilterBuilder {
+               public DummyBeanFilterA() {
+                       super(A.class);
+               }
+       }
+       public static class DummyBeanFilterB extends BeanFilterBuilder {
+               public DummyBeanFilterB() {
+                       super(B.class);
+               }
+       }
+       public static class DummyBeanFilterC extends BeanFilterBuilder {
+               public DummyBeanFilterC() {
+                       super(C.class);
+               }
+       }
+       public static class C {}
+
+       private void assertSameCache(ParserBuilder p1b, ParserBuilder p2b) {
+               Parser p1 = p1b.build(), p2 = p2b.build();
+               
assertTrue(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
+               assertTrue(p1.getBeanContext().hashCode() == 
p2.getBeanContext().hashCode());
+       }
+
+       private void assertDifferentCache(ParserBuilder p1b, ParserBuilder p2b) 
{
+               Parser p1 = p1b.build(), p2 = p2b.build();
+               
assertFalse(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
+               assertFalse(p1.getBeanContext().hashCode() == 
p2.getBeanContext().hashCode());
+       }
+
+       
//====================================================================================================
+       // testNotABeanReasons
+       
//====================================================================================================
+       @Test
+       public void testNotABeanNonStaticInnerClass() throws Exception {
+               BeanContext bc = BeanContext.DEFAULT;
+               ClassMeta cm = bc.getClassMeta(C1.class);
+               assertFalse(cm.canCreateNewInstance());
+       }
+
+       public class C1 {
+               public int f1;
+       }
+
+       
//====================================================================================================
+       // testAddingToArrayProperty
+       // This tests the speed of the BeanMap.add() method against array 
properties.
+       // For performance reasons, array properties are stored as temporary 
ArrayLists until the
+       // BeanMap.getBean() method is called.
+       
//====================================================================================================
+       @Test(timeout=1000) // Should be around 100ms at most.
+       public void testAddingToArrayProperty() throws Exception {
+               BeanSession session = BeanContext.DEFAULT.createSession();
+               BeanMap<D> bm = session.newBeanMap(D.class);
+               for (int i = 0; i < 5000; i++) {
+                       bm.add("f1", i);
+                       bm.add("f2", i);
+                       bm.add("f3", i);
+                       bm.add("f4", i);
+               }
+               D d = bm.getBean();
+               assertEquals(d.f1.length, 5000);
+               assertEquals(d.f2.length, 5000);
+               assertEquals(d.f3.length, 5003);
+               assertEquals(d.f4.length, 5003);
+       }
+
+       public class D {
+               public int[] f1;
+               private int[] f2;
+               public int[] f3 = new int[]{1,2,3};
+               private int[] f4 = new int[]{1,2,3};
+               public int[] getF2() {return f2;}
+               public void setF2(int[] f2) {this.f2 = f2;}
+               public int[] getF4() {return f4;}
+               public void setF4(int[] f4) {this.f4 = f4;}
+       }
+
+       
//====================================================================================================
+       // testClassClassMeta
+       // Make sure we can get ClassMeta objects against the Class class.
+       
//====================================================================================================
+       @Test
+       public void testClassClassMeta() throws Exception {
+               ClassMeta cm = BeanContext.DEFAULT.getClassMeta(Class.class);
+               assertNotNull(cm);
+
+               cm = BeanContext.DEFAULT.getClassMeta(Class[].class);
+               assertNotNull(cm);
+       }
+
+       
//====================================================================================================
+       // testBlanks
+       
//====================================================================================================
+       @Test
+       public void testBlanks() throws Exception {
+               BeanSession session = BeanContext.DEFAULT.createSession();
+
+               // Blanks get interpreted as the default value for primitives 
and null for boxed objects.
+               assertEquals(0, (int)session.convertToType("", int.class));
+               assertNull(session.convertToType("", Integer.class));
+
+               // Booleans are handled different since 'new Boolean("")' is 
valid and resolves to false
+               // while 'new Integer("")' produces an exception.
+               assertEquals(false, (boolean)session.convertToType("", 
boolean.class));
+               assertEquals(false, session.convertToType("", Boolean.class));
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
new file mode 100755
index 0000000..8b6f383
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
@@ -0,0 +1,137 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class BeanFilterTest {
+
+       
//====================================================================================================
+       // Test sub types
+       
//====================================================================================================
+       @Test
+       public void testSubTypes() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               JsonParser p = JsonParser.DEFAULT;
+
+               A1 a1 = new A1();
+               a1.f1 = "f1";
+               a1.fb = new B2();
+               ((B2)a1.fb).f2 = "f2";
+               String r = s.serialize(a1);
+               
assertEquals("{_type:'A1',f0:'f0',fb:{_type:'B2',f0b:'f0b',f2:'f2'},f1:'f1'}", 
r);
+
+               A a = p.parse(r, A.class);
+               assertTrue(a instanceof A1);
+               assertTrue(a.fb instanceof B2);
+               assertEquals("f1", ((A1)a).f1);
+               assertEquals("f2", ((B2)a.fb).f2);
+
+               // Try out-of-order creation.
+               r = 
"{f0:'f0',f1:'f1',_type:'A1',fb:{f0b:'f0b',f2:'f2',_type:'B2'}}";
+               a = p.parse(r, A.class);
+               assertTrue(a instanceof A1);
+               assertTrue(a.fb instanceof B2);
+               assertEquals("f1", ((A1)a).f1);
+               assertEquals("f2", ((B2)a.fb).f2);
+       }
+
+       @Bean(beanDictionary={A1.class, A2.class})
+       public static abstract class A {
+               public String f0 = "f0";
+               public B fb;
+       }
+
+       @Bean(typeName="A1")
+       public static class A1 extends A {
+               public String f1;
+       }
+
+       @Bean(typeName="A2")
+       public static class A2 extends A {
+               public String f2;
+       }
+
+       @Bean(beanDictionary={B1.class,B2.class})
+       public static abstract class B {
+               public String f0b = "f0b";
+       }
+
+       @Bean(typeName="B1")
+       public static class B1 extends B {
+               public String f1;
+       }
+
+       @Bean(typeName="B2")
+       public static class B2 extends B {
+               public String f2;
+       }
+
+       
//====================================================================================================
+       // Test parent class used as filter
+       
//====================================================================================================
+       @Test
+       public void testParentClassFilter() throws Exception {
+               JsonSerializer s = new 
JsonSerializerBuilder().simple().beanFilters(C1.class).build();
+
+               C1 c1 = new C2();
+               String r = s.serialize(c1);
+               assertEquals("{f0:'f0'}", r);
+
+               List<C1> l = new LinkedList<C1>();
+               l.add(new C2());
+               r = s.serialize(l);
+               assertEquals("[{f0:'f0'}]", r);
+       }
+
+       public static class C1 {
+               public String f0 = "f0";
+       }
+
+       public static class C2 extends C1 {
+               public String f1 = "f1";
+       }
+
+       
//====================================================================================================
+       // Test non-static parent class used as filter
+       
//====================================================================================================
+       @Test
+       public void testParentClassFilter2() throws Exception {
+               JsonSerializer s = new 
JsonSerializerBuilder().simple().beanFilters(D1.class).build();
+
+               D1 d1 = new D2();
+               String r = s.serialize(d1);
+               assertEquals("{f0:'f0'}", r);
+
+               List<D1> l = new LinkedList<D1>();
+               l.add(new D2());
+               r = s.serialize(l);
+               assertEquals("[{f0:'f0'}]", r);
+       }
+
+       public class D1 {
+               public String f0 = "f0";
+       }
+
+       public class D2 extends D1 {
+               public String f1 = "f1";
+       }
+
+}

Reply via email to