/**
* DSS - Digital Signature Services
* Copyright (C) 2015 European Commission, provided under the CEF programme
*
* This file is part of the "DSS - Digital Signature Services" project.
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package eu.europa.esig.dss;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* This class allows to handle different mime types. It also allows to add
* (define) new mime-type.
*/
@SuppressWarnings("serial")
public class MimeType implements Serializable {
private static Map<String, MimeType> mimeTypes = new HashMap<String, MimeType>();
public static final MimeType BINARY = new MimeType("application/octet-stream");
public static final MimeType XML = new MimeType("text/xml");
public static final MimeType PDF = new MimeType("application/pdf");
public static final MimeType PKCS7 = new MimeType("application/pkcs7-signature");
public static final MimeType ASICS = new MimeType("application/vnd.etsi.asic-s+zip");
public static final MimeType ASICE = new MimeType("application/vnd.etsi.asic-e+zip");
public static final MimeType ODT = new MimeType("application/vnd.oasis.opendocument.text");
public static final MimeType ODS = new MimeType("application/vnd.oasis.opendocument.spreadsheet");
public static final MimeType TEXT = new MimeType("text/plain");
public static final MimeType PNG = new MimeType("image/png");
public static final MimeType JPEG = new MimeType("image/jpeg");
private String mimeTypeString;
private static Map<String, MimeType> fileExtensions = new HashMap<String, MimeType>() {
{
put("xml", XML);
put("pkcs7", PKCS7);
put("p7s", PKCS7);
put("pdf", PDF);
put("asics", ASICS);
put("scs", ASICS);
put("asice", ASICE);
put("sce", ASICE);
// estonian bdoc file type is handled as asic-e document
put("bdoc", ASICE);
// ASiC-E + XML (not XAdES)
put("odt", ODT);
put("ods", ODS);
put("txt", TEXT);
put("png", PNG);
put("jpg", JPEG);
put("jpeg", JPEG);
}
};
/**
* This constructor is used only by the web-services.
*/
public MimeType() {
}
/**
* The default constructor for MimeType.
*
* @param mimeTypeString
* is a string identifier composed of two parts: a "type" and a
* "subtype"
*/
private MimeType(final String mimeTypeString) {
if (!mimeTypeString.matches("([\\w])*/([\\w\\-\\+\\.])*")) {
throw new DSSException("'" + mimeTypeString + "' is not conformant mime-type string!");
}
if (mimeTypes.get(mimeTypeString) != null) {
throw new DSSException(
"'" + mimeTypeString + "' corresponding MimeType exists already! Use #fromMimeTypeString method to obtain the corresponding object.");
}
this.mimeTypeString = mimeTypeString;
mimeTypes.put(mimeTypeString, this);
}
/**
* This constructor allows to create a new MimeType related to given file
* extension. Be careful, if the file extension has already an associated
* {@code MimeType} then this relation will be lost.
*
* @param mimeTypeString
* is a string identifier composed of two parts: a "type" and a
* "subtype"
* @param extension
* to be defined. Example: "txt", note that there is no point
* before the extension name.
*/
public MimeType(final String mimeTypeString, final String extension) {
this(mimeTypeString);
fileExtensions.put(extension, this);
}
/**
* @return the mimeTypeString
*/
public String getMimeTypeString() {
return mimeTypeString;
}
/**
* This setter is used by the web-services.
*
* @param mimeTypeString
* is a string identifier composed of two parts: a "type" and a
* "subtype"
*/
public void setMimeTypeString(String mimeTypeString) {
this.mimeTypeString = mimeTypeString;
}
/**
* This method returns the mime-type extrapolated from the file name.
*
* @param fileName
* the file name to be analysed
* @return the extrapolated mime-type of the file name
*/
public static MimeType fromFileName(final String fileName) {
final String inLowerCaseName = fileName.toLowerCase();
final String fileExtension = getFileExtension(inLowerCaseName);
final MimeType mimeType = fileExtensions.get(fileExtension);
if (mimeType != null) {
return mimeType;
}
return BINARY;
}
public static String getExtension(MimeType mimeType) {
for (Entry<String, MimeType> entry : fileExtensions.entrySet()) {
if (mimeType.equals(entry.getValue())) {
return entry.getKey();
}
}
return "";
}
/**
* Returns the file extension based on the position of the '.' in the path.
* The paths as "xxx.y/toto" are not handled.
*
* @param path
* to be analysed
* @return the file extension or null
*/
public static String getFileExtension(final String path) {
String extension = null;
int lastIndexOf = path.lastIndexOf('.');
if (lastIndexOf > 0) {
extension = path.substring(lastIndexOf + 1);
}
return extension;
}
/**
* This method returns the mime-type extrapolated from the file.
*
* @param file
* the file to be analysed
* @return the extrapolated mime-type of the file
*/
public static MimeType fromFile(final File file) {
final String fileName = file.getName();
final MimeType mimeType = fromFileName(fileName);
return mimeType;
}
/**
* This method returns the first representation of the {@code MimeType}
* corresponding to the given mime-type string.
*
* @param mimeTypeString
* is a string identifier composed of two parts: a "type" and a
* "subtype"
* @return the extrapolated mime-type from the {@code String}
*/
public static MimeType fromMimeTypeString(final String mimeTypeString) {
MimeType mimeType = mimeTypes.get(mimeTypeString);
if (mimeType == null) {
mimeType = new MimeType(mimeTypeString);
}
return mimeType;
}
/**
* This method allows to define a new relationship between a file extension
* and a {@code MimeType}.
*
* @param extension
* to be defined. Example: "txt", note that there is no point
* before the extension name.
*/
public void defineFileExtension(final String extension) {
fileExtensions.put(extension, this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + ((mimeTypeString == null) ? 0 : mimeTypeString.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MimeType other = (MimeType) obj;
if (mimeTypeString == null) {
if (other.mimeTypeString != null) {
return false;
}
} else if (!mimeTypeString.equals(other.mimeTypeString)) {
return false;
}
return true;
}
}