OSDN Git Service

removed all files
[xerial/xerial-core.git] / src / main / java / org / xerial / util / bean / impl / BeanBindingProcess.java
diff --git a/src/main/java/org/xerial/util/bean/impl/BeanBindingProcess.java b/src/main/java/org/xerial/util/bean/impl/BeanBindingProcess.java
deleted file mode 100755 (executable)
index c01e00e..0000000
+++ /dev/null
@@ -1,486 +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\r
-//\r
-// BeanBindingProcess.java\r
-// Since: Dec 18, 2007 5:09:59 PM\r
-//\r
-// $URL: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/bean/impl/BeanBindingProcess.java $\r
-// $Author: leo $\r
-//--------------------------------------\r
-package org.xerial.util.bean.impl;\r
-\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.xerial.core.XerialErrorCode;\r
-import org.xerial.core.XerialException;\r
-import org.xerial.util.ArrayDeque;\r
-import org.xerial.util.Deque;\r
-import org.xerial.util.Pair;\r
-import org.xerial.util.bean.BeanBinder;\r
-import org.xerial.util.bean.BeanBinderSet;\r
-import org.xerial.util.bean.BeanUpdator;\r
-import org.xerial.util.bean.BeanUpdatorType;\r
-import org.xerial.util.bean.BeanUtil;\r
-import org.xerial.util.bean.TypeConverter;\r
-import org.xerial.util.bean.TypeInfo;\r
-import org.xerial.util.log.Logger;\r
-import org.xerial.util.tree.TreeVisitor;\r
-import org.xerial.util.tree.TreeWalker;\r
-\r
-/**\r
- * \r
- * Tree-structured data to object binding process implementation\r
- * \r
- * @author leo\r
- * \r
- */\r
-public class BeanBindingProcess implements TreeVisitor\r
-{\r
-    private static Logger                        _logger                = Logger.getLogger(BeanBindingProcess.class);\r
-\r
-    // private final ArrayList<Object> beanStack = new ArrayList<Object>();\r
-\r
-    /*\r
-     * <pre>\r
-     * class A\r
-     * {\r
-     *    public void setB(C value);\r
-     *    public void putD(E key, F value); \r
-     *    public void addG(H value);\r
-     * }\r
-     *\r
-     * XML\r
-     * \r
-     * <A>\r
-     *  <B>c-value</B>\r
-     *  <D><key>k1</key><value>v1</value></D>\r
-     *  <D><key>k2</key><value>v2</value></D>\r
-     *  <G>1</G>\r
-     *  <G>2</G>\r
-     * </A>\r
-     * \r
-     * JSON\r
-     * { "A" : { "B":"c-value", "D":[{"key":"k1", "value":"v1"}, {"key":"k2", "value":"v2"}], G:[1, 2] } }\r
-     *\r
-     *\r
-     * level, event\r
-     * [0] visit(A)\r
-     *  [1] visit(B)\r
-     *  [1] leave(B) \r
-     *  [1] visit(D) \r
-     *   [2] visit(key) "k1"\r
-     *   [2] leave(key) \r
-     *  \r
-     *   [2] visit(value) "v1"\r
-     *   [2] leave(value) \r
-     *  [1] leave(D) A.putD(KeyValue("k1", "v1"))\r
-     * \r
-     *  [1] visit(D)\r
-     *   [2] visit(key) "k2"\r
-     *   [2] leave(key) \r
-     *   [2] visit(value) "v2"\r
-     *   [2] leave(value)\r
-     *  [1] leave(D) A.putD(KeyValue("k2", "v2"))\r
-     *  \r
-     *  [1] visit(G) 1\r
-     *  [1] leave(G) \r
-     *  [1] visit(G) 2\r
-     *  [1] leave(G)\r
-     * [0] leave(A)\r
-     * \r
-     * \r
-     * bean stack\r
-     * [0] new A() (given by constructor)\r
-     * [1] new B()\r
-     * [1] D (new KeyValuePair())\r
-     * [2] key <- "k1"\r
-     * [2] value <- "v1"  \r
-     * [1] D (new KeyValuePair())\r
-     * [2] key <- "k2"\r
-     * [2] value  <- "v2"\r
-     * [1] new G() <- 1  \r
-     * [1] new G() <- 2\r
-     * \r
-     * </pre>\r
-     * \r
-     */\r
-\r
-    /*\r
-     * class T extends TreeMap<Integer, String> {}\r
-     * \r
-     * \r
-     * <T>\r
-     *  <elem><key>k1</key><value>v1</value></elem>\r
-     *  <elem><key>k2</key><value>v2</value></elem>\r
-     * </T>\r
-     * \r
-     * {"elem":[{"key":"k1", "value":v2}, {"key":"k2", "value":"v2"}]}\r
-     * \r
-     * \r
-     */\r
-\r
-    private final TreeMap<Integer, Object>       contextBeanOfEachLevel = new TreeMap<Integer, Object>();\r
-    private final TreeMap<Integer, Map< ? , ? >> mapAssociatedWithBean  = new TreeMap<Integer, Map< ? , ? >>();\r
-    private final Deque<StringBuilder>           textStack              = new ArrayDeque<StringBuilder>();\r
-    private final static StringBuilder           EMPTY_TEXT_BUILDER     = new StringBuilder(0);\r
-\r
-    private int                                  currentLevel           = 0;\r
-    private BindRuleGenerator                    bindRuleGenerator      = new BindRuleGeneratorImpl();\r
-\r
-    class BindRuleGeneratorImpl implements BindRuleGenerator\r
-    {\r
-        public <T> BeanBinderSet getBeanBinderSet(Class<T> beanClass) throws XerialException {\r
-            return BeanUtil.getBeanLoadRule(beanClass);\r
-        }\r
-    }\r
-\r
-    public BeanBindingProcess(Class< ? > beanClass) throws XerialException {\r
-        this(BeanUtil.createInstance(beanClass));\r
-    }\r
-\r
-    public BeanBindingProcess(Object bean) {\r
-        setContextBean(0, bean);\r
-    }\r
-\r
-    public static BeanBindingProcess newBinderWithRootContext(Object rootNode) {\r
-        BeanBindingProcess proc = new BeanBindingProcess(rootNode);\r
-        proc.currentLevel = 1;\r
-        return proc;\r
-    }\r
-\r
-    /**\r
-     * \r
-     * \r
-     * @param bean\r
-     * @param bindRuleGenerator\r
-     *            set the context bean corresponding to the root node\r
-     */\r
-    public BeanBindingProcess(Object bean, BindRuleGenerator bindRuleGenerator) {\r
-        setContextBean(0, bean);\r
-        this.bindRuleGenerator = bindRuleGenerator;\r
-    }\r
-\r
-    public Object getResultBean() {\r
-        return getContextBean(0);\r
-    }\r
-\r
-    public Object getContextBean(int level) {\r
-        if (level < 0 || level >= contextBeanOfEachLevel.size())\r
-            return null;\r
-        else\r
-            return contextBeanOfEachLevel.get(level);\r
-    }\r
-\r
-    private void setContextBean(int level, Object bean) {\r
-        contextBeanOfEachLevel.put(level, bean);\r
-    }\r
-\r
-    private void removeContextBean(int level) {\r
-        contextBeanOfEachLevel.remove(level);\r
-    }\r
-\r
-    public void finish(TreeWalker walker) throws XerialException {\r
-    // do nothing\r
-    }\r
-\r
-    public void init(TreeWalker walker) throws XerialException {\r
-    // do nothing\r
-    }\r
-\r
-    protected <T> BeanBinderSet getBindRuleSet(Class<T> beanClass) throws XerialException {\r
-        return bindRuleGenerator.getBeanBinderSet(beanClass);\r
-    }\r
-\r
-    public void visitNode(String nodeName, String nodeValue, TreeWalker walker) throws XerialException {\r
-        textStack.addLast(EMPTY_TEXT_BUILDER);\r
-\r
-        int nodeLevel = currentLevel++;\r
-        //_logger.trace("visit[" + nodeLevel + "] " + nodeName);\r
-\r
-        Object parentBean = getContextBean(nodeLevel - 1);\r
-        if (parentBean == null)\r
-            return;\r
-\r
-        // prepare the context bean for this depth\r
-        Object nodeValueBean = getContextBean(nodeLevel);\r
-        if (nodeValueBean == null) {\r
-            assert (currentLevel > 0); // the bean cannot be null when level is 0\r
-\r
-            BeanBinderSet bindRuleSet = getBindRuleSet(parentBean.getClass());\r
-            BeanUpdator updator = getUpdator(bindRuleSet, nodeName);\r
-            if (updator != null) {\r
-                int targetArgIndex = 0;\r
-                Method updateMethod = updator.getMethod();\r
-                // We have to instantiate a bean class of the node name\r
-                switch (updator.getType()) {\r
-                case SETTER:\r
-                case COLLECTION_ADDER:\r
-                case APPENDER:\r
-                    Class< ? > elementType = updator.getInputType();\r
-                    if (parentBean instanceof KeyValuePair) {\r
-                        // for map elment\r
-                        KeyValuePair keyValuePair = KeyValuePair.class.cast(parentBean);\r
-                        updateMethod = keyValuePair.putter();\r
-                        if (nodeName.equalsIgnoreCase("key")) {\r
-                            elementType = keyValuePair.keyType();\r
-                        }\r
-                        else if (nodeName.equalsIgnoreCase("value")) {\r
-                            elementType = keyValuePair.valueType();\r
-                            targetArgIndex = 1;\r
-                        }\r
-                    }\r
-\r
-                    if (TypeInfo.isBasicType(elementType)) {\r
-                        // this bean can be generated directly from the element text value, so\r
-                        // there is no need to instantiate the object here.\r
-                        bindValue(parentBean, nodeName, nodeValue, nodeLevel);\r
-                        break;\r
-                    }\r
-                    else if (TypeInfo.isMap(elementType)) {\r
-                        // when input of setter/ or K, V of putSomthing(K, V) is map\r
-                        Pair<Class< ? >, Class< ? >> keyValueClassPair = BeanUtil.getGenericMapTypesOfMethodArgument(\r
-                                updateMethod, targetArgIndex);\r
-\r
-                        BeanBinderSet mapBindRuleSet = getBindRuleSet(elementType);\r
-                        MapPutter putter = mapBindRuleSet.getStandardMapPutter();\r
-                        if (keyValueClassPair != null) {\r
-                            setContextBean(nodeLevel, new KeyValuePair(putter, keyValueClassPair.getFirst(),\r
-                                    keyValueClassPair.getSecond()));\r
-                        }\r
-                        else {\r
-                            // no need to put this sub tree since no putter is found\r
-                            //walker.skipDescendants();\r
-                            setContextBean(nodeLevel, new KeyValuePair(putter));\r
-\r
-                        }\r
-                    }\r
-                    else if (elementType != Object.class) {\r
-                        Object newBean = BeanUtil.createInstance(elementType);\r
-                        setContextBean(nodeLevel, newBean);\r
-                    }\r
-                    else\r
-                        bindValue(parentBean, nodeName, nodeValue, nodeLevel);\r
-\r
-                    break;\r
-                case MAP_PUTTER:\r
-                    MapPutter mapPutter = MapPutter.class.cast(updator);\r
-                    // prepare the key and value pair instance\r
-                    KeyValuePair keyVal = new KeyValuePair(mapPutter);\r
-                    if (nodeValue != null)\r
-                        keyVal.setValue(nodeValue);\r
-                    setContextBean(nodeLevel, keyVal);\r
-                    break;\r
-                default:\r
-                    throw new XerialException(XerialErrorCode.UnknownBeanUpdator);\r
-                }\r
-\r
-            }\r
-            else {\r
-                // We can safely skip the descendants of this node, since there is\r
-                // no descendant nodes to bind\r
-                walker.skipDescendants();\r
-            }\r
-\r
-        }\r
-\r
-    }\r
-\r
-    private void bindValue(Object parentBean, String nodeName, String nodeValue, int nodeLevel) throws XerialException {\r
-        if (parentBean == null)\r
-            return;\r
-\r
-        // bind immediate text value\r
-        BeanBinderSet bindRuleSet = getBindRuleSet(parentBean.getClass());\r
-        BeanUpdator updator = getUpdator(bindRuleSet, nodeName);\r
-        if (updator != null) {\r
-            Object valueBean = getContextBean(nodeLevel);\r
-            if (valueBean == null) {\r
-                if (nodeValue != null && nodeValue.length() > 0) {\r
-                    valueBean = nodeValue;\r
-                }\r
-            }\r
-\r
-            // no value to bind\r
-            if (valueBean == null)\r
-                return;\r
-\r
-            switch (updator.getType()) {\r
-            case SETTER:\r
-            case COLLECTION_ADDER:\r
-            case APPENDER:\r
-                try {\r
-                    if (parentBean instanceof KeyValuePair) {\r
-                        KeyValuePair keyValuePair = KeyValuePair.class.cast(parentBean);\r
-                        if (nodeName.equalsIgnoreCase("key"))\r
-                            bindValue(parentBean, updator, keyValuePair.keyType(), valueBean);\r
-                        else if (nodeName.equalsIgnoreCase("value"))\r
-                            bindValue(parentBean, updator, keyValuePair.valueType(), valueBean);\r
-                    }\r
-                    else {\r
-                        bindValue(parentBean, updator, valueBean);\r
-                    }\r
-\r
-                }\r
-                catch (XerialException e) {\r
-                    _logger.error(e);\r
-                }\r
-                break;\r
-            case MAP_PUTTER:\r
-                // at key, value data depth\r
-                try {\r
-                    KeyValuePair keyValuePair = KeyValuePair.class.cast(valueBean);\r
-                    if (keyValuePair.getValue() == null)\r
-                        keyValuePair.setValue(nodeValue);\r
-                    if (keyValuePair.hasKeyAndValue()) {\r
-                        bindMapElement(parentBean, MapPutter.class.cast(updator), keyValuePair);\r
-                    }\r
-                    mapAssociatedWithBean.remove(parentBean.hashCode());\r
-                }\r
-                catch (ClassCastException e) {\r
-                    _logger.error(e);\r
-                    // skip this element\r
-                }\r
-                break;\r
-            default:\r
-                throw new XerialException(XerialErrorCode.UnknownBeanUpdator);\r
-            }\r
-        }\r
-\r
-    }\r
-\r
-    public void text(String nodeName, String nodeValue, TreeWalker walker) throws XerialException {\r
-        Object parentBean = getContextBean(currentLevel - 2);\r
-        if (parentBean != null) {\r
-            BeanBinderSet bindRuleSet = getBindRuleSet(parentBean.getClass());\r
-            BeanUpdator updator = getUpdator(bindRuleSet, nodeName);\r
-            if (updator != null && updator.getType() == BeanUpdatorType.APPENDER) {\r
-                // use appender\r
-                bindValue(parentBean, updator, nodeValue);\r
-            }\r
-            else {\r
-                // use internal string buffer\r
-                StringBuilder textBuffer = textStack.peekLast();\r
-                if (textBuffer == EMPTY_TEXT_BUILDER) {\r
-                    textStack.removeLast();\r
-                    textBuffer = new StringBuilder();\r
-                    textStack.addLast(textBuffer);\r
-                }\r
-                textBuffer.append(nodeValue);\r
-            }\r
-\r
-        }\r
-\r
-    }\r
-\r
-    public void leaveNode(String nodeName, TreeWalker walker) throws XerialException {\r
-        int nodeLevel = --currentLevel;\r
-        //_logger.trace("leave[" + nodeLevel + "] " + nodeName + " value = " + nodeValue);\r
-\r
-        StringBuilder textBuffer = textStack.removeLast();\r
-        Object parentBean = getContextBean(nodeLevel - 1);\r
-        if (parentBean == null)\r
-            return;\r
-\r
-        //  if (textBuffer != EMPTY_TEXT_BUILDER)\r
-        bindValue(parentBean, nodeName, textBuffer.toString(), nodeLevel);\r
-\r
-        // clear the bean stack\r
-        removeContextBean(nodeLevel);\r
-\r
-    }\r
-\r
-    public static BeanUpdator getUpdator(BeanBinderSet bindRuleSet, String ruleName) throws XerialException {\r
-        BeanBinder binder = bindRuleSet.findRule(ruleName);\r
-        if (binder == null)\r
-            return null;\r
-        else {\r
-            if (!BeanUpdator.class.isAssignableFrom(binder.getClass())) {\r
-                _logger.warn(binder.getClass().getName() + " cannot be used to bind data");\r
-                return null;\r
-            }\r
-            else\r
-                return (BeanUpdator) binder;\r
-        }\r
-    }\r
-\r
-    private void bindMapElement(Object bean, MapPutter mapPutter, KeyValuePair keyValuePair) throws XerialException {\r
-        try {\r
-            mapPutter.getMethod().invoke(bean, convertType(mapPutter.getKeyType(), keyValuePair.getKey()),\r
-                    convertType(mapPutter.getValueType(), keyValuePair.getValue()));\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
-    @SuppressWarnings("unchecked")\r
-    private void bindValue(Object bean, BeanUpdator updator, Class targetType, Object value) throws XerialException {\r
-        try {\r
-            if (value.getClass() == KeyValuePair.class && TypeInfo.isMap(targetType)) {\r
-                Map map = null;\r
-                if (mapAssociatedWithBean.containsKey(bean.hashCode())) {\r
-                    map = mapAssociatedWithBean.get(bean.hashCode());\r
-                }\r
-                else {\r
-                    map = Map.class.cast(BeanUtil.createInstance(targetType));\r
-                    mapAssociatedWithBean.put(bean.hashCode(), map);\r
-                }\r
-                KeyValuePair keyValuePair = KeyValuePair.class.cast(value);\r
-                map.put(keyValuePair.getKey(), keyValuePair.getValue());\r
-\r
-                updator.getMethod().invoke(bean, map);\r
-            }\r
-            else\r
-                updator.getMethod().invoke(bean, convertType(targetType, value));\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
-            Throwable cause = e.getCause();\r
-            if (cause == null)\r
-                throw new XerialException(XerialErrorCode.InvocationTargetException, String.format(\r
-                        "value=%s, updator=%s", value, updator.getMethod().getName()));\r
-            else\r
-                throw new XerialException(XerialErrorCode.InvocationTargetException, cause);\r
-        }\r
-\r
-    }\r
-\r
-    private void bindValue(Object bean, BeanUpdator updator, Object value) throws XerialException {\r
-        bindValue(bean, updator, updator.getInputType(), value);\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    public static Object convertType(Class targetType, Object value) throws XerialException {\r
-        return TypeConverter.convertType(targetType, value);\r
-    }\r
-\r
-}\r