org.daisy.streamline.api.tasks.library.XsltTask Maven / Gradle / Ivy
The newest version!
package org.daisy.streamline.api.tasks.library;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.daisy.streamline.api.media.AnnotatedFile;
import org.daisy.streamline.api.media.DefaultAnnotatedFile;
import org.daisy.streamline.api.option.UserOption;
import org.daisy.streamline.api.option.UserOptionValue;
import org.daisy.streamline.api.tasks.InternalTaskException;
import org.daisy.streamline.api.tasks.ReadWriteTask;
/**
* Task that runs an XSLT conversion.
* Input file type requirement: XML
*
* @author Joel Håkansson
*/
public class XsltTask extends ReadWriteTask {
private static final Logger logger = Logger.getLogger(XsltTask.class.getCanonicalName());
private final XsltApplier applier;
final URL url;
final Map options;
List uiOptions;
/**
* Create a new XSLT task.
*
* User options are collected from the xslt itself.
*
* The following applies to an XSLT, given that the namespace
* xtd
is bound to
* https://www.ologolo.org/ns/doc/xsl
:
*
* - The value of
@xtd:desc
on any top level
* xsl:param
will be used as description
* for the parameter.
*
* The value of @xtd:default
on any top level
* xsl:param
will be used as default
* value for the parameter.
* Note: Determining the default value from @select is
* unfortunately very tricky to do from another XSLT as it requires dynamic
* XPath evaluation and, in the general cases, access to the input document
* as well.
*
* - The value of
@xtd:values
on any top level
* xsl:param
will be used to enumerate
* acceptable values for the parameter.
*
*
* @param name task name
* @param url relative path to XSLT
* @param options XSLT parameters
* @param applier an xslt applier
*/
public XsltTask(String name, URL url, Map options, XsltApplier applier) {
this(name, url, options, null, applier);
}
/**
* Creates a new XSLT task. Use system property javax.xml.transform.TransformerFactory
* to set factory implementation if needed.
* @param name the task name
* @param url the relative path to the XSLT
* @param options the xslt parameters
* @param uiOptions the options presented to a user
* @param applier xml applier
*/
public XsltTask(String name, URL url, Map options, List uiOptions, XsltApplier applier) {
super(name);
this.url = url;
this.options = options;
this.uiOptions = uiOptions;
this.applier = applier;
}
private List buildOptions() {
List ret = new ArrayList<>();
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
applier.transform(
toSource(url),
toResult(os),
toSource(this.getClass().getResource("resource-files/list-params.xsl")),
new HashMap()
);
Properties px = new Properties();
px.loadFromXML(new ByteArrayInputStream(os.toByteArray()));
for (Entry