package er.attachment.utils; import java.io.File; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; import com.webobjects.foundation.NSArray; import er.extensions.foundation.ERXProperties; /** * <span class="en"> * ERMimeTypeManager provides an interface to looking up mime type metadata. * </span> * * <span class="ja"> * ERMimeTypeManager は MIME タイプのメタデータをルックアップするインタフェースを提供します。 * </span> * * @property er.attachment.mimeTypes * @property er.attachment.additionalMimeTypes * @property er.attachment.mimeType.[mimeType].name * @property er.attachment.mimeType.[mimeType].uti * @property er.attachment.mimeType.[mimeType].extensions * * @author mschrag */ public class ERMimeTypeManager { private static ERMimeTypeManager INSTANCE; /** * <span class="en"> * Returns the singleton mime type manager. See the top level documentation on information * about configuring custom mime types. * * @return the singleton mime type manager * </span> * * <span class="ja"> * MIME タイプ・マネージャのシングルトンを戻します。 * * @return MIME タイプ・マネージャのシングルトン * </span> */ public static synchronized ERMimeTypeManager mimeTypeManager() { if (ERMimeTypeManager.INSTANCE == null) { ERMimeTypeManager mimeTypeManager = new ERMimeTypeManager(); NSArray<String> mimeTypes = ERXProperties.componentsSeparatedByString("er.attachment.mimeTypes", ","); NSArray<String> additionalMimeTypes = ERXProperties.componentsSeparatedByString("er.attachment.additionalMimeTypes", ","); if (additionalMimeTypes != null) { mimeTypes = mimeTypes.arrayByAddingObjectsFromArray(additionalMimeTypes); } for (String mimeType : mimeTypes) { String name = ERXProperties.stringForKeyWithDefault("er.attachment.mimeType." + mimeType + ".name", mimeType); String uti = ERXProperties.stringForKeyWithDefault("er.attachment.mimeType." + mimeType + ".uti", null); NSArray<String> extensions = ERXProperties.componentsSeparatedByString("er.attachment.mimeType." + mimeType + ".extensions", ","); mimeTypeManager.addMimeType(new ERMimeType(name, mimeType, uti, extensions)); } ERMimeTypeManager.INSTANCE = mimeTypeManager; } return ERMimeTypeManager.INSTANCE; } /** * <span class="en"> * Returns the primary extension for the given mime type. * * @param mimeTypeStr the mime type string to lookup * * @return the primary extension or null if there is no mime type in the system that matches * </span> * * <span class="ja"> * 指定 MIME タイプの優先される拡張子を戻します。 * * @param mimeTypeStr - ルックアップする MIME タイプ * * @return 優先する拡張子、まだはマッチしなければ null * </span> */ public static String primaryExtension(String mimeTypeStr) { ERMimeType mimeType = ERMimeTypeManager.mimeTypeManager().mimeTypeForMimeTypeString(mimeTypeStr, false); String extension = null; if (mimeType != null) { extension = mimeType.primaryExtension(); } return extension; } private List<ERMimeType> _mimeTypes; private ERMimeTypeManager() { _mimeTypes = new LinkedList<>(); } /** * <span class="en"> * Removes all the mime types from this manager. * </span> * * <span class="ja"> * マネージャよりすべての MIME タイプを削除します。 * </span> */ public void clearMimeTypes() { _mimeTypes.clear(); } /** * <span class="en"> * Removes the given mime type definition from this manager. * * @param mimeType the mime type to remove * </span> * * <span class="ja"> * 指定の MIME タイプをマネージャより削除します。 * * @param mimeType - 削除する MIME タイプ * </span> */ public void removeMimeType(ERMimeType mimeType) { _mimeTypes.remove(mimeType); } /** * <span class="en"> * Adds a mime type definition to the manager. * * @param mimeType the mime type to add * </span> * * <span class="ja"> * 指定の MIME タイプをマネージャに追加します。 * * @param mimeType - 追加する MIME タイプ * </span> */ public void addMimeType(ERMimeType mimeType) { _mimeTypes.add(mimeType); } /** * <span class="en"> * Returns the extension for the given filename. * * @param fileName the filename * * @return the extension of the filename (or null) * </span> * * <span class="ja"> * 指定ファイル名の拡張子を戻します。 * * @param fileName - ファイル名 * * @return ファイルの拡張子、又は null * </span> */ public String extensionForFileName(String fileName) { String extension = null; if (fileName != null) { int dotIndex = fileName.lastIndexOf('.'); if (dotIndex != -1) { extension = fileName.substring(dotIndex + 1); } } return extension; } /** * <span class="en"> * Returns the ERMimeType for the given file name, optionally throwing an exception * if the type isn't found. * * @param fileName the file name to lookup * @param exceptionIfNotFound if true, a NoSuchElementException exception is thrown if the mime type isn't found * * @return the matching ERMimeType * </span> * * <span class="ja"> * 指定ファイル名の ERMimeType を戻します。 * オプション指定により、見つからない場合にはエラーを発生させます。 * * @param fileName - ルックアップするファイル名 * @param exceptionIfNotFound - true の場合には見つからない時に NoSuchElementException を発生させます。 * * @return マッチされた ERMimeType * </span> */ public ERMimeType mimeTypeForFileName(String fileName, boolean exceptionIfNotFound) { return mimeTypeForExtension(extensionForFileName(fileName), exceptionIfNotFound); } /** * <span class="en"> * Returns the ERMimeType for the given file, optionally throwing an exception * if the type isn't found. * * @param file the file to lookup * @param exceptionIfNotFound if true, a NoSuchElementException exception is thrown if the mime type isn't found * * @return the matching ERMimeType * </span> * * <span class="ja"> * 指定ファイルの ERMimeType を戻します。 * オプション指定により、見つからない場合にはエラーを発生させます。 * * @param file - ルックアップするファイル * @param exceptionIfNotFound - true の場合には見つからない時に NoSuchElementException を発生させます。 * * @return マッチされた ERMimeType * </span> */ public ERMimeType mimeTypeForFile(File file, boolean exceptionIfNotFound) { String extension = (file == null ? null : extensionForFileName(file.getName())); return mimeTypeForExtension(extension, exceptionIfNotFound); } /** * <span class="en"> * Returns the ERMimeType for the given mime type string, optionally throwing an exception * if the type isn't found. * * @param mimeType the mime type string to lookup * @param exceptionIfNotFound if true, a NoSuchElementException exception is thrown if the mime type isn't found * * @return the matching ERMimeType * </span> * * <span class="ja"> * 指定 MIME タイプの ERMimeType を戻します。 * オプション指定により、見つからない場合にはエラーを発生させます。 * * @param mimeType - ルックアップする MIME タイプ * @param exceptionIfNotFound - true の場合には見つからない時に NoSuchElementException を発生させます。 * * @return マッチされた ERMimeType * </span> */ public ERMimeType mimeTypeForMimeTypeString(String mimeType, boolean exceptionIfNotFound) { ERMimeType matchingMimeType = null; if (mimeType != null) { Iterator<ERMimeType> mimeTypesIter = _mimeTypes.iterator(); while (matchingMimeType == null && mimeTypesIter.hasNext()) { ERMimeType possibleMatchingMimeType = mimeTypesIter.next(); if (possibleMatchingMimeType.mimeType().equals(mimeType)) { matchingMimeType = possibleMatchingMimeType; } } if (mimeType != null && mimeType.indexOf("*") != -1) { matchingMimeType = new ERGlobMimeType(mimeType); } if (exceptionIfNotFound && matchingMimeType == null) { throw new NoSuchElementException("There is no registered mime type for the type " + mimeType + "."); } } return matchingMimeType; } /** * <span class="en"> * Returns the ERMimeType for the given file extension, optionally throwing an exception * if the type isn't found. * * @param extension the file extension to lookup * @param exceptionIfNotFound if true, a NoSuchElementException exception is thrown if the mime type isn't found * * @return the matching ERMimeType * </span> * * <span class="ja"> * 指定拡張子の ERMimeType を戻します。 * オプション指定により、見つからない場合にはエラーを発生させます。 * * @param extension - ルックアップする拡張子 * @param exceptionIfNotFound - true の場合には見つからない時に NoSuchElementException を発生させます。 * * @return マッチされた ERMimeType * </span> */ public ERMimeType mimeTypeForExtension(String extension, boolean exceptionIfNotFound) { ERMimeType matchingMimeType = null; if (extension != null) { String lowercaseExtension = extension.toLowerCase(); Iterator<ERMimeType> mimeTypesIter = _mimeTypes.iterator(); while (matchingMimeType == null && mimeTypesIter.hasNext()) { ERMimeType mimeType = mimeTypesIter.next(); if (mimeType.isRepresentedByExtension(lowercaseExtension)) { matchingMimeType = mimeType; } } } if (exceptionIfNotFound && matchingMimeType == null) { throw new NoSuchElementException("There is no registered mime type for the extension " + extension + "."); } return matchingMimeType; } /** * <span class="en"> * Returns the ERMimeType for the given UTI, optionally throwing an exception * if the type isn't found. * * @param uti the UTI to lookup * @param exceptionIfNotFound if true, a NoSuchElementException exception is thrown if the mime type isn't found * * @return the matching ERMimeType * </span> * * <span class="ja"> * 指定 UTI の ERMimeType を戻します。 * オプション指定により、見つからない場合にはエラーを発生させます。 * * @param uti - ルックアップする UTI * @param exceptionIfNotFound - true の場合には見つからない時に NoSuchElementException を発生させます。 * * @return マッチされた ERMimeType * </span> */ public ERMimeType mimeTypeForUTI(String uti, boolean exceptionIfNotFound) { ERMimeType matchingMimeType = null; if (uti != null) { Iterator<ERMimeType> mimeTypesIter = _mimeTypes.iterator(); while (matchingMimeType == null && mimeTypesIter.hasNext()) { ERMimeType mimeType = mimeTypesIter.next(); if (uti.equals(mimeType.uti())) { matchingMimeType = mimeType; } } } if (exceptionIfNotFound && matchingMimeType == null) { throw new NoSuchElementException("There is no registered mime type for the uti '" + uti + "'."); } return matchingMimeType; } }