> Andrew, sounds interesting. Maintaing custom patches is never fun; > let's have a look at it.
See attached patch TypeFactory-AE-20020809.txt and new files TypeFactory.java and TypeFactoryBase.java. This builds OK on my machine, and our product runs OK with it too. As far as the patch goes, I modified my original Integer only patch to support the other data types. I basically shifted the contents of the characterData method into the TypeFactoryBase class, along with the dateformat member, and removed the ParseException import in XmlRpc. I had to modify the XmlWriter as well, since it uses the XmlRpc dateformat member. This had a TODO next to it, so I just gave it its own dateformat member. I've modified XmlRpcServer and WebServer, but not SecureWebServer, that will come if the patch is accepted. It would be nice to have a factory for creating WebServer's anyway. > JUnit tests for the existing interfaces and for any new code would be > VERY helpful as well. We use JUnit internally, so I think I could put together some basic tests: a) check that each of the methods in TypeFactory is called for a suitably crafted request. b) check the behaviour (with corner cases) of the TypeFactoryBase. c) check that an arbitrary TypeFactory instance doesn't throw an exception on an accepted set of 'legal' values. As far as tests for other interfaces go, I am interested in contributing both new code and more tests. I would like to look into restructuring the way decoding works so that thread handling on the server side can be better specified by the user. Ideally to allow the request and response to be handled by different threads. Andrew.
Index: WebServer.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.11 diff -u -r1.11 WebServer.java --- WebServer.java 20 Mar 2002 15:11:03 -0000 1.11 +++ WebServer.java 9 Aug 2002 08:45:44 -0000 @@ -157,12 +157,21 @@ } /** - * Creates a Web server at the specified port number and IP address. - */ + * Creates a Web server at the specified port number and IP address, + */ public WebServer(int port, InetAddress add) throws IOException { + this(port, add, new XmlRpcServer()); + } + + /** + * Creates a Web server at the specified port number and IP address, + * that will pass requests to the specified XmlRpcServer. + */ + public WebServer(int port, InetAddress add, XmlRpcServer xmlrpc) throws +IOException + { this.port = port; - xmlrpc = new XmlRpcServer(); + this.xmlrpc = xmlrpc; accept = new Vector(); deny = new Vector(); threadpool = new Stack(); Index: XmlRpc.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpc.java,v retrieving revision 1.27 diff -u -r1.27 XmlRpc.java --- XmlRpc.java 7 Aug 2002 17:48:59 -0000 1.27 +++ XmlRpc.java 9 Aug 2002 08:45:44 -0000 @@ -56,7 +56,6 @@ */ import java.io.InputStream; -import java.text.ParseException; import java.util.Hashtable; import java.util.Stack; import java.util.Vector; @@ -130,12 +129,6 @@ Value currentValue; /** - * Thread-safe wrapper for the <code>DateFormat</code> object used - * to parse date/time values. - */ - static DateTool dateformat = new DateTool(); - - /** * Used to collect character data (<code>CDATA</code>) of * parameter values. */ @@ -192,6 +185,22 @@ static String encoding = XmlWriter.ISO8859_1; /** + * Default factory for creating integer elements + */ + static TypeFactory staticDefaultTypeFactory = new TypeFactoryBase(); + protected TypeFactory typeFactory; + + public XmlRpc() + { + this(staticDefaultTypeFactory); + } + + public XmlRpc(TypeFactory typeFactory) + { + this.typeFactory = typeFactory; + } + + /** * Set the SAX Parser to be used. The argument can either be the * full class name or a user friendly shortcut if the parser is * known to this class. The parsers that can currently be set by @@ -604,30 +613,22 @@ switch (type) { case INTEGER: - value = new Integer(cdata.trim ()); + value = typeFactory.createInteger(cdata); break; case BOOLEAN: - value = ("1".equals(cdata.trim ()) - ? Boolean.TRUE : Boolean.FALSE); + value = typeFactory.createBoolean(cdata); break; case DOUBLE: - value = new Double(cdata.trim ()); + value = typeFactory.createDouble(cdata); break; case DATE: - try - { - value = dateformat.parse(cdata.trim()); - } - catch (ParseException p) - { - throw new RuntimeException(p.getMessage()); - } - break; + value = typeFactory.createDate(cdata); + break; case BASE64: - value = Base64.decode(cdata.getBytes()); + value = typeFactory.createBase64(cdata); break; case STRING: - value = cdata; + value = typeFactory.createString(cdata); break; case STRUCT: // this is the name to use for the next member of this struct Index: XmlRpcServer.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v retrieving revision 1.27 diff -u -r1.27 XmlRpcServer.java --- XmlRpcServer.java 7 Aug 2002 17:09:44 -0000 1.27 +++ XmlRpcServer.java 9 Aug 2002 08:45:45 -0000 @@ -85,11 +85,30 @@ private int workers; /** + * Default factory for creating integer elements + */ + static TypeFactory staticDefaultTypeFactory = new TypeFactoryBase(); + protected TypeFactory serverTypeFactory; + + /** * Construct a new XML-RPC server. You have to register handlers * to make it do something useful. */ public XmlRpcServer() { + this.serverTypeFactory = staticDefaultTypeFactory; + handlers = new Hashtable(); + pool = new Stack(); + workers = 0; + } + + /** + * Construct a new XML-RPC server with a specified factory for integers. + * You have to register handlers to make it do something useful. + */ + public XmlRpcServer(TypeFactory serverTypeFactory) + { + this.serverTypeFactory = serverTypeFactory; handlers = new Hashtable(); pool = new Stack(); workers = 0; @@ -194,6 +213,7 @@ */ protected Worker() { + super(serverTypeFactory); inParams = new Vector(); buffer = new ByteArrayOutputStream(); } Index: XmlWriter.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlWriter.java,v retrieving revision 1.2 diff -u -r1.2 XmlWriter.java --- XmlWriter.java 8 Aug 2002 21:31:50 -0000 1.2 +++ XmlWriter.java 9 Aug 2002 08:45:46 -0000 @@ -103,6 +103,12 @@ */ private static Properties encodings = new Properties(); + /** + * Thread-safe wrapper for the <code>DateFormat</code> object used + * to parse date/time values. + */ + static DateTool dateformat = new DateTool(); + static { encodings.put(UTF8, "UTF-8"); @@ -185,8 +191,7 @@ { startElement("dateTime.iso8601"); Date d = (Date) obj; - // TODO: Stop using package private variable from XmlRpc - write(XmlRpc.dateformat.format(d)); + write(dateformat.format(d)); endElement("dateTime.iso8601"); } else if (obj instanceof byte[])
TypeFactory.java
Description: Binary data
TypeFactoryBase.java
Description: Binary data