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