1 package org.apache.turbine.services.mimetype.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 /***
24 * This class maintains a set of mappers defining mappings
25 * between MIME types and the corresponding file name extensions.
26 * The mappings are defined as lines formed by a MIME type name
27 * followed by a list of extensions separated by a whitespace.
28 * The definitions can be listed in MIME type files located in user's
29 * home directory, Java home directory or the current class jar.
30 * In addition, this class maintains static default mappings
31 * and constructors support application specific mappings.
32 *
33 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
34 * @version $Id: MimeTypeMap.java 264148 2005-08-29 14:21:04Z henning $
35 */
36 public class MimeTypeMap
37 {
38 /***
39 * The default MIME type when nothing else is applicable.
40 */
41 public static final MimeType DEFAULT_MIMETYPE =
42 MimeType.APPLICATION_OCTET_STREAM;
43
44 /***
45 * The default MIME type as a string.
46 */
47 public static final String DEFAULT_TYPE = DEFAULT_MIMETYPE.toString();
48
49 /***
50 * The name for MIME type mapper resources.
51 */
52 public static final String MIMETYPE_RESOURCE = "mime.types";
53
54 /***
55 * Common MIME type extensions.
56 */
57 public static final String EXT_HTML = "html";
58 public static final String EXT_HTM = "htm";
59 public static final String EXT_WML = "wml";
60 public static final String EXT_HDML = "hdml";
61 public static final String EXT_HDM = "hdm";
62 public static final String EXT_CHTML = "chtml";
63 public static final String EXT_TEXT = "txt";
64 public static final String EXT_GIF = "gif";
65 public static final String EXT_JPEG = "jpeg";
66 public static final String EXT_JPG = "jpg";
67 public static final String EXT_WBMP = "wbmp";
68
69 /***
70 * Priorities of available mappers.
71 */
72 private static final int MAP_PROG = 0;
73 private static final int MAP_HOME = 1;
74 private static final int MAP_SYS = 2;
75 private static final int MAP_JAR = 3;
76 private static final int MAP_COM = 4;
77
78 /***
79 * A common MIME type mapper.
80 */
81 private static MimeTypeMapper commonMapper = new MimeTypeMapper();
82
83 static
84 {
85 commonMapper.setContentType(
86 MimeType.TEXT_HTML.toString() + " " + EXT_HTML + " " + EXT_HTM);
87 commonMapper.setContentType(
88 MimeType.TEXT_WML.toString() + " " + EXT_WML);
89 commonMapper.setContentType(
90 MimeType.TEXT_HDML.toString() + " " + EXT_HDML + " " + EXT_HDM);
91 commonMapper.setContentType(
92 MimeType.TEXT_CHTML.toString() + " " + EXT_CHTML);
93 commonMapper.setContentType(
94 MimeType.TEXT_PLAIN.toString() + " " + EXT_TEXT);
95 commonMapper.setContentType(
96 MimeType.IMAGE_GIF.toString() + " " + EXT_GIF);
97 commonMapper.setContentType(
98 MimeType.IMAGE_JPEG.toString() + " " + EXT_JPEG + " " + EXT_JPG);
99 commonMapper.setContentType(
100 MimeType.IMAGE_WBMP.toString() + " " + EXT_WBMP);
101 }
102
103 /***
104 * An array of available MIME type mappers.
105 */
106 private MimeTypeMapper mappers[] = new MimeTypeMapper[5];
107
108 /***
109 * Loads mappings from a file path.
110 *
111 * @param path a file path.
112 * @return the mappings.
113 * @throws IOException for an incorrect file.
114 */
115 protected static MimeTypeMapper loadPath(String path)
116 throws IOException
117 {
118 return new MimeTypeMapper(path);
119 }
120
121 /***
122 * Loads mappings from a resource.
123 *
124 * @param name a resource name.
125 * @return the mappings.
126 */
127 protected static MimeTypeMapper loadResource(String name)
128 {
129 InputStream input = MimeTypeMap.class.getResourceAsStream(name);
130 if (input != null)
131 {
132 try
133 {
134 return new MimeTypeMapper(input);
135 }
136 catch (IOException x)
137 {
138 return null;
139 }
140 }
141 else
142 {
143 return null;
144 }
145 }
146
147 /***
148 * Constructs a new MIME type map with default mappers.
149 */
150 public MimeTypeMap()
151 {
152 String path;
153 try
154 {
155
156 path = System.getProperty("user.home");
157 if (path != null)
158 {
159 path = path + File.separator + MIMETYPE_RESOURCE;
160 mappers[MAP_HOME] = loadPath(path);
161 }
162 }
163 catch (Exception x)
164 {
165 }
166
167 try
168 {
169
170 path = System.getProperty("java.home") +
171 File.separator + "lib" + File.separator + MIMETYPE_RESOURCE;
172 mappers[MAP_SYS] = loadPath(path);
173 }
174 catch (Exception x)
175 {
176 }
177
178
179 mappers[MAP_JAR] = loadResource("/META-INF/" + MIMETYPE_RESOURCE);
180
181
182 mappers[MAP_COM] = commonMapper;
183 }
184
185 /***
186 * Contructs a MIME type map read from a stream.
187 *
188 * @param input an input stream.
189 * @throws IOException for an incorrect stream.
190 */
191 public MimeTypeMap(InputStream input)
192 throws IOException
193 {
194 this();
195 mappers[MAP_PROG] = new MimeTypeMapper(input);
196 }
197
198 /***
199 * Contructs a MIME type map read from a file.
200 *
201 * @param path an input file.
202 * @throws IOException for an incorrect input file.
203 */
204 public MimeTypeMap(File file)
205 throws IOException
206 {
207 this();
208 mappers[MAP_PROG] = new MimeTypeMapper(file);
209 }
210
211 /***
212 * Contructs a MIME type map read from a file path.
213 *
214 * @param path an input file path.
215 * @throws IOException for an incorrect input file.
216 */
217 public MimeTypeMap(String path)
218 throws IOException
219 {
220 this();
221 mappers[MAP_PROG] = new MimeTypeMapper(path);
222 }
223
224 /***
225 * Sets a MIME content type mapping to extensions.
226 *
227 * @param spec a MIME type extension specification to set.
228 */
229 public synchronized void setContentType(String spec)
230 {
231 if (mappers[MAP_PROG] == null)
232 {
233 mappers[MAP_PROG] = new MimeTypeMapper();
234 }
235 mappers[MAP_PROG].setContentType(spec);
236 }
237
238 /***
239 * Gets the MIME content type for a file as a string.
240 *
241 * @param file the file.
242 * @return the MIME type string.
243 */
244 public String getContentType(File file)
245 {
246 return getContentType(file.getName());
247 }
248
249 /***
250 * Gets the MIME content type for a named file as a string.
251 *
252 * @param name the name of the file.
253 * @return the MIME type string.
254 */
255 public String getContentType(String name)
256 {
257 int i = name.lastIndexOf('.');
258 if (i >= 0)
259 {
260 String ext = name.substring(i + 1);
261 return ext.length() > 0 ?
262 getContentType(ext, DEFAULT_TYPE) : DEFAULT_TYPE;
263 }
264 else
265 {
266 return DEFAULT_TYPE;
267 }
268 }
269
270 /***
271 * Gets the MIME content type for a file name extension as a string.
272 *
273 * @param ext the file name extension.
274 * @param def the default type if none is found.
275 * @return the MIME type string.
276 */
277 public String getContentType(String ext,
278 String def)
279 {
280 int i = ext.lastIndexOf('.');
281 if (i >= 0)
282 {
283 ext = ext.substring(i + 1);
284 }
285
286 String mime;
287 MimeTypeMapper mapper;
288 for (i = 0; i < mappers.length; i++)
289 {
290 mapper = mappers[i];
291 if (mapper != null)
292 {
293 mime = mapper.getContentType(ext);
294 if (mime != null)
295 {
296 return mime;
297 }
298 }
299 }
300 return def;
301 }
302
303 /***
304 * Gets the MIME content type for a file.
305 *
306 * @param file the file.
307 * @return the MIME type.
308 */
309 public MimeType getMimeContentType(File file)
310 {
311 try
312 {
313 return new MimeType(getContentType(file));
314 }
315 catch (Exception x)
316 {
317 return DEFAULT_MIMETYPE;
318 }
319 }
320
321 /***
322 * Gets the MIME content type for a named file.
323 *
324 * @param name the name of the file.
325 * @return the MIME type.
326 */
327 public MimeType getMimeContentType(String name)
328 {
329 try
330 {
331 return new MimeType(getContentType(name));
332 }
333 catch (Exception x)
334 {
335 return DEFAULT_MIMETYPE;
336 }
337 }
338
339 /***
340 * Gets the MIME content type for a file name extension.
341 *
342 * @param ext the file name extension.
343 * @param def the default type if none is found.
344 * @return the MIME type.
345 */
346 public MimeType getMimeContentType(String ext,
347 String def)
348 {
349 try
350 {
351 return new MimeType(getContentType(ext, def));
352 }
353 catch (Exception x)
354 {
355 return DEFAULT_MIMETYPE;
356 }
357 }
358
359 /***
360 * Gets the default file name extension for a MIME type.
361 * Note that the mappers are called in the reverse order.
362 *
363 * @param type the MIME type as a string.
364 * @return the file name extension or null.
365 */
366 public String getDefaultExtension(String type)
367 {
368 String ext;
369 MimeTypeMapper mapper;
370 int i = type.indexOf(';');
371 if (i >= 0)
372 {
373 type = type.substring(0, i);
374 }
375 type = type.trim();
376 for (i = mappers.length - 1; i >= 0; i--)
377 {
378 mapper = mappers[i];
379 if (mapper != null)
380 {
381 ext = mapper.getExtension(type);
382 if (ext != null)
383 {
384 return ext;
385 }
386 }
387 }
388 return null;
389 }
390
391 /***
392 * Gets the default file name extension for a MIME type.
393 * Note that the mappers are called in the reverse order.
394 *
395 * @param mime the MIME type.
396 * @return the file name extension or null.
397 */
398 public String getDefaultExtension(MimeType mime)
399 {
400 return getDefaultExtension(mime.getTypes());
401 }
402
403 /***
404 * Sets a common MIME content type mapping to extensions.
405 *
406 * @param spec a MIME type extension specification to set.
407 */
408 protected synchronized void setCommonContentType(String spec)
409 {
410 mappers[MAP_COM].setContentType(spec);
411 }
412 }