package org.xmlrpc.android; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; //import android.util.Log; class XMLRPCSerializer implements IXMLRPCSerializer { static SimpleDateFormat dateFormat = new SimpleDateFormat(DATETIME_FORMAT); @SuppressWarnings("unchecked") public void serialize(XmlSerializer serializer, Object object) throws IOException { // This code supplied by mattias.ellback as part of issue #19 if (object == null){ serializer.startTag(null, TYPE_NULL).endTag(null, TYPE_NULL); } else // check for scalar types: if (object instanceof Integer || object instanceof Short || object instanceof Byte) { serializer.startTag(null, TYPE_I4).text(object.toString()).endTag(null, TYPE_I4); } else if (object instanceof Long) { serializer.startTag(null, TYPE_I8).text(object.toString()).endTag(null, TYPE_I8); } else if (object instanceof Double || object instanceof Float) { serializer.startTag(null, TYPE_DOUBLE).text(object.toString()).endTag(null, TYPE_DOUBLE); } else if (object instanceof Boolean) { Boolean bool = (Boolean) object; String boolStr = bool.booleanValue() ? "1" : "0"; serializer.startTag(null, TYPE_BOOLEAN).text(boolStr).endTag(null, TYPE_BOOLEAN); } else if (object instanceof String) { serializer.startTag(null, TYPE_STRING).text(object.toString()).endTag(null, TYPE_STRING); } else if (object instanceof Date || object instanceof Calendar) { String dateStr = dateFormat.format(object); serializer.startTag(null, TYPE_DATE_TIME_ISO8601).text(dateStr).endTag(null, TYPE_DATE_TIME_ISO8601); } else if (object instanceof byte[] ){ String value = new String(Base64Coder.encode((byte[])object)); serializer.startTag(null, TYPE_BASE64).text(value).endTag(null, TYPE_BASE64); } else if (object instanceof List) { serializer.startTag(null, TYPE_ARRAY).startTag(null, TAG_DATA); List<Object> list = (List<Object>) object; Iterator<Object> iter = list.iterator(); while (iter.hasNext()) { Object o = iter.next(); serializer.startTag(null, TAG_VALUE); serialize(serializer, o); serializer.endTag(null, TAG_VALUE); } serializer.endTag(null, TAG_DATA).endTag(null, TYPE_ARRAY); } else if (object instanceof Object[]) { serializer.startTag(null, TYPE_ARRAY).startTag(null, TAG_DATA); Object[] objects = (Object[]) object; for (int i=0; i<objects.length; i++) { Object o = objects[i]; serializer.startTag(null, TAG_VALUE); serialize(serializer, o); serializer.endTag(null, TAG_VALUE); } serializer.endTag(null, TAG_DATA).endTag(null, TYPE_ARRAY); } else if (object instanceof Map) { serializer.startTag(null, TYPE_STRUCT); Map<String, Object> map = (Map<String, Object>) object; Iterator<Entry<String, Object>> iter = map.entrySet().iterator(); while (iter.hasNext()) { Entry<String, Object> entry = iter.next(); String key = entry.getKey(); Object value = entry.getValue(); serializer.startTag(null, TAG_MEMBER); serializer.startTag(null, TAG_NAME).text(key).endTag(null, TAG_NAME); serializer.startTag(null, TAG_VALUE); serialize(serializer, value); serializer.endTag(null, TAG_VALUE); serializer.endTag(null, TAG_MEMBER); } serializer.endTag(null, TYPE_STRUCT); } else if (object instanceof XMLRPCSerializable) { XMLRPCSerializable serializable = (XMLRPCSerializable) object; serialize(serializer, serializable.getSerializable()); } else { throw new IOException("Cannot serialize " + object); } } public Object deserialize(XmlPullParser parser) throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, null, TAG_VALUE); if (parser.isEmptyElementTag()) { // degenerated <value />, return empty string return ""; } Object obj; boolean hasType = true; String typeNodeName = null; try { parser.nextTag(); typeNodeName = parser.getName(); if (typeNodeName.equals(TAG_VALUE) && parser.getEventType() == XmlPullParser.END_TAG) { // empty <value></value>, return empty string return ""; } } catch (XmlPullParserException e) { hasType = false; } if (hasType) { // This code submitted by mattias.ellback in issue #19 if (typeNodeName.equals(TYPE_NULL)){ parser.nextTag(); obj = null; } else if (typeNodeName.equals(TYPE_INT) || typeNodeName.equals(TYPE_I4)) { String value = parser.nextText(); obj = Integer.parseInt(value); } else if (typeNodeName.equals(TYPE_I8)) { String value = parser.nextText(); obj = Long.parseLong(value); } else if (typeNodeName.equals(TYPE_DOUBLE)) { String value = parser.nextText(); obj = Double.parseDouble(value); } else if (typeNodeName.equals(TYPE_BOOLEAN)) { String value = parser.nextText(); obj = value.equals("1") ? Boolean.TRUE : Boolean.FALSE; } else if (typeNodeName.equals(TYPE_STRING)) { obj = parser.nextText(); } else if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) { String value = parser.nextText(); try { obj = dateFormat.parseObject(value); } catch (ParseException e) { throw new IOException("Cannot deserialize dateTime " + value); } } else if (typeNodeName.equals(TYPE_BASE64)) { String value = parser.nextText(); BufferedReader reader = new BufferedReader(new StringReader(value)); String line; StringBuffer sb = new StringBuffer(); while ((line = reader.readLine()) != null) { sb.append(line); } obj = Base64Coder.decode(sb.toString()); } else if (typeNodeName.equals(TYPE_ARRAY)) { parser.nextTag(); // TAG_DATA (<data>) parser.require(XmlPullParser.START_TAG, null, TAG_DATA); parser.nextTag(); List<Object> list = new ArrayList<Object>(); while (parser.getName().equals(TAG_VALUE)) { list.add(deserialize(parser)); parser.nextTag(); } parser.require(XmlPullParser.END_TAG, null, TAG_DATA); parser.nextTag(); // TAG_ARRAY (</array>) parser.require(XmlPullParser.END_TAG, null, TYPE_ARRAY); obj = list.toArray(); } else if (typeNodeName.equals(TYPE_STRUCT)) { parser.nextTag(); Map<String, Object> map = new HashMap<String, Object>(); while (parser.getName().equals(TAG_MEMBER)) { String memberName = null; Object memberValue = null; while (true) { parser.nextTag(); String name = parser.getName(); if (name.equals(TAG_NAME)) { memberName = parser.nextText(); } else if (name.equals(TAG_VALUE)) { memberValue = deserialize(parser); } else { break; } } if (memberName != null && memberValue != null) { map.put(memberName, memberValue); } parser.require(XmlPullParser.END_TAG, null, TAG_MEMBER); parser.nextTag(); } parser.require(XmlPullParser.END_TAG, null, TYPE_STRUCT); obj = map; } else { throw new IOException("Cannot deserialize " + parser.getName()); } } else { // TYPE_STRING (<string>) is not required obj = parser.getText(); } parser.nextTag(); // TAG_VALUE (</value>) parser.require(XmlPullParser.END_TAG, null, TAG_VALUE); return obj; } }