OSDN Git Service

removed all files
[xerial/xerial-core.git] / src / main / java / org / xerial / util / bean / BeanUtil.java
diff --git a/src/main/java/org/xerial/util/bean/BeanUtil.java b/src/main/java/org/xerial/util/bean/BeanUtil.java
deleted file mode 100755 (executable)
index ece70d1..0000000
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*--------------------------------------------------------------------------\r
- *  Copyright 2007 Taro L. Saito\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License");\r
- *  you may not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS,\r
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *--------------------------------------------------------------------------*/\r
-//--------------------------------------\r
-// XerialJ Project\r
-//\r
-// BeanUtil.java\r
-// Since: 2007/03/29\r
-//\r
-// $URL$ \r
-// $Author$\r
-//--------------------------------------\r
-package org.xerial.util.bean;\r
-\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.io.Reader;\r
-import java.io.StringReader;\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Modifier;\r
-import java.lang.reflect.ParameterizedType;\r
-import java.lang.reflect.Type;\r
-import java.net.URL;\r
-import java.sql.ResultSet;\r
-import java.sql.ResultSetMetaData;\r
-import java.sql.SQLException;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.Vector;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-import org.w3c.dom.Element;\r
-import org.xerial.core.XerialErrorCode;\r
-import org.xerial.core.XerialException;\r
-import org.xerial.json.JSONArray;\r
-import org.xerial.json.JSONBoolean;\r
-import org.xerial.json.JSONDouble;\r
-import org.xerial.json.JSONInteger;\r
-import org.xerial.json.JSONLong;\r
-import org.xerial.json.JSONObject;\r
-import org.xerial.json.JSONString;\r
-import org.xerial.json.JSONValue;\r
-import org.xerial.lens.Lens;\r
-import org.xerial.silk.SilkWalker;\r
-import org.xerial.util.Pair;\r
-import org.xerial.util.bean.impl.Appender;\r
-import org.xerial.util.bean.impl.ArraySetter;\r
-import org.xerial.util.bean.impl.BeanBindingProcess;\r
-import org.xerial.util.bean.impl.BeanStreamReader;\r
-import org.xerial.util.bean.impl.BeanUtilImpl;\r
-import org.xerial.util.bean.impl.BindRuleGeneratorForBeanStream;\r
-import org.xerial.util.bean.impl.CollectionAdder;\r
-import org.xerial.util.bean.impl.CollectionSetter;\r
-import org.xerial.util.bean.impl.Getter;\r
-import org.xerial.util.bean.impl.MapPutter;\r
-import org.xerial.util.bean.impl.MapSetter;\r
-import org.xerial.util.bean.impl.Setter;\r
-import org.xerial.util.xml.XMLGenerator;\r
-\r
-/**\r
- * BeanUtil class supports data binding between JSON data and a bean class.\r
- * \r
- * A bean class must have the followings: - A public default (no argument)\r
- * constructor - To bind data object to a class, there must be public\r
- * getter/seter methods in the target class, prefixd with get/set. -- Allowable\r
- * data classes are: ---- primitive types: int/Integer, double/Double,\r
- * float/Float, boolean/Boolean, String ---- bean classes ---- Collection of\r
- * allowable data classes. e.g. List<String>, Set<Integer>, etc. ---- Map with\r
- * key and value classes. key and value also must be allowable classes. ------\r
- * to bind JSON data to map object, putSomething() method is requried. See the\r
- * following description.\r
- * \r
- * For example, a Person class with integer id and string name values must have\r
- * <code>public int getId()</code> and <code>public String getName()</code>, and\r
- * <code>public void setId(int id)</code> and\r
- * <code>public void setName(String name)</code> methods.\r
- * \r
- * Usage Example. <code>\r
- * class Person {\r
- *   int id;\r
- *   String name;\r
- *   public Person();\r
- *   public Person(int id, String name)\r
- *   { this.id = id; this.name = name; } \r
- *   \r
- *   public int getId() { return id; }\r
- *   public String getName() { return name; }\r
- *   public void setId(int id) { this.id = id; }\r
- *   public void setName(String name) { this.name = name; }\r
- * }\r
- * \r
- * Person p1 = new Person(1, "leo");\r
- * String json = BeanUtil.toJSON(p1); // it will give a json string { "id" : 1, "name" : "leo"}\r
- * \r
- * Person p2 = new Person() // empty data\r
- * BeanUtil.populate(p2, json);        // fill p2 with a give json data\r
- * // p2.id = 1, p2.name = "leo"\r
- * \r
- * </code>\r
- * \r
- * \r
- * \r
- * In the GWT (Google Web Toolkit) of the current version (1.3.3, Mar 2007), the\r
- * generics feature of Jave (since JDK1.5) cannot be used within the client Java\r
- * codes. This is a problematic since GWT cannot compile the following method:\r
- * <code>\r
- * void setPersonList(List<Person> personList) { this.personList = personList; }\r
- * </code> So you have to change the argument of the avobe method as: <code>\r
- * void setPersonList(List personList) { ... }\r
- * </code>\r
- * But, with this setter method, we have no information about the element type\r
- * contained in the List class. So given a JSON data, e.g.,{ "personList" : [\r
- * {"id":1, "name":"leo"}, {"id":2, "name":"taro"}] }, BeanUtil class cannot\r
- * instantiate any Person classes.\r
- * \r
- * To resolve this problem, BeanUtil supports data binding via adder methods.\r
- * For example, instead of using setters, by using the follwing adder, you can\r
- * load several Person class data as a collection:\r
- * <code>void addPersonList(Person person) { personList.add(person); }</code>\r
- * \r
- * Note that, in order to use adders correctly, the target of an adder, that is,\r
- * a collection class, must be initialized before the invocation of the adder.\r
- * For example, <code> \r
- * public PersonList {\r
- *   Vector<Person> personList = new Vector<Person>(); // it must be initialized. \r
- *   public PersonList() {}\r
- *   void addPersonList(Person p) { personList.add(p); }\r
- *   public getPersonList() { return personList; } \r
- * }\r
- * </code>\r
- * \r
- * Otherwise, BeanUtil.populate method cuases NullPointerException or some other\r
- * undisired effects.\r
- * \r
- * In BeanUtil, a setter method, whose argument has no generic type parameter,\r
- * e.g., <code>public void setList(List l)</code> never be used to bind JSON\r
- * data to a class instance.\r
- * \r
- * \r
- * In order to use a Bean class with Map<K, V> objects, you must define\r
- * <code>public Map getSomething()</code> and\r
- * <code>public void putSomething(KeyType key, ValueType value)</code> methods,\r
- * since BeanUtil learns class types K, V from the putSomething(K key, V value)\r
- * methods. If a method <code>public void setSomething(Map map)</code> exists,\r
- * BeanUtil simply ignores it.\r
- * \r
- * \r
- * The following is an example of a bean class with Map object. <code>\r
- * public MapBean\r
- * {\r
- *   Map entry = new TreeMap();\r
- *   \r
- *   public MapBean(){}\r
- *   \r
- *   public void putEntry(Key key, Value v)\r
- *   {\r
- *      entry.put(key, value);\r
- *   }\r
- *   \r
- *   public Map getEntry()\r
- *   {\r
- *      return entry;\r
- *   }\r
- * }\r
- * </code>\r
- * \r
- * @author leo\r
- * \r
- */\r
-public class BeanUtil\r
-{\r
-\r
-    private static HashMap<Class< ? >, BinderSet> _beanOutputRuleRegistry = new HashMap<Class< ? >, BinderSet>();\r
-\r
-    private static HashMap<Class< ? >, BinderSet> _beanLoadRuleRegistry   = new HashMap<Class< ? >, BinderSet>();\r
-\r
-    public static BeanBinderSet getBeanOutputRule(Class< ? > c) throws XerialException {\r
-        if (_beanOutputRuleRegistry.containsKey(c))\r
-            return _beanOutputRuleRegistry.get(c);\r
-        else {\r
-            BinderSet beanOutputRule = inspectGetters(c);\r
-            _beanOutputRuleRegistry.put(c, beanOutputRule);\r
-            return beanOutputRule;\r
-        }\r
-    }\r
-\r
-    public static BeanBinderSet getBeanLoadRule(Class< ? > c) throws XerialException {\r
-        if (_beanLoadRuleRegistry.containsKey(c))\r
-            return _beanLoadRuleRegistry.get(c);\r
-        else {\r
-            BinderSet beanLoadRule = inspectSetter(c);\r
-            _beanLoadRuleRegistry.put(c, beanLoadRule);\r
-            return beanLoadRule;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * retrieve getter methods fo the form: getSomething(), then define how to\r
-     * use these methods according to the return type of the getter.\r
-     * \r
-     * If the return type is: - primitiveType type: crate a rule that simply\r
-     * invokes getSomething() method, and recieves a value. - collection iterate\r
-     * for each element in the collection\r
-     * \r
-     * @param bean\r
-     * @throws UTGBException\r
-     */\r
-    private static BinderSet inspectGetters(Class< ? > beanClass) throws XerialException {\r
-        BinderSet outputRuleSet = new BinderSet(beanClass);\r
-\r
-        Method[] method = beanClass.getMethods();\r
-        for (Method m : method) {\r
-            if (!Modifier.isPublic(m.getModifiers())) // is public?\r
-                continue;\r
-            String methodName = m.getName();\r
-            String parameterName = BeanUtil.pickPropertyName(methodName);\r
-            if (parameterName == null || parameterName.length() == 0)\r
-                continue;\r
-\r
-            if (!methodName.startsWith("get") || methodName.equals("getClass"))\r
-                continue; // Object\r
-\r
-            Class< ? >[] parameterType = m.getParameterTypes();\r
-            if (parameterType.length != 0) // we cannot use the getter unless\r
-                // it requires no argument.\r
-                continue;\r
-            outputRuleSet.addRule(new Getter(m, parameterName));\r
-        }\r
-\r
-        return outputRuleSet;\r
-    }\r
-\r
-    public static BinderSet inspectSetter(Class< ? > beanClass) throws XerialException {\r
-        BinderSet inputRuleSet = new BinderSet(beanClass);\r
-\r
-        // create a rule set of binding rules from setters of the bean class\r
-        for (Method method : beanClass.getMethods()) {\r
-            String methodName = method.getName();\r
-\r
-            String parameterName = BeanUtil.pickPropertyName(methodName); // retrieve\r
-            // setter,\r
-            // getter,\r
-            // adder,\r
-            // putter\r
-            // parameter\r
-            // name\r
-            if (parameterName == null)\r
-                continue;\r
-\r
-            if (!Modifier.isPublic(method.getModifiers())) // is public\r
-                // setter/adder/putter?\r
-                continue;\r
-\r
-            Class< ? >[] parameterType = method.getParameterTypes();\r
-            if (methodName.startsWith("put")) {\r
-                if (parameterType.length != 2)\r
-                    continue;\r
-\r
-                Class< ? >[] mapElementType = resolveActualTypeOfMapElement(beanClass, parameterType);\r
-\r
-                if (parameterName.length() == 0 && TypeInfo.isMap(beanClass)) {\r
-                    // bean.put(Key k, Value v)\r
-                    inputRuleSet.addRule(new MapPutter(method, "elem", mapElementType[0], mapElementType[1]));\r
-                }\r
-                else {\r
-                    // putSomething(Key k, Value v)\r
-                    inputRuleSet.addRule(new MapPutter(method, parameterName, mapElementType[0], mapElementType[1]));\r
-                }\r
-                continue;\r
-            }\r
-\r
-            if (methodName.startsWith("add")) {\r
-                if (parameterType.length != 1)\r
-                    continue;\r
-\r
-                Class< ? > addType = resolveActualTypeOfCollectionElement(beanClass, parameterType[0]);\r
-\r
-                if (parameterName.length() == 0 && TypeInfo.isCollection(beanClass)) {\r
-                    // bean.add(E element)\r
-                    inputRuleSet.addRule(new CollectionAdder(method, "elem", addType));\r
-                }\r
-                else {\r
-                    // bean.addSomething(E element)\r
-                    inputRuleSet.addRule(new CollectionAdder(method, parameterName, addType));\r
-                }\r
-                continue;\r
-            }\r
-\r
-            if (methodName.startsWith("append")) {\r
-                if (parameterType.length != 1)\r
-                    continue;\r
-\r
-                Class< ? > addType = resolveActualTypeOfCollectionElement(beanClass, parameterType[0]);\r
-                inputRuleSet.addRule(new Appender(addType, method, parameterName));\r
-                continue;\r
-            }\r
-\r
-            if (methodName.startsWith("set")) {\r
-                if (parameterType.length != 1 || parameterName.length() == 0)\r
-                    continue;\r
-\r
-                Class< ? > inputTypeOfTheSetter = parameterType[0];\r
-\r
-                if (inputTypeOfTheSetter.isArray()) {\r
-                    // setSomething(int[] array) etc\r
-                    Class< ? > componentType = inputTypeOfTheSetter.getComponentType();\r
-                    inputRuleSet.addRule(new ArraySetter(method, parameterName, componentType));\r
-                }\r
-                else if (TypeInfo.isCollection(inputTypeOfTheSetter)) {\r
-                    if (method.getGenericParameterTypes()[0] instanceof ParameterizedType) {\r
-                        ParameterizedType genericSetterArgumentType = (ParameterizedType) method\r
-                                .getGenericParameterTypes()[0];\r
-                        Type[] actualTypeList = genericSetterArgumentType.getActualTypeArguments();\r
-                        if (actualTypeList.length > 0) {\r
-                            Class< ? > elementType = resolveRawType(actualTypeList[0]);\r
-                            inputRuleSet.addRule(new CollectionSetter(method, parameterName, inputTypeOfTheSetter,\r
-                                    elementType));\r
-                        }\r
-                    }\r
-                    // setSomething(Collection) method wihtout any type\r
-                    // parameter cannot be used to bind JSON data, thus skip\r
-                }\r
-                else if (TypeInfo.isMap(inputTypeOfTheSetter)) {\r
-                    // setSomething(Map<K, V> map) method\r
-                    Pair<Class< ? >, Class< ? >> keyValueTypePair = getGenericMapTypesOfMethodArgument(method, 0);\r
-                    if (keyValueTypePair != null) {\r
-                        inputRuleSet.addRule(new MapSetter(method, parameterName, inputTypeOfTheSetter,\r
-                                keyValueTypePair.getFirst(), keyValueTypePair.getSecond()));\r
-                        continue;\r
-                    }\r
-                    // setMap(Map map) without any type parameter cannot be used\r
-                }\r
-                else {\r
-                    inputRuleSet.addRule(new Setter(method, parameterName, inputTypeOfTheSetter));\r
-                }\r
-            }\r
-        }\r
-\r
-        return inputRuleSet;\r
-    }\r
-\r
-    public static Pair<Class< ? >, Class< ? >> getGenericMapTypesOfMethodArgument(Method method, int argIndex) {\r
-\r
-        ParameterizedType genericSetterArgumentType = getParentParameterizedType(\r
-                method.getGenericParameterTypes()[argIndex], Map.class);\r
-\r
-        if (genericSetterArgumentType != null) {\r
-            Type[] actualTypeList = genericSetterArgumentType.getActualTypeArguments();\r
-            if (actualTypeList.length >= 2) {\r
-                Class< ? > keyType = resolveRawType(actualTypeList[0]);\r
-                Class< ? > valueType = resolveRawType(actualTypeList[1]);\r
-                return new Pair<Class< ? >, Class< ? >>(keyType, valueType);\r
-            }\r
-        }\r
-\r
-        return null;\r
-\r
-    }\r
-\r
-    public static ParameterizedType getParameterizedType(Type t) {\r
-        if (t == null)\r
-            return null;\r
-\r
-        if (t instanceof ParameterizedType) {\r
-            ParameterizedType pt = (ParameterizedType) t;\r
-            return pt;\r
-        }\r
-        if (t instanceof Class)\r
-            return getParameterizedType(((Class< ? >) t).getGenericSuperclass());\r
-        else\r
-            return null;\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    public static ParameterizedType getParentParameterizedType(Type t, Class target) {\r
-        if (t == null)\r
-            return null;\r
-\r
-        if (t instanceof ParameterizedType) {\r
-            ParameterizedType pt = (ParameterizedType) t;\r
-            if (target.isAssignableFrom((Class) pt.getRawType())) {\r
-                return pt;\r
-            }\r
-        }\r
-\r
-        if (t instanceof Class) {\r
-            Class c = (Class) t;\r
-            return getParentParameterizedType(c.getGenericSuperclass(), target);\r
-        }\r
-        else\r
-            return null;\r
-    }\r
-\r
-    public static Class< ? > resolveActualTypeOfCollectionElement(Type type, Class< ? > orig) {\r
-        ParameterizedType pt = getParentParameterizedType(type, Collection.class);\r
-        if (pt != null) {\r
-            Type[] actualType = pt.getActualTypeArguments();\r
-            if (actualType.length > 0)\r
-                return resolveRawType(actualType[0], orig);\r
-        }\r
-        return orig;\r
-    }\r
-\r
-    public static Class< ? >[] resolveActualTypeOfMapElement(Type type, Class< ? >[] orig) {\r
-        ParameterizedType pt = getParentParameterizedType(type, Map.class);\r
-        if (pt != null) {\r
-            Type[] actualType = pt.getActualTypeArguments();\r
-            if (actualType.length > 0)\r
-                return new Class[] { resolveRawType(actualType[0], orig[0]), resolveRawType(actualType[1], orig[1]) };\r
-        }\r
-        return orig;\r
-    }\r
-\r
-    private static Class< ? > resolveRawType(Type type, Class< ? > orig) {\r
-        if (type instanceof ParameterizedType) {\r
-            ParameterizedType pt = (ParameterizedType) type;\r
-            return resolveRawType(pt.getRawType(), orig);\r
-        }\r
-        else if (type instanceof Class)\r
-            return (Class< ? >) type;\r
-        else\r
-            return orig;\r
-    }\r
-\r
-    private static Class< ? > resolveRawType(Type type) {\r
-        if (type instanceof ParameterizedType) {\r
-            ParameterizedType pt = (ParameterizedType) type;\r
-            return resolveRawType(pt.getRawType());\r
-        }\r
-        else if (type instanceof Class)\r
-            return (Class< ? >) type;\r
-        else\r
-            return Object.class;\r
-    }\r
-\r
-    // non constructable\r
-    private BeanUtil() {}\r
-\r
-    /**\r
-     * @param methodName\r
-     *            method name of getter or setters. e.g. setSomething,\r
-     *            getSomething\r
-     * @param patternType\r
-     *            set(ter) or get(ter)\r
-     * @return property name of the method name\r
-     * \r
-     * \r
-     * \r
-     */\r
-    public static String pickPropertyName(String methodName) {\r
-        Matcher m = null;\r
-        m = _setGetAddMethodPattern.matcher(methodName);\r
-        if (!m.matches())\r
-            return null;\r
-        else {\r
-            if (m.group(2) != null)\r
-                return m.group(3).toLowerCase() + m.group(4);\r
-            else\r
-                return "";\r
-        }\r
-    }\r
-\r
-    static private Pattern _setGetAddMethodPattern = Pattern.compile("^(set|get|add|put|append)((\\S)(\\S*))?");\r
-\r
-    private static class BeanToXMLProcess\r
-    {\r
-        private ByteArrayOutputStream _buffer = new ByteArrayOutputStream();\r
-\r
-        private XMLGenerator          _out    = new XMLGenerator(_buffer);\r
-\r
-        public BeanToXMLProcess() {\r
-\r
-        }\r
-\r
-        public String generateXML(String tagName, Object bean) throws XerialException {\r
-            try {\r
-                toXML(tagName, bean);\r
-                _out.endDocument();\r
-                _out.flush();\r
-                return _buffer.toString();\r
-            }\r
-            catch (IllegalArgumentException e) {\r
-                throw new XerialException(XerialErrorCode.IllegalArgument, e);\r
-            }\r
-        }\r
-\r
-        private void toXML(String tagName, Object bean) throws XerialException {\r
-            if (bean == null)\r
-                return;\r
-\r
-            Class< ? > beanClass = bean.getClass();\r
-\r
-            if (beanClass.isArray()) {\r
-                Object[] array = (Object[]) bean;\r
-                int i = 0;\r
-                for (; i < array.length - 1; i++) {\r
-                    toXML(tagName, array[i]);\r
-                    _out.text(",");\r
-                }\r
-                toXML(tagName, array[i]);\r
-            }\r
-            else if (TypeInfo.isBasicType(beanClass)) {\r
-                _out.element(tagName, bean.toString());\r
-            }\r
-            else {\r
-                if (TypeInfo.isCollection(beanClass)) {\r
-                    Collection< ? > collection = (Collection< ? >) bean;\r
-                    for (Object elem : collection) {\r
-                        toXML(tagName, elem);\r
-                    }\r
-                }\r
-                else if (TypeInfo.isMap(beanClass)) {\r
-                    Map< ? , ? > map = (Map< ? , ? >) bean;\r
-\r
-                    for (Object key : map.keySet()) {\r
-                        _out.startTag(tagName);\r
-                        _out.element("key", key.toString());\r
-                        _out.element("value", map.get(key).toString());\r
-                        _out.endTag();\r
-                    }\r
-                }\r
-                else {\r
-                    // return an XML elemenet\r
-                    _out.startTag(tagName);\r
-                    BeanBinderSet outputRuleSet = BeanUtil.getBeanOutputRule(beanClass);\r
-                    for (BeanBinder rule : outputRuleSet.getBindRules()) {\r
-                        Method getter = rule.getMethod();\r
-                        String parameterName = rule.getParameterName();\r
-\r
-                        Object parameterValue = invokeGetterMethod(getter, bean);\r
-                        toXML(parameterName, parameterValue);\r
-                    }\r
-                    _out.endTag();\r
-                }\r
-            }\r
-\r
-        }\r
-    }\r
-\r
-    public static String toXML(String tagName, Object bean) throws XerialException {\r
-        BeanToXMLProcess bp = new BeanToXMLProcess();\r
-        return bp.generateXML(tagName, bean);\r
-    }\r
-\r
-    public static String toJSONFromResultSet(ResultSet resultSet) throws SQLException {\r
-        StringBuilder builder = new StringBuilder();\r
-        ResultSetMetaData metadata = resultSet.getMetaData();\r
-        int colCount = metadata.getColumnCount();\r
-        builder.append("{");\r
-        for (int i = 1; i <= colCount; i++) {\r
-            if (i >= 2)\r
-                builder.append(",");\r
-            Object value = resultSet.getObject(i);\r
-            builder.append("\"");\r
-            builder.append(metadata.getColumnName(i));\r
-            builder.append("\":");\r
-            if (value != null) {\r
-                builder.append("\"");\r
-                builder.append(value.toString());\r
-                builder.append("\"");\r
-            }\r
-            else\r
-                builder.append("null");\r
-        }\r
-        builder.append("}");\r
-        return builder.toString();\r
-    }\r
-\r
-    public static String toJSON(Object bean) throws XerialException {\r
-        return outputAsJSONValue(bean).toString();\r
-    }\r
-\r
-    public static JSONObject toJSONObject(Object bean) throws XerialException {\r
-        return outputAsJSONValue(bean).getJSONObject();\r
-    }\r
-\r
-    public static JSONObject toJSONObject(Collection< ? > collection) throws XerialException {\r
-        JSONObject jsonObj = new JSONObject();\r
-        jsonObj.put("elem", outputAsJSONValue(collection));\r
-        return jsonObj;\r
-    }\r
-\r
-    public static JSONValue getValue(Object bean, String propertyName) throws XerialException {\r
-        JSONObject json = toJSONObject(bean);\r
-        return json.get(propertyName);\r
-    }\r
-\r
-    private static JSONValue outputAsJSONValue(Object bean) throws XerialException {\r
-        if (bean == null)\r
-            return null;\r
-        Class< ? > beanClass = bean.getClass();\r
-\r
-        if (beanClass.isArray()) {\r
-            Object[] array = (Object[]) bean;\r
-            JSONArray jsonArray = new JSONArray();\r
-            for (Object obj : array)\r
-                jsonArray.add(outputAsJSONValue(obj));\r
-            return jsonArray;\r
-        }\r
-        else if (TypeInfo.isBasicType(beanClass)) {\r
-            String jsonStr = bean.toString();\r
-            JSONValue value = null;\r
-            if (beanClass == String.class)\r
-                value = new JSONString(jsonStr);\r
-            else if (beanClass == int.class || beanClass == Integer.class)\r
-                value = new JSONInteger(jsonStr);\r
-            else if (beanClass == double.class || beanClass == Double.class)\r
-                value = new JSONDouble(jsonStr);\r
-            else if (beanClass == float.class || beanClass == Float.class)\r
-                value = new JSONDouble(jsonStr);\r
-            else if (beanClass == boolean.class || beanClass == Boolean.class)\r
-                value = new JSONBoolean((Boolean) bean);\r
-            else if (beanClass == long.class || beanClass == Long.class)\r
-                value = new JSONLong(jsonStr);\r
-            else\r
-                throw new XerialException(XerialErrorCode.InvalidBeanClass, beanClass.toString() + " is not basic type");\r
-            return value;\r
-        }\r
-        else {\r
-\r
-            if (TypeInfo.isCollection(beanClass)) {\r
-                Collection< ? > collection = (Collection< ? >) bean;\r
-                JSONArray jsonArray = new JSONArray();\r
-                for (Object obj : collection)\r
-                    jsonArray.add(outputAsJSONValue(obj));\r
-\r
-                if (hasGetter(beanClass)) {\r
-                    // extended Array class\r
-                    JSONObject json = new JSONObject();\r
-                    json.put("elem", jsonArray);\r
-                    return outputBeanParameters(json, bean);\r
-                }\r
-                else\r
-                    return jsonArray;\r
-            }\r
-            else if (TypeInfo.isMap(beanClass)) {\r
-                Map< ? , ? > map = (Map< ? , ? >) bean;\r
-                JSONArray jsonArray = new JSONArray();\r
-                for (Object key : map.keySet()) {\r
-                    JSONObject pair = new JSONObject();\r
-                    pair.put("key", outputAsJSONValue(key));\r
-                    pair.put("value", outputAsJSONValue(map.get(key)));\r
-                    jsonArray.add(pair);\r
-                }\r
-\r
-                BeanBinderSet outputRuleSet = BeanUtil.getBeanOutputRule(beanClass);\r
-                if (outputRuleSet.getBindRules().size() > 0) {\r
-                    // extended Map class\r
-                    JSONObject json = new JSONObject();\r
-                    json.put("elem", jsonArray);\r
-                    return outputBeanParameters(json, bean);\r
-                }\r
-                else\r
-                    return jsonArray;\r
-            }\r
-            else\r
-                return outputBeanParameters(new JSONObject(), bean);\r
-        }\r
-\r
-    }\r
-\r
-    private static boolean hasGetter(Class< ? > beanClass) throws XerialException {\r
-        BeanBinderSet outputRuleSet = BeanUtil.getBeanOutputRule(beanClass);\r
-        return outputRuleSet.getBindRules().size() > 0;\r
-    }\r
-\r
-    private static JSONObject outputBeanParameters(JSONObject json, Object bean) throws XerialException {\r
-        BeanBinderSet outputRuleSet = BeanUtil.getBeanOutputRule(bean.getClass());\r
-        for (BeanBinder rule : outputRuleSet.getBindRules()) {\r
-            Method getter = rule.getMethod();\r
-            String parameterName = rule.getParameterName();\r
-\r
-            Object parameterValue = invokeGetterMethod(getter, bean);\r
-            if (parameterValue != null)\r
-                json.put(parameterName, outputAsJSONValue(parameterValue));\r
-        }\r
-        return json;\r
-    }\r
-\r
-    private static Object invokeGetterMethod(Method getter, Object bean) throws XerialException {\r
-        try {\r
-            return getter.invoke(bean);\r
-        }\r
-        catch (IllegalArgumentException e) {\r
-            throw new XerialException(XerialErrorCode.IllegalArgument, e);\r
-        }\r
-        catch (IllegalAccessException e) {\r
-            throw new XerialException(XerialErrorCode.IllegalAccess, e);\r
-        }\r
-        catch (InvocationTargetException e) {\r
-            throw new XerialException(XerialErrorCode.InvocationTargetException, e);\r
-        }\r
-    }\r
-\r
-    public static void populateBeanWithMap(Object bean, Map< ? , ? > map) throws XerialException {\r
-        BeanUtilImpl.populateBeanWithMap(bean, map);\r
-    }\r
-\r
-    public static void populateBeanWithXML(Object bean, Reader xmlReader) throws XerialException {\r
-        if (bean == null)\r
-            throw new XerialException(XerialErrorCode.BeanObjectIsNull);\r
-\r
-        BeanUtilImpl.populateBeanWithXML(bean, xmlReader);\r
-\r
-    }\r
-\r
-    public static void populateBeanWithXML(Object bean, String xmlData) throws XerialException {\r
-        populateBeanWithXML(bean, new StringReader(xmlData));\r
-    }\r
-\r
-    public static void populateBeanWithXML(Object bean, Element xmlElement) throws XerialException {\r
-        if (xmlElement == null)\r
-            return; // there is nothing to bind\r
-\r
-        BeanUtilImpl.populateBeanWithXML(bean, xmlElement);\r
-    }\r
-\r
-    // protected static void populateBeanWithXML(Object bean, Object xmlValue)\r
-    // throws BeanException\r
-    // {\r
-    // if (xmlValue == null)\r
-    // return;\r
-    //\r
-    // Class beanClass = bean.getClass();\r
-    // if (TypeInformation.isBasicType(beanClass))\r
-    // {\r
-    // bean = populateBasicTypeWithXML(beanClass, xmlValue);\r
-    // }\r
-    // else\r
-    // {\r
-    // if (TypeInformation.isDOMElement(xmlValue.getClass()))\r
-    // populateBeanWithXML(bean, (Element) xmlValue);\r
-    // else\r
-    // {\r
-    // throw new BeanException(XerialErrorCode.UnsupportedXMLDataType,\r
-    // "unsupported value type: "\r
-    // + xmlValue.getClass().toString());\r
-    // }\r
-    // }\r
-    // }\r
-\r
-    public static void populateBeanWithJSON(Object bean, Reader jsonReader) throws XerialException, IOException {\r
-        BeanUtilImpl.populateBeanWithJSON(bean, jsonReader);\r
-    }\r
-\r
-    /**\r
-     * fill a bean class with a given JSON data\r
-     * \r
-     * @param bean\r
-     *            a bean class\r
-     * @param jsonData\r
-     *            a string representation of a JSON data\r
-     * @throws IOException\r
-     * @throws InvalidJSONDataException\r
-     *             when the input json data is invalid (cannot interpret as a\r
-     *             JSON object)\r
-     * @throws InvalidXerialException\r
-     *             when a bean class has invalid structure\r
-     */\r
-    public static void populateBeanWithJSON(Object bean, String jsonData) throws XerialException {\r
-        // parse the input JSON data\r
-        try {\r
-            populateBeanWithJSON(bean, new StringReader(jsonData));\r
-        }\r
-        catch (IOException e) {\r
-            throw new XerialException(XerialErrorCode.IOError, e);\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * fill a bean class with a given JSONObject data\r
-     * \r
-     * @param bean\r
-     *            a bean class\r
-     * @param json\r
-     *            a JSONOBject\r
-     * @throws InvalidXerialException\r
-     * @throws InvalidJSONDataException\r
-     * @throws IllegalAccessException\r
-     * @throws InstantiationException\r
-     */\r
-    public static void populateBean(Object bean, JSONObject json) throws XerialException {\r
-        try {\r
-            BeanUtilImpl.populateBeanWithJSON(bean, new StringReader(json.toJSONString()));\r
-        }\r
-        catch (IOException e) {\r
-            throw new XerialException(XerialErrorCode.IOError, e.getMessage());\r
-        }\r
-    }\r
-\r
-    /*\r
-     * Map<K, V> m m.json = { "elem":[{"key":k1, "value":v1}, {"key":k2, "value":v2}, ...] }\r
-     * \r
-     * Map a = Map<A, Map<B, C>> a.json = \r
-     * { "elem" : [{"key":"a1", "value":{"elem" : [{"key":b1, "value":c1}, {"key":b2, "value":c2}, ...]}}]}, \r
-     * "\r
-     * \r
-     * Collection { "elem" : [f1, f2, ..., ] }\r
-     * \r
-     * Array [f1, f2, ... ]\r
-     * \r
-     * When a JSONArray comes as an input, it is bound to Object[]\r
-     * \r
-     * @throws IllegalAccessException\r
-     * @throws InstantiationException\r
-     * @throws InvalidJSONDataException\r
-     */\r
-    protected static void populateBean(Object bean, JSONArray jsonArray) throws XerialException {\r
-        Class< ? > beanClass = bean.getClass();\r
-        if (beanClass.isArray()) {\r
-            Object[] array = (Object[]) bean;\r
-            Class< ? > componentType = beanClass.getComponentType();\r
-            for (int i = 0; i < jsonArray.size(); i++) {\r
-                try {\r
-                    array[i] = componentType.newInstance();\r
-                }\r
-                catch (InstantiationException e) {\r
-                    throw new XerialException(XerialErrorCode.InstantiationFailure, e);\r
-                }\r
-                catch (IllegalAccessException e) {\r
-                    throw new XerialException(XerialErrorCode.IllegalAccess, e);\r
-                }\r
-                populateBeanWithJSON(array[i], jsonArray.get(i));\r
-            }\r
-        }\r
-        else\r
-            throw new XerialException(XerialErrorCode.InvalidJSONArray,\r
-                    "to bind json array to a bean, it must be an instance array (e.g. Object[])");\r
-\r
-    }\r
-\r
-    protected static void populateBeanWithJSON(Object bean, Object jsonValue) throws XerialException {\r
-        if (jsonValue.getClass() == JSONObject.class) {\r
-            populateBean(bean, (JSONObject) jsonValue);\r
-        }\r
-        else if (jsonValue.getClass() == JSONArray.class) {\r
-            populateBean(bean, (JSONArray) jsonValue);\r
-        }\r
-        else {\r
-            // the object is a JSONValue\r
-            Class< ? > beanClass = bean.getClass();\r
-            if (TypeInfo.isBasicType(beanClass)) {\r
-                String jsonStr = jsonValue.toString();\r
-                if (beanClass == String.class)\r
-                    bean = new String(jsonStr);\r
-                else if (beanClass == int.class || beanClass == Integer.class)\r
-                    bean = new Integer(jsonStr);\r
-                else if (beanClass == double.class || beanClass == Double.class)\r
-                    bean = new Double(jsonStr);\r
-                else if (beanClass == float.class || beanClass == Float.class)\r
-                    bean = new Float(jsonStr);\r
-                else if (beanClass == boolean.class || beanClass == Boolean.class)\r
-                    bean = new Boolean(jsonStr);\r
-                else\r
-                    throw new XerialException(XerialErrorCode.InvalidBeanClass);\r
-            }\r
-        }\r
-    }\r
-\r
-    public static <T> T populateBeanWithSilk(T bean, URL silkResourceLocation) throws XerialException, IOException {\r
-        try {\r
-            Lens.loadSilk(bean, silkResourceLocation);\r
-        }\r
-        catch (IOException e) {\r
-            throw new XerialException(XerialErrorCode.IO_EXCEPTION, e);\r
-        }\r
-\r
-        return bean;\r
-    }\r
-\r
-    public static Object createBeanFromJSON(Class< ? > beanType, Reader jsonReader) throws IOException, XerialException {\r
-        try {\r
-            return BeanUtilImpl.createBeanFromJSON(beanType, jsonReader);\r
-        }\r
-        catch (XerialException e) {\r
-            throw new XerialException(XerialErrorCode.BindFailure, e.getMessage());\r
-        }\r
-    }\r
-\r
-    public static Object createBeanFromJSON(Class< ? > beanType, String json) throws XerialException {\r
-        try {\r
-            return BeanUtilImpl.createBeanFromJSON(beanType, new StringReader(json));\r
-        }\r
-        catch (IOException e) {\r
-            throw new XerialException(XerialErrorCode.IOError, e.getMessage());\r
-        }\r
-    }\r
-\r
-    public static Object createInstance(Class< ? > c) throws XerialException {\r
-        return TypeInfo.createInstance(c);\r
-    }\r
-\r
-    public static <E> E createXMLBean(Class<E> valueType, Reader xmlReader) throws XerialException, IOException,\r
-            XerialException {\r
-\r
-        return BeanUtilImpl.createBeanFromXML(valueType, xmlReader);\r
-    }\r
-\r
-    public static Object createXMLBean(Class< ? > valueType, String xmlData) throws XerialException {\r
-        Object bean;\r
-        bean = createInstance(valueType);\r
-        populateBeanWithXML(bean, xmlData);\r
-        return bean;\r
-    }\r
-\r
-    public static <T> T createSilkBean(Class<T> beanClass, URL silkFileLocation) throws XerialException {\r
-        T bean = TypeInfo.createInstance(beanClass);\r
-        BeanBindingProcess bindingProcess = BeanBindingProcess.newBinderWithRootContext(bean);\r
-\r
-        try {\r
-            SilkWalker walker = new SilkWalker(silkFileLocation);\r
-            walker.walk(bindingProcess);\r
-        }\r
-        catch (IOException e) {\r
-            throw new XerialException(XerialErrorCode.IO_EXCEPTION, e);\r
-        }\r
-\r
-        return bean;\r
-    }\r
-\r
-    public static <T> void loadJSON(Reader jsonReader, Class<T> beanClass, BeanHandler<T> beanHandler)\r
-            throws IOException, XerialException {\r
-        BeanBindingProcess bindingProcess = new BeanBindingProcess(new BeanStreamReader<T>(beanHandler),\r
-                new BindRuleGeneratorForBeanStream<T>(beanClass));\r
-\r
-        JSONStreamWalker walker = new JSONStreamWalker(jsonReader);\r
-        walker.walk(bindingProcess);\r
-\r
-    }\r
-\r
-    public static <T> void loadJSON(Reader jsonReader, Class<T> beanClass, String targetNodeName,\r
-            BeanHandler<T> beanHandler) throws IOException, XerialException {\r
-\r
-        BeanBindingProcess bindingProcess = new BeanBindingProcess(new BeanStreamReader<T>(beanHandler),\r
-                new BindRuleGeneratorForBeanStream<T>(beanClass, targetNodeName));\r
-\r
-        JSONStreamWalker walker = new JSONStreamWalker(jsonReader);\r
-        walker.walk(bindingProcess);\r
-\r
-    }\r
-\r
-}\r
-\r
-enum BeanParameterType {\r
-    primitiveType,\r
-    primitiveTypeCollection,\r
-    primitiveTypeArray,\r
-    nestedBean,\r
-    beanArray,\r
-    beanCollection,\r
-    unknownTypeCollection,\r
-    primitiveTypeAdder,\r
-    beanAdder,\r
-    primitiveTypeArrayAdder,\r
-    beanArrayAdder,\r
-    map\r
-}\r
-\r
-/**\r
- * TODO A hash structure may have better performance, especially for findRule()\r
- * method.\r
- * \r
- * @author leo\r
- * \r
- */\r
-class BinderSet implements BeanBinderSet\r
-{\r
-    Class< ? >         beanClass;\r
-\r
-    Vector<BeanBinder> _bindRule = new Vector<BeanBinder>();\r
-\r
-    public BinderSet(Class< ? > beanClass) {\r
-        this.beanClass = beanClass;\r
-    }\r
-\r
-    // @see org.utgenome.util.BeanBinderSet#addRule(org.utgenome.util.Binder)\r
-    public void addRule(BeanBinder binder) {\r
-        _bindRule.add(binder);\r
-    }\r
-\r
-    // @see org.utgenome.util.BeanBinderSet#getBindRules()\r
-    public Vector<BeanBinder> getBindRules() {\r
-        return _bindRule;\r
-    }\r
-\r
-    // @see org.utgenome.util.BeanBinderSet#findRule(java.lang.String)\r
-    public BeanBinder findRule(String name) {\r
-        for (BeanBinder rule : _bindRule) {\r
-            if (rule.getParameterName().equalsIgnoreCase(name))\r
-                return rule;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    public MapPutter getStandardMapPutter() {\r
-        for (BeanBinder rule : _bindRule) {\r
-            if (rule.getMethod().getName().equals("put"))\r
-                return MapPutter.class.cast(rule);\r
-        }\r
-        return null;\r
-    }\r
-}\r