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