Skip to content

Commit

Permalink
modules-registry: add ability to list a module's XSLT packages
Browse files Browse the repository at this point in the history
  • Loading branch information
bertfrees committed Nov 11, 2024
1 parent c13b9d8 commit 2b30214
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 12 deletions.
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<dependency>
<groupId>org.daisy.pipeline</groupId>
<artifactId>saxon-adapter</artifactId>
<version>5.0.0</version>
<version>5.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.daisy.pipeline</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.NoSuchElementException;
import java.util.Set;

import javax.xml.stream.XMLInputFactory;

import com.google.common.collect.Iterators;

import org.daisy.common.file.URLs;
Expand All @@ -44,6 +46,7 @@ public abstract class Module {
private String title;
protected final Map<URI,Supplier<Component>> components = new HashMap<>();
private final Map<String,Supplier<Entity>> entities = new HashMap<>();
private final Map<String,XSLTPackage> xsltPackages = new HashMap<>();
private ResourceLoader loader;

private static final Logger mLogger = LoggerFactory.getLogger(Module.class);
Expand Down Expand Up @@ -258,6 +261,19 @@ protected boolean addEntity(Entity entity) {
return true;
}

protected boolean addXSLTPackage(String path, XMLInputFactory parser) throws NoSuchFileException, IllegalArgumentException {
return addXSLTPackage(new XSLTPackage(this, path, parser));
}

protected boolean addXSLTPackage(String name, String version, String path) throws NoSuchFileException {
return addXSLTPackage(new XSLTPackage(this, name, version, path));
}

protected boolean addXSLTPackage(XSLTPackage pack) {
xsltPackages.put(pack.getName(), pack);
return true;
}

/**
* Gets the name.
*/
Expand Down Expand Up @@ -361,6 +377,20 @@ public Entity getEntity(String publicId) throws NoSuchElementException, Resoluti
return e;
}

/**
* Gets the list of XSLT packages.
*/
public Iterable<XSLTPackage> getXSLTPackages() {
return xsltPackages.values();
}

/**
* Gets the XSLT package identified by the given name.
*/
public XSLTPackage getXSLTPackage(String name) {
return xsltPackages.get(name);
}

@Override
public String toString() {
return getName() + " [" + getVersion() + "]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public interface ModuleRegistry extends Iterable<Module> {
*/
public Module getModuleByEntity(String publicId);

/**
* Gets the module which has an XSLT package identified by the given name.
*/
public Module getModuleByXSLTPackage(String name);

/**
* Gets the module which has the specified class among its resources, or {@code null} if no such
* module can be found.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.daisy.pipeline.modules;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.NoSuchFileException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class XSLTPackage extends XSLTResource {

private String name;
private String version;

public XSLTPackage(Module module, String name, String version, String path) throws NoSuchFileException {
super(module, path);
this.name = name;
this.version = version != null
? version
: module.getVersion().replaceAll("-SNAPSHOT$", "");
}

public XSLTPackage(Module module, String path, XMLInputFactory parser) throws NoSuchFileException, IllegalArgumentException {
super(module, path);
getPackageNameAndVersion(getResource(), parser);
if (version == null)
version = module.getVersion().replaceAll("-SNAPSHOT$", "");
}

public String getName() {
return name;
}

public String getVersion() {
return version;
}

private void getPackageNameAndVersion(URL xsltFile, XMLInputFactory parser) throws IllegalArgumentException {
try (InputStream is = xsltFile.openStream()) {
XMLEventReader reader = parser.createXMLEventReader(is);
try {
while (reader.hasNext()) {
XMLEvent event = reader.peek();
if (event.isStartElement()) {
StartElement elem = event.asStartElement();
QName elemName = elem.getName();
if (!XSL_PACKAGE.equals(elemName))
throw new IllegalArgumentException(
"File is not a XSLT package: " + xsltFile + ": found root element " + elemName);
Attribute name = elem.getAttributeByName(_NAME);
if (name == null)
throw new IllegalArgumentException(
"" + xsltFile + ": Invalid XSLT: missing name attribute on " + elemName);
this.name = name.getValue();
Attribute version = elem.getAttributeByName(_PACKAGE_VERSION);
if (version != null)
this.version = version.getValue();
return;
}
reader.next();
}
throw new IllegalStateException("coding error"); // document without a root element: can not happen
} finally {
reader.close();
}
} catch (IOException e) {
throw new RuntimeException("Couldn't access XSLT file " + xsltFile, e);
} catch (XMLStreamException e) {
throw new RuntimeException("Couldn't parse XSLT file " + xsltFile, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public class XSLTResource {
private static final QName XSL_INCLUDE = new QName(XSLT_NS, "include");
private static final QName XSL_USE_PACKAGE = new QName(XSLT_NS, "use-package");
private static final QName _HREF = new QName("href");
private static final QName _NAME = new QName("name");
private static final QName _PACKAGE_VERSION = new QName("package-version");
protected static final QName _NAME = new QName("name");
protected static final QName _PACKAGE_VERSION = new QName("package-version");

private final URL resource;
private final Module module;
Expand All @@ -59,6 +59,10 @@ public XSLTResource(Component component) {
this.module = component.getModule();
}

public URL getResource() {
return resource;
}

/**
* List the dependencies of this resource.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.daisy.pipeline.modules.Module;
import org.daisy.pipeline.modules.ModuleRegistry;
import org.daisy.pipeline.modules.ResolutionException;
import org.daisy.pipeline.modules.XSLTPackage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -41,6 +42,7 @@ public class DefaultModuleRegistry implements ModuleRegistry {

private final HashMap<URI,Module> componentsMap = new HashMap<>();
private final HashMap<String,Module> entityMap = new HashMap<>();
private final HashMap<String,Module> xsltPackageMap = new HashMap<>();
private final HashMap<URL,Module> codeSourceLocationMap = new HashMap<>();
private final List<Module> modules = new ArrayList<>();
private Iterator<Module> nextModules;
Expand Down Expand Up @@ -165,6 +167,9 @@ else if (!modulesBeingInitialized.isEmpty()) {
// ignore entities that can not be resolved
}
}
for (XSLTPackage pack : module.getXSLTPackages()) {
xsltPackageMap.put(pack.getName(), module);
}
URL codeSourceLocation = getCodeSourceLocation(module.getClass());
if (codeSourceLocationMap.containsKey(codeSourceLocation))
throw new IllegalStateException("Not more than one module is allowed in one bundle");
Expand Down Expand Up @@ -344,6 +349,25 @@ public synchronized Iterable<String> getEntities() {
return entityMap.keySet();
}

/**
* {@link Module} objects that call this method should be aware that this may call their own
* {@link Module#resolveDependencies} method.
*/
@Override
public synchronized Module getModuleByXSLTPackage(String name) {
do {
Module module = xsltPackageMap.get(name);
if (module != null)
return module;
try {
addNextModule();
} catch (NoSuchElementException e) {
break;
}
} while (true);
return null;
}

/**
* {@link Module} objects that call this method should be aware that this may call their own
* {@link Module#resolveDependencies} method.
Expand Down
14 changes: 5 additions & 9 deletions saxon-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</parent>

<artifactId>saxon-adapter</artifactId>
<version>5.0.1-SNAPSHOT</version>
<version>5.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>

<name>DAISY Pipeline 2 :: Adapter for Saxon</name>
Expand All @@ -21,6 +21,10 @@
<groupId>org.daisy.pipeline</groupId>
<artifactId>common-utils</artifactId>
</dependency>
<dependency>
<groupId>org.daisy.pipeline</groupId>
<artifactId>modules-registry</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand All @@ -43,14 +47,6 @@
<artifactId>ds-to-spi-runtime</artifactId>
<scope>provided</scope>
</dependency>
<!--
runtime dependencies (for javax.xml.transform.URIResolver)
-->
<dependency>
<groupId>org.daisy.pipeline</groupId>
<artifactId>modules-registry</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.URIResolver;

import net.sf.saxon.Configuration;
Expand All @@ -22,6 +26,9 @@
import net.sf.saxon.xpath.XPathFactoryImpl;

import org.daisy.common.xpath.saxon.XPathFunctionRegistry;
import org.daisy.pipeline.modules.Module;
import org.daisy.pipeline.modules.ModuleRegistry;
import org.daisy.pipeline.modules.XSLTPackage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -144,6 +151,32 @@ public void addPackageDetails(PackageDetails pack) {
packages.add(pack);
}

@Reference(
name = "ModuleRegistry",
unbind = "-",
service = ModuleRegistry.class,
cardinality = ReferenceCardinality.OPTIONAL,
policy = ReferencePolicy.STATIC
)
public void setModuleRegistry(ModuleRegistry moduleRegistry) {
for (Module module : moduleRegistry) {
for (XSLTPackage pack : module.getXSLTPackages()) {
addPackageDetails(
new PackageDetails() {{
try {
nameAndVersion = new VersionedPackageName(pack.getName(), pack.getVersion());
URL url = pack.getResource();
sourceLocation = new StreamSource(url.openStream(), url.toURI().toASCIIString());
} catch (XPathException|IOException|URISyntaxException e) {
throw new IllegalStateException(
"Failed to create PackageDetails object for package '" + pack.getName() + "'", e);
}
}}
);
}
}
}

public void removePackageDetails(PackageDetails pack) {
if (packages != null)
packages.remove(pack);
Expand Down

0 comments on commit 2b30214

Please sign in to comment.