1   package org.daisy.pipeline.braille.pef.impl;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.List;
6   import java.util.stream.Collectors;
7   
8   import com.google.common.base.Optional;
9   
10  import org.daisy.dotify.api.factory.FactoryProperties;
11  import org.daisy.dotify.api.table.Table;
12  import org.daisy.dotify.api.table.TableProvider;
13  
14  import org.daisy.pipeline.braille.common.Query;
15  import org.daisy.pipeline.braille.common.Query.MutableQuery;
16  import static org.daisy.pipeline.braille.common.Query.util.mutableQuery;
17  import org.daisy.pipeline.braille.pef.AbstractTableProvider;
18  
19  import org.osgi.service.component.annotations.Component;
20  import org.osgi.service.component.annotations.Reference;
21  import org.osgi.service.component.annotations.ReferenceCardinality;
22  import org.osgi.service.component.annotations.ReferencePolicy;
23  
24  // Note that although the name suggests it, this class doesn't use instances
25  // of the TableCatalog interface. It uses instances of the more low-level
26  // org.daisy.dotify.api.table.TableProvider directly. The name was chosen
27  // because it more or less provides the same functionality as a TableCatalog,
28  // except that it's based on the query syntax instead of ID's.
29  @Component(
30  	name = "org.daisy.pipeline.braille.pef.impl.BrailleUtilsTableCatalog",
31  	service = { org.daisy.pipeline.braille.pef.TableProvider.class }
32  )
33  public class BrailleUtilsTableCatalog extends AbstractTableProvider {
34  
35  	@Override
36  	protected Iterable<Table> _get(Query query) {
37  		MutableQuery q = mutableQuery(query);
38  		if (q.containsKey("id")) {
39  			String id = q.removeOnly("id").getValue().get();
40  			if (q.isEmpty())
41  				return get(id); }
42  		return empty;
43  	}
44  	
45  	private Iterable<Table> get(String id) {
46  		for (TableProvider p : providers)
47  			for (FactoryProperties fp : p.list())
48  				if (fp.getIdentifier().equals(id))
49  					return Optional.fromNullable(p.newFactory(id)).asSet();
50  		return empty;
51  	}
52  
53  	// list all available tables, not only those from the cache (for unit test)
54  	Collection<FactoryProperties> listAll() {
55  		return providers.stream().flatMap(p -> p.list().stream()).collect(Collectors.toList());
56  	}
57  
58  	private final static Iterable<Table> empty = Optional.<Table>absent().asSet();
59  	
60  	private final List<TableProvider> providers = new ArrayList<>();
61  	
62  	@Reference(
63  		name = "TableProvider",
64  		unbind = "-",
65  		service = TableProvider.class,
66  		cardinality = ReferenceCardinality.MULTIPLE,
67  		policy = ReferencePolicy.STATIC
68  	)
69  	public void addTableProvider(TableProvider provider) {
70  		providers.add(provider);
71  	}
72  	
73  	public void removeTableProvider(TableProvider provider) {
74  		providers.remove(provider);
75  	}
76  }