1   package org.daisy.pipeline.braille.liblouis.pef.impl;
2   
3   import java.util.Set;
4   
5   import com.google.common.base.Function;
6   import com.google.common.base.Optional;
7   import static com.google.common.base.Predicates.notNull;
8   import com.google.common.collect.ImmutableSet;
9   import static com.google.common.collect.Iterables.filter;
10  import static com.google.common.collect.Iterables.transform;
11  
12  import org.daisy.dotify.api.factory.AbstractFactory;
13  import org.daisy.dotify.api.table.BrailleConverter;
14  import org.daisy.dotify.api.table.Table;
15  
16  import org.daisy.pipeline.braille.common.Query;
17  import org.daisy.pipeline.braille.common.Query.Feature;
18  import org.daisy.pipeline.braille.common.Query.MutableQuery;
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.liblouis.impl.LiblouisTableJnaImplProvider;
22  import org.daisy.pipeline.braille.liblouis.impl.LiblouisTableJnaImplProvider.LiblouisTableJnaImpl;
23  import org.daisy.pipeline.braille.liblouis.pef.LiblouisDisplayTableBrailleConverter;
24  import org.daisy.pipeline.braille.pef.AbstractTableProvider;
25  import org.daisy.pipeline.braille.pef.TableProvider;
26  
27  import org.liblouis.Translator;
28  
29  import org.osgi.service.component.annotations.Activate;
30  import org.osgi.service.component.annotations.Component;
31  import org.osgi.service.component.annotations.Reference;
32  import org.osgi.service.component.annotations.ReferenceCardinality;
33  import org.osgi.service.component.annotations.ReferencePolicy;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  @Component(
38  	name = "org.daisy.pipeline.braille.liblouis.pef.impl.LiblouisDisplayTableProvider",
39  	service = {
40  		TableProvider.class
41  		// org.daisy.dotify.api.table.TableProvider.class
42  	}
43  )
44  public class LiblouisDisplayTableProvider extends AbstractTableProvider {
45  	
46  	private LiblouisTableJnaImplProvider tableProvider;
47  	
48  	@Reference(
49  		name = "LiblouisTableJnaImplProvider",
50  		unbind = "-",
51  		service = LiblouisTableJnaImplProvider.class,
52  		cardinality = ReferenceCardinality.MANDATORY,
53  		policy = ReferencePolicy.STATIC
54  	)
55  	protected void bindLiblouisTableJnaImplProvider(LiblouisTableJnaImplProvider provider) {
56  		tableProvider = provider;
57  	}
58  	
59  	protected void unbindLiblouisTableJnaImplProvider(LiblouisTableJnaImplProvider provider) {
60  		tableProvider = null;
61  	}
62  
63  	@Activate
64  	protected void init() {
65  		// pre-load a selection of tables in order to expose them in preview-table dropdown list
66  		for (Table t : get(query("(liblouis-table:'http://www.liblouis.org/tables/nl-print.dis')"))); // needed for include-pdf option
67  	}
68  
69  	private static Set<String> supportedFeatures = ImmutableSet.of("liblouis-table", "locale", "id");
70  
71  	@Override
72  	protected Iterable<Table> _get(Query query) {
73  		for (Feature feature : query)
74  			if (!supportedFeatures.contains(feature.getKey())) {
75  				logger.debug("Unsupported feature: " + feature);
76  				return empty; }
77  		MutableQuery q = mutableQuery(query);
78  		if (q.containsKey("id")) {
79  			String id = q.removeOnly("id").getValue().get();
80  			if (!q.isEmpty())
81  				return empty;
82  			q.add("liblouis-table", id); }
83  		if (!q.containsKey("liblouis-table"))
84  			q.add("type", "display");
85  		return filter(
86  			transform(
87  				tableProvider.get(q),
88  				new Function<LiblouisTableJnaImpl,Table>() {
89  					public Table apply(LiblouisTableJnaImpl table) {
90  						String displayName = table.getDisplayName();
91  						if (displayName == null) {
92  							String id = table.getTranslator().getTable();
93  							if (id.startsWith("http://www.liblouis.org/tables/")) // default path
94  								id = id.substring("http://www.liblouis.org/tables/".length());
95  							displayName = "Liblouis table '" + id + "'";
96  						}
97  						String description = null;
98  						if ("http://www.liblouis.org/tables/nl-print.dis".equals(table.getTranslator().getTable()))
99  							// FIXME: move description to Liblouis
100 							description = "Table for Dutch that maps dot patterns to their original meaning as much as possible.";
101 						return new LiblouisDisplayTable(table.getTranslator(), displayName, description); }}),
102 			notNull());
103 	}
104 	
105 	private final static Iterable<Table> empty = Optional.<Table>absent().asSet();
106 	
107 	@SuppressWarnings("serial")
108 	private static class LiblouisDisplayTable extends AbstractFactory implements Table {
109 		
110 		final Translator table;
111 		
112 		private LiblouisDisplayTable(Translator table, String displayName, String description) {
113 			super(displayName, description, table.getTable());
114 			this.table = table;
115 		}
116 		
117 		public BrailleConverter newBrailleConverter() {
118 			return new LiblouisDisplayTableBrailleConverter(table.asDisplayTable());
119 		}
120 		
121 		public void setFeature(String key, Object value) {
122 			throw new IllegalArgumentException("Unknown feature: " + key);
123 		}
124 		
125 		public Object getFeature(String key) {
126 			throw new IllegalArgumentException("Unknown feature: " + key);
127 		}
128 		
129 		public Object getProperty(String key) {
130 			return null;
131 		}
132 	}
133 		
134 	private static final Logger logger = LoggerFactory.getLogger(LiblouisDisplayTableProvider.class);
135 	
136 }