/*
* Copyright 2002-2020 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
*
* https://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 org.springframework.mail.javamail;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
Spring-configurable FileTypeMap
implementation that will read MIME type to file extension mappings from a standard JavaMail MIME type mapping file, using a standard MimetypesFileTypeMap
underneath. The mapping file should be in the following format, as specified by the
Java Activation Framework:
# map text/html to .htm and .html files
text/html html htm HTML HTM
Lines starting with #
are treated as comments and are ignored. All other lines are treated as mappings. Each mapping line should contain the MIME type as the first entry and then each file extension to map to that MIME type as subsequent entries. Each entry is separated by spaces or tabs. By default, the mappings in the mime.types
file located in the same package as this class are used, which cover many common file extensions (in contrast to the out-of-the-box mappings in activation.jar
). This can be overridden using the mappingLocation
property.
Additional mappings can be added via the mappings
bean property, as lines that follow the mime.types
file format.
Author: Rob Harrop, Juergen Hoeller See Also: Since: 1.2
/**
* Spring-configurable {@code FileTypeMap} implementation that will read
* MIME type to file extension mappings from a standard JavaMail MIME type
* mapping file, using a standard {@code MimetypesFileTypeMap} underneath.
*
* <p>The mapping file should be in the following format, as specified by the
* Java Activation Framework:
*
* <pre class="code">
* # map text/html to .htm and .html files
* text/html html htm HTML HTM</pre>
*
* Lines starting with {@code #} are treated as comments and are ignored. All
* other lines are treated as mappings. Each mapping line should contain the MIME
* type as the first entry and then each file extension to map to that MIME type
* as subsequent entries. Each entry is separated by spaces or tabs.
*
* <p>By default, the mappings in the {@code mime.types} file located in the
* same package as this class are used, which cover many common file extensions
* (in contrast to the out-of-the-box mappings in {@code activation.jar}).
* This can be overridden using the {@code mappingLocation} property.
*
* <p>Additional mappings can be added via the {@code mappings} bean property,
* as lines that follow the {@code mime.types} file format.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 1.2
* @see #setMappingLocation
* @see #setMappings
* @see javax.activation.MimetypesFileTypeMap
*/
public class ConfigurableMimeFileTypeMap extends FileTypeMap implements InitializingBean {
The Resource
to load the mapping file from. /**
* The {@code Resource} to load the mapping file from.
*/
private Resource mappingLocation = new ClassPathResource("mime.types", getClass());
Used to configure additional mappings.
/**
* Used to configure additional mappings.
*/
@Nullable
private String[] mappings;
The delegate FileTypeMap, compiled from the mappings in the mapping file and the entries in the mappings
property. /**
* The delegate FileTypeMap, compiled from the mappings in the mapping file
* and the entries in the {@code mappings} property.
*/
@Nullable
private FileTypeMap fileTypeMap;
Specify the Resource
from which mappings are loaded. Needs to follow the mime.types
file format, as specified by the Java Activation Framework, containing lines such as:
text/html html htm HTML HTM
/**
* Specify the {@code Resource} from which mappings are loaded.
* <p>Needs to follow the {@code mime.types} file format, as specified
* by the Java Activation Framework, containing lines such as:<br>
* {@code text/html html htm HTML HTM}
*/
public void setMappingLocation(Resource mappingLocation) {
this.mappingLocation = mappingLocation;
}
Specify additional MIME type mappings as lines that follow the mime.types
file format, as specified by the Java Activation Framework. For example:
text/html html htm HTML HTM
/**
* Specify additional MIME type mappings as lines that follow the
* {@code mime.types} file format, as specified by the
* Java Activation Framework. For example:<br>
* {@code text/html html htm HTML HTM}
*/
public void setMappings(String... mappings) {
this.mappings = mappings;
}
Creates the final merged mapping set.
/**
* Creates the final merged mapping set.
*/
@Override
public void afterPropertiesSet() {
getFileTypeMap();
}
Return the delegate FileTypeMap, compiled from the mappings in the mapping file and the entries in the mappings
property. See Also:
/**
* Return the delegate FileTypeMap, compiled from the mappings in the mapping file
* and the entries in the {@code mappings} property.
* @see #setMappingLocation
* @see #setMappings
* @see #createFileTypeMap
*/
protected final FileTypeMap getFileTypeMap() {
if (this.fileTypeMap == null) {
try {
this.fileTypeMap = createFileTypeMap(this.mappingLocation, this.mappings);
}
catch (IOException ex) {
throw new IllegalStateException(
"Could not load specified MIME type mapping file: " + this.mappingLocation, ex);
}
}
return this.fileTypeMap;
}
Compile a FileTypeMap
from the mappings in the given mapping file and the given mapping entries. The default implementation creates an Activation Framework MimetypesFileTypeMap
, passing in an InputStream from the mapping resource (if any) and registering the mapping lines programmatically.
Params: - mappingLocation – a
mime.types
mapping resource (can be null
) - mappings – an array of MIME type mapping lines (can be
null
)
Throws: - IOException – if resource access failed
See Also: Returns: the compiled FileTypeMap
/**
* Compile a {@link FileTypeMap} from the mappings in the given mapping file
* and the given mapping entries.
* <p>The default implementation creates an Activation Framework {@link MimetypesFileTypeMap},
* passing in an InputStream from the mapping resource (if any) and registering
* the mapping lines programmatically.
* @param mappingLocation a {@code mime.types} mapping resource (can be {@code null})
* @param mappings an array of MIME type mapping lines (can be {@code null})
* @return the compiled FileTypeMap
* @throws IOException if resource access failed
* @see javax.activation.MimetypesFileTypeMap#MimetypesFileTypeMap(java.io.InputStream)
* @see javax.activation.MimetypesFileTypeMap#addMimeTypes(String)
*/
protected FileTypeMap createFileTypeMap(@Nullable Resource mappingLocation, @Nullable String[] mappings) throws IOException {
MimetypesFileTypeMap fileTypeMap = null;
if (mappingLocation != null) {
try (InputStream is = mappingLocation.getInputStream()) {
fileTypeMap = new MimetypesFileTypeMap(is);
}
}
else {
fileTypeMap = new MimetypesFileTypeMap();
}
if (mappings != null) {
for (String mapping : mappings) {
fileTypeMap.addMimeTypes(mapping);
}
}
return fileTypeMap;
}
Delegates to the underlying FileTypeMap.
See Also: - getFileTypeMap()
/**
* Delegates to the underlying FileTypeMap.
* @see #getFileTypeMap()
*/
@Override
public String getContentType(File file) {
return getFileTypeMap().getContentType(file);
}
Delegates to the underlying FileTypeMap.
See Also: - getFileTypeMap()
/**
* Delegates to the underlying FileTypeMap.
* @see #getFileTypeMap()
*/
@Override
public String getContentType(String fileName) {
return getFileTypeMap().getContentType(fileName);
}
}