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  }