/*
* Copyright (c) 2013 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.werval.runtime.mime;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Properties;
import io.werval.api.mime.MimeTypes;
import io.werval.runtime.exceptions.WervalRuntimeException;
import static java.util.Locale.US;
import static io.werval.util.IllegalArguments.ensureNotEmpty;
import static io.werval.util.IllegalArguments.ensureNotNull;
/**
* Application MimeType instance.
*/
public class MimeTypesInstance
implements MimeTypes
{
private final Charset defaultCharset;
private final Properties extToType = new Properties();
private final Map<String, Charset> textuals;
public MimeTypesInstance( Charset defaultCharset,
Map<String, Charset> textuals )
{
this.defaultCharset = defaultCharset;
try( InputStream input = getClass().getResourceAsStream( "mime-types-extensions.properties" ) )
{
extToType.load( input );
}
catch( IOException ex )
{
throw new WervalRuntimeException( "Unable to load internal mime types database: " + ex.getMessage(), ex );
}
this.textuals = textuals;
}
public MimeTypesInstance( Charset defaultCharset,
Map<String, String> supplementaryMimetypes,
Map<String, Charset> textuals )
{
this( defaultCharset, textuals );
this.extToType.putAll( supplementaryMimetypes );
}
@Override
public String ofFile( File file )
{
ensureNotNull( "File", file );
return ofFilename( file.getName() );
}
@Override
public String ofFileWithCharset( File file )
{
return withCharsetIfTextual( ofFile( file ) );
}
@Override
public String ofFileWithCharset( File file, Charset charset )
{
return withCharset( ofFile( file ), charset );
}
@Override
public String ofPath( String path )
{
ensureNotEmpty( "Path", path );
return ofFile( new File( path ) );
}
@Override
public String ofPathWithCharset( String path )
{
return withCharsetIfTextual( ofPath( path ) );
}
@Override
public String ofPathWithCharset( String path, Charset charset )
{
return withCharset( ofPath( path ), charset );
}
@Override
public String ofFilename( String filename )
{
ensureNotEmpty( "Filename", filename );
int lastDotIndex = filename.lastIndexOf( '.' );
if( lastDotIndex > 0 )
{
return ofExtension( filename.substring( lastDotIndex + 1 ) );
}
return APPLICATION_OCTET_STREAM;
}
@Override
public String ofFilenameWithCharset( String filename )
{
return withCharsetIfTextual( ofFilename( filename ) );
}
@Override
public String ofFilenameWithCharset( String filename, Charset charset )
{
return withCharset( ofFilename( filename ), charset );
}
@Override
public String ofExtension( String extension )
{
ensureNotEmpty( "Extension", extension );
String mimeType = extToType.getProperty( extension );
return mimeType == null ? APPLICATION_OCTET_STREAM : mimeType;
}
@Override
public String ofExtensionWithCharset( String extension )
{
return withCharsetIfTextual( ofExtension( extension ) );
}
@Override
public String ofExtensionWithCharset( String extension, Charset charset )
{
return withCharset( ofExtension( extension ), charset );
}
@Override
public boolean isTextual( String mimetype )
{
ensureNotEmpty( "MimeType", mimetype );
if( mimetype.startsWith( "text/" ) )
{
return true;
}
for( Map.Entry<String, Charset> textual : textuals.entrySet() )
{
if( mimetype.startsWith( textual.getKey() ) )
{
return true;
}
}
return false;
}
@Override
public Charset charsetOfTextual( String mimetype )
{
if( !isTextual( mimetype ) )
{
throw new IllegalArgumentException( mimetype + " is not textual" );
}
Charset charset = textuals.get( mimetype );
return charset == null ? defaultCharset : charset;
}
@Override
public String withCharset( String mimetype, Charset charset )
{
String charsetString = charset.name().toLowerCase( US );
return mimetype + "; charset=" + charsetString;
}
@Override
public String withCharsetOfTextual( String mimetype )
{
return withCharset( mimetype, charsetOfTextual( mimetype ) );
}
private String withCharsetIfTextual( String mimetype )
{
if( isTextual( mimetype ) )
{
return withCharset( mimetype, charsetOfTextual( mimetype ) );
}
return mimetype;
}
}