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.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             // Check for continuation line.
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 }