/** * If the type of the object cannot be determined, and thus no Marshal class can handle the object, this * method is called. It will build either a SoapPrimitive or a SoapObject * * @param parser * @param typeNamespace * @param typeName * @return unknownObject wrapped as a SoapPrimitive or SoapObject * @throws IOException * @throws XmlPullParserException */ protected Object readUnknown(XmlPullParser parser, String typeNamespace, String typeName) { String name = parser.getName(); String namespace_ = parser.getNamespace(); // cache the attribute info list from the current element before we move on List <object> attributeInfoVector = new List <object>(); for (int attributeCount = 0; attributeCount < parser.getAttributeCount(); attributeCount++) { AttributeInfo attributeInfo = new AttributeInfo(); attributeInfo.setName(parser.getAttributeName(attributeCount)); attributeInfo.setValue(parser.getAttributeValue(attributeCount)); attributeInfo.setNamespace(parser.getAttributeNamespace(attributeCount)); attributeInfo.setType(parser.getAttributeType(attributeCount)); attributeInfoVector.Add(attributeInfo); } parser.next(); // move to text, inner start tag or end tag Object result = null; String text = null; if (parser.getEventType() == XmlPullParser.TEXT) { text = parser.getText(); SoapPrimitive sp = new SoapPrimitive(typeNamespace, typeName, text); result = sp; // apply all the cached attribute info list before we add the property and descend further for parsing for (int i = 0; i < attributeInfoVector.Count; i++) { sp.addAttribute((AttributeInfo)attributeInfoVector[i]); } parser.next(); } else if (parser.getEventType() == XmlPullParser.END_TAG) { SoapObject so = new SoapObject(typeNamespace, typeName); // apply all the cached attribute info list before we add the property and descend further for parsing for (int i = 0; i < attributeInfoVector.Count; i++) { so.addAttribute((AttributeInfo)attributeInfoVector[i]); } result = so; } if (parser.getEventType() == XmlPullParser.START_TAG) { if (text != null && text.Trim().Length != 0) { throw new Exception("Malformed input: Mixed content"); } SoapObject so = new SoapObject(typeNamespace, typeName); // apply all the cached attribute info list before we add the property and descend further for parsing for (int i = 0; i < attributeInfoVector.Count; i++) { so.addAttribute((AttributeInfo)attributeInfoVector[i]); } while (parser.getEventType() != XmlPullParser.END_TAG) { so.addProperty(parser.getNamespace(), parser.getName(), read(parser, so, so.getPropertyCount(), null, null, PropertyInfo.OBJECT_TYPE)); parser.nextTag(); } result = so; } parser.require(XmlPullParser.END_TAG, namespace_, name); return(result); }
/** * Returns a new object read from the given parser. If no mapping is found, null is returned. This method * is used by the SoapParser in order to convert the XML code to Java objects. */ public Object readInstance(XmlPullParser parser, String namespace_, String name, PropertyInfo expected) { SoapPrimitive key = new SoapPrimitive(namespace_, name, null); if (!qNameToClass.ContainsKey(key)) { return(null); } Object obj = qNameToClass[key]; if (obj is Marshal) { return(((Marshal)obj).readInstance(parser, namespace_, name, expected)); } else if (obj is SoapObject) { obj = ((SoapObject)obj).newInstance(); } else if (obj == typeof(SoapObject)) { obj = new SoapObject(namespace_, name); } else { try { obj = Activator.CreateInstance((Type)obj); } catch (Exception e) { throw new Exception(e.ToString()); } } if (obj is HasAttributes) { HasAttributes soapObject = (HasAttributes)obj; int cnt = parser.getAttributeCount(); for (int counter = 0; counter < cnt; counter++) { AttributeInfo attributeInfo = new AttributeInfo(); attributeInfo.setName(parser.getAttributeName(counter)); attributeInfo.setValue(parser.getAttributeValue(counter)); attributeInfo.setNamespace(parser.getAttributeNamespace(counter)); attributeInfo.setType(parser.getAttributeType(counter)); soapObject.setAttribute(attributeInfo); } } // ok, obj is now the instance, fill it.... if (obj is SoapObject) { readSerializable(parser, (SoapObject)obj); } else if (obj is FvmSerializable) { if (obj is HasInnerText) { ((HasInnerText)obj).setInnerText((parser.getText() != null) ? parser.getText() : ""); } readSerializable(parser, (FvmSerializable)obj); } else if (obj is List <object> ) { readVector(parser, (List <object>)obj, expected.elementType); } else { throw new Exception("no deserializer for " + obj.GetType()); } return(obj); }
/** * Read a FvmSerializable. */ protected void readSerializable(XmlPullParser parser, FvmSerializable obj) { int tag = 0; try { tag = parser.nextTag(); } catch (XmlPullParserException e) { if (obj is HasInnerText) { ((HasInnerText)obj).setInnerText((parser.getText() != null) ? parser.getText() : ""); } tag = parser.nextTag(); } while (tag != XmlPullParser.END_TAG) { String name = parser.getName(); if (!implicitTypes || !(obj is SoapObject)) { PropertyInfo info = new PropertyInfo(); int propertyCount = obj.getPropertyCount(); bool propertyFound = false; for (int i = 0; i < propertyCount && !propertyFound; i++) { info.clear(); obj.getPropertyInfo(i, properties, info); if ((name.Equals(info.name) && info.namespace_ == null) || (name.Equals(info.name) && parser.getNamespace().Equals(info.namespace_))) { propertyFound = true; obj.setProperty(i, read(parser, obj, i, null, null, info)); } } if (!propertyFound) { if (avoidExceptionForUnknownProperty) { // Dummy loop to read until corresponding END tag while (parser.next() != XmlPullParser.END_TAG || !name.Equals(parser.getName())) { } ; } else { throw new Exception("Unknown Property: " + name); } } else { if (obj is HasAttributes) { HasAttributes soapObject = (HasAttributes)obj; int cnt = parser.getAttributeCount(); for (int counter = 0; counter < cnt; counter++) { AttributeInfo attributeInfo = new AttributeInfo(); attributeInfo.setName(parser.getAttributeName(counter)); attributeInfo.setValue(parser.getAttributeValue(counter)); attributeInfo.setNamespace(parser.getAttributeNamespace(counter)); attributeInfo.setType(parser.getAttributeType(counter)); soapObject.setAttribute(attributeInfo); } } } } else { // I can only make this work for SoapObjects - hence the check above // I don't understand namespaces well enough to know whether it is correct in the next line... ((SoapObject)obj).addProperty(parser.getName(), read(parser, obj, obj.getPropertyCount(), ((SoapObject)obj).getNamespace(), name, PropertyInfo.OBJECT_TYPE)); } try { tag = parser.nextTag(); } catch (XmlPullParserException e) { if (obj is HasInnerText) { ((HasInnerText)obj).setInnerText((parser.getText() != null) ? parser.getText() : ""); } tag = parser.nextTag(); } } parser.require(XmlPullParser.END_TAG, null, null); }