public static Object deserialize()

in modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java [445:655]


    public static Object deserialize(Class beanClass,
                                     OMElement beanElement,
                                     ObjectSupplier objectSupplier,
                                     String arrayLocalName)
            throws AxisFault {
        Object beanObj;
        try {
            // Added this block as a fix for issues AXIS2-2055 and AXIS2-1899
            // to support polymorphism in POJO approach.
            // Retrieve the type name of the instance from the 'type' attribute
            // and retrieve the class.
            String instanceTypeName = null;
            if (beanClass != null && !beanClass.isArray()) {
                instanceTypeName = beanElement.getAttributeValue(new QName(
                        Constants.XSI_NAMESPACE, "type"));
            }
            boolean hexBin = false;
            if (instanceTypeName != null) {
                MessageContext messageContext = MessageContext.getCurrentMessageContext();
                // we can have this support only at the server side. we need to find the axisservice
                // to get the type table.
                if (messageContext != null) {
                    AxisService axisService = messageContext.getAxisService();
                    if (axisService != null) {
                        QName typeQName = beanElement.resolveQName(instanceTypeName);
                        //Need this flag to differentiate "xsd:hexBinary" and "xsd:base64Binary" data. 
                        if(org.apache.ws.commons.schema.constants.Constants.XSD_HEXBIN.equals(typeQName)){
                            hexBin = true;
                        }
                        TypeTable typeTable = axisService.getTypeTable();
                        String className = typeTable.getClassNameForQName(typeQName);
                        if (className != null) {
                            try {
                                beanClass = Loader.loadClass(axisService.getClassLoader(), className);
                            } catch (ClassNotFoundException ce) {
                                throw AxisFault.makeFault(ce);
                            }
                        } else {
                            throw new AxisFault("Unknow type " + typeQName);
                        }
                    }
                }
            }

            // check for nil attribute:
            QName nilAttName = new QName(Constants.XSI_NAMESPACE, Constants.NIL, "xsi");
            if (beanElement.getAttribute(nilAttName) != null) {
                return null;
            }
            
            if(beanClass.getName().equals(DataHandler.class.getName())){
                return SimpleTypeMapper.getDataHandler(beanElement,hexBin);
            }

            if (beanClass.isArray()) {
                ArrayList<Object> valueList = new ArrayList<Object>();
                Class arrayClassType = beanClass.getComponentType();
                if ("byte".equals(arrayClassType.getName())) {
                    // find the part first and decode it
                    OMElement partElement = null;
                    for (Iterator iter = beanElement.getChildElements(); iter.hasNext();) {
                        partElement = (OMElement) iter.next();
                        if (partElement.getLocalName().equals(arrayLocalName)) {
                            break;
                        }
                    }
                    return Base64Utils.decode(partElement.getText());
                } else {
                    Iterator parts = beanElement.getChildElements();
                    OMElement omElement;
                    while (parts.hasNext()) {
                        Object objValue = parts.next();
                        if (objValue instanceof OMElement) {
                            omElement = (OMElement) objValue;
                            if ((arrayLocalName != null) && !arrayLocalName.equals(omElement.getLocalName())) {
                                continue;
                            }
                            // this is a multi dimentional array so always inner element is array
                            Object obj = deserialize(arrayClassType,
                                                     omElement,
                                                     objectSupplier, "array");

                            valueList.add(obj);
                        }
                    }
                    return ConverterUtil.convertToArray(arrayClassType, valueList);
                }
            }else if(SimpleTypeMapper.isDomDocument(beanClass)){
                return convertOMtoDOM(beanElement);
                
            } else if (XMLGregorianCalendar.class.getName().equals(
                    beanClass.getName())) {
                return getXMLGregorianCalendar(beanElement);

            } else {
                if (SimpleTypeMapper.isSimpleType(beanClass)) {
                    return getSimpleTypeObjectChecked(beanClass, beanElement);
                } else if ("java.lang.Object".equals(beanClass.getName())) {
                    return beanElement.getFirstOMChild();
                }

                //use a comaprator to ignore the case of the bean element
                //names eg. if the property descriptor is getServiceName it
                //should accept child element with ServiceName as well.
                //but currently accepts only serviceName
                Comparator comparator = new Comparator() {
                    public int compare(Object o1, Object o2) {
                        String string1 = (String) o1;
                        String string2 = (String) o2;
                        return string1.compareToIgnoreCase(string2);
                    }
                };
                Map<String, PropertyDescriptor> properties = new TreeMap<String, PropertyDescriptor>(comparator);


                BeanInfo beanInfo = getBeanInfo(beanClass);
                PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors();
                for (PropertyDescriptor proprty : propDescs) {
                    properties.put(proprty.getName(), proprty);
                }
                Iterator elements = beanElement.getChildren();
                beanObj = objectSupplier.getObject(beanClass);
                while (elements.hasNext()) {
                    // the beanClass could be an abstract one.
                    // so create an instance only if there are elements, in
                    // which case a concrete subclass is available to instantiate.
                    OMElement parts;
                    Object objValue = elements.next();
                    if (objValue instanceof OMElement) {
                        parts = (OMElement) objValue;
                    } else {
                        continue;
                    }
                    OMAttribute attribute = parts.getAttribute(
                            new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi"));

                    // 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 = properties.remove(partsLocalName);
                    if (prty != null) {
                        Class parameters = prty.getPropertyType();
                        if (prty.getName().equals("class"))
                            continue;

                        Object partObj;
                        boolean isNil = false;
                        if (attribute != null) {
                            String nilValue = attribute.getAttributeValue();
                            if ("true".equals(nilValue) || "1".equals(nilValue)) {
                                isNil = true;
                            }
                        }
                        if (isNil) {
                            partObj = null;
                        } else {
                            if (SimpleTypeMapper.isSimpleType(parameters)) {
                                partObj = SimpleTypeMapper.getSimpleTypeObject(parameters, parts);
                            } else if (SimpleTypeMapper.isHashSet(parameters)) {
                                partObj = SimpleTypeMapper.getHashSet((OMElement)
                                        parts.getParent(), prty.getName());
                            } else if (SimpleTypeMapper.isCollection(parameters)) {
                                Type type = prty.getReadMethod().getGenericReturnType();
                                partObj = processGenericCollection(parts, type, null, objectSupplier);  

                            } else if (SimpleTypeMapper.isDataHandler(parameters)) {
                                partObj = SimpleTypeMapper.getDataHandler(parts);
                            } else if (parameters.isArray()) {
                                partObj = deserialize(parameters, (OMElement) parts.getParent(),
                                                      objectSupplier, prty.getName());
                            } else if (SimpleTypeMapper.isMap(parameters)){
                                partObj = null;
                                final Type type = prty.getReadMethod().getGenericReturnType();
                                if (type instanceof ParameterizedType) {
                                    ParameterizedType aType = (ParameterizedType) type;
                                    Type[] parameterArgTypes = aType.getActualTypeArguments();
                                    partObj = processGenericsMapElement(parameterArgTypes
                                          , (OMElement) parts.getParent(), null, parts.getChildren(), objectSupplier, beanClass);
                                } else {
                                    Type[] parameterArgTypes = {Object.class,Object.class}; 
                                    partObj = processGenericsMapElement(parameterArgTypes
                                             , (OMElement) parts.getParent(), null, parts.getChildren(), objectSupplier, beanClass);
                                }
                            }else if (SimpleTypeMapper.isEnum(parameters)) {
                                partObj =processEnumObject(parameters , parts);
                            } else {
                                partObj = deserialize(parameters, parts, objectSupplier, null);
                            }
                        }
                        Object[] parms = new Object[]{partObj};
                        Method writeMethod = prty.getWriteMethod();
                        if (writeMethod != null) {
                            writeMethod.setAccessible(true);
                            writeMethod.invoke(beanObj, parms);
                        }
                    }
                }
                return beanObj;
            }
        } catch (IllegalAccessException e) {
            throw new AxisFault("IllegalAccessException : " + e);
        } catch (InvocationTargetException e) {
            throw new AxisFault("InvocationTargetException : " + e);
        } catch (IntrospectionException e) {
            throw new AxisFault("IntrospectionException : " + e);
        } catch (DatatypeConfigurationException e) {
            throw new AxisFault("DatatypeConfigurationException : " + e);            
        }


    }