Coverage Report - org.apache.fulcrum.mimetype.util.MimeTypeMapper
 
Classes in this File Line Coverage Branch Coverage Complexity
MimeTypeMapper
72%
44/61
64%
18/28
2,444
 
 1  
 package org.apache.fulcrum.mimetype.util;
 2  
 
 3  
 
 4  
 /*
 5  
  * Licensed to the Apache Software Foundation (ASF) under one
 6  
  * or more contributor license agreements.  See the NOTICE file
 7  
  * distributed with this work for additional information
 8  
  * regarding copyright ownership.  The ASF licenses this file
 9  
  * to you under the Apache License, Version 2.0 (the
 10  
  * "License"); you may not use this file except in compliance
 11  
  * with the License.  You may obtain a copy of the License at
 12  
  *
 13  
  *   http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing,
 16  
  * software distributed under the License is distributed on an
 17  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 18  
  * KIND, either express or implied.  See the License for the
 19  
  * specific language governing permissions and limitations
 20  
  * under the License.
 21  
  */
 22  
 
 23  
 
 24  
 import java.io.File;
 25  
 import java.io.FileReader;
 26  
 import java.io.StringReader;
 27  
 import java.io.InputStream;
 28  
 import java.io.InputStreamReader;
 29  
 import java.io.BufferedReader;
 30  
 import java.io.IOException;
 31  
 import java.util.Map;
 32  
 import java.util.HashMap;
 33  
 import java.util.StringTokenizer;
 34  
 
 35  
 /**
 36  
  * This class defines mappings between MIME types and the corresponding
 37  
  * file name extensions. The mappings are defined as lines formed
 38  
  * by a MIME type name followed by a list of extensions separated
 39  
  * by a whitespace.
 40  
  *
 41  
  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
 42  
  * @author Daniel Rall
 43  
  * @version $Id: MimeTypeMapper.java 826489 2009-10-18 18:54:59Z tv $
 44  
  */
 45  
 public class MimeTypeMapper
 46  
 {
 47  
     /**
 48  
      * Mappings between MIME types and file name extensions.
 49  
      */
 50  33
     private HashMap mimeTypeExtensions = new HashMap();
 51  33
     protected HashMap extensionMimeTypes = new HashMap();
 52  
 
 53  
     /**
 54  
      * Constructs an empty MIME type mapper.
 55  
      */
 56  
     public MimeTypeMapper()
 57  15
     {
 58  
         // do nothing
 59  15
     }
 60  
 
 61  
     /**
 62  
      * Constructs a mapper reading from a stream.
 63  
      *
 64  
      * @param input an input stream.
 65  
      * @throws IOException for an incorrect stream.
 66  
      */
 67  
     public MimeTypeMapper(InputStream input)
 68  
         throws IOException
 69  0
     {
 70  0
         parse(new BufferedReader(
 71  
             new InputStreamReader(input,CharSetMap.DEFAULT_CHARSET)));
 72  0
     }
 73  
 
 74  
     /**
 75  
      * Constructs a mapper reading from a file.
 76  
      *
 77  
      * @param file an input file.
 78  
      * @throws IOException for an incorrect file.
 79  
      */
 80  
     public MimeTypeMapper(File file)
 81  
         throws IOException
 82  18
     {
 83  18
         FileReader freader = new FileReader(file);
 84  
         try
 85  
         {
 86  0
             parse(new BufferedReader(freader));
 87  
         }
 88  
         finally
 89  
         {
 90  0
             try
 91  
             {
 92  0
                 freader.close();
 93  
             }
 94  0
             catch (IOException x)
 95  
             {
 96  
                 // ignore
 97  0
             }
 98  0
         }
 99  0
     }
 100  
 
 101  
     /**
 102  
      * Constructs a mapper reading from a file path.
 103  
      *
 104  
      * @param path an input file path.
 105  
      * @throws IOException for an incorrect file.
 106  
      */
 107  
     public MimeTypeMapper(String path)
 108  
         throws IOException
 109  
     {
 110  18
       this(new File(path));
 111  0
     }
 112  
 
 113  
     /**
 114  
      * Sets a MIME content type mapping to extensions.
 115  
      *
 116  
      * @param spec a MIME type extension specification to parse.
 117  
      */
 118  
     public void setContentType(String spec)
 119  
     {
 120  
       try
 121  
       {
 122  36
           parse(new BufferedReader(new StringReader(spec)));
 123  
       }
 124  0
       catch (IOException x)
 125  
       {
 126  
           // ignore
 127  36
       }
 128  36
     }
 129  
 
 130  
     /**
 131  
      * Gets a MIME content type corresponding to a specified file name
 132  
      * extension.  If a mapping is initially not found, tries a second
 133  
      * lookup using the provided extension in lower case.
 134  
      *
 135  
      * @param ext The file name extension to resolve.
 136  
      * @return The MIME type, or <code>null</code> if not found.
 137  
      */
 138  
     public String getContentType(String ext)
 139  
     {
 140  30
         String mimeType = (String) mimeTypeExtensions.get(ext);
 141  30
         if (mimeType == null && ext != null)
 142  
         {
 143  12
             String lcExt = ext.toLowerCase();
 144  12
             if (!ext.equals(lcExt))
 145  
             {
 146  
                 // Original file extension didn't resolve, but was
 147  
                 // mixed case.  Try it again with lower case chars.
 148  12
                 mimeType = (String) mimeTypeExtensions.get(lcExt);
 149  
             }
 150  
         }
 151  30
         return mimeType;
 152  
     }
 153  
 
 154  
     /**
 155  
      * Gets a file name extension corresponding to a specified MIME content type.
 156  
      *
 157  
      * @param type a MIME type as a string.
 158  
      * @return the corresponding file name extension or null.
 159  
      */
 160  
     public String getExtension(String type)
 161  
     {
 162  12
         return (String) extensionMimeTypes.get(type);
 163  
     }
 164  
 
 165  
     /**
 166  
      * Parses MIME type extensions.
 167  
      *
 168  
      * @param reader a reader to parse.
 169  
      * @throws IOException for an incorrect reader.
 170  
      */
 171  
     protected synchronized void parse(BufferedReader reader)
 172  
         throws IOException
 173  
     {
 174  36
       int l,count = 0;
 175  
       String next;
 176  36
       String str = null;
 177  36
       HashMap mimeTypes = (HashMap) extensionMimeTypes.clone();
 178  36
       HashMap extensions = (HashMap) mimeTypeExtensions.clone();
 179  72
       while ((next = reader.readLine()) != null)
 180  
       {
 181  36
           str = str == null ? next : str + next;
 182  36
           if ((l = str.length()) == 0)
 183  
           {
 184  0
               str = null;
 185  0
               continue;
 186  
           }
 187  
           // Check for continuation line.
 188  36
           if (str.charAt(l - 1) != '\\')
 189  
           {
 190  36
               count += parseMimeTypeExtension(str,mimeTypes,extensions);
 191  36
               str = null;
 192  
           }
 193  
           else
 194  
           {
 195  0
               str = str.substring(0,l - 1);
 196  
           }
 197  
       }
 198  36
       if (str != null)
 199  
       {
 200  0
           count += parseMimeTypeExtension(str,mimeTypes,extensions);
 201  
       }
 202  36
       if (count > 0)
 203  
       {
 204  36
           extensionMimeTypes = mimeTypes;
 205  36
           mimeTypeExtensions = extensions;
 206  
       }
 207  36
     }
 208  
 
 209  
     /**
 210  
      * Parses a MIME type extension.
 211  
      *
 212  
      * @param spec an extension specification to parse.
 213  
      * @param mimeTypes a map of MIME types.
 214  
      * @param extensions a map of extensions.
 215  
      * @return the number of file name extensions parsed.
 216  
      */
 217  
     protected int parseMimeTypeExtension(String spec,
 218  
                                          Map mimeTypes,
 219  
                                          Map extensions)
 220  
     {
 221  36
         int count = 0;
 222  36
         spec = spec.trim();
 223  36
         if ((spec.length() > 0) &&
 224  
             (spec.charAt(0) != '#'))
 225  
         {
 226  36
             StringTokenizer tokens = new StringTokenizer(spec);
 227  36
             String type = tokens.nextToken();
 228  
             String ext;
 229  105
             while (tokens.hasMoreTokens())
 230  
             {
 231  69
                 ext = tokens.nextToken();
 232  69
                 if (ext.length() == 0)
 233  
                 {
 234  0
                     continue;
 235  
                 }
 236  69
                 extensions.put(ext,type);
 237  69
                 if (count++ == 0)
 238  
                 {
 239  36
                     mimeTypes.put(type,ext);
 240  
                 }
 241  
             }
 242  
         }
 243  36
         return count;
 244  
     }
 245  
 }