| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| MimeTypeMapper |
|
| 2.4444444444444446;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 | } |