View Javadoc

1   package org.apache.turbine.services.mimetype.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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             // Check whether the user directory contains mappings.
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             // Check whether the system directory contains mappings.
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         // Check whether the current class jar contains mappings.
182         mappers[MAP_JAR] = loadResource("/META-INF/" + MIMETYPE_RESOURCE);
183 
184         // Set the common mapper to have the lowest priority.
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 }