Hi,
we all know and like XSP. However, we also know quite a few of its problems.
Therefore I'd like to propose an alternative to XSP which may be, in many
cases, a viable and much easier to use option.
The basic idea has come up at least once on this list: perform a mapping
between XML space and OO space like this:
- map an XML namespace onto a class which implements certain interfaces
- map XML element names within the namespace onto method names
- pass attributes and children of the mapped element to the method.
This mapping can either be performed in a generator or a transformer. Although
the current implementation only supports the generator option, it already
features a separation of the processing functionality into a separate class
which makes the implementation of the transformer quite trivial.
--- The implementation in detail:
As the classes onto which the XML namespaces are mapped act as delegates in
the production of XML fragments, they have been called "SAXLets".
Consequently, the generator is called "SAXLetGenerator". The SAXLetGenerator
uses a SAXLetProcessor as a delegate for the processing.
The SAXLets must be implementations of avalon Components with an additional
interface SAXLet. The SAXLet interface is currently only a marker-interface
and it has to be seen, if it makes sense to get rid of it in the future.
SAXLets may implement any of the Avalon lifestyle and life-cycle interfaces to
control their management and two more interfaces to control their
configuration:
- SAXLets implementing XMLProducer will be passed a reference to an
XMLConsumer
- SAXLets implementing SitemapModelComponent will be set up like other
SitemapModelComponents
During one processing session, only on instance of each SAXLet will be created
(i.e. retrieved from the ComponentSelector).
The mapping of element names to method names is subject to the following
rules:
- some-element becomes someElement
- ELEMENT becomes eLEMENT
The mapping is currently far from being fool-proof and probably has to be
improved. Methody may be declared without parameters, or as takin an Avalon
Configuration. In the latter case, the SAXLet processor will pass attributes
and children of the mapped element to the method in the form of the
Configuration.
It's quite obvoius that the SAXLetProcessor uses reflection to lookup and
invoke the SAXLet methods. Now, I know your qualms about reflection, however,
I've come to the comclusion that reflection is quite "fast enough":
- It's the lookup of the method which takes a huge about of time. The
invocation using Method.invoke() is much faster. Therefore the implementation
caches the looked-up methods.
- Benchmarks show, that dynamic invocation is (sxcluding the lookup) still
about 30 times slower (on JDK 1.3) than static invocation. However, to put
this into perspective, I've found my machine (900MHz, intel) to take roughly
1us per dynamic invocation. Or, in other words, if a page contains 10 SAXLet
elements, the machine will spend about 10s for 1M-hits on the dynamic
invocation. I think that's a reasonable figure.
Methods may produce output three ways:
- A method may return an scalar Object. In this case the Object will be
converted to String and, wrapped in an element of the same name as the
invoking element, and sent down the pipeline.
- A method may return an array of Objects. This is the same as the scalar
case, just that ther will be an element with content for each array element.
- A method may produce SAX events on it's own. In this case the SAXLet must
implement XMLProducer, so that the reference to the consumer is available. The
XML events will be filtered through a XMLFragmentCompleter (a new utility
class) which makes sure that the XML is well-formed even in the case of
premature returns.
Excetions thrown by the SAXLet methods are caught, logged, and re-trown
wrapped in SAXExceptions.
The implementation comes with a very simple example, the RequestSAXLet, which
re-implements the functionality of the request logicsheet as a SAXLet. The
sample has ist's own sub-sitemap, the mounting of the sub-sitemap is up to
you.
--- Future stuff and RT
Obviously, XSP can do a few things that SAXLets can't do, e.g. iteration and
conditional processing of the input. However, one could argue that the need
for iteration or conditional processing is an indication for a possible mixing
of concerns. On the other hand, at least iteration and conditionals could be
implemented, albeit in a less natural way than the simple delegation of the
XML production.
Currently, the generator does not support caching. However, SAXLets could very
well implement Cacheable so that the cacheable descision could be delegated to
the SAXLets. We intend to add this RSN.
An additional performance improvement for the Generator can be achieved by
caching the input events together with the references to the SAXLets and their
methods, in order to get rid of the parsing of the input and lookup of the
namespaces that is currently necessary.
---
I suppose that some of you will hate the SAXLet approach as it is quite
incompatible with XSP and breaks all the current value-added functionality
(logicsheets). But please let your comments roll in.
Joerg Henne
saxlet.zip
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]