1 package org.daisy.pipeline.file.saxon.impl; 2 3 import java.net.URI; 4 import java.net.URISyntaxException; 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.Item; 10 import net.sf.saxon.om.Sequence; 11 import net.sf.saxon.om.StructuredQName; 12 import net.sf.saxon.trans.XPathException; 13 import net.sf.saxon.type.BuiltInAtomicType; 14 import net.sf.saxon.value.BooleanValue; 15 import net.sf.saxon.value.SequenceType; 16 import net.sf.saxon.value.StringValue; 17 18 import static org.daisy.pipeline.file.FileUtils.normalizeURI; 19 20 import org.osgi.service.component.annotations.Component; 21 22 @Component( 23 name = "pf:normalize-uri", 24 service = { ExtensionFunctionDefinition.class } 25 ) 26 @SuppressWarnings("serial") 27 public class NormalizeURI extends ExtensionFunctionDefinition { 28 29 private static final StructuredQName funcname = new StructuredQName( 30 "pf", 31 "http://www.daisy.org/ns/pipeline/functions", 32 "normalize-uri"); 33 34 @Override 35 public SequenceType[] getArgumentTypes() { 36 return new SequenceType[] { 37 SequenceType.OPTIONAL_STRING, 38 SequenceType.SINGLE_BOOLEAN 39 }; 40 } 41 42 @Override 43 public int getMinimumNumberOfArguments() { 44 return 1; 45 } 46 47 @Override 48 public int getMaximumNumberOfArguments() { 49 return 2; 50 } 51 52 @Override 53 public StructuredQName getFunctionQName() { 54 return funcname; 55 } 56 57 @Override 58 public SequenceType getResultType(SequenceType[] arg0) { 59 return SequenceType.SINGLE_STRING; 60 } 61 62 @Override 63 public ExtensionFunctionCall makeCallExpression() { 64 return new ExtensionFunctionCall() { 65 66 @SuppressWarnings({ "unchecked", "rawtypes" }) 67 public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { 68 try { 69 URI uri; { 70 Item i = arguments[0].head(); 71 try { 72 uri = new URI(i != null ? i.getStringValue().trim() : ""); 73 } catch (URISyntaxException e) { 74 throw new XPathException("Not a valid URI: " + i, e); 75 } 76 } 77 boolean fragment = arguments.length > 1 ? ((BooleanValue)arguments[1]).getBooleanValue() : true; 78 return new StringValue(normalizeURI(uri, !fragment).toASCIIString(), BuiltInAtomicType.STRING); 79 } catch (XPathException e) { 80 throw e; 81 } catch (Throwable e) { 82 throw new XPathException("Unexpected error in pf:normalize-uri", e); 83 } 84 } 85 }; 86 } 87 }