Joe Nellis wrote:
Hi Mark,
*1* TransformRepresentation doesn't seem to have a way to inject xslt
parameters. Am I missing it? Is there someone having a patch or
opinion on
how to do it? (ideas welcomed both on implementation and usage level)
This is done with the JAXP convention on the resulting
javax.xml.transform.Transformer object. Because the
TransformRepresentation
class invokes lazy initialization on the actual Transformer object, all I
did was create a wrapper to the Transformer.setParameter/getParameter
methods. This is a common use case and I've mentioned before it should
be included. JAXP is still only XSLT1.0 compliant. Eventually there
will be support for starting the transform on a named template. Saxon
already provides this but there is no JAXP equivalent yet. Also, getting
a stylesheet from an xml pre-processing directive should be supported.
public void setParameter(String key, Object value){
this.getTransformer().setParameter(key,value);
}
yep, this is surely one way of going about it, but I personally was
looking more into either
- overloading the call to the actual write() by adding an optional map
of parameters to be applied on the transformer just before the
transformation is started...
(that and setting output-parameters seems like a useful thing to have)
- having some convention on upgrading URI-request-parameters to be
applied as xslt parameters
(but that probably is way to specific)
*2* Sax-readyness:
- TransformRepresentation should be able to send output to sax.
- Equally it should be ready to get xml and xsl input from sax
- And finally the provided context-resolver should be (configurable?)
providing SAXSources rather then the current StreamSources
Could you maybe provide a code example. If sax is important then why
not DOM. Where does it end.
Good point. Looking at the available JAXP input-sources I think it would
end at having support for streams, sax and dom, no?
Why it is important is obvious (and the same reason why SaxSource and
DomSource have been added to the jaxp api in the first place):
"To avoid serializing / parsing overhead between processed that are
providing input-output to the xslt process in a format that is already
*parsed* "
Use case: think about any input to the process (that includes the
input-xml, the xslt sheet, and off course those pulled in via
xsl:include, xsl:import or document() that would be available in the
system not as a file/bytestream, but as an already *parsed* format.
Those could e.g. be
- DOM trees crafted by code
- DOM trees parsed from file and then modified by code
- output from other xslt transforms that are available as sax or dom
With today's transformer support in restlet all those inputs need to be
serialized and parsed again which is highly inefficient.
(essentially it boils down to having efficient support for a more
generic version of the two-step view pattern from Martin Fowler, see
http://martinfowler.com/eaaCatalog/twoStepView.html )
And bluntly: this need to fit generic sax-pipelining onto the restlet
system is purely mine. (having a background in the pipelines of Apache
Cocoon I see tremendous benefit of having a combination of both
programming models)
I was hoping the discussion/thought gathering could start here, and
maybe gradually/naturally point out if this should become part of or
kept separately from restlet.
I think the goal should be to expose as few operations as possible that
still cover the bulk of common use cases. I rarely use SAX so I have
yeah, but of course this depends on the scope you are taking: the "bulk
of common use cases" of restlet (scoping all restlet based projects out
there) might very well not include xslt whatsoever
applying your rule to the extreme would suggest removing what we already
have and maybe just list it as a sample?
little exposure to this particular case. As I mentioned before, if we
can keep the user from having to pull out JAXP code for anything but
fringe scenarios AND still not bloat the class with JAXP wrapper code,
that is best.
IMHO the restlet user is a programmer. If such person thinks he needs
xslt in his system, it probably is because he already knows xslt, or at
least will benefit from learning it anyway, no?
From that angle, I'm really fundamentally reconsidering how xslt
transformations are currently added into restlet. So maybe we really
should do an effort of listing the use cases?
Maybe someone could explain the backward compatability issues of this
class, because frankly, it was broken, badly, so who has been using it?
I assume documentation could help us out here quite a bit.
On the other hand: I think the current patch in issue 377 (have you
tested it?) is fixing the include/import/document issues without
changing the public interface: so I think that accounts for proper
backwards compatibility (unless you want to _keep_ support for the
broken way of working?)
As for the more fundamental approach and rethinking of xslt (and sax
pipelining in my case) I would suggest to put this in a new package all
together, how the one fades in and the other fades out (period of
deprecation) is then just a matter of being considerate enough.
Also, is there more on this RIPA protocol?
see issue 374. In case you want to test: the working code is only
available in svn-trunk.
'riap' stands for 'restlet internal application protocol' and is a
mechanism (pseudo-protocol) that allows various applications to call
upon each other to retrieve resources for further processing (this fits
in with my previous statements about avoiding serialization where possible)
being a URI-notation these calls now fall naturally under appliance of
the uniform interface. So think about this application x that needs a
resource y that is available on a configurable base-uri (whatever that
baseUri is, it should just use the context.getClientDispatcher() to get it.)
then by 'injecting' (=calling setResourceYBaseUri(...)) application x
with the appropriate baseUri, it will eventually call up that resource y
either at
file://whateverpath/y
http://external-service-provider/somepath/y
riap://component/application Z/somepath/y
this last version assumes that resource y will be made available by
another application within the same restlet 'component'
Additional Notes:
* this serialization avoidance for 'locally available' representations
is not only for xml vs sax/dom but also for avoiding java object
ser-deserialization
* the riap protocol not only avoids serialization, it also avoids noise
on the lower network network layers which you would have with traffic
towards e.g. http://localhost/publicpath Z/** (see also issue 357)
* and finally it even allows for application Z not to have a public URI,
but only an internal one (extra shielding if needed)
All in all the story here is one of flexibly decomposing your
'component' in smaller reusable/configurable/interchange-able
'applications' while assuring optimal efficiency when calling upon each
other.
I hope this clarifies some...
-marc=