Bug #2236
closedParameters set using Transformer.setParameter() not accessible using getParameter()
100%
Description
I had been successfully using the Java extension functions: full interface (http://www.saxonica.com/documentation/html/extensibility/integratedfunctions/ext-full-J.html) throughout the 9.5 versions.
Specifically, I was able to access a custom "global context" of the running application, to be able to access cached items and other resources. Using the standard javax.xml.transform.Transformer
API obtained from a call to Templates.newTransformer
(which was actually returned as a net.sf.saxon.Controller@) as "@t@", I was able to call @t.setParameter("myGlobalContextKey", myGlobalContext)
before calling @t.transform(...)@. Any parameters set here could be accessed by the Transformer's XSLT - as well as from the XPathContext within an ExtensionFunctionCall, by calling:
xPathContext.getController().getParameter("myGlobalContextKey")
In 9.6, this is no longer working. The value returned by getParameter is now always null. In 9.5, Controller.setParameter
was pretty straight-forward. In 9.6, this is now implemented by net.sf.saxon.jaxp.TransformerImpl.setParameter
- which among other things, will immediately return without setting anything if the parameter was not found to exist on the xsltExecutable / defined as a parameter within the XSLT.
At least in my scenarios, the XSLTs are to remain ignorant of this functionality - they should not need to define parameters within themselves, just because they may be needed internally by the other custom extension functions that they are able to call.
I have referenced the following change documentation - both of which directly seem to related to this change:
-
http://www.saxonica.com/documentation/#!changes/JAXP/9.5.1-9.6
-
http://www.saxonica.com/documentation/#!changes/s9api/9.5.1-9.6
However, I don't see an equivalent replacement of the parameter handling.
I would like to avoid referencing the Controller if at all possible, as it is now documented as "From 9.6 this class should no longer be considered a public API.". Even worse, I would not like to access its .getBindery
- documented as "This method is intended for internal use only." I don't see any other way to pass arbitrary data between a javax.xml.transform.Transformer instance and a ExtensionFunctionCall that it will call. This leaves me with 2 remaining options that I can currently see:
-
Cast the
Transformer
to aTransformerImpl@, then call its @.getUnderlyingController().setUserData(...)
method. This is documented as "This method is intended primarily for internal use, though it may also be used by advanced applications." I could then retrieve the data from the ExtensionFunctionCall using @xPathContext.getController().getUserData(...)@. -
Bypass the Saxon API entirely, and use some combination of a ThreadLocal hack combined with a Map of the current Transformer along with the custom global context I'm hoping to pass.
Any guidance or recommendations would be much appreciated. Thanks!
Please register to edit this issue