1 package nl.dedicon.pipeline.braille.impl;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Map;
6 import java.net.URI;
7
8 import com.google.common.base.MoreObjects;
9 import com.google.common.collect.ImmutableList;
10 import com.google.common.collect.ImmutableMap;
11 import java.util.Arrays;
12 import java.util.Locale;
13
14 import org.daisy.common.file.URIs;
15 import org.daisy.common.file.URLs;
16 import org.daisy.pipeline.braille.common.AbstractBrailleTranslator;
17 import org.daisy.pipeline.braille.common.AbstractTransformProvider;
18 import org.daisy.pipeline.braille.common.AbstractTransformProvider.util.Function;
19 import org.daisy.pipeline.braille.common.AbstractTransformProvider.util.Iterables;
20 import static org.daisy.pipeline.braille.common.AbstractTransformProvider.util.Iterables.concat;
21 import static org.daisy.pipeline.braille.common.AbstractTransformProvider.util.Iterables.transform;
22 import static org.daisy.pipeline.braille.common.AbstractTransformProvider.util.logCreate;
23 import static org.daisy.pipeline.braille.common.AbstractTransformProvider.util.logSelect;
24 import org.daisy.pipeline.braille.common.BrailleTranslator;
25 import org.daisy.pipeline.braille.common.BrailleTranslatorProvider;
26 import org.daisy.pipeline.braille.common.CSSStyledText;
27 import org.daisy.pipeline.braille.common.Hyphenator;
28 import org.daisy.pipeline.braille.common.HyphenatorProvider;
29 import org.daisy.pipeline.braille.common.Query;
30 import org.daisy.pipeline.braille.common.Query.Feature;
31 import org.daisy.pipeline.braille.common.Query.MutableQuery;
32 import static org.daisy.pipeline.braille.common.Query.util.mutableQuery;
33 import static org.daisy.pipeline.braille.common.Query.util.query;
34 import org.daisy.pipeline.braille.common.TransformProvider;
35 import static org.daisy.pipeline.braille.common.TransformProvider.util.dispatch;
36 import static org.daisy.pipeline.braille.common.TransformProvider.util.memoize;
37 import static org.daisy.pipeline.braille.common.util.Locales.parseLocale;
38 import org.daisy.pipeline.braille.liblouis.LiblouisTranslator;
39
40 import org.osgi.service.component.annotations.Activate;
41 import org.osgi.service.component.annotations.Component;
42 import org.osgi.service.component.annotations.Reference;
43 import org.osgi.service.component.annotations.ReferenceCardinality;
44 import org.osgi.service.component.annotations.ReferencePolicy;
45 import org.osgi.service.component.ComponentContext;
46
47 public interface DediconTranslator {
48
49 @Component(
50 name = "nl.dedicon.pipeline.braille.impl.DediconTranslator.Provider",
51 service = {
52 TransformProvider.class,
53 BrailleTranslatorProvider.class
54 }
55 )
56 public class Provider extends AbstractTransformProvider<BrailleTranslator> implements BrailleTranslatorProvider<BrailleTranslator> {
57
58 private URI href;
59
60 @Activate
61 void activate(final Map<?, ?> properties) {
62 href = URIs.asURI(URLs.getResourceFromJAR("/xml/xproc/block-translate.xpl", DediconTranslator.class));
63 }
64
65 private final static Iterable<BrailleTranslator> empty = Iterables.<BrailleTranslator>empty();
66
67 private final static List<String> supportedInput = ImmutableList.of("css", "text-css", "dtbook", "html");
68 private final static List<String> supportedOutput = ImmutableList.of("css", "braille");
69
70
71
72
73
74
75
76
77 @Override
78 protected final Iterable<BrailleTranslator> _get(Query query) {
79
80 final Query liblouisTable = query("(locale:nl_NL)");
81 Query hyphenationLocale = null;
82
83 final MutableQuery q = mutableQuery(query);
84 for (Feature f : q.removeAll("input")) {
85 if (!supportedInput.contains(f.getValue().get())) {
86 return empty;
87 }
88 }
89 for (Feature f : q.removeAll("output")) {
90 if (!supportedOutput.contains(f.getValue().get())) {
91 return empty;
92 }
93 }
94 if (q.containsKey("locale")) {
95 hyphenationLocale = mutableQuery().addAll(q.removeAll("locale"));
96 }
97 if (hyphenationLocale == null) {
98 return empty;
99 }
100 if (q.containsKey("translator")) {
101 if ("dedicon".equals(q.removeOnly("translator").getValue().get())) {
102 if (q.isEmpty()) {
103
104 Query hyphenTable = mutableQuery(hyphenationLocale).add("hyphenator", "hyphen");
105 Query fallbackHyphenationTable = mutableQuery(hyphenationLocale).add("hyphenator", "tex");
106
107 Iterable<Hyphenator> hyphenators = concat(
108 logSelect(hyphenTable, hyphenatorProvider),
109 logSelect(fallbackHyphenationTable, hyphenatorProvider)
110 );
111 return concat(
112 transform(
113 concat(
114 transform(
115 hyphenators,
116 new Function<Hyphenator, String>() {
117 @Override
118 public String _apply(Hyphenator h) {
119 return h.getIdentifier();
120 }
121 }
122 ),
123 "liblouis"
124 ),
125 new Function<String, Iterable<BrailleTranslator>>() {
126 @Override
127 public Iterable<BrailleTranslator> _apply(String hyphenator) {
128 final Query translatorQuery = mutableQuery(liblouisTable).add("hyphenator", hyphenator);
129 return transform(
130 logSelect(translatorQuery, liblouisTranslatorProvider),
131 new Function<LiblouisTranslator, BrailleTranslator>() {
132 @Override
133 public BrailleTranslator _apply(LiblouisTranslator translator) {
134 return __apply(logCreate(new TransformImpl(translatorQuery.toString(), translator)));
135 }
136 }
137 );
138 }
139 }
140 )
141 );
142 }
143 }
144 }
145 return empty;
146 }
147
148 private class TransformImpl extends AbstractBrailleTranslator {
149
150 private final FromStyledTextToBraille translator;
151 private final XProc xproc;
152
153 private TransformImpl(String translatorQuery, LiblouisTranslator translator) {
154 Map<String, String> options = ImmutableMap.of("text-transform", mutableQuery().add("id", this.getIdentifier()).toString());
155 xproc = new XProc(href, null, options);
156 this.translator = translator.fromStyledTextToBraille();
157 }
158
159 @Override
160 public XProc asXProc() {
161 return xproc;
162 }
163
164 @Override
165 public FromStyledTextToBraille fromStyledTextToBraille() {
166 return fromStyledTextToBraille;
167 }
168
169 private final FromStyledTextToBraille fromStyledTextToBraille = new FromStyledTextToBraille() {
170 @Override
171 public java.lang.Iterable<String> transform(java.lang.Iterable<CSSStyledText> styledText, int from, int to) {
172 return translator.transform(styledText, from, to);
173 }
174 };
175
176 @Override
177 public String toString() {
178 return MoreObjects.toStringHelper(DediconTranslator.class.getSimpleName())
179 .add("id", getIdentifier())
180 .add("liblouisTranslator", translator)
181 .toString();
182 }
183 }
184
185 @Reference(
186 name = "LiblouisTranslatorProvider",
187 unbind = "unbindLiblouisTranslatorProvider",
188 service = LiblouisTranslator.Provider.class,
189 cardinality = ReferenceCardinality.MULTIPLE,
190 policy = ReferencePolicy.DYNAMIC
191 )
192 protected void bindLiblouisTranslatorProvider(LiblouisTranslator.Provider provider) {
193 liblouisTranslatorProviders.add(provider);
194 }
195
196 protected void unbindLiblouisTranslatorProvider(LiblouisTranslator.Provider provider) {
197 liblouisTranslatorProviders.remove(provider);
198 liblouisTranslatorProvider.invalidateCache();
199 }
200
201 private final List<TransformProvider<LiblouisTranslator>> liblouisTranslatorProviders
202 = new ArrayList<>();
203 private final TransformProvider.util.MemoizingProvider<LiblouisTranslator> liblouisTranslatorProvider
204 = memoize(dispatch(liblouisTranslatorProviders));
205
206 @Reference(
207 name = "HyphenatorProvider",
208 unbind = "unbindHyphenatorProvider",
209 service = HyphenatorProvider.class,
210 cardinality = ReferenceCardinality.MULTIPLE,
211 policy = ReferencePolicy.DYNAMIC
212 )
213 @SuppressWarnings(
214 "unchecked"
215 )
216 protected void bindHyphenatorProvider(HyphenatorProvider<?> provider) {
217 hyphenatorProviders.add((TransformProvider<Hyphenator>) provider);
218 }
219
220 protected void unbindHyphenatorProvider(HyphenatorProvider<?> provider) {
221 hyphenatorProviders.remove((HyphenatorProvider)provider);
222 hyphenatorProvider.invalidateCache();
223 }
224
225 private final List<TransformProvider<Hyphenator>> hyphenatorProviders
226 = new ArrayList<>();
227 private final TransformProvider.util.MemoizingProvider<Hyphenator> hyphenatorProvider
228 = memoize(dispatch(hyphenatorProviders));
229
230 }
231 }