1   package org.daisy.pipeline.braille.css.saxon.impl;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import net.sf.saxon.expr.XPathContext;
7   import net.sf.saxon.lib.ExtensionFunctionCall;
8   import net.sf.saxon.lib.ExtensionFunctionDefinition;
9   import net.sf.saxon.om.NodeInfo;
10  import net.sf.saxon.om.Sequence;
11  import net.sf.saxon.om.StructuredQName;
12  import net.sf.saxon.s9api.XdmItem;
13  import net.sf.saxon.s9api.XdmNode;
14  import net.sf.saxon.trans.XPathException;
15  import net.sf.saxon.value.SequenceType;
16  
17  import org.daisy.common.saxon.SaxonInputValue;
18  import org.daisy.common.saxon.SaxonOutputValue;
19  import org.daisy.common.transform.TransformerException;
20  
21  import org.osgi.service.component.annotations.Component;
22  
23  @Component(
24  	name = "css:render-table-by",
25  	service = { ExtensionFunctionDefinition.class }
26  )
27  public class RenderTableByDefinition extends ExtensionFunctionDefinition {
28  	
29  	private static final String XMLNS_CSS = "http://www.daisy.org/ns/pipeline/braille-css";
30  	
31  	private static final StructuredQName funcname = new StructuredQName("css", XMLNS_CSS, "render-table-by");
32  	
33  	public StructuredQName getFunctionQName() {
34  		return funcname;
35  	}
36  	
37  	public SequenceType[] getArgumentTypes() {
38  		return new SequenceType[] {
39  			SequenceType.SINGLE_STRING,
40  			SequenceType.SINGLE_NODE // SINGLE_ELEMENT_NODE
41  		};
42  	}
43  	
44  	public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
45  		return SequenceType.SINGLE_NODE; // SINGLE_ELEMENT_NODE
46  	}
47  	
48  	public ExtensionFunctionCall makeCallExpression() {
49  		return new ExtensionFunctionCall() {
50  			public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
51  				try {
52  					String axes = arguments[0].head().getStringValue();
53  					NodeInfo tableElement = (NodeInfo)arguments[1].head();
54  					
55  					// FIXME: why does this not work?
56  					// URI base = new URI(tableElement.getBaseURI());
57  					List<XdmItem> result = new ArrayList<>();
58  					new TableAsList(axes)
59  					.transform(
60  						new SaxonInputValue(tableElement),
61  						new SaxonOutputValue(result::add, context.getConfiguration()))
62  					.run();
63  					if (result.size() != 1 || !(result.get(0) instanceof XdmNode))
64  						throw new RuntimeException(); // should not happen
65  					return ((XdmNode)result.get(0)).getUnderlyingNode();
66  				} catch (TransformerException e) {
67  					throw new XPathException(e.getMessage(), e.getCause());
68  				} catch (Throwable e) {
69  					throw new XPathException("Unexpected error in css:render-table-by", e);
70  				}
71  			}
72  		};
73  	}
74  }