001 package org.apache.fulcrum.mimetype; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.io.File; 023 import java.io.IOException; 024 import java.util.Locale; 025 026 import org.apache.avalon.framework.activity.Initializable; 027 import org.apache.avalon.framework.configuration.Configurable; 028 import org.apache.avalon.framework.configuration.Configuration; 029 import org.apache.avalon.framework.context.Context; 030 import org.apache.avalon.framework.context.ContextException; 031 import org.apache.avalon.framework.context.Contextualizable; 032 import org.apache.avalon.framework.logger.AbstractLogEnabled; 033 import org.apache.fulcrum.mimetype.util.CharSetMap; 034 import org.apache.fulcrum.mimetype.util.MimeType; 035 import org.apache.fulcrum.mimetype.util.MimeTypeMap; 036 /** 037 * The MimeType Service maintains mappings between MIME types and 038 * the corresponding file name extensions, and between locales and 039 * character encodings. 040 * 041 * <p>The MIME type mappings can be defined in MIME type files 042 * located in user's home directory, Java home directory or 043 * the current class jar. The default mapping file is defined 044 * with the mime.type.file property. In addition, the service maintains 045 * a set of most common mappings. 046 * 047 * <p>The charset mappings can be defined in property files 048 * located in user's home directory, Java home directory or 049 * the current class jar. The default mapping file is defined 050 * with the charset.file property. In addition, the service maintains 051 * a set of most common mappings. 052 * 053 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a> 054 * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a> 055 * @version $Id: DefaultMimeTypeService.java 813677 2009-09-11 06:48:11Z tv $ 056 * 057 * @avalon.component name="mimetype" lifestyle="singleton" 058 * @avalon.service type="org.apache.fulcrum.mimetype.MimeTypeService" 059 */ 060 public class DefaultMimeTypeService 061 extends AbstractLogEnabled 062 implements MimeTypeService, Configurable, Initializable, Contextualizable 063 { 064 private String applicationRoot; 065 /** 066 * The MIME type file property. 067 */ 068 public static final String MIME_TYPES = "mimetypes"; 069 /** 070 * The charset file property. 071 */ 072 public static final String CHARSETS = "charsets"; 073 // path to a mimetypes-file_extension mapping file 074 private String mimetypePath; 075 // path to a charset-language mapping file 076 private String charsetPath; 077 /** 078 * The MIME type map used by the service. 079 */ 080 private MimeTypeMap mimeTypeMap; 081 /** 082 * The charset map used by the service. 083 */ 084 private CharSetMap charSetMap; 085 086 /** 087 * Constructs a new service. 088 */ 089 public DefaultMimeTypeService() 090 { 091 // empty 092 } 093 /** 094 * Sets a MIME content type mapping to extensions to the map. 095 * The extension is specified by a MIME type name followed 096 * by a list of file name extensions separated by a whitespace. 097 * 098 * @param spec a MIME type extension specification to add. 099 */ 100 public void setContentType(String spec) 101 { 102 mimeTypeMap.setContentType(spec); 103 } 104 /** 105 * Gets the MIME content type for a file as a string. 106 * 107 * @param file The file to look up a MIME type mapping for. 108 * @return the MIME type string. 109 */ 110 public String getContentType(File file) 111 { 112 return mimeTypeMap.getContentType(file); 113 } 114 /** 115 * Gets the MIME content type for a named file as a string. 116 * 117 * @param fileName The name of the file to look up a MIME type 118 * mapping for. 119 * @return the MIME type string. 120 */ 121 public String getContentType(String fileName) 122 { 123 return mimeTypeMap.getContentType(fileName); 124 } 125 /** 126 * Gets the MIME content type for a file name extension as a string. 127 * 128 * @param fileName The name of the file to look up a MIME type 129 * mapping for. 130 * @param def The default MIME type to use if no mapping exists. 131 * @return the MIME type string. 132 */ 133 public String getContentType(String fileName, String def) 134 { 135 return mimeTypeMap.getContentType(fileName, def); 136 } 137 /** 138 * Gets the MIME content type for a file. 139 * 140 * @param file the file. 141 * @return the MIME type. 142 */ 143 public MimeType getMimeContentType(File file) 144 { 145 return mimeTypeMap.getMimeContentType(file); 146 } 147 /** 148 * Gets the MIME content type for a named file. 149 * 150 * @param name the name of the file. 151 * @return the MIME type. 152 */ 153 public MimeType getMimeContentType(String name) 154 { 155 return mimeTypeMap.getMimeContentType(name); 156 } 157 /** 158 * Gets the MIME content type for a file name extension. 159 * 160 * @param ext the file name extension. 161 * @param def the default type if none is found. 162 * @return the MIME type. 163 */ 164 public MimeType getMimeContentType(String ext, String def) 165 { 166 return mimeTypeMap.getMimeContentType(ext, def); 167 } 168 /** 169 * Gets the default file name extension for a MIME type. 170 * Note that the mappers are called in the reverse order. 171 * 172 * @param type the MIME type as a string. 173 * @return the file name extension or null. 174 */ 175 public String getDefaultExtension(String type) 176 { 177 return mimeTypeMap.getDefaultExtension(type); 178 } 179 /** 180 * Gets the default file name extension for a MIME type. 181 * Note that the mappers are called in the reverse order. 182 * 183 * @param mime the MIME type. 184 * @return the file name extension or null. 185 */ 186 public String getDefaultExtension(MimeType mime) 187 { 188 return mimeTypeMap.getDefaultExtension(mime); 189 } 190 /** 191 * Sets a locale-charset mapping. 192 * 193 * @param key the key for the charset. 194 * @param charset the corresponding charset. 195 */ 196 public void setCharSet(String key, String charset) 197 { 198 charSetMap.setCharSet(key, charset); 199 } 200 /** 201 * Gets the charset for a locale. First a locale specific charset 202 * is searched for, then a country specific one and lastly a language 203 * specific one. If none is found, the default charset is returned. 204 * 205 * @param locale the locale. 206 * @return the charset. 207 */ 208 public String getCharSet(Locale locale) 209 { 210 return charSetMap.getCharSet(locale); 211 } 212 /** 213 * Gets the charset for a locale with a variant. The search 214 * is performed in the following order: 215 * "lang"_"country"_"variant"="charset", 216 * _"counry"_"variant"="charset", 217 * "lang"__"variant"="charset", 218 * __"variant"="charset", 219 * "lang"_"country"="charset", 220 * _"country"="charset", 221 * "lang"="charset". 222 * If nothing of the above is found, the default charset is returned. 223 * 224 * @param locale the locale. 225 * @param variant a variant field. 226 * @return the charset. 227 */ 228 public String getCharSet(Locale locale, String variant) 229 { 230 return charSetMap.getCharSet(locale, variant); 231 } 232 /** 233 * Gets the charset for a specified key. 234 * 235 * @param key the key for the charset. 236 * @return the found charset or the default one. 237 */ 238 public String getCharSet(String key) 239 { 240 return charSetMap.getCharSet(key); 241 } 242 /** 243 * Gets the charset for a specified key. 244 * 245 * @param key the key for the charset. 246 * @param def the default charset if none is found. 247 * @return the found charset or the given default. 248 */ 249 public String getCharSet(String key, String def) 250 { 251 return charSetMap.getCharSet(key, def); 252 } 253 254 private String getRealPath(String path) 255 { 256 String absolutePath = null; 257 if (applicationRoot == null) 258 { 259 absolutePath = new File(path).getAbsolutePath(); 260 } 261 else 262 { 263 absolutePath = new File(applicationRoot, path).getAbsolutePath(); 264 } 265 return absolutePath; 266 } 267 // ---------------- Avalon Lifecycle Methods --------------------- 268 /** 269 * Avalon component lifecycle method 270 */ 271 public void configure(Configuration conf) 272 { 273 mimetypePath = conf.getAttribute(MIME_TYPES, null); 274 charsetPath = conf.getAttribute(CHARSETS, null); 275 if (mimetypePath != null) 276 { 277 mimetypePath = getRealPath(mimetypePath); 278 } 279 if (charsetPath != null) 280 { 281 charsetPath = getRealPath(charsetPath); 282 } 283 } 284 /** 285 * Avalon component lifecycle method 286 */ 287 public void initialize() throws Exception 288 { 289 if (mimetypePath != null) 290 { 291 try 292 { 293 mimeTypeMap = new MimeTypeMap(mimetypePath); 294 } 295 catch (IOException x) 296 { 297 throw new Exception(mimetypePath, x); 298 } 299 } 300 else 301 { 302 mimeTypeMap = new MimeTypeMap(); 303 } 304 if (charsetPath != null) 305 { 306 try 307 { 308 charSetMap = new CharSetMap(charsetPath); 309 } 310 catch (IOException x) 311 { 312 throw new Exception(charsetPath, x); 313 } 314 } 315 else 316 { 317 charSetMap = new CharSetMap(); 318 } 319 } 320 321 /** 322 * @see org.apache.avalon.framework.context.Contextualizable 323 * @avalon.entry key="urn:avalon:home" type="java.io.File" 324 */ 325 public void contextualize(Context context) throws ContextException 326 { 327 this.applicationRoot = context.get( "urn:avalon:home" ).toString(); 328 } 329 330 }