Package org.apache.axis2.databinding.utils

Source Code of org.apache.axis2.databinding.utils.BeanUtil

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.axis2.databinding.utils;


import org.apache.axis2.AxisFault;
import org.apache.axis2.databinding.typemapping.SimpleTypeMapper;
import org.apache.axis2.wsdl.builder.SchemaGenerator;
import org.apache.ws.commons.om.OMAbstractFactory;
import org.apache.ws.commons.om.OMAttribute;
import org.apache.ws.commons.om.OMElement;
import org.apache.ws.commons.om.OMFactory;
import org.apache.ws.commons.om.impl.builder.StAXOMBuilder;
import org.apache.ws.commons.om.impl.llom.factory.OMXMLBuilderFactory;
import org.codehaus.jam.JClass;
import org.codehaus.jam.JProperty;
import org.codehaus.jam.JamClassIterator;
import org.codehaus.jam.JamService;
import org.codehaus.jam.JamServiceFactory;
import org.codehaus.jam.JamServiceParams;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;


public class BeanUtil {

    /**
     * To Serilize Bean object this method is used, this will create an object array using given
     * bean object
     *
     * @param beanObject
     * @param beanName
     */
    public static XMLStreamReader getPullParser(Object beanObject, QName beanName) {
        try {
            JamServiceFactory factory = JamServiceFactory.getInstance();
            JamServiceParams jam_service_parms = factory.createServiceParams();
            //setting the classLoder
//        jam_service_parms.setParentClassLoader(factory.createJamClassLoader(classLoader));
            //it can posible to add the classLoader as well
            jam_service_parms.addClassLoader(beanObject.getClass().getClassLoader());
            jam_service_parms.includeClass(beanObject.getClass().getName());
            JamService service = factory.createService(jam_service_parms);
            JamClassIterator jClassIter = service.getClasses();
            JClass jClass = null;
            while (jClassIter.hasNext()) {
                jClass = (JClass) jClassIter.next();

            }
            // properties from JAM
            JProperty properties [] = jClass.getDeclaredProperties();

            BeanInfo beanInfo = Introspector.getBeanInfo(beanObject.getClass());
            PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
            HashMap propertMap = new HashMap();
            for (int i = 0; i < propDescs.length; i++) {
                PropertyDescriptor propDesc = propDescs[i];
                propertMap.put(propDesc.getName(), propDesc);
            }
            ArrayList object = new ArrayList();
            for (int i = 0; i < properties.length; i++) {
                JProperty property = properties[i];
                PropertyDescriptor propDesc = (PropertyDescriptor) propertMap.get(
                        SchemaGenerator.getCorrectName(property.getSimpleName()));
                if (propDesc == null) {
                    // JAM does bad thing so I need to add this
                    continue;
                }
                Class ptype = propDesc.getPropertyType();
                if (propDesc.getName().equals("class")) {
                    continue;
                }
                if (SimpleTypeMapper.isSimpleType(ptype)) {
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            (Object[]) null);
                    object.add(propDesc.getName());
                    object.add(value.toString());
                } else if (ptype.isArray()) {
                    Object value [] = (Object[]) propDesc.getReadMethod().invoke(beanObject,
                            (Object[]) null);
                    if (SimpleTypeMapper.isSimpleType(ptype.getComponentType())) {
                        for (int j = 0; j < value.length; j++) {
                            Object o = value[j];
                            object.add(propDesc.getName());
                            object.add(o.toString());
                        }
                    } else {
                        for (int j = 0; j < value.length; j++) {
                            Object o = value[j];
                            object.add(new QName(propDesc.getName()));
                            object.add(o);
                        }
                    }

                } else if (SimpleTypeMapper.isArrayList(ptype)) {
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            (Object[]) null);
                    ArrayList objList = (ArrayList) value;
                    if (objList != null && objList.size() > 0) {
                        //this was given error , when the array.size = 0
                        // and if the array contain simple type , then the ADBPullParser asked
                        // PullParser from That simpel type
                        for (int j = 0; j < objList.size(); j++) {
                            Object o = objList.get(j);
                            if (SimpleTypeMapper.isSimpleType(o)) {
                                object.add(propDesc.getName());
                                object.add(o);
                            } else {
                                object.add(new QName(propDesc.getName()));
                                object.add(o);
                            }
                        }

                    }
                } else {
                    object.add(new QName(propDesc.getName()));
                    Object value = propDesc.getReadMethod().invoke(beanObject,
                            (Object[]) null);
                    object.add(value);
                }
            }
            return ADBPullParser.createPullParser(beanName, object.toArray(), null);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * to get the pull parser for a given bean object , generate the wrpper elemnet using class name
     *
     * @param beanObject
     */
    public static XMLStreamReader getPullParser(Object beanObject) {
        String className = beanObject.getClass().getName();
        if (className.indexOf(".") > 0) {
            className = className.substring(className.lastIndexOf('.') + 1, className.length());
        }
        return getPullParser(beanObject, new QName(className));
    }

    public static Object deserialize(Class beanClass, OMElement beanElement) throws AxisFault {
        Object beanObj;
        try {
            if (beanClass.isArray()) {
                ArrayList valueList = new ArrayList();
                Class arrayClassType = beanClass.getComponentType();
                Iterator parts = beanElement.getChildElements();
                OMElement omElement;
                while (parts.hasNext()) {
                    Object objValue = parts.next();
                    if (objValue instanceof OMElement) {
                        omElement = (OMElement) objValue;
                        valueList.add(deserialize(arrayClassType, omElement));
                    }
                }
                return ConverterUtil.convertToArray(arrayClassType,
                        valueList);
            } else {
                if (SimpleTypeMapper.isSimpleType(beanClass)) {
                    return SimpleTypeMapper.getSimpleTypeObject(beanClass, beanElement);
                }
                HashMap properties = new HashMap();
                BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
                PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
                for (int i = 0; i < propDescs.length; i++) {
                    PropertyDescriptor proprty = propDescs[i];
                    properties.put(proprty.getName(), proprty);
                }

                beanObj = beanClass.newInstance();
                Iterator elements = beanElement.getChildren();
                while (elements.hasNext()) {
                    OMElement parts;
                    Object objValue = elements.next();
                    if (objValue instanceof OMElement) {
                        parts = (OMElement) objValue;
                    } else {
                        continue;
                    }
                    // if parts/@href != null then need to find element with id and deserialize.
                    // before that first check whether we already have it in the hashtable
                    String partsLocalName = parts.getLocalName();
                    PropertyDescriptor prty = (PropertyDescriptor) properties.get(partsLocalName);
                    if (prty != null) {
                        Class parameters = prty.getPropertyType();
                        if (prty.equals("class"))
                            continue;

                        Object partObj;
                        if (SimpleTypeMapper.isSimpleType(parameters)) {
                            partObj = SimpleTypeMapper.getSimpleTypeObject(parameters, parts);
                        } else if (SimpleTypeMapper.isArrayList(parameters)) {
                            //todo : Deepal , the array handling is completely wrong , this has to be
                            // improved
                            partObj = SimpleTypeMapper.getArrayList((OMElement) parts.getParent(), prty.getName());
                        } else {
                            partObj = deserialize(parameters, parts);
                        }
                        Object [] parms = new Object[]{partObj};
                        prty.getWriteMethod().invoke(beanObj, parms);
                    }
                }
                return beanObj;
            }
        } catch (InstantiationException e) {
            throw new AxisFault("InstantiationException : " + e);
        } catch (IllegalAccessException e) {
            throw new AxisFault("IllegalAccessException : " + e);
        } catch (InvocationTargetException e) {
            throw new AxisFault("InvocationTargetException : " + e);
        } catch (IntrospectionException e) {
            throw new AxisFault("IntrospectionException : " + e);
        }


    }

    public static Object deserialize(Class beanClass,
                                     OMElement beanElement,
                                     MultirefHelper helper) throws AxisFault {
        Object beanObj;
        try {
            HashMap properties = new HashMap();
            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor [] propDescs = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propDescs.length; i++) {
                PropertyDescriptor proprty = propDescs[i];
                properties.put(proprty.getName(), proprty);
            }

            beanObj = beanClass.newInstance();
            Iterator elements = beanElement.getChildren();
            while (elements.hasNext()) {
                Object child = elements.next();
                OMElement parts;
                if (child instanceof OMElement) {
                    parts = (OMElement) child;
                } else {
                    continue;
                }
                String partsLocalName = parts.getLocalName();
                PropertyDescriptor prty = (PropertyDescriptor) properties.get(partsLocalName.toLowerCase());
                if (prty != null) {
                    Class parameters = prty.getPropertyType();
                    if (prty.equals("class"))
                        continue;
                    Object partObj;
                    OMAttribute attr = MultirefHelper.processRefAtt(parts);
                    if (attr != null) {
                        String refId = MultirefHelper.getAttvalue(attr);
                        partObj = helper.getObject(refId);
                        if (partObj == null) {
                            partObj = helper.processRef(parameters, refId);
                        }
                    } else {
                        partObj = SimpleTypeMapper.getSimpleTypeObject(parameters, parts);
                        if (partObj == null) {
                            partObj = deserialize(parameters, parts);
                        }
                    }
                    Object [] parms = new Object[]{partObj};
                    prty.getWriteMethod().invoke(beanObj, parms);
                }
            }
        } catch (InstantiationException e) {
            throw new AxisFault("InstantiationException : " + e);
        } catch (IllegalAccessException e) {
            throw new AxisFault("IllegalAccessException : " + e);
        } catch (InvocationTargetException e) {
            throw new AxisFault("InvocationTargetException : " + e);
        } catch (IntrospectionException e) {
            throw new AxisFault("IntrospectionException : " + e);
        }
        return beanObj;
    }


    /**
     * To get JavaObjects from XML elemnt , the element most of the time contains only one element
     * in that case that element will be converted to the JavaType specified by the javaTypes array
     * The algo is as follows, get the childerns of the response element , and if it conatian more than
     * one element then check the retuen type of that element and conver that to corresponding JavaType
     *
     * @param response  OMElement
     * @param javaTypes Array of JavaTypes
     * @return Array of objects
     * @throws AxisFault
     */
    public static Object [] deserialize(OMElement response, Object [] javaTypes) throws AxisFault {
        /**
         * Take the number of parameters in the method and , only take that much of child elements
         * from the OMElement , other are ignore , as an example
         * if the method is , foo(String a , int b)
         * and if the OMElemet
         * <foo>
         <arg0>Val1</arg0>
         <arg1>Val2</arg1>
         <arg2>Val3</arg2>
         *
         * only the val1 and Val2 take into account
         */
        int length = javaTypes.length;
        int count = 0;
        Object [] retObjs = new Object[length];

/**
* If the body first child contains , then there can not be any other element withot
* refs , so I can assume if the first child of the body first element has ref then
* the message has to handle as mutiref message.
* as an exmple if the body is like below
* <foo>
<arg0 href="#0"/>
* </foo>
*
* then there can not be any element without refs , meaning following we are not handling
* <foo>
<arg0 href="#0"/>
<arg1>absbsbs</arg1>
* </foo>
*/
        Iterator parts = response.getChildren();
        //to handle multirefs
        //have to check the instanceof
        MultirefHelper helper = new MultirefHelper((OMElement) response.getParent());
        //to support array . if the parameter type is array , then all the omelemnts with that paramtre name
        // has to  get and add to the list
        Class classType;
        String currentLocalName;
        while (parts.hasNext() && count < length) {
            Object objValue = parts.next();
            OMElement omElement;
            if (objValue instanceof OMElement) {
                omElement = (OMElement) objValue;
            } else {
                continue;
            }
            currentLocalName = omElement.getLocalName();
            classType = (Class) javaTypes[count];
            if (classType.isArray()) {
                ArrayList valueList = new ArrayList();
                Class arrayClassType = classType.getComponentType();
                valueList.add(processObject(omElement, arrayClassType, helper));
                while (parts.hasNext()) {
                    objValue = parts.next();
                    if (objValue instanceof OMElement) {
                        omElement = (OMElement) objValue;
                    } else {
                        continue;
                    }
                    if (!currentLocalName.equals(omElement.getLocalName())) {
                        break;
                    }
                    valueList.add(processObject(omElement, arrayClassType,
                            helper));
                }
                retObjs[count] = ConverterUtil.convertToArray(arrayClassType,
                        valueList);
            } else {
                //handling refs
                retObjs[count] = processObject(omElement, classType, helper);
            }
            count ++;
        }

        helper.clean();
        return retObjs;
    }

    public static Object processObject(OMElement omElement,
                                       Class classType,
                                       MultirefHelper helper) throws AxisFault {
        boolean hasRef = false;
        OMAttribute omatribute = MultirefHelper.processRefAtt(omElement);
        String ref = null;
        if (omatribute != null) {
            hasRef = true;
            ref = MultirefHelper.getAttvalue(omatribute);
        }
        if (OMElement.class.isAssignableFrom(classType)) {
            if (hasRef) {
                OMElement elemnt = helper.getOMElement(ref);
                if (elemnt == null) {
                    return helper.processOMElementRef(ref);
                } else {
                    return omElement;
                }
            } else
                return omElement;
        } else {
            if (hasRef) {
                if (helper.getObject(ref) != null) {
                    return helper.getObject(ref);
                } else {
                    return helper.processRef(classType, ref);
                }
            } else {
                if (SimpleTypeMapper.isSimpleType(classType)) {
                    return SimpleTypeMapper.getSimpleTypeObject(classType, omElement);
                } else if (SimpleTypeMapper.isArrayList(classType)) {
                    return SimpleTypeMapper.getArrayList(omElement);
                } else {
                    return BeanUtil.deserialize(classType, omElement);
                }
            }
        }
    }

    public static OMElement getOMElement(QName opName, Object [] args, String partName) {
        ArrayList objects;
        objects = new ArrayList();
        int argCount = 0;
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            if (arg == null) {
                continue;
            }
            //todo if the request parameter has name other than argi (0<i<n) , there should be a
            //way to do that , to solve that problem we need to have RPCRequestParameter
            //note that The value of request parameter can either be simple type or JavaBean
            if (arg instanceof Object[]) {
                Object array [] = (Object[]) arg;
                for (int j = 0; j < array.length; j++) {
                    Object o = array[j];
                    if (SimpleTypeMapper.isSimpleType(o)) {
                        objects.add("item" + argCount);
                        objects.add(o.toString());
                    } else {
                        objects.add(new QName("item" + argCount));
                        if (o instanceof OMElement) {
                            OMFactory fac = OMAbstractFactory.getOMFactory();
                            OMElement wrappingElement;
                            if (partName == null) {
                                wrappingElement = fac.createOMElement("item" + argCount, null);
                                wrappingElement.addChild((OMElement) o);
                            } else {
                                wrappingElement = fac.createOMElement(partName, null);
                                wrappingElement.addChild((OMElement) o);
                            }
                            objects.add(wrappingElement);
                        } else {
                            objects.add(o);
                        }
                    }
                }
            } else {
                if (SimpleTypeMapper.isSimpleType(arg)) {
                    if (partName == null) {
                        objects.add("arg" + argCount);
                    } else {
                        objects.add(partName);
                    }
                    objects.add(arg.toString());
                } else {
                    if (partName == null) {
                        objects.add(new QName("arg" + argCount));
                    } else {
                        objects.add(new QName(partName));
                    }
                    if (arg instanceof OMElement) {
                        OMFactory fac = OMAbstractFactory.getOMFactory();
                        OMElement wrappingElement;
                        if (partName == null) {
                            wrappingElement = fac.createOMElement("arg" + argCount, null);
                            wrappingElement.addChild((OMElement) arg);
                        } else {
                            wrappingElement = fac.createOMElement(partName, null);
                            wrappingElement.addChild((OMElement) arg);
                        }
                        objects.add(wrappingElement);
                    } else {
                        objects.add(arg);
                    }
                }
            }
            argCount ++;
        }

        XMLStreamReader xr = ADBPullParser.createPullParser(opName, objects.toArray(), null);
        StAXOMBuilder stAXOMBuilder =
                OMXMLBuilderFactory.createStAXOMBuilder(
                        OMAbstractFactory.getSOAP11Factory(), xr);
        return stAXOMBuilder.getDocumentElement();
    }

}
TOP

Related Classes of org.apache.axis2.databinding.utils.BeanUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.