1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.search;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.Iterator;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Properties;
30 import java.util.StringTokenizer;
31
32 import org.apache.log4j.Logger;
33 import org.xnap.XNap;
34 import org.xnap.event.ListEvent;
35 import org.xnap.event.ListListener;
36 import org.xnap.event.ListSupport;
37 import org.xnap.util.FileHelper;
38
39 /***
40 * Manages search providers. SearchManager follows the singleton pattern.
41 */
42 public class SearchManager
43 {
44
45
46
47 public static String MEDIA_TYPE_FILE = "mediatypes.properties";
48
49 /***
50 * Default media type that matches anything.
51 */
52 public static MediaType MEDIA_ANYTHING = new AnythingMediaType();
53
54 /***
55 * Default media type that matches audio files.
56 */
57 public static MediaType MEDIA_AUDIO
58 = new DefaultMediaType("audio", XNap.tr("Audio"));
59
60 /***
61 * Default media type that matches document files.
62 */
63 public static MediaType MEDIA_DOCUMENTS
64 = new DefaultMediaType("text", XNap.tr("Documents"));
65
66 /***
67 * Default media type that matches image files.
68 */
69 public static MediaType MEDIA_IMAGES
70 = new DefaultMediaType("image", XNap.tr("Images"));
71
72 /***
73 * Default media type that matches software files.
74 */
75 public static MediaType MEDIA_SOFTWARE
76 = new DefaultMediaType("application", XNap.tr("Software"));
77
78 /***
79 * Default media type that matches video files.
80 */
81 public static MediaType MEDIA_VIDEO
82 = new DefaultMediaType("video", XNap.tr("Video"));
83
84 public static MediaType[] DEFAULT_MEDIA_TYPES = {
85 MEDIA_ANYTHING, MEDIA_AUDIO, MEDIA_DOCUMENTS, MEDIA_IMAGES,
86 MEDIA_SOFTWARE, MEDIA_VIDEO,
87 };
88
89
90
91 private static Logger logger = Logger.getLogger(SearchManager.class);
92 private static SearchManager instance = new SearchManager();
93
94 private SearchManagerListener listener = null;
95
96 private List providers = new LinkedList();
97 private ListSupport providerSupport = new ListSupport(this);
98
99
100
101 private SearchManager()
102 {
103 initializeMediaTypes();
104 }
105
106
107
108 /***
109 * Returns the instance of <code>SearchManager</code>.
110 */
111 public static SearchManager getInstance()
112 {
113 return instance;
114 }
115
116 public static MediaType getMediaType(String filename)
117 {
118
119 for (int i = 1; i < DEFAULT_MEDIA_TYPES.length; i++) {
120 if (DEFAULT_MEDIA_TYPES[i].matches(filename)) {
121 return DEFAULT_MEDIA_TYPES[i];
122 }
123 }
124 return null;
125 }
126
127 /***
128 * Adds <code>provider</code> to the list of available search providers.
129 */
130 public synchronized void add(SearchProvider provider)
131 {
132 providers.add(provider);
133 providerSupport.fireItemAdded(provider);
134 }
135
136 /***
137 * <code>Listener</code> is notified when a new search provider is
138 * added.
139 */
140 public synchronized void addListListener(ListListener listener)
141 {
142 providerSupport.addListListener(listener);
143 for (Iterator i = providers.iterator(); i.hasNext();) {
144 listener.itemAdded
145 (new ListEvent(this, ListEvent.ITEM_ADDED, i.next()));
146 }
147 }
148
149 /***
150 * Asks the search manager to handle <code>search</code>. The search object
151 * is passed to the listener that starts the search and displays the
152 * results. If no listener is set nothing happens.
153 *
154 * @see SearchManagerListener
155 */
156 public synchronized void handle(Search search)
157 {
158 if (listener != null) {
159 listener.handle(search);
160 }
161 }
162
163 /***
164 * Reads the extensions for the default media types from a property file.
165 */
166 public void initializeMediaTypes()
167 {
168 Properties props = new Properties();
169 InputStream in = null;
170 try {
171 File f = new File(FileHelper.getHomeDir() + MEDIA_TYPE_FILE);
172 if (f.exists()) {
173 logger.debug("reading media types file: " + f);
174 in = new FileInputStream(f);
175 props.load(in);
176 }
177 else {
178 in = FileHelper.getResourceAsStream(MEDIA_TYPE_FILE);
179 if (in != null) {
180 logger.debug("reading media types resource: "
181 + MEDIA_TYPE_FILE);
182 props.load(in);
183 }
184 else {
185 logger.debug("media types file not found");
186 }
187
188 }
189 }
190 catch (IOException e) {
191 logger.debug("could not read media types file", e);
192 }
193 finally {
194 try {
195 if (in != null) {
196 in.close();
197 }
198 }
199 catch (Exception e) {
200 }
201 }
202
203 if (props != null) {
204
205 for (int i = 1; i < DEFAULT_MEDIA_TYPES.length; i++) {
206 String key = DEFAULT_MEDIA_TYPES[i].getRealm();
207 String extensions = props.getProperty(key, "");
208 StringTokenizer t = new StringTokenizer(extensions, ";");
209
210 while (t.hasMoreTokens()) {
211 DefaultMediaType dmt
212 = (DefaultMediaType)DEFAULT_MEDIA_TYPES[i];
213 dmt.add(t.nextToken());
214 }
215 }
216 }
217 }
218
219
220 /***
221 * Removes <code>provider</code> from the list of available search
222 * providers.
223 */
224 public synchronized void remove(SearchProvider provider)
225 {
226 providers.remove(provider);
227 providerSupport.fireItemRemoved(provider);
228 }
229
230 /***
231 * <code>Listener</code> is notified when a new search provider is
232 * removed.
233 */
234 public void removeListListener(ListListener listener)
235 {
236 providerSupport.removeListListener(listener);
237 }
238
239 /***
240 * Returns a new <code>SearchContainer</code> that searches all networks.
241 */
242 public synchronized Search searchAll(SearchFilter filter)
243 {
244 SearchContainer c = new SearchContainer(filter);
245
246 for (Iterator i = providers.iterator(); i.hasNext();) {
247 c.add(((SearchProvider)i.next()).search(filter));
248 }
249
250 return c;
251 }
252
253 /***
254 * Registers <code>listener</code> as the user search handler.
255 */
256 public synchronized void setListener(SearchManagerListener listener)
257 {
258 this.listener = listener;
259 }
260
261 }