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);
}
}