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