/*
* 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);
}
}