Project

Profile

Help

Feature #5477

open

Provide another way to specify an initializer (config file, feature, etc).

Added by David Cramer 9 days ago. Updated 7 days ago.

Status:
New
Priority:
Low
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2022-05-06
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

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.

Actions #1

Updated by Norm Tovey-Walsh 8 days ago

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 :-)

Actions #2

Updated by Michael Kay 8 days ago

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?

Actions #3

Updated by David Cramer 8 days ago

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

Actions #4

Updated by David Cramer 8 days ago

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 ;-)

Actions #5

Updated by Michael Kay 8 days ago

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.

Actions #6

Updated by Vladimir Nesterovsky 7 days ago

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:

  1. It better supports decomposition and testing;
  2. 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.

Please register to edit this issue

Also available in: Atom PDF