View Javadoc

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