1 |
771 |
jeremybenn |
/* MimeTypeMapper.java -- A class for mapping file names to MIME types
|
2 |
|
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
3 |
|
|
|
4 |
|
|
This file is part of GNU Classpath.
|
5 |
|
|
|
6 |
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
7 |
|
|
it under the terms of the GNU General Public License as published by
|
8 |
|
|
the Free Software Foundation; either version 2, or (at your option)
|
9 |
|
|
any later version.
|
10 |
|
|
|
11 |
|
|
GNU Classpath is distributed in the hope that it will be useful, but
|
12 |
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
|
|
General Public License for more details.
|
15 |
|
|
|
16 |
|
|
You should have received a copy of the GNU General Public License
|
17 |
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
18 |
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 |
|
|
02110-1301 USA.
|
20 |
|
|
|
21 |
|
|
Linking this library statically or dynamically with other modules is
|
22 |
|
|
making a combined work based on this library. Thus, the terms and
|
23 |
|
|
conditions of the GNU General Public License cover the whole
|
24 |
|
|
combination.
|
25 |
|
|
|
26 |
|
|
As a special exception, the copyright holders of this library give you
|
27 |
|
|
permission to link this library with independent modules to produce an
|
28 |
|
|
executable, regardless of the license terms of these independent
|
29 |
|
|
modules, and to copy and distribute the resulting executable under
|
30 |
|
|
terms of your choice, provided that you also meet, for each linked
|
31 |
|
|
independent module, the terms and conditions of the license of that
|
32 |
|
|
module. An independent module is a module which is not derived from
|
33 |
|
|
or based on this library. If you modify this library, you may extend
|
34 |
|
|
this exception to your version of the library, but you are not
|
35 |
|
|
obligated to do so. If you do not wish to do so, delete this
|
36 |
|
|
exception statement from your version. */
|
37 |
|
|
|
38 |
|
|
package java.net;
|
39 |
|
|
|
40 |
|
|
import gnu.classpath.SystemProperties;
|
41 |
|
|
|
42 |
|
|
import java.io.FileReader;
|
43 |
|
|
import java.io.IOException;
|
44 |
|
|
import java.io.LineNumberReader;
|
45 |
|
|
import java.util.Hashtable;
|
46 |
|
|
import java.util.Iterator;
|
47 |
|
|
import java.util.Map;
|
48 |
|
|
import java.util.NoSuchElementException;
|
49 |
|
|
import java.util.StringTokenizer;
|
50 |
|
|
import java.util.TreeMap;
|
51 |
|
|
|
52 |
|
|
|
53 |
|
|
/**
|
54 |
|
|
* This non-public class is used to implement the FileNameMap interface
|
55 |
|
|
* which defines a mechanism for mapping filenames to MIME types.
|
56 |
|
|
*
|
57 |
|
|
* @version 0.5
|
58 |
|
|
*
|
59 |
|
|
* @author Aaron M. Renn (arenn@urbanophile.com)
|
60 |
|
|
*/
|
61 |
|
|
class MimeTypeMapper implements FileNameMap
|
62 |
|
|
{
|
63 |
|
|
/**
|
64 |
|
|
* This array of strings is used to identify a MIME type based on a file
|
65 |
|
|
* extension. This is list is based on the Apache mime.types file.
|
66 |
|
|
*/
|
67 |
|
|
protected static final String[][] mime_strings =
|
68 |
|
|
{
|
69 |
|
|
{ "ai", "application/postscript" }
|
70 |
|
|
, { "aif", "audio/x-aiff" }
|
71 |
|
|
, { "aifc", "audio/x-aiff" }
|
72 |
|
|
, { "aiff", "audio/x-aiff" }
|
73 |
|
|
, { "asc", "text/plain" }
|
74 |
|
|
, { "au", "audio/basic" }
|
75 |
|
|
, { "avi", "video/x-msvideo" }
|
76 |
|
|
, { "bcpio", "application/x-bcpio" }
|
77 |
|
|
, { "bin", "application/octet-stream" }
|
78 |
|
|
, { "bmp", "image/bmp" }
|
79 |
|
|
, { "bz2", "application/x-bzip2" }
|
80 |
|
|
, { "cdf", "application/x-netcdf" }
|
81 |
|
|
, { "chrt", "application/x-kchart" }
|
82 |
|
|
, { "class", "application/octet-stream" }
|
83 |
|
|
, { "cpio", "application/x-cpio" }
|
84 |
|
|
, { "cpt", "application/mac-compactpro" }
|
85 |
|
|
, { "csh", "application/x-csh" }
|
86 |
|
|
, { "css", "text/css" }
|
87 |
|
|
, { "dcr", "application/x-director" }
|
88 |
|
|
, { "dir", "application/x-director" }
|
89 |
|
|
, { "djv", "image/vnd.djvu" }
|
90 |
|
|
, { "djvu", "image/vnd.djvu" }
|
91 |
|
|
, { "dll", "application/octet-stream" }
|
92 |
|
|
, { "dms", "application/octet-stream" }
|
93 |
|
|
, { "doc", "application/msword" }
|
94 |
|
|
, { "dvi", "application/x-dvi" }
|
95 |
|
|
, { "dxr", "application/x-director" }
|
96 |
|
|
, { "eps", "application/postscript" }
|
97 |
|
|
, { "etx", "text/x-setext" }
|
98 |
|
|
, { "exe", "application/octet-stream" }
|
99 |
|
|
, { "ez", "application/andrew-inset" }
|
100 |
|
|
, { "gif", "image/gif" }
|
101 |
|
|
, { "gtar", "application/x-gtar" }
|
102 |
|
|
, { "gz", "application/x-gzip" }
|
103 |
|
|
, { "hdf", "application/x-hdf" }
|
104 |
|
|
, { "hqx", "application/mac-binhex40" }
|
105 |
|
|
, { "htm", "text/html" }
|
106 |
|
|
, { "html", "text/html" }
|
107 |
|
|
, { "ice", "x-conference/x-cooltalk" }
|
108 |
|
|
, { "ief", "image/ief" }
|
109 |
|
|
, { "iges", "model/iges" }
|
110 |
|
|
, { "igs", "model/iges" }
|
111 |
|
|
, { "img", "application/octet-stream" }
|
112 |
|
|
, { "iso", "application/octet-stream" }
|
113 |
|
|
, { "jpe", "image/jpeg" }
|
114 |
|
|
, { "jpeg", "image/jpeg" }
|
115 |
|
|
, { "jpg", "image/jpeg" }
|
116 |
|
|
, { "js", "application/x-javascript" }
|
117 |
|
|
, { "kar", "audio/midi" }
|
118 |
|
|
, { "kil", "application/x-killustrator" }
|
119 |
|
|
, { "kpr", "application/x-kpresenter" }
|
120 |
|
|
, { "kpt", "application/x-kpresenter" }
|
121 |
|
|
, { "ksp", "application/x-kspread" }
|
122 |
|
|
, { "kwd", "application/x-kword" }
|
123 |
|
|
, { "kwt", "application/x-kword" }
|
124 |
|
|
, { "latex", "application/x-latex" }
|
125 |
|
|
, { "lha", "application/octet-stream" }
|
126 |
|
|
, { "lzh", "application/octet-stream" }
|
127 |
|
|
, { "m3u", "audio/x-mpegurl" }
|
128 |
|
|
, { "man", "application/x-troff-man" }
|
129 |
|
|
, { "me", "application/x-troff-me" }
|
130 |
|
|
, { "mesh", "model/mesh" }
|
131 |
|
|
, { "mid", "audio/midi" }
|
132 |
|
|
, { "midi", "audio/midi" }
|
133 |
|
|
, { "mif", "application/vnd.mif" }
|
134 |
|
|
, { "mov", "video/quicktime" }
|
135 |
|
|
, { "movie", "video/x-sgi-movie" }
|
136 |
|
|
, { "mp2", "audio/mpeg" }
|
137 |
|
|
, { "mp3", "audio/mpeg" }
|
138 |
|
|
, { "mpe", "video/mpeg" }
|
139 |
|
|
, { "mpeg", "video/mpeg" }
|
140 |
|
|
, { "mpg", "video/mpeg" }
|
141 |
|
|
, { "mpga", "audio/mpeg" }
|
142 |
|
|
, { "ms", "application/x-troff-ms" }
|
143 |
|
|
, { "msh", "model/mesh" }
|
144 |
|
|
, { "mxu", "video/vnd.mpegurl" }
|
145 |
|
|
, { "nc", "application/x-netcdf" }
|
146 |
|
|
, { "ogg", "application/ogg" }
|
147 |
|
|
, { "pbm", "image/x-portable-bitmap" }
|
148 |
|
|
, { "pdb", "chemical/x-pdb" }
|
149 |
|
|
, { "pdf", "application/pdf" }
|
150 |
|
|
, { "pgm", "image/x-portable-graymap" }
|
151 |
|
|
, { "pgn", "application/x-chess-pgn" }
|
152 |
|
|
, { "png", "image/png" }
|
153 |
|
|
, { "pnm", "image/x-portable-anymap" }
|
154 |
|
|
, { "ppm", "image/x-portable-pixmap" }
|
155 |
|
|
, { "ppt", "application/vnd.ms-powerpoint" }
|
156 |
|
|
, { "ps", "application/postscript" }
|
157 |
|
|
, { "qt", "video/quicktime" }
|
158 |
|
|
, { "ra", "audio/x-realaudio" }
|
159 |
|
|
, { "ram", "audio/x-pn-realaudio" }
|
160 |
|
|
, { "ras", "image/x-cmu-raster" }
|
161 |
|
|
, { "rgb", "image/x-rgb" }
|
162 |
|
|
, { "rm", "audio/x-pn-realaudio" }
|
163 |
|
|
, { "roff", "application/x-troff" }
|
164 |
|
|
, { "rpm", "application/x-rpm" }
|
165 |
|
|
, { "rtf", "text/rtf" }
|
166 |
|
|
, { "rtx", "text/richtext" }
|
167 |
|
|
, { "sgm", "text/sgml" }
|
168 |
|
|
, { "sgml", "text/sgml" }
|
169 |
|
|
, { "sh", "application/x-sh" }
|
170 |
|
|
, { "shar", "application/x-shar" }
|
171 |
|
|
, { "silo", "model/mesh" }
|
172 |
|
|
, { "sit", "application/x-stuffit" }
|
173 |
|
|
, { "skd", "application/x-koan" }
|
174 |
|
|
, { "skm", "application/x-koan" }
|
175 |
|
|
, { "skp", "application/x-koan" }
|
176 |
|
|
, { "skt", "application/x-koan" }
|
177 |
|
|
, { "smi", "application/smil" }
|
178 |
|
|
, { "smil", "application/smil" }
|
179 |
|
|
, { "snd", "audio/basic" }
|
180 |
|
|
, { "so", "application/octet-stream" }
|
181 |
|
|
, { "spl", "application/x-futuresplash" }
|
182 |
|
|
, { "src", "application/x-wais-source" }
|
183 |
|
|
, { "stc", "application/vnd.sun.xml.calc.template" }
|
184 |
|
|
, { "std", "application/vnd.sun.xml.draw.template" }
|
185 |
|
|
, { "sti", "application/vnd.sun.xml.impress.template" }
|
186 |
|
|
, { "stw", "application/vnd.sun.xml.writer.template" }
|
187 |
|
|
, { "sv4cpio", "application/x-sv4cpio" }
|
188 |
|
|
, { "sv4crc", "application/x-sv4crc" }
|
189 |
|
|
, { "swf", "application/x-shockwave-flash" }
|
190 |
|
|
, { "sxc", "application/vnd.sun.xml.calc" }
|
191 |
|
|
, { "sxd", "application/vnd.sun.xml.draw" }
|
192 |
|
|
, { "sxg", "application/vnd.sun.xml.writer.global" }
|
193 |
|
|
, { "sxi", "application/vnd.sun.xml.impress" }
|
194 |
|
|
, { "sxm", "application/vnd.sun.xml.math" }
|
195 |
|
|
, { "sxw", "application/vnd.sun.xml.writer" }
|
196 |
|
|
, { "t", "application/x-troff" }
|
197 |
|
|
, { "tar", "application/x-tar" }
|
198 |
|
|
, { "tcl", "application/x-tcl" }
|
199 |
|
|
, { "tex", "application/x-tex" }
|
200 |
|
|
, { "texi", "application/x-texinfo" }
|
201 |
|
|
, { "texinfo", "application/x-texinfo" }
|
202 |
|
|
, { "tgz", "application/x-gzip" }
|
203 |
|
|
, { "tif", "image/tiff" }
|
204 |
|
|
, { "tiff", "image/tiff" }
|
205 |
|
|
, { "torrent", "application/x-bittorrent" }
|
206 |
|
|
, { "tr", "application/x-troff" }
|
207 |
|
|
, { "tsv", "text/tab-separated-values" }
|
208 |
|
|
, { "txt", "text/plain" }
|
209 |
|
|
, { "ustar", "application/x-ustar" }
|
210 |
|
|
, { "vcd", "application/x-cdlink" }
|
211 |
|
|
, { "vrml", "model/vrml" }
|
212 |
|
|
, { "wav", "audio/x-wav" }
|
213 |
|
|
, { "wbmp", "image/vnd.wap.wbmp" }
|
214 |
|
|
, { "wbxml", "application/vnd.wap.wbxml" }
|
215 |
|
|
, { "wml", "text/vnd.wap.wml" }
|
216 |
|
|
, { "wmlc", "application/vnd.wap.wmlc" }
|
217 |
|
|
, { "wmls", "text/vnd.wap.wmlscript" }
|
218 |
|
|
, { "wmlsc", "application/vnd.wap.wmlscriptc" }
|
219 |
|
|
, { "wrl", "model/vrml" }
|
220 |
|
|
, { "xbm", "image/x-xbitmap" }
|
221 |
|
|
, { "xht", "application/xhtml+xml" }
|
222 |
|
|
, { "xhtml", "application/xhtml+xml" }
|
223 |
|
|
, { "xls", "application/vnd.ms-excel" }
|
224 |
|
|
, { "xml", "text/xml" }
|
225 |
|
|
, { "xpm", "image/x-xpixmap" }
|
226 |
|
|
, { "xsl", "text/xml" }
|
227 |
|
|
, { "xwd", "image/x-xwindowdump" }
|
228 |
|
|
, { "xyz", "chemical/x-xyz" }
|
229 |
|
|
, { "zip", "application/zip" }
|
230 |
|
|
};
|
231 |
|
|
|
232 |
|
|
/**
|
233 |
|
|
* The MIME types above are put into this Hashtable for faster lookup.
|
234 |
|
|
*/
|
235 |
|
|
private Hashtable<String, String> mime_types
|
236 |
|
|
= new Hashtable<String, String>(150);
|
237 |
|
|
|
238 |
|
|
/**
|
239 |
|
|
* Create a new <code>MimeTypeMapper</code> object.
|
240 |
|
|
*/
|
241 |
|
|
public MimeTypeMapper()
|
242 |
|
|
{
|
243 |
|
|
for (int i = 0; i < mime_strings.length; i++)
|
244 |
|
|
mime_types.put(mime_strings[i][0], mime_strings[i][1]);
|
245 |
|
|
|
246 |
|
|
// Now read from the system mime database, if it exists. Entries found
|
247 |
|
|
// here override our internal ones.
|
248 |
|
|
try
|
249 |
|
|
{
|
250 |
|
|
// On Linux this usually means /etc/mime.types.
|
251 |
|
|
String file
|
252 |
|
|
= SystemProperties.getProperty("gnu.classpath.mime.types.file");
|
253 |
|
|
if (file != null)
|
254 |
|
|
fillFromFile(mime_types, file);
|
255 |
|
|
}
|
256 |
|
|
catch (IOException ignore)
|
257 |
|
|
{
|
258 |
|
|
}
|
259 |
|
|
}
|
260 |
|
|
|
261 |
|
|
public static void fillFromFile (Map<String, String> table, String fname)
|
262 |
|
|
throws IOException
|
263 |
|
|
{
|
264 |
|
|
LineNumberReader reader =
|
265 |
|
|
new LineNumberReader (new FileReader (fname));
|
266 |
|
|
|
267 |
|
|
while (reader.ready ())
|
268 |
|
|
{
|
269 |
|
|
StringTokenizer tokenizer =
|
270 |
|
|
new StringTokenizer (reader.readLine ());
|
271 |
|
|
|
272 |
|
|
try
|
273 |
|
|
{
|
274 |
|
|
String t = tokenizer.nextToken ();
|
275 |
|
|
|
276 |
|
|
if (! t.startsWith ("#"))
|
277 |
|
|
{
|
278 |
|
|
while (true)
|
279 |
|
|
{
|
280 |
|
|
// Read the next extension
|
281 |
|
|
String e = tokenizer.nextToken ();
|
282 |
|
|
if ((e != null) && (! e.startsWith ("#")))
|
283 |
|
|
table.put (e, t);
|
284 |
|
|
else
|
285 |
|
|
break;
|
286 |
|
|
}
|
287 |
|
|
}
|
288 |
|
|
}
|
289 |
|
|
catch (NoSuchElementException ex)
|
290 |
|
|
{
|
291 |
|
|
// Do nothing.
|
292 |
|
|
}
|
293 |
|
|
}
|
294 |
|
|
}
|
295 |
|
|
|
296 |
|
|
/**
|
297 |
|
|
* The method returns the MIME type of the filename passed as an argument.
|
298 |
|
|
* The value returned is based on the extension of the filename. The
|
299 |
|
|
* default content type returned if this method cannot determine the
|
300 |
|
|
* actual content type is "application/octet-stream"
|
301 |
|
|
*
|
302 |
|
|
* @param filename The name of the file to return the MIME type for
|
303 |
|
|
*
|
304 |
|
|
* @return The MIME type
|
305 |
|
|
*/
|
306 |
|
|
public String getContentTypeFor(String filename)
|
307 |
|
|
{
|
308 |
|
|
int index = filename.lastIndexOf(".");
|
309 |
|
|
if (index != -1)
|
310 |
|
|
{
|
311 |
|
|
if (index == filename.length())
|
312 |
|
|
return "application/octet-stream";
|
313 |
|
|
else
|
314 |
|
|
filename = filename.substring(index + 1);
|
315 |
|
|
}
|
316 |
|
|
|
317 |
|
|
String type = (String) mime_types.get(filename);
|
318 |
|
|
if (type == null)
|
319 |
|
|
return "application/octet-stream";
|
320 |
|
|
else
|
321 |
|
|
return type;
|
322 |
|
|
}
|
323 |
|
|
|
324 |
|
|
/**
|
325 |
|
|
* Run this class as a program to create a new mime_strings table.
|
326 |
|
|
*/
|
327 |
|
|
public static void main(String[] args) throws IOException
|
328 |
|
|
{
|
329 |
|
|
TreeMap<String, String> map = new TreeMap<String, String>();
|
330 |
|
|
// It is fine to hard-code the name here. This is only ever
|
331 |
|
|
// used by maintainers, who can hack it if they need to re-run
|
332 |
|
|
// it.
|
333 |
|
|
fillFromFile(map, "/etc/mime.types");
|
334 |
|
|
Iterator<String> it = map.keySet().iterator();
|
335 |
|
|
boolean first = true;
|
336 |
|
|
while (it.hasNext())
|
337 |
|
|
{
|
338 |
|
|
String key = it.next();
|
339 |
|
|
String value = map.get(key);
|
340 |
|
|
// Put the "," first since it is easier to make correct syntax this way.
|
341 |
|
|
System.out.println(" " + (first ? " " : ", ")
|
342 |
|
|
+ "{ \"" + key + "\", \"" + value + "\" }");
|
343 |
|
|
first = false;
|
344 |
|
|
}
|
345 |
|
|
}
|
346 |
|
|
}
|