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.BufferedReader;
20 import java.io.File;
21 import java.io.FileReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.StringReader;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.StringTokenizer;
29
30 /***
31 * This class defines mappings between MIME types and the corresponding
32 * file name extensions. The mappings are defined as lines formed
33 * by a MIME type name followed by a list of extensions separated
34 * by a whitespace.
35 *
36 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
37 * @version $Id: MimeTypeMapper.java 264148 2005-08-29 14:21:04Z henning $
38 */
39 public class MimeTypeMapper
40 {
41 /***
42 * Mappings between MIME types and file name extensions.
43 */
44 private HashMap mimeTypeExtensions = new HashMap();
45 protected HashMap extensionMimeTypes = new HashMap();
46
47 /***
48 * Constructs an empty MIME type mapper.
49 */
50 public MimeTypeMapper()
51 {
52 }
53
54 /***
55 * Constructs a mapper reading from a stream.
56 *
57 * @param input an input stream.
58 * @throws IOException for an incorrect stream.
59 */
60 public MimeTypeMapper(InputStream input)
61 throws IOException
62 {
63 parse(new BufferedReader(
64 new InputStreamReader(input, CharSetMap.DEFAULT_CHARSET)));
65 }
66
67 /***
68 * Constructs a mapper reading from a file.
69 *
70 * @param file an input file.
71 * @throws IOException for an incorrect file.
72 */
73 public MimeTypeMapper(File file)
74 throws IOException
75 {
76 FileReader freader = new FileReader(file);
77 try
78 {
79 parse(new BufferedReader(freader));
80 }
81 finally
82 {
83 try
84 {
85 freader.close();
86 }
87 catch (IOException x)
88 {
89 }
90 }
91 }
92
93 /***
94 * Constructs a mapper reading from a file path.
95 *
96 * @param path an input file path.
97 * @throws IOException for an incorrect file.
98 */
99 public MimeTypeMapper(String path)
100 throws IOException
101 {
102 this(new File(path));
103 }
104
105 /***
106 * Sets a MIME content type mapping to extensions.
107 *
108 * @param spec a MIME type extension specification to parse.
109 */
110 public void setContentType(String spec)
111 {
112 try
113 {
114 parse(new BufferedReader(new StringReader(spec)));
115 }
116 catch (IOException x)
117 {
118 }
119 }
120
121 /***
122 * Gets a MIME content type corresponding to a specified file name extension.
123 *
124 * @param ext a file name extension.
125 * @return the corresponding MIME type as a string or null.
126 */
127 public String getContentType(String ext)
128 {
129 return (String) mimeTypeExtensions.get(ext);
130 }
131
132 /***
133 * Gets a file name extension corresponding to a specified MIME content type.
134 *
135 * @param mime a MIME type as a string.
136 * @return the corresponding file name extension or null.
137 */
138 public String getExtension(String type)
139 {
140 return (String) extensionMimeTypes.get(type);
141 }
142
143 /***
144 * Parses MIME type extensions.
145 *
146 * @param reader a reader to parse.
147 * @throws IOException for an incorrect reader.
148 */
149 protected synchronized void parse(BufferedReader reader)
150 throws IOException
151 {
152 int l,count = 0;
153 String next;
154 String str = null;
155 HashMap mimeTypes = (HashMap) extensionMimeTypes.clone();
156 HashMap extensions = (HashMap) mimeTypeExtensions.clone();
157 while ((next = reader.readLine()) != null)
158 {
159 str = str == null ? next : str + next;
160 if ((l = str.length()) == 0)
161 {
162 str = null;
163 continue;
164 }
165
166 if (str.charAt(l - 1) != '//')
167 {
168 count += parseMimeTypeExtension(str, mimeTypes, extensions);
169 str = null;
170 }
171 else
172 {
173 str = str.substring(0, l - 1);
174 }
175 }
176 if (str != null)
177 {
178 count += parseMimeTypeExtension(str, mimeTypes, extensions);
179 }
180 if (count > 0)
181 {
182 extensionMimeTypes = mimeTypes;
183 mimeTypeExtensions = extensions;
184 }
185 }
186
187 /***
188 * Parses a MIME type extension.
189 *
190 * @param spec an extension specification to parse.
191 * @param mimeTypes a map of MIME types.
192 * @param extensions a map of extensions.
193 * @return the number of file name extensions parsed.
194 */
195 protected int parseMimeTypeExtension(String spec,
196 Map mimeTypes,
197 Map extensions)
198 {
199 int count = 0;
200 spec = spec.trim();
201 if ((spec.length() > 0) &&
202 (spec.charAt(0) != '#'))
203 {
204 StringTokenizer tokens = new StringTokenizer(spec);
205 String type = tokens.nextToken();
206 String ext;
207 while (tokens.hasMoreTokens())
208 {
209 ext = tokens.nextToken();
210 if (ext.length() == 0)
211 {
212 continue;
213 }
214 extensions.put(ext, type);
215 if (count++ == 0)
216 {
217 mimeTypes.put(type, ext);
218 }
219 }
220 }
221 return count;
222 }
223 }