Feature #5477
closed
Provide another way to specify an initializer (config file, feature, etc).
Fix Committed on Branch:
trunk
Fixed in Maintenance Release:
Description
Beginning in Saxon 9.3 we can pass in a class that implements the interface net.sf.saxon.lib.Initializer to register extension functions: https://www.saxonica.com/documentation10/index.html#!changes/command-line/9.2-9.3
"A new option -init:initializer is available on all command line interfaces. The value is the name of a user-supplied class that implements the interface net.sf.saxon.lib.Initializer; this initializer will be called during the initialization process, and may be used to set any options required on the Configuration programmatically. It is particularly useful for such tasks as registering extension functions, collations, or external object models, especially in Saxon-HE where the option does not exist to do this via a configuration file. Saxon only calls the initializer when running from the command line, but of course the same code may be invoked to perform initialization when running user application code ." (Emphasis added).
However, when using Saxon via a third-party it is not possible to perform the initialization if the application has not given you a hook. The issue exists, for example, In XMLCalabash https://github.com/ndw/xmlcalabash1/issues/335 and until recently, it was not possible to use initializer-based extensions with Schematron in Oxygen.
It's not clear to me what affordances one has in the general case. System properties, maybe. Environment variables, maybe. Configuration files, maybe.
In the short term, I can add the option to XML Calabash :-)
Philosophical question: if A calls B and B calls C, should one provide mechanisms to allow A to modify the behaviour of C without B knowing about it? Or should B be allowed to totally encapsulate C so that B is in total control of C's behaviour?
Michael Kay wrote in #note-2:
Philosophical question: if A calls B and B calls C, should one provide mechanisms to allow A to modify the behaviour of C without B knowing about it? Or should B be allowed to totally encapsulate C so that B is in total control of C's behaviour?
You could give B the some mechanism to disable the modification of C in the way that Saxon has several ALLOW_* and DISABLE_* features to control potentially dangerous things a stylesheet writer might do. In this case, if B calls C with DISABLE_INITIALIZERS set to true, then the initializer provided by A would be ignored with a warning or error.
David
Norm Tovey-Walsh wrote in #note-1:
It's not clear to me what affordances one has in the general case. System properties, maybe. Environment variables, maybe. Configuration files, maybe.
In the short term, I can add the option to XML Calabash :-)
That would be wonderful! I'm you have so much pull with XML Calabash's maintainer ;-)
I'm reminded of the problems/opportunities afforded by the JAXP TransformerFactory mechanism: if application B invokes a transformation T using this mechanism. then by tampering with environment variables or the classpath you can cause B to use an XSLT processor that's incapable of executing T or that executes it differently or incorrectly.
You can exploit this of course; you can create your own custom TransformerFactory that delegates to the Saxon TransformerFactory after setting selected configuration options.
Current fashion advices to use Dependency Injection code pattern, where construction and initialization of objects is isolated from their use.
This contrasts with early fashions of use of singletons and similar code patterns.
Rationale of Dependency Injection is that:
- It better supports decomposition and testing;
- It allows to delegate construction to the point and to the party that knows better how to construct and initialize objects.
There are many libraries both in Java and in .NET supporting this code pattern. Some of them are unobtrusive, and do not require any changes in classes to be ready for Dependency Injection.
- Category set to Configuration
- Assignee set to Michael Kay
For SaxonJ 12.x I have introduced the ability to set the Java system property SAXON_INITIALIZER
to the name of a class that implements net.sf.saxon.lib.Initialize
(the same class as currently supports -init
on the command line). If present, this will be invoked during the instantiation of a Configuration.
- Status changed from New to Closed
- Fix Committed on Branch trunk added
- Platforms Java added
Please register to edit this issue
Also available in: Atom
PDF