/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.commons.utils; import eu.medsea.mimeutil.MimeUtil; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import java.io.IOException; import java.io.InputStream; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class MimeTypeResolver { protected static final Log LOG = ExoLogger.getLogger("exo.kernel.commons.MimeTypeResolver"); /** * Name of mime cache file property parameter. */ private static final String MIME_CACHE = "exo.mime.cache"; static { SecurityHelper.doPrivilegedAction(new PrivilegedAction<Void>() { public Void run() { String mimeCacheFile = PropertyManager.getProperty(MIME_CACHE); if (mimeCacheFile != null && !mimeCacheFile.isEmpty()) { new eu.medsea.mimeutil.detector.OpendesktopMimeDetector(mimeCacheFile); MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.OpendesktopMimeDetector"); } else { MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector"); } return null; } }); } private Map<String, List<String>> mimeTypes = new HashMap<String, List<String>>(); private Map<String, List<String>> extentions = new HashMap<String, List<String>>(); private String defaultMimeType = "application/octet-stream"; public MimeTypeResolver() { try { SecurityHelper.doPrivilegedIOExceptionAction(new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { Scanner scanner = null; String mimeTypeProperties = System.getProperty("org.exoplatform.mimetypes"); if (mimeTypeProperties != null) { InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(mimeTypeProperties); if (stream != null) { scanner = new Scanner(stream, "ISO-8859-1"); } } if (scanner == null) { scanner = new Scanner(getClass().getResourceAsStream("mimetypes.properties"), "ISO-8859-1"); } try { while (scanner.hasNextLine()) { processLine(scanner.nextLine()); } } finally { scanner.close(); } return null; } }); } catch (IOException e) { throw new InternalError("Unable to load mimetypes: " + e.toString()); } } /** * Returns default MIMEType. * * @return String */ public String getDefaultMimeType() { return defaultMimeType; } /** * Set default MIMEType. * * @param defaultMimeType * String, default MIMEType */ public void setDefaultMimeType(String defaultMimeType) { this.defaultMimeType = defaultMimeType.toLowerCase(); } /** * Get MIMEType which corresponds to file extension. If file extension is unknown the default * MIMEType will be returned. If there are more than one MIMETypes for specific extension the * first occurred in the list will be returned. * * @param filename * @return String MIMEType */ public String getMimeType(String filename) { String ext = filename.substring(filename.lastIndexOf(".") + 1); if (ext.isEmpty()) { ext = filename; } List<String> values = mimeTypes.get(ext.toLowerCase()); return values == null ? defaultMimeType : values.get(0); } /** * Get MIMEType which corresponds to file content. If file content * does not allow to determine MIMEtype, the default MIMEType will be returned. * * @param fileName * @param is * @return String MIMEType */ public String getMimeType(String fileName, InputStream is) { String mimeType = getMimeType(fileName); if (mimeType.equals(defaultMimeType)) { Collection<?> mimeTypes = MimeUtil.getMimeTypes(is); if (!mimeTypes.isEmpty()) { mimeType = mimeTypes.toArray()[0].toString().toLowerCase(); } } return mimeType; } /** * Get file extension corresponds to MIMEType. If MIMEType is empty or equals * default MIMEType empty string will be returned. If there is no file extension * for specific MIMEType the empty string will be returned also. In case when * there are more than one extension for specific MIMEType the first occurred * extension in the list will be returned if MIMEType ends with this extension * otherwise just first occurred. * * @param mimeType * MIMEType * @return file extension */ public String getExtension(String mimeType) { mimeType = mimeType.toLowerCase(); if (mimeType.isEmpty() || mimeType.equals(defaultMimeType)) { return ""; } List<String> values = extentions.get(mimeType); if (values == null) { return ""; } String resultExt = ""; for (String ext : values) { if (mimeType.endsWith(ext)) { return ext; } if (resultExt.isEmpty()) { resultExt = ext; } } return resultExt; } /** * Load MIMEType and corresponding extension. * * @param aLine */ protected void processLine(String aLine) { aLine = aLine.toLowerCase(); int p = aLine.indexOf("="); String ext = aLine.substring(0, p); String mimetype = aLine.substring(p + 1); // add mimetype List<String> values = mimeTypes.get(ext); if (values == null) { values = new ArrayList<String>(); mimeTypes.put(ext, values); } values.add(mimetype); // add extension values = extentions.get(mimetype); if (values == null) { values = new ArrayList<String>(); extentions.put(mimetype, values); } values.add(ext); } }