/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2003-2004 Pierre G. Richard * * Copyright (C) 2003-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.xml.rpc; // Copyright (C) 2004 Nimkathana (www.nimkathana.com), USA // // License: LGPL // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation; either version 2.1 of // the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, execute to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA import totalcross.util.*; import totalcross.xml.AttributeList; import totalcross.xml.ContentHandler; /** * Methods here are called by the XML parser used in XmlRpcClient * * @version March 2006 * @author Added to SuperWaba by Guich * @author Nimkathana (<a href="http://www.nimkathana.com">www.nimkathana.com</a>) */ public class XmlRpcContentHandler extends ContentHandler { private Vector values; private StringBuffer cdata; private XmlRpcValue currentValue; private boolean readCdata; /** Gets the object unmarshalled from the last XML-RPC response parsing */ public Object result; /** Tells if a fault occurred during the parsing */ public boolean faultOccured; public XmlRpcContentHandler() { values = new Vector(50); cdata = new StringBuffer(128); } public void characters(String chars) { if (readCdata) cdata.append(chars); } public void endElement(int tag) { // finalize character data, if appropriate if (currentValue != null && readCdata) { currentValue.characterData(cdata.toString()); cdata.setLength(0); readCdata = false; } if (tag == XmlRpcValue.VALUE) { int depth = values.size(); // Only handle top level objects or objects contained in arrays here. // For objects contained in structs, wait for </member> (see code below). if (depth < 2 || values.items[depth - 2].hashCode() != XmlRpcValue.STRUCT) { XmlRpcValue v = currentValue; try {values.pop();} catch (ElementNotFoundException e) {} if (depth < 2) { // This is a top-level object result = v.getValue(); currentValue = null; } else { // add object to sub-array; if current container is a struct, add later (at </member>) try {currentValue = (XmlRpcValue) values.peek();} catch (ElementNotFoundException e) {} currentValue.endElement(v); } } } if (tag == XmlRpcValue.MEMBER) { // Handle objects contained in structs. XmlRpcValue v = currentValue; try {values.pop();} catch (ElementNotFoundException e) {} try {currentValue = (XmlRpcValue) values.peek();} catch (ElementNotFoundException e) {} currentValue.endElement(v); } else if (tag == XmlRpcValue.METHODNAME) { // String methodName = cdata.toString(); cdata.setLength(0); readCdata = false; } } public void startElement(int tag, AttributeList atts) { switch (tag) { case XmlRpcValue.ARRAY: case XmlRpcValue.STRUCT: currentValue.setType(tag); break; case XmlRpcValue.FAULT: faultOccured = true; break; case XmlRpcValue.NAME: //isStructName = true; // fall thru case XmlRpcValue.METHODNAME: case XmlRpcValue.STRING: cdata.setLength(0); readCdata = true; break; case XmlRpcValue.I4: tag = XmlRpcValue.INTEGER; case XmlRpcValue.DATE: case XmlRpcValue.BASE64: case XmlRpcValue.DOUBLE: case XmlRpcValue.BOOLEAN: case XmlRpcValue.INTEGER: case XmlRpcValue.LONG: currentValue.setType(tag); cdata.setLength(0); readCdata = true; break; case XmlRpcValue.VALUE: XmlRpcValue v = new XmlRpcValue(); values.push(v); currentValue = v; // cdata object is reused cdata.setLength(0); readCdata = true; break; default: break; } } }