Jochen,
I agree with many of your points.
I would like to add my views.
The XmlWriter should be extensible.
I have been using 1.2 as a base and have made the XmlWriter a configurable parameter by using a factory. I did this so I could have automatic conversion between base XML-RPC types and my own classes.
Stream-based would be great.
Samples, examples and how-to docs would be extremely helpful for newbies.
Although it would violate the spec, typing the <struct> element would be very helpful.
i.e. <struct name="org.mshillin.util.Address">
Probably wishful thinking on the last one...
Mike
Jochen Wiedmann wrote:
Hi,
I'd like to present my view of what XML-RPC could and should be. Please, read on.
Regards,
Jochen
XML-RPC 3 =========
1.) Status of XML-RPC sources
The current source tree is obviously grown over the years and without serious attempts to reorganize. The following problems are obvious:
- Code duplication; for example, a lot of code implemented in SimpleXmlRpcClient and XmlRpc should actually have been moved to HandlerBase. Another example, user authentication and other types of HTTP header generation are handled in the various implementations of XmlRpcTransport, although it could very well be handled in a common level above.
- Architecture: The dependency between the various classes is at best non-obvious. In particular, it isn't easy to understand, what should be configured where and what component reads which configuration parameters how. Besides, a lot of configuration settings are stored in static variables (per application), although they should in fact be per client or even per request.
- Extensibility: The current framework has clearly been designed with the XML-RPC specification in mind. As a consequence, it does very well, what it is implemented for. However, it could do much more: Support for all basic Java types, the null value, serializable objects or even embedded XML documents (DOM, JDOM, JAXB) are worth being implemented.
Of course, these would be violating the XML-RPC specification. However, fact is, that most of us aren't so much interested in interoperability. A compromise might very well be, that the extensions are disabled by default and need explicit enabling by the user. In other words: The user needs to be aware, that he is violating the specification. Additionally, the violations could very well be made obvious on the protocol level by using XML namespaces.
- Performance: This is possibly not so much an issue on the client side. However, on the server side it definitely is. XML-RPC has several disadvantages in terms of performance, that could easily be fixed: In particular, it is based on large internal strings and byte arrays, although it could easily be completely streaming. Likewise, several things could easily be implemented as singletons, although they aren't or at least not by default. For example, in the recommended configuration, the XmlRpcServer's XmlHandlerMapping is initialized for any request, although (depending on the application) this initalization is quite heavy, if it involves a lot of Java reflection. A better approach would be using singletons.
2.) Goals and Non-goals
- XML-RPC 3 would *not* be defined for source code compatibility. Compatibility would be an issue, but not necessary. If required, porting should be easy.
- In view of the above, XML-RPC 3 would be defined for Java 1.3 and JAXP 1.1. In particular, it would use a SAX 2 parser (possibly still including MinML and a suitable adapter) and support the Java collections framework. Arrays, Lists would be synonyms. Vectors and Hashtables would be special cases of Lists and Maps.
- Implementation is completely based on SAX, aka streams. Unless necessary, no internal byte arrays or large strings are created.
- XML-RPC 3 should have a clearly defined architecture, based on the following objects. (For the sake of simplicity, I describe the client, although this is obviously applicable to the server.)
A new "configuration" object is being created. The purpose of the object is to hold per request data: Server URL, credentials, encoding, requested compression, whether to enable extensions, and so on. For use by derived factories, it should also contain a method
String getProperty(String);
The purpose of the "configuration" object is being passed through the various methods. For example,
XmlRpcHandler.execute(String, Vector);
would become
XmlRpcHandler.execute(Configuration, String, List);
A typical application would use a singleton configuration. Moreover, it would possibly just use an instance of XmlRpcClient with an implicit configuration and the method
client.execute(String, List)
which would simply be a shortcut for
client.execute(client.getConfiguration(), String, List);
The clients role would be basically reduced to an object factory. By default, most objects would be implemented as singletons. (The exception being SAX handlers, which need state.) In particular, the XmlHandlerMapping could easily be made a singleton.
- Ease of use: A default servlet would be added, which takes as input a list of classes (from a property file, or something similar), which are being exposed as handler classes.