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.SequenceType; 12 import net.sf.saxon.value.StringValue; 13 14 import org.daisy.dotify.api.table.Table; 15 import org.daisy.pipeline.braille.common.Query; 16 import static org.daisy.pipeline.braille.common.Query.util.mutableQuery; 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 import org.slf4j.Logger; 26 import org.slf4j.LoggerFactory; 27 28 @Component( 29 name = "pef:encode", 30 service = { ExtensionFunctionDefinition.class } 31 ) 32 @SuppressWarnings("serial") 33 public class EncodeDefinition extends ExtensionFunctionDefinition { 34 35 private static final StructuredQName funcname = new StructuredQName("pef", 36 "http://www.daisy.org/ns/2008/pef", "encode"); 37 38 @Reference( 39 name = "TableRegistry", 40 unbind = "-", 41 service = TableRegistry.class, 42 cardinality = ReferenceCardinality.MANDATORY, 43 policy = ReferencePolicy.STATIC 44 ) 45 protected void bindTableRegistry(TableRegistry registry) { 46 tableRegistry = registry; 47 } 48 49 private TableRegistry tableRegistry; 50 private final Query fallbackQuery = mutableQuery() 51 .add("id", "org.daisy.braille.impl.table.DefaultTableProvider.TableType.EN_US"); 52 53 @Override 54 public StructuredQName getFunctionQName() { 55 return funcname; 56 } 57 58 @Override 59 public int getMinimumNumberOfArguments() { 60 return 2; 61 } 62 63 @Override 64 public int getMaximumNumberOfArguments() { 65 return 2; 66 } 67 68 @Override 69 public SequenceType[] getArgumentTypes() { 70 return new SequenceType[] { 71 SequenceType.SINGLE_STRING, 72 SequenceType.SINGLE_STRING}; 73 } 74 75 @Override 76 public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) { 77 return SequenceType.SINGLE_STRING; 78 } 79 80 @Override 81 public ExtensionFunctionCall makeCallExpression() { 82 return new ExtensionFunctionCall() { 83 public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { 84 try { 85 Query tableQuery = query(arguments[0].head().getStringValue()); 86 String braille = arguments[1].head().getStringValue(); 87 Table table; 88 try { 89 table = tableRegistry.get(tableQuery).iterator().next(); } 90 catch (NoSuchElementException e) { 91 try { 92 table = tableRegistry.get(fallbackQuery).iterator().next(); } 93 catch (NoSuchElementException e2) { 94 throw new XPathException("Could not find a table for query: " + tableQuery); }} 95 return new StringValue(table.newBrailleConverter().toText(braille)); } 96 catch (XPathException e) { 97 throw e; } 98 catch (Throwable e) { 99 throw new XPathException("Unexpected error in pef:encode", e); } 100 } 101 }; 102 } 103 104 private static final Logger logger = LoggerFactory.getLogger(EncodeDefinition.class); 105 106 }