You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by John Bellone <jo...@flipsidesoftware.com> on 2008/02/06 00:31:35 UTC
Hacking apart the Parser
I figured since this list has helped me greatly that I would contribute
back and include some examples on how I was able to successfully get the
XML-RPC parser inside of the library working without the actual need for
the servlets to run. We already had a working network structure and all
I needed was the actual type parser, and well, it wasn't as easy as I
thought it would have been to get it working. But I did! So here's the
basics.
XmlRpcControllerImpl.java
public class XmlRpcControllerImpl extends XmlRpcController {
private final StreamConfig config = new StreamConfig();
protected XmlRpcWorkerFactory getDefaultXmlRpcWorkerFactory() { return null; }
public XmlRpcConfig getConfig() { return config; }
// @summary: Implementation of the configuration for the Apache XMLRPC parser. This is
// a default configuration that most likely will never need to be changed.
// @author: John Bellone (john.bellone@flipsidesoftware.com)
private class StreamConfig implements XmlRpcStreamConfig
{
public StreamConfig() { }
public String getEncoding() { return UTF8_ENCODING; }
public boolean isEnabledForExtensions() { return false; }
public java.util.TimeZone getTimeZone() { return java.util.TimeZone.getDefault(); }
}
}
XmlRpcTransportParser.java
// @summary: The implementation of the XMLRPC parser that interfaces with
// the apache XMLRPC parser.
// @author: John Bellone (john.bellone@flipsidesoftware.com)
public class XmlRpcTransportParser extends AbstractTransportParser {
public XmlRpcTransportParser()
{
}
// @summary: This method takes the information from the input stream and parses it
// through the Apache XML-RPC library (and the SAX XML Parser) to produce our custom
// MethodCall object.
public MethodCall parse(ByteBuffer buf)
throws Exception
{
final XmlRpcRequestParser parser
= new XmlRpcRequestParser( new StreamConfig(), new TypeFactoryImpl(new XmlRpcControllerImpl()) );
final XMLReader xr = SAXParsers.newXMLReader();
xr.setContentHandler(parser);
StringBuffer packet = new StringBuffer();
String line = "";
BufferedReader reader = AbstractTransportParser.newBufferedReader(buf);
while( (line = reader.readLine()) != null)
packet.append(line);
try {
xr.parse( new InputSource( new StringReader(packet.toString()) ) );
}
catch(SAXParseException se)
{
throw se;
}
return new MethodCall(parser.getMethodName(), parser.getParams() );
}
// @summary: Implementation of the configuration for the Apache XMLRPC parser. This is
// a default configuration that most likely will never need to be changed.
// @author: John Bellone (john.bellone@flipsidesoftware.com)
private class StreamConfig implements XmlRpcStreamConfig
{
public String getEncoding() { return UTF8_ENCODING; }
public boolean isEnabledForExtensions() { return false; }
public java.util.TimeZone getTimeZone() { return java.util.TimeZone.getDefault(); }
}
}
XmlRpcTransportSerializer.java
// @summary: This is the XML-RPC implementation of the Transport Serializer.
// We're using the Apache XML-RPC library to do the serialization.
// @author: John Bellone (john.bellone@flipsidesoftware.com)
class XmlRpcTransportSerializer extends AbstractTransportSerializer {
private XmlWriterFactory writerFactory = new DefaultXMLWriterFactory();
public ByteBuffer serialize(MethodResponse result)
throws Exception
{
ByteBuffer outcomm = ByteBuffer.allocateDirect(AbstractTransportSerializer.MAXSIZE);
OutputStream stream = AbstractTransportSerializer.newOutputStream(outcomm);
XmlRpcWriter writer = new XmlRpcWriter( new StreamConfig(),
writerFactory.getXmlWriter(new StreamConfig(), stream),
new TypeFactoryImpl(new XmlRpcControllerImpl()) );
writer.write(new RequestConfig(), result.getResult() );
return outcomm;
}
// @summary: Implementation of the configuration for the Apache XMLRPC parser. This is
// a default configuration that most likely will never need to be changed.
// @author: John Bellone (john.bellone@flipsidesoftware.com)
private class StreamConfig implements XmlRpcStreamConfig
{
public String getEncoding() { return UTF8_ENCODING; }
public boolean isEnabledForExtensions() { return false; }
public java.util.TimeZone getTimeZone() { return java.util.TimeZone.getDefault(); }
}
private class RequestConfig implements XmlRpcRequestConfig
{
public boolean isEnabledForExtensions() { return false; }
public java.util.TimeZone getTimeZone() { return java.util.TimeZone.getDefault(); }
}
}
Now that is essentially all the code needed to make the parser active without actually needing to run the server code
that was included with the library. I am posting this because I believe there might be a need for it (for at least someone)
and it took me a couple of weeks to get it working without a hitch. As you can see we are not enabling the parser to accept
extensions. We are also using a default of UTF-8 encoding (which you can change).
The code is basically a hack and we're currently redesigning the whole project. So I figured there would be no foul in psoting
this for anyone that is interested in doing something similar (not needing the built-in servers). If you have any questions feel
free to ask away. We used a custom MethodCall and MethodResponse object. I don't see a need to release that code (as they contain
some of the structure of the rest of the project) and they are pretty straight forward anyway.
Enjoy!
--
-John Bellone
john.bellone@flipsidesoftware.com
609.489.3112