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