1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.jsword.book.filter;
21  
22  import java.util.HashMap;
23  import java.util.Locale;
24  import java.util.Map;
25  
26  import org.crosswire.common.util.PluginUtil;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  /**
31   * A simple container for all the known SourceFilters.
32   * 
33   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
34   * @author Joe Walker
35   */
36  public final class SourceFilterFactory {
37      /**
38       * Prevent instantiation
39       */
40      private SourceFilterFactory() {
41      }
42  
43      /**
44       * Find a filter given a lookup string. If lookup is null or the filter is
45       * not found then the default filter will be used.
46       * 
47       * @param lookup the lookup string for the filter
48       * @return the matching filter
49       */
50      public static SourceFilter getFilter(String lookup) {
51          SourceFilter reply = filters.get(lookup.toLowerCase(Locale.ENGLISH));
52  
53          if (reply == null) {
54              reply = deft;
55          }
56  
57          return reply.clone();
58      }
59  
60      /**
61       * Find a filter given a lookup string
62       * 
63       * @return the default filter
64       */
65      public static SourceFilter getDefaultFilter() {
66          return deft.clone();
67      }
68  
69      /**
70       * Add to our list of known filters
71       * 
72       * @param name 
73       * @param instance 
74       */
75      public static void addFilter(String name, SourceFilter instance) {
76          filters.put(name.toLowerCase(Locale.ENGLISH), instance);
77      }
78  
79      /**
80       * The lookup table of filters
81       */
82      private static Map<String, SourceFilter> filters = new HashMap<String, SourceFilter>();
83  
84      /**
85       * The log stream
86       */
87      private static final Logger log = LoggerFactory.getLogger(SourceFilterFactory.class);
88  
89      /**
90       * The lookup table of filters
91       */
92      private static volatile SourceFilter deft;
93  
94      /**
95       * Populate the lookup table of filters and the default from the properties
96       * file.
97       */
98      static {
99          Map<String, Class<SourceFilter>> map = PluginUtil.getImplementorsMap(SourceFilter.class);
100 
101         // the default value
102         try {
103             Class<SourceFilter> cdeft = map.remove("default");
104             deft = cdeft.newInstance();
105         } catch (InstantiationException e) {
106             log.error("Failed to get default filter, will attempt to use first", e);
107         } catch (IllegalAccessException e) {
108             log.error("Failed to get default filter, will attempt to use first", e);
109         }
110 
111         // the lookup table
112         SourceFilter instance = null;
113         for (Map.Entry<String, Class<SourceFilter>> entry : map.entrySet()) {
114             try {
115                 Class<SourceFilter> clazz = entry.getValue();
116                 instance = clazz.newInstance();
117                 addFilter(entry.getKey(), instance);
118             } catch (InstantiationException ex) {
119                 log.error("Failed to add filter", ex);
120             } catch (IllegalAccessException ex) {
121                 log.error("Failed to add filter", ex);
122             }
123         }
124 
125         // if the default didn't work then make a stab at an answer
126         if (deft == null) {
127             deft = instance;
128         }
129     }
130 }
131