Re: Kuddi: xmlrpc'ing vectors

"Thomas Koch" <[email protected]> Fri, 7 Mar 2003 09:15:31 +0100
Newsgroups gmane.comp.java.enhydra.kxmlrpc
Organization OrbiTeam Software GmbH http://www.orbiteam.de
Message-ID <[email protected]>
This is a multi-part message in MIME format.

------=_NextPart_000_0025_01C2E48A.1A52A9C0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Henrik,
we've encoutered the same problem when starting our tests with the
kXmlRpc lib and found some fixes for this. I posted an according message
to the list in September last year.It's attached for your information.

As there was no response on the list and also no updates of code or list
archive I do now assume that the kxml-rpc project is 'on-hold'. Any
'official' comment from the kxml-rpc maintainers would be highly
welcome.

BTW, we're also doing work with kxml-rpc lib and J2ME midlets - I'd be
interested in experience of other users with that technology
combination.

kind regards,

Thomas Koch
__________________________________________________________
Thomas Koch                         [email protected]
OrbiTeam Software GmbH              http://www.orbiteam.de
Endenicher Allee 35                 phone: +49 228 4101400
53121 Bonn                          fax:   +49 228 4101401
Germany

----- Original Message -----
From: "Henrik Plate (GMX)" <[email protected]>
To: <[email protected]>
Sent: Thursday, March 06, 2003 5:43 PM
Subject: Kuddi: xmlrpc'ing vectors


> Hi everybody!
>
> Beside (k)XMLRPC is really lightweight, easy to use/learn and
efficient I do
> have some problems transfering vectors from a XMLRPC server to a
MIDlet.
>
> I've got a servlet (source below, modified Apache class
> org.apache.xmlrpc.XmlRpcProxyServlet) which acts as a XMLRPC server.
The
> servlet itself is registered as the default handler and got the method
> getProviders, which simply returns a newly constructed Vector. Other
methods
> like getServerInfo, which returns a String, succeed.
>
> When I call the servlet with a J2SE client (slightly modified Apache
> example) the resulting object is a Vector. Fine.
>
> When I call the method from a MIDlet, the Wireless Toolkit prints the
> following exception:
>
> org.kxml.io.ParseException: unexpected: StartTag <data> line: -1 attr:
null
> @-1:-1
> at org.kxml.parser.AbstractXmlParser.read(+53)
> at org.kxmlrpc.XmlRpcParser.parseValue(+15)
> at org.kxmlrpc.XmlRpcParser.parseArray(+23)
> at org.kxmlrpc.XmlRpcParser.parseValue(+241)
> at org.kxmlrpc.XmlRpcParser.parseParams(+46)
> at org.kxmlrpc.XmlRpcParser.parseResponse(+144)
> at org.kxmlrpc.XmlRpcClient.execute(+200)
> at midlet.ServerConnection.callMethod(+15)
> at midlet.XmlRpcTestControl$1.run(+18)
>
> The via HTTP transfered xml response of the servlet is
>
>     <?xml version="1.0" encoding="ISO-8859-1"?>
>     <methodResponse>
>         <params>
>             <param>
>                 <value>
>                     <array>
>                         <data>
>                             <value>String 1</value>
>                             <value>String 2</value>
>                         </data>
>                     </array>
>                 </value>
>             </param>
>         </params>
>     </methodResponse>
>
> Seems to be OK.
>
> Does kXMLRPC miss the implementation of Vector transfers? I can't
imagine,
> cause the parser fails at the data-, not the array-tag. Is it
versioning
> problem?
>
> Here's my enviroment:
>
> kXMLRPC 0.6
> XMLRPC 1.1 from Apache
> J2SE 1.4.1
> Tomcat 4.0.1
>
> Relevant part of the servlet source:
>
>     import org.apache.xmlrpc.*;
>
>     public class XmlRpcServlet extends HttpServlet  {
>
>         // The xml-rpc server.
>         final XmlRpcServer server = new XmlRpcServer();
>
>         public void init(ServletConfig config)throws ServletException{
>
>             // Config the xml-rpc server.
>             XmlRpc.setDebug(true);
>             server.addHandler("$default", this);
>         }
>
>         public String getServerInfo() { return "XmlRpcServlet"; }
> //"$Name$"; }
>
>         public Vector getProviders() {
>             final Vector v = new Vector();
>             v.add("String 1");
>             v.add("String 2");
>             return v;
>         }
>
>         public void service(HttpServletRequest req,
HttpServletResponse
> res)throws ServletException, IOException{
>             byte[] result = server.execute(req.getInputStream ());
>             res.setContentType("text/xml");
>             res.setContentLength(result.length);
>             OutputStream output = res.getOutputStream();
>             output.write(result);
>             output.flush();
>         }
>     }
>
> Another question: If a XMLRPC call fails, the XmlRpcClient class
returns the
> result of the previous call. Is that desireable? Not sure of this.
>
> Greetings und thanks in advance,
> Henrik
>
>
>
>
>
>
>
> _______________________________________________
> Kuddi mailing list
> [email protected]
> http://support.enhydra.org/mailman/listinfo.cgi/kxmlrpc
>

------=_NextPart_000_0025_01C2E48A.1A52A9C0
Content-Type: message/rfc822;
	name="Fixes to org.kxml.parser.XmlRpcParser .eml"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="Fixes to org.kxml.parser.XmlRpcParser .eml"

From: "Thomas Koch" <[email protected]>
To: <[email protected]>
Subject: Fixes to org.kxml.parser.XmlRpcParser 
Date: Wed, 25 Sep 2002 12:15:21 +0200
Organization: OrbiTeam Software GmbH http://www.orbiteam.de
MIME-Version: 1.0
Content-Type: multipart/mixed;
	boundary="----=_NextPart_000_0023_01C2648D.3832E0E0"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4807.1700
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700

This is a multi-part message in MIME format.

------=_NextPart_000_0023_01C2648D.3832E0E0
Content-Type: text/plain;
	charset="Windows-1252"
Content-Transfer-Encoding: 7bit

Hi,
I've downloaded kXML-RPC version 0.6 from http://kxmlrpc.enhydra.org and
made some experiments with it. The package is very nice and runs out of
the box but I found some minor problems when interacting with a
python-based XML-RPC server:

- it seems that the parser sometimes cannot handle whitespaces when
parsing the Response

- when parsing a response type "Array" the parser does not
expect/consume the <data> tag, but the XML-RPC spec defines
<array> as follows:
"An <array> contains a single <data> element, which can contain any
number of <value>s."
e.g.
   <array><data>
      <value><string>Egypt</string></value>
      <value><boolean>0</boolean></value>
    </data></array>

The fixes are as follows:

in org.kxml.parser.XmlRpcParser:

fixed:
 Object parseResponse()
added:
 parser.skip();
before:
 Hashtable fault = (Hashtable) parseValue();

fixed:
 Object parseParams()
added:
 parser.skip();
before:
 params.addElement( parseValue() );

fixed:
 Vector parseArray()
added:
 parser.read( Xml.START_TAG, "", "data" );
 parser.skip();
before:
 while( parser.peek().getType() != Xml.END_TAG ) {

fixed:
 Vector parseArray()
added:
 parser.read( Xml.END_TAG, "", "data" );
 parser.skip();
before:
 return v;

The new XmlRpcParser.java is attached.
It has been tested with xmlrpc-lib of python2.2 - any comments are
welcome.

Please excuse if this has already been posted, but I couldn't browse the
mailing list archive (it's empty on the website). I'm looking forward to
further releases of kXML-RPC.


kind regards

Thomas Koch
_______________________________________________________________
Thomas Koch                         [email protected]
OrbiTeam Software GmbH              http://www.orbiteam.de/
Rathausallee 10                     phone: +49 2241 397996-0
53757 Sankt Augustin                fax:   +49 2241 397996-1
Germany



------=_NextPart_000_0023_01C2648D.3832E0E0
Content-Type: application/octet-stream;
	name="XmlRpcParser.java"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="XmlRpcParser.java"

/* kxmlrpc=0A=
 *=0A=
 * The contents of this file are subject to the Enhydra Public License=0A=
 * Version 1.1 (the "License"); you may not use this file except in=0A=
 * compliance with the License. You may obtain a copy of the License=0A=
 * on the Enhydra web site ( http://www.enhydra.org/ ).=0A=
 *=0A=
 * Software distributed under the License is distributed on an "AS IS"=0A=
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See=0A=
 * the License for the specific terms governing rights and limitations=0A=
 * under the License.=0A=
 *=0A=
 * The Initial Developer of kxmlrpc is Kyle Gabhart. Copyright (C) 2001 =0A=
 * Kyle Gabhart -- [email protected] . All Rights Reserved.=0A=
 *=0A=
 * Contributor(s): Stefan Haustein=0A=
 */=0A=
=0A=
package org.kxmlrpc;=0A=
=0A=
import java.io.*;=0A=
import java.util.*;=0A=
=0A=
import org.kxml.*;=0A=
import org.kxml.parser.*;=0A=
=0A=
import org.kobjects.isodate.IsoDate;=0A=
import org.kobjects.base64.Base64;=0A=
=0A=
/**=0A=
 * This abstract base class provides basic XML-RPC parsing capabilities. =
The =0A=
 * kxml parser is required by this class.=0A=
 */=0A=
public class XmlRpcParser {=0A=
=0A=
    AbstractXmlParser   parser;=0A=
    String              methodName;=0A=
    Vector              params =3D new Vector();=0A=
=0A=
    /**=0A=
     * @param parser    a kxml parser object reference=0A=
     */=0A=
    public XmlRpcParser( AbstractXmlParser parser ) {=0A=
	this.parser =3D parser;=0A=
    }//end XmlRpcParser( AbstractXmlParser )=0A=
    =0A=
    public String getMethodName() {=0A=
	return methodName;=0A=
    }//end getMethodName()=0A=
=0A=
    public Vector getParams() {=0A=
	return params;=0A=
    }//end getParams()=0A=
=0A=
    /*=0A=
    // This method is used to parse an incoming Client request=0A=
    //  kxmlrpc does not currently support this feature=0A=
    public void parseCall() throws IOException {=0A=
	parser.skip(); =0A=
	parser.read( Xml.START_TAG, "", "methodCall" );=0A=
=0A=
	parser.skip();=0A=
	parser.read( Xml.START_TAG, "", "methodName" );=0A=
        methodName =3D parser.readText();=0A=
	parser.read( Xml.END_TAG, "", "methodName" );=0A=
=0A=
	parser.skip();=0A=
=0A=
	if( parser.peek().getType() !=3D Xml.END_TAG ) =0A=
	    parseParams();=0A=
=0A=
	parser.read( Xml.END_TAG, "", "methodCall" );=0A=
	parser.skip();=0A=
	parser.read( Xml.END_DOCUMENT, null, null );=0A=
    }//end parseCall()=0A=
    */=0A=
    =0A=
    /** =0A=
     * Called by a client to parse an XML-RPC response returned by a =
server.=0A=
     *=0A=
     * @return The return parameter sent back by the server.=0A=
     */=0A=
    public Object parseResponse() throws IOException {=0A=
        ParseEvent      event;=0A=
        Object          result;=0A=
        =0A=
        parser.skip();=0A=
	parser.read( Xml.START_TAG, "", "methodResponse" );=0A=
	parser.skip();=0A=
=0A=
	event =3D parser.peek();=0A=
	result =3D null;=0A=
=0A=
	if( event.getType() =3D=3D Xml.START_TAG ) {=0A=
	    // If an error occurred, the server will return a Fault=0A=
            if( "fault".equals( event.getName() ) ) {         	=0A=
		parser.read();=0A=
		parser.skip(); // NEW: added 02-09-25, TKo		=0A=
                // Fault's are returned as structs (which are mapped to =
Hashtables)=0A=
		Hashtable fault =3D (Hashtable) parseValue();=0A=
		parser.skip();=0A=
		parser.read( Xml.END_TAG, "", "fault" );=0A=
                // Ultimately, a client-side exception object is =
generated=0A=
		result =3D new XmlRpcException =0A=
		    ( ( (Integer) fault.get( "faultCode" ) ).intValue(),=0A=
		     (String) fault.get( "faultString" ) );=0A=
	    }=0A=
            /* The current version of the XML-RPC spec -- =
http://www.xmlrpc.org/spec=0A=
                does not permit multiple parameter values to be =
returned, although=0A=
                a complex type (struct or array) containing multiple =
values (and even=0A=
                other complext types) is permitted.  This aspect of the =
spec is currently=0A=
                being debated and may be changed in the future. */=0A=
	    else if( "params".equals( event.getName() ) ) {=0A=
		parseParams();=0A=
		if( params.size() > 1 ) =0A=
		    throw new IOException( "too many return parameters" );=0A=
		else if( params.size() =3D=3D 1 ) =0A=
		    result =3D params.elementAt(0);=0A=
	    }=0A=
	    else throw new IOException =0A=
		( "<fault> or <params> expected instead of " + event );=0A=
	}//end if( event.getType() =3D=3D Xml.START_TAG ) {=0A=
=0A=
	parser.skip();=0A=
	parser.read( Xml.END_TAG, "", "methodResponse" );=0A=
	parser.skip();=0A=
	parser.read( Xml.END_DOCUMENT, null, null );=0A=
=0A=
	return result;=0A=
    }//end parseResponse()=0A=
=0A=
    /**=0A=
     * All data in an XML-RPC call is passed as a parameter. This method =
parses =0A=
     * the parameter values out of each parameter by calling the =
parseValue() =0A=
     * method. =0A=
     */=0A=
    void parseParams() throws IOException {=0A=
	parser.read( Xml.START_TAG, "", "params" );=0A=
	parser.skip();=0A=
        =0A=
	while( parser.peek().getType() !=3D Xml.END_TAG ) {=0A=
	    parser.read( Xml.START_TAG, "", "param" );=0A=
            // Retrieve a Java representation of the XML-RPC parameter =
value=0A=
            parser.skip(); // NEW: added 02-09-20, TKo=0A=
	    params.addElement( parseValue() );=0A=
	    parser.skip();=0A=
	    parser.read( Xml.END_TAG, "", "param" );=0A=
	    parser.skip();=0A=
	}//end while( parser.peek().getType() !=3D Xml.END_TAG )=0A=
	=0A=
	parser.read( Xml.END_TAG, "", "params" );=0A=
	parser.skip();=0A=
    }//end parseParams()=0A=
=0A=
    /** =0A=
     * Core method for parsing XML-RPC values into Java data types. It =
is called =0A=
     * recursively by the parseStruct() and parseArray() methods when =
handling =0A=
     * complex data types =0A=
     * =0A=
     * @return A Java representation of the XML-RPC value=0A=
     */=0A=
    Object parseValue() throws IOException {=0A=
	Object      result =3D null;=0A=
        =0A=
	parser.read( Xml.START_TAG, "", "value" );=0A=
	parser.skip();=0A=
=0A=
	if( parser.peek().getType() !=3D Xml.START_TAG ) =0A=
	    result =3D parser.readText();=0A=
	else {=0A=
	    ParseEvent event =3D parser.read( Xml.START_TAG, "", null );=0A=
	    String name =3D event.getName();=0A=
	=0A=
	    if( name.equals("string") )=0A=
		result =3D parser.readText();=0A=
	    else if( name.equals("i4") || name.equals("int") )=0A=
		result =3D new Integer =0A=
		    ( Integer.parseInt( parser.readText().trim() ) );=0A=
	    else if( name.equals("boolean") )=0A=
		result =3D new Boolean( parser.readText().trim().equals("1") );=0A=
	    else if( name.equals("dateTime.iso8601") )=0A=
		result =3D IsoDate.stringToDate  =0A=
		    ( parser.readText(), IsoDate.DATE_TIME );=0A=
	    else if( name.equals("base64") )=0A=
		result =3D Base64.decode( parser.readText() );=0A=
            else if( name.equals("struct") ) =0A=
		result =3D parseStruct(); =0A=
	    else if( name.equals("array") )=0A=
		result =3D parseArray();=0A=
            // kxmlrpc does not currently support the XML-RPC double =
data type=0A=
            //  the temporary workaround is to process double values as =
strings=0A=
            else if( name.equals("double") )=0A=
                result =3D parser.readText();=0A=
=0A=
	    parser.read( Xml.END_TAG, "", name );=0A=
	    parser.skip();=0A=
	}//end if( parser.peek().getType() !=3D Xml.START_TAG )=0A=
=0A=
	parser.read( Xml.END_TAG, "", "value" );=0A=
	return result;=0A=
    }//end parseValue()=0A=
=0A=
    /**=0A=
     * @return kxmlrpc maps XML-RPC structs to java.util.Hashtables=0A=
     */=0A=
    Hashtable parseStruct() throws IOException {=0A=
	Hashtable h =3D new Hashtable();=0A=
	parser.skip();=0A=
	=0A=
	while( parser.peek().getType() !=3D Xml.END_TAG ) {=0A=
	    parser.read( Xml.START_TAG, "", "member" );=0A=
	    parser.skip();=0A=
	    parser.read( Xml.START_TAG, "", "name" );=0A=
	    String name =3D parser.readText();=0A=
	    parser.read( Xml.END_TAG, "", "name" );=0A=
	    parser.skip();=0A=
	    h.put( name, parseValue() ); // parse this member value=0A=
	    parser.skip();=0A=
	    parser.read( Xml.END_TAG, "", "member" );=0A=
	    parser.skip();=0A=
	}//end while( parser.peek().getType() !=3D Xml.END_TAG )=0A=
	return h;=0A=
    }//end parseStruct()=0A=
=0A=
    /**=0A=
     * @return kxmlrpc maps XML-RPC arrays to java.util.Vectors=0A=
     */=0A=
    Vector parseArray() throws IOException {=0A=
	Vector v =3D new Vector();=0A=
	parser.skip();=0A=
=0A=
	// NEW: need to consume <data> tag! (TKo)=0A=
	parser.read( Xml.START_TAG, "", "data" );=0A=
	parser.skip();=0A=
	// end new=0A=
	=0A=
	while( parser.peek().getType() !=3D Xml.END_TAG ) {=0A=
	    v.addElement( parseValue() ); // parse this element value=0A=
	    parser.skip();=0A=
	}//end while( parser.peek().getType() !=3D Xml.END_TAG )=0A=
	=0A=
	// NEW: need to consume </data> tag! (TKo)=0A=
	parser.read( Xml.END_TAG, "", "data" );=0A=
	parser.skip();=0A=
	// end new=0A=
	=0A=
	return v;=0A=
    }//end parseArray()=0A=
}//end XmlRpcParser
------=_NextPart_000_0023_01C2648D.3832E0E0--

------=_NextPart_000_0025_01C2E48A.1A52A9C0--