/** * Copyright (C) 2012-2017 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 ninja.utils; import java.io.InputStream; import java.util.Enumeration; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import ninja.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.google.inject.Singleton; /** * MimeTypes utils Adapted from play 1.2.4 */ @Singleton public class MimeTypes { private final Logger logger = LoggerFactory.getLogger(MimeTypes.class); private final String PROPERTY_MIMETYPE_PREFIX = "mimetype."; private final String DEFAULT_MIMET_TYPE_LOCATIONS = "ninja/utils/mime-types.properties"; private final Properties mimetypes; private final Pattern extPattern; private final NinjaProperties ninjaProperties; @Inject public MimeTypes(NinjaProperties ninjaProperties) { this.ninjaProperties = ninjaProperties; this.extPattern = Pattern.compile("^.*\\.([^.]+)$"); mimetypes = new Properties(); initMimetypes(); } /** * return the mimetype from a file name * * @param filename * the file name * @return the mimetype or the empty string if not found */ public String getMimeType(String filename) { return getMimeType(filename, ""); } /** * return the mimetype from a file name.<br/> * * @param filename * the file name * @param defaultMimeType * the default mime type to return when no matching mimetype is * found * @return the mimetype */ public String getMimeType(String filename, String defaultMimeType) { Matcher matcher = extPattern.matcher(filename.toLowerCase()); String ext = ""; if (matcher.matches()) { ext = matcher.group(1); } if (ext.length() > 0) { String mimeType = mimetypes.getProperty(ext); if (mimeType == null) { return defaultMimeType; } return mimeType; } return defaultMimeType; } /** * return the content-type from a file name. If none is found returning * application/octet-stream<br/> * For a text-based content-type, also return the encoding suffix eg. * <em>"text/plain; charset=utf-8"</em> * * @param filename * the file name * @return the content-type deduced from the file extension. */ public String getContentType(Context context, String filename) { return getContentType(context, filename, "application/octet-stream"); } /** * return the content-type from a file name.<br/> * For a text-based content-type, also return the encoding suffix eg. * <em>"text/plain; charset=utf-8"</em> * * @param filename * the file name * @param defaultContentType * the default content-type to return when no matching * content-type is found * @return the content-type deduced from the file extension. */ public String getContentType(Context context, String filename, String defaultContentType) { String contentType = getMimeType(filename, null); if (contentType == null) { contentType = defaultContentType; } if (contentType != null && contentType.startsWith("text/")) { // UTF-8 is fixed for now as ninja only supports utf-8 in files... return contentType + "; charset=utf-8"; } return contentType; } /** * check the mimetype is referenced in the mimetypes database * * @param mimeType * the mimeType to verify */ public boolean isValidMimeType(String mimeType) { if (mimeType == null) { return false; } else if (mimeType.indexOf(";") != -1) { return mimetypes.contains(mimeType.split(";")[0]); } else { return mimetypes.contains(mimeType); } } private void initMimetypes() { // Load default mimetypes from the framework try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(DEFAULT_MIMET_TYPE_LOCATIONS);) { mimetypes.load(is); } catch (Exception e) { logger.error("Failed to load mimetypes", e); } // Load custom mimetypes from the application configuration Enumeration confenum = ninjaProperties.getAllCurrentNinjaProperties() .propertyNames(); while (confenum.hasMoreElements()) { String key = (String) confenum.nextElement(); if (key.startsWith(PROPERTY_MIMETYPE_PREFIX)) { String type = key.substring(key.indexOf('.') + 1).toLowerCase(); String value = (String) ninjaProperties.get(key); mimetypes.setProperty(type, value); } } } }