1 package org.daisy.pipeline.common.saxon.impl; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.google.common.base.CharMatcher; 7 8 import net.sf.saxon.expr.XPathContext; 9 import net.sf.saxon.lib.ExtensionFunctionCall; 10 import net.sf.saxon.lib.ExtensionFunctionDefinition; 11 import net.sf.saxon.om.Item; 12 import net.sf.saxon.om.Sequence; 13 import net.sf.saxon.om.StructuredQName; 14 import net.sf.saxon.trans.XPathException; 15 import net.sf.saxon.value.QNameValue; 16 import net.sf.saxon.value.SequenceType; 17 18 import org.osgi.service.component.annotations.Component; 19 20 import org.slf4j.helpers.MessageFormatter; 21 22 @Component( 23 name = "pf:error", 24 service = { ExtensionFunctionDefinition.class } 25 ) 26 @SuppressWarnings("serial") 27 public class ErrorDefinition extends ExtensionFunctionDefinition { 28 29 private static final StructuredQName funcname = new StructuredQName("pf", 30 "http://www.daisy.org/ns/pipeline/functions", "error"); 31 32 public StructuredQName getFunctionQName() { 33 return funcname; 34 } 35 36 @Override 37 public int getMinimumNumberOfArguments() { 38 return 2; 39 } 40 41 @Override 42 public int getMaximumNumberOfArguments() { 43 return 3; 44 } 45 46 public SequenceType[] getArgumentTypes() { 47 return new SequenceType[] { 48 SequenceType.SINGLE_STRING, 49 SequenceType.ATOMIC_SEQUENCE, 50 SequenceType.OPTIONAL_QNAME 51 }; 52 } 53 54 public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) { 55 return SequenceType.EMPTY_SEQUENCE; 56 } 57 58 public ExtensionFunctionCall makeCallExpression() { 59 return new ExtensionFunctionCall() { 60 public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { 61 try { 62 String msg = CharMatcher.WHITESPACE.trimAndCollapseFrom( 63 arguments[0].head().getStringValue(), ' '); 64 if (arguments.length > 1) { 65 String[] args = MessageDefinition.sequenceToArray(arguments[1]); 66 msg = MessageFormatter.format(msg, args).getMessage(); 67 } 68 XPathException xe = new XPathException(msg); 69 if (arguments.length > 2) { 70 Item i = arguments[2].head(); 71 if (i != null) { 72 StructuredQName code = ((QNameValue)i).getStructuredQName(); 73 xe.setErrorCodeQName(code); 74 } 75 } 76 throw xe; } 77 catch (XPathException e) { 78 throw e; } 79 catch (Throwable e) { 80 throw new XPathException("Unexpected error in pf:error", e); } 81 } 82 }; 83 } 84 }