1   package org.daisy.pipeline.braille.pef.saxon.impl;
2   
3   import java.util.NoSuchElementException;
4   
5   import net.sf.saxon.expr.XPathContext;
6   import net.sf.saxon.lib.ExtensionFunctionCall;
7   import net.sf.saxon.lib.ExtensionFunctionDefinition;
8   import net.sf.saxon.om.Sequence;
9   import net.sf.saxon.om.StructuredQName;
10  import net.sf.saxon.trans.XPathException;
11  import net.sf.saxon.value.EmptySequence;
12  import net.sf.saxon.value.SequenceType;
13  import net.sf.saxon.value.StringValue;
14  
15  import org.daisy.dotify.api.table.Table;
16  import org.daisy.pipeline.braille.common.Query;
17  import static org.daisy.pipeline.braille.common.Query.util.query;
18  import org.daisy.pipeline.braille.pef.TableRegistry;
19  
20  import org.osgi.service.component.annotations.Component;
21  import org.osgi.service.component.annotations.Reference;
22  import org.osgi.service.component.annotations.ReferenceCardinality;
23  import org.osgi.service.component.annotations.ReferencePolicy;
24  
25  @Component(
26  	name = "pef:get-table-id",
27  	service = { ExtensionFunctionDefinition.class }
28  )
29  public class GetTableIdDefinition extends ExtensionFunctionDefinition {
30  	
31  	private static final StructuredQName funcname = new StructuredQName("pef",
32  			"http://www.daisy.org/ns/2008/pef", "get-table-id");
33  	
34  	@Reference(
35  		name = "TableRegistry",
36  		unbind = "-",
37  		service = TableRegistry.class,
38  		cardinality = ReferenceCardinality.MANDATORY,
39  		policy = ReferencePolicy.STATIC
40  	)
41  	protected void bindTableRegistry(TableRegistry registry) {
42  		tableRegistry = registry;
43  	}
44  	
45  	private TableRegistry tableRegistry;
46  	
47  	@Override
48  	public StructuredQName getFunctionQName() {
49  		return funcname;
50  	}
51  	
52  	@Override
53  	public int getMinimumNumberOfArguments() {
54  		return 1;
55  	}
56  	
57  	@Override
58  	public int getMaximumNumberOfArguments() {
59  		return 1;
60  	}
61  	
62  	@Override
63  	public SequenceType[] getArgumentTypes() {
64  		return new SequenceType[] {
65  				SequenceType.SINGLE_STRING};
66  	}
67  	
68  	@Override
69  	public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
70  		return SequenceType.OPTIONAL_STRING;
71  	}
72  	
73  	@Override
74  	public ExtensionFunctionCall makeCallExpression() {
75  		return new ExtensionFunctionCall() {
76  			public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
77  				try {
78  					Query tableQuery = query(arguments[0].head().getStringValue());
79  					Table table;
80  					try {
81  						table = tableRegistry.get(tableQuery).iterator().next(); }
82  					catch (NoSuchElementException e) {
83  						return EmptySequence.getInstance(); }
84  					return new StringValue(table.getIdentifier()); }
85  				catch (Throwable e) {
86  					throw new XPathException("Unexpected error in pef:get-table-id", e); }
87  			}
88  		};
89  	}
90  }