Skip to content

Commit

Permalink
Drop requirement that XPath extension function must be implemented in…
Browse files Browse the repository at this point in the history
… same module

as the XSLT that uses it. Check that the class can be resolved if it
is not in the same module.

See commit b3a0826.
  • Loading branch information
bertfrees committed Nov 26, 2024
1 parent e9a0e71 commit b58462c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.daisy.pipeline.modules;

/**
* Java dependency of an XSLT resource. The Java resource (class) is assumed to live in the same
* module as the XSLT resource.
* Java dependency of an XSLT resource.
*/
public class JavaDependency implements Dependency {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ public XProcResource(Component component) {
* (internal) {@link JavaDependency}. XSLT/XProc/RelaxNG resources from the same module are
* handled recursively.
*/
public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourceRoots, XMLInputFactory parser) {
return listDependencies(resource, true, false, module, resolver, sourceRoots, parser, new LinkedList<>());
public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourceRoots, ClassLoader compileClassPath,
XMLInputFactory parser) {
return listDependencies(resource, true, false, module, resolver, sourceRoots, compileClassPath, parser, new LinkedList<>());
}

/**
Expand All @@ -83,8 +84,8 @@ public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourc
* @param parser The StAX input factory for parsing the XML.
*/
private static Set<Dependency> listDependencies(URL file, boolean ensureXProc, boolean ensureXSLT, Module module,
ModuleRegistry resolver, Set<File> sourceRoots, XMLInputFactory parser,
Deque<URL> stack) {
ModuleRegistry resolver, Set<File> sourceRoots, ClassLoader compileClassPath,
XMLInputFactory parser, Deque<URL> stack) {
if (cache.containsKey(file)) {
return cache.get(file);
} else {
Expand All @@ -108,7 +109,8 @@ private static Set<Dependency> listDependencies(URL file, boolean ensureXProc, b
throw new IllegalArgumentException(
"File is not XProc: " + file + ": found root element " + name);
else if (XSLTResource.XSL_STYLESHEET.equals(name) || XSLTResource.XSL_PACKAGE.equals(name))
return XSLTResource.listDependencies(file, module, resolver, sourceRoots, parser);
return XSLTResource.listDependencies(file, module, resolver, sourceRoots,
compileClassPath, parser);
else if (ensureXSLT)
throw new IllegalArgumentException(
"File is not XSLT: " + file + ": found root element " + name);
Expand Down Expand Up @@ -144,7 +146,8 @@ else if (uri.isAbsolute()) {
stack.push(file);
dependencies.addAll(
listDependencies(URLs.resolve(URLs.asURI(file), uri).toURL(), P_IMPORT.equals(name),
CX_IMPORT.equals(name), module, resolver, sourceRoots, parser, stack));
CX_IMPORT.equals(name), module, resolver, sourceRoots, compileClassPath,
parser, stack));
stack.pop();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ public URL getResource() {
* (internal) {@link JavaDependency}. Imported/included resources from the same module are
* handled recursively.
*/
public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourceRoots, XMLInputFactory parser) {
return listDependencies(resource, module, resolver, sourceRoots, parser);
public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourceRoots, ClassLoader compileClassPath,
XMLInputFactory parser) {
return listDependencies(resource, module, resolver, sourceRoots, compileClassPath, parser);
}

/**
Expand All @@ -89,7 +90,7 @@ public Set<Dependency> listDependencies(ModuleRegistry resolver, Set<File> sourc
* @param parser The StAX input factory for parsing the XML.
*/
static Set<Dependency> listDependencies(URL xsltFile, Module module, ModuleRegistry resolver, Set<File> sourceRoots,
XMLInputFactory parser) {
ClassLoader compileClassPath, XMLInputFactory parser) {
if (cache.containsKey(xsltFile)) {
return cache.get(xsltFile);
} else {
Expand Down Expand Up @@ -126,7 +127,7 @@ static Set<Dependency> listDependencies(URL xsltFile, Module module, ModuleRegis
// resolve relative path
dependencies.addAll(
listDependencies(URLs.resolve(URLs.asURI(xsltFile), uri).toURL(), module,
resolver, sourceRoots, parser));
resolver, sourceRoots, compileClassPath, parser));
}
} else if (depth == 1 && XSL_USE_PACKAGE.equals(elemName)) {
Attribute name = elem.getAttributeByName(_NAME);
Expand All @@ -146,9 +147,10 @@ static Set<Dependency> listDependencies(URL xsltFile, Module module, ModuleRegis
// fully qualified Java class name, use the heuristic that
// ExtensionFunctionProvider classes are not in the default package.
if (FQCN.matcher(nsUri).matches() && nsUri.contains(".")) {
String className = nsUri;
// assuming it is the namespace of a XPath extension function, and the function
// is used within this element
String className = nsUri;
// try to resolve the class
String javaSourceFile = className.split("\\$")[0].replace('.', '/') + ".java";
boolean internal = false; {
if (sourceRoots != null)
Expand All @@ -158,11 +160,24 @@ static Set<Dependency> listDependencies(URL xsltFile, Module module, ModuleRegis
internal = true;
break; }}
if (!internal) {
// require that the function is implemented in the same module (and exposed
// through a public XSLT to other modules)
throw new RuntimeException(
"" + xsltFile + ": Java dependency could not be resolved: " + className
+ " (expected to be in the same module)");
// if the function is not implemented in the same module, the class must be
// on the class path and resolvable through ModuleRegistry
Class c; {
try {
c = Class.forName(className, true, compileClassPath);
} catch (Throwable e) {
throw new RuntimeException(
"" + xsltFile
+ ": Java dependency could not be resolved: class not on class path: "
+ className);
}
}
if (resolver.getModuleByClass(c) == null)
throw new RuntimeException(
"" + xsltFile
+ ": Java dependency could not be resolved: no module provides class: "
+ className);

}
dependencies.add(new JavaDependency(module, className));
}
Expand Down

0 comments on commit b58462c

Please sign in to comment.