1 package nl.dedicon.pipeline.braille.calabash.impl;
2
3 import com.xmlcalabash.core.XProcException;
4 import com.xmlcalabash.core.XProcRuntime;
5 import com.xmlcalabash.core.XProcStep;
6 import com.xmlcalabash.io.ReadablePipe;
7 import com.xmlcalabash.io.WritablePipe;
8 import com.xmlcalabash.library.DefaultStep;
9 import com.xmlcalabash.runtime.XAtomicStep;
10 import java.io.InputStream;
11 import java.net.URL;
12 import java.util.ArrayList;
13 import java.util.List;
14 import net.sf.saxon.om.NodeInfo;
15 import net.sf.saxon.s9api.QName;
16 import net.sf.saxon.s9api.SaxonApiException;
17 import net.sf.saxon.s9api.XQueryCompiler;
18 import net.sf.saxon.s9api.XQueryEvaluator;
19 import net.sf.saxon.s9api.XQueryExecutable;
20 import net.sf.saxon.s9api.XdmAtomicValue;
21 import net.sf.saxon.s9api.XdmItem;
22 import net.sf.saxon.s9api.XdmNode;
23 import net.sf.saxon.s9api.XdmValue;
24 import org.daisy.braille.api.embosser.FileFormat;
25 import org.daisy.common.xproc.calabash.XProcStepProvider;
26 import static org.daisy.pipeline.braille.common.Provider.util.dispatch;
27 import static org.daisy.pipeline.braille.common.Provider.util.memoize;
28 import org.daisy.pipeline.braille.common.Provider.util.MemoizingProvider;
29 import org.daisy.pipeline.braille.common.Query;
30 import static org.daisy.pipeline.braille.common.Query.util.mutableQuery;
31 import static org.daisy.pipeline.braille.common.Query.util.query;
32 import org.daisy.pipeline.braille.pef.FileFormatProvider;
33 import org.osgi.service.component.annotations.Component;
34 import org.osgi.service.component.annotations.Reference;
35 import org.osgi.service.component.annotations.ReferenceCardinality;
36 import org.osgi.service.component.annotations.ReferencePolicy;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45 public class BrlUrisStep extends DefaultStep {
46
47 private static final String DEDICON_NAMESPACE = "http://www.dedicon.nl";
48
49 private static final Logger logger = LoggerFactory.getLogger(MetadataStep.class);
50
51 private static final QName _xquery = new QName("xquery");
52 private static final QName _brf_dir_href = new QName("brf-dir-href");
53 private static final QName _brf_file_extension = new QName("brf-file-extension");
54 private static final QName _brf_file_format = new QName("brf-file-format");
55 private static final QName _brf_name_pattern = new QName("brf-name-pattern");
56 private static final QName _brf_number_width = new QName("brf-number-width");
57
58 private final MemoizingProvider<Query,FileFormat> fileFormatProvider;
59
60 private ReadablePipe source = null;
61 private WritablePipe result = null;
62
63 private BrlUrisStep(XProcRuntime runtime, XAtomicStep step, MemoizingProvider<Query,FileFormat> fileFormatProvider) {
64 super(runtime, step);
65 this.fileFormatProvider = fileFormatProvider;
66 }
67
68 @Override
69 public void setInput(String port, ReadablePipe pipe) {
70 source = pipe;
71 }
72
73 @Override
74 public void setOutput(String port, WritablePipe pipe) {
75 result = pipe;
76 }
77
78 @Override
79 public void reset() {
80 source.resetReader();
81 result.resetWriter();
82 }
83
84 @Override
85 public void run() throws SaxonApiException {
86 super.run();
87
88 try {
89
90 XdmNode pef = source.read();
91
92 String xquery = getOption(_xquery, "");
93 String brfDirHref = getOption(_brf_dir_href, "");
94 String brfFileFormat = getOption(_brf_file_format, "");
95 String brfNamePattern = getOption(_brf_name_pattern, "");
96 int brfNumberWidth = getOption(_brf_number_width, 0);
97
98 String brfFileExtension = getFileExtension(brfFileFormat);
99 InputStream query = new URL(xquery).openConnection().getInputStream();
100
101 XQueryCompiler xqCompiler = runtime.getProcessor().newXQueryCompiler();
102
103 XQueryExecutable xqExecutable = xqCompiler.compile(query);
104 XQueryEvaluator xqEvaluator = xqExecutable.load();
105
106 xqEvaluator.setSource(pef.asSource());
107 xqEvaluator.setExternalVariable(_brf_dir_href, new XdmAtomicValue(brfDirHref));
108 xqEvaluator.setExternalVariable(_brf_name_pattern, new XdmAtomicValue(brfNamePattern));
109 xqEvaluator.setExternalVariable(_brf_number_width, new XdmAtomicValue(brfNumberWidth));
110 xqEvaluator.setExternalVariable(_brf_file_extension, new XdmAtomicValue(brfFileExtension));
111
112 XdmValue xqResult = xqEvaluator.evaluate();
113
114 for (XdmValue xqValue : xqResult) {
115 if (xqValue instanceof XdmNode) {
116 result.write((XdmNode)xqValue);
117 }
118 };
119
120 } catch (Exception e) {
121
122 logger.error("dedicon:brl-uris failed", e);
123 throw new XProcException(step.getNode(), e);
124
125 }
126 }
127
128 private String getFileExtension (String fileFormatQuery) {
129 Query.MutableQuery q = mutableQuery(query(fileFormatQuery));
130 Iterable<FileFormat> fileFormats = fileFormatProvider.get(q);
131 String fileExtension = "";
132 for (FileFormat fileFormat : fileFormats) {
133 fileExtension = fileFormat.getFileExtension();
134 break;
135 }
136 return fileExtension;
137 }
138
139 @Component(
140 name = "dedicon:brl-uris",
141 service = {XProcStepProvider.class},
142 property = {"type:String={http://www.dedicon.nl}brl-uris"}
143 )
144 public static class Provider implements XProcStepProvider {
145
146 private List<FileFormatProvider> fileFormatProviders = new ArrayList<>();
147 private MemoizingProvider<Query,FileFormat> fileFormatProvider = memoize(dispatch(fileFormatProviders));
148
149 @Override
150 public XProcStep newStep(XProcRuntime runtime, XAtomicStep step) {
151 return new BrlUrisStep(runtime, step, fileFormatProvider);
152 }
153
154 @Reference(
155 name = "FileFormatProvider",
156 unbind = "unbindFileFormatProvider",
157 service = FileFormatProvider.class,
158 cardinality = ReferenceCardinality.MULTIPLE,
159 policy = ReferencePolicy.DYNAMIC
160 )
161 protected void bindFileFormatProvider(FileFormatProvider provider) {
162 fileFormatProviders.add(provider);
163 }
164
165 protected void unbindFileFormatProvider(FileFormatProvider provider) {
166 fileFormatProviders.remove(provider);
167 this.fileFormatProvider.invalidateCache();
168 }
169 }
170 }