/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.framework.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
/**
* This class implements the mime type resolver.
*/
@Component("mimeTypeResolver")
public final class MimeTypeResolverImpl
implements MimeTypeResolver, InitializingBean, ServletContextAware
{
private static final Logger LOG = LoggerFactory.getLogger( MimeTypeResolverImpl.class.getName() );
/**
* Default mime type.
*/
private final static String DEFAULT_MIME_TYPE = "application/octet-stream";
/**
* Mime types collection.
*/
private Properties mimeTypes;
private ServletContext servletContext;
private String mimetypesLocation;
/**
* Construct the resolver.
*/
public MimeTypeResolverImpl()
{
}
@Override
public void afterPropertiesSet()
throws Exception
{
this.mimeTypes = loadMimeTypes( mimetypesLocation );
}
/**
* Return the mime type by file.
*/
@Override
public String getMimeType( String fileName )
{
String ext = fileName.substring( fileName.lastIndexOf( "." ) + 1 );
if ( ext.equals( "" ) )
{
ext = fileName;
}
return getMimeTypeByExtension( ext );
}
/**
* Return the mime type by extension.
*/
@Override
public String getMimeTypeByExtension( String ext )
{
final String key = ext.toLowerCase();
final String localProperty = this.mimeTypes.getProperty( key );
if ( localProperty != null )
{
return localProperty;
}
if ( servletContext != null )
{
final String containerProperty = servletContext.getMimeType( key );
if ( containerProperty != null )
{
return containerProperty;
}
}
else
{
return DEFAULT_MIME_TYPE;
}
return DEFAULT_MIME_TYPE;
}
/**
* Find extension by mime type.
*/
@Override
public String getExtension( String mimeType )
{
String ext = "";
if ( mimeType == null || ext.equals( mimeType ) || DEFAULT_MIME_TYPE.equals( mimeType ) )
{
return ext;
}
for ( final Map.Entry entry : mimeTypes.entrySet() )
{
final String key = (String) entry.getKey();
final String value = (String) entry.getValue();
if ( value.equals( mimeType ) && mimeType.endsWith( key ) )
{
return key;
}
if ( value.equals( mimeType ) && ext.equals( "" ) )
{
ext = key;
}
else if ( value.equals( mimeType ) && !ext.equals( "" ) )
{
return ext;
}
}
return ext;
}
/**
* Load mime types. User can override default mimetypes by own in CMS_HOME directory.
*
* @param mimetypesLocation location of .properties file
* @return map of mime types
*/
private Properties loadMimeTypes( final String mimetypesLocation )
{
final Properties userProps = new Properties();
final Properties systemProps = new Properties();
try
{
// load user defined mime types from mimetypesLocation ( e.g. CMS_HOME )
final File file = new File( mimetypesLocation );
if ( file.exists() )
{
userProps.load( new FileInputStream( file ) );
LOG.info( "loaded {} user-defined mimetypes from file {}", userProps.size(), mimetypesLocation );
}
}
catch ( Exception e )
{
LOG.error( "Unable to load user mimetypes from {}. Reason: {}", mimetypesLocation, e.toString() );
}
try
{
final InputStream input = MimeTypeResolverImpl.class.getResourceAsStream( "mimetypes.properties" );
if ( input == null )
{
throw new InternalError( "Unable to find mimetypes.properties" );
}
systemProps.load( input );
}
catch ( IOException e )
{
throw new InternalError( "Unable to load system mimetypes: " + e.toString() );
}
// overwrite default properties with user properties
systemProps.putAll( userProps );
return systemProps;
}
@Value("${cms.home}/config/mimetypes.properties")
public void setMimetypesLocation( String mimetypesLocation )
{
this.mimetypesLocation = mimetypesLocation;
}
public void setServletContext( final ServletContext servletContext )
{
this.servletContext = servletContext;
}
}