/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/kernel/trunk/kernel-impl/src/main/java/org/sakaiproject/content/impl/BasicContentTypeImageService.java $ * $Id: BasicContentTypeImageService.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Sakai Foundation * * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.content.impl; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.content.api.ContentTypeImageService; import org.sakaiproject.util.Resource; import org.sakaiproject.util.ResourceLoader; /** * <p> * BasicContentTypeImage implements the ContentTypeImageService. * </p> */ public class BasicContentTypeImageService implements ContentTypeImageService { private ServerConfigurationService serverConfigurationService = null; /** Our logger. */ private static Log M_log = LogFactory.getLog(BasicContentTypeImageService.class); /** Map content type to image file name. */ //protected Properties m_contentTypeImages = null; /** Map content type to display name. */ //protected Properties m_contentTypeDisplayNames = null; /** Map content type to file extension. */ //protected Properties m_contentTypeExtensions = null; /** Map file extension to content type. */ protected Properties m_contentTypes = null; protected SortedMap<String, SortedSet<String>> m_mimetypes = null; /** Default file extension for unknown types. */ protected static final String DEFAULT_EXTENSION = ""; /** Default image file for unknown types. */ protected static final String DEFAULT_IMAGE = "/sakai/generic.gif"; /** Default file display name for unknown types. */ protected static final String DEFAULT_DISPLAY_NAME = "Unknown"; /** Default content type for unknown extensions. */ protected static final String UNKNOWN_TYPE = "application/octet-stream"; /** Another type reported when the file is unknown, Mac IE 5.2. */ // Note: although this is reported by IE, it's not just binary... // protected static final String UNKNOWN_TYPE_II = "application/x-macbinary"; /** The file name containing the image definitions. */ protected String m_imageFileName = null; /** The file name containing the name definitions. */ protected String m_nameFileName = null; /** The file name containing the extension definitions. */ protected String m_extensionFileName = null; /** localized properties **/ private static final String DEFAULT_RESOURCECLASS = "org.sakaiproject.localization.util.ContentTypeProperties"; private static final String DEFAULT_EXTENSIONFILEBUNDLE = "org.sakaiproject.localization.bundle.content_type.content_type_extensions"; private static final String DEFAULT_IMAGEFILEBUNDLE = "org.sakaiproject.localization.bundle.content_type.content_type_images"; private static final String DEFAULT_NAMEFILEBUNDLE = "org.sakaiproject.localization.bundle.content_type.content_type_names"; private static final String RESOURCECLASS = "resource.class.contenttype"; private static final String EXTENSIONFILEBUNDLE = "resource.bundle.contenttype.extensionfile"; private static final String IMAGEFILEBUNDLE = "resource.bundle.contenttype.imagefile"; private static final String NAMEFILEBUNDLE = "resource.bundle.contenttype.namefile"; protected ResourceLoader m_contentTypeExtensions = null; protected ResourceLoader m_contentTypeImages = null; protected ResourceLoader m_contentTypeDisplayNames = null; /********************************************************************************************************************************************************************************************************************************************************** * Constructors, Dependencies and their setter methods *********************************************************************************************************************************************************************************************************************************************************/ /** * Inject ServerConfigurationService * @param serverConfigurationService */ public void setServerConfigurationService(ServerConfigurationService service) { serverConfigurationService = service; } /** * Set the file name containing the image definitions. * * @param name * the file name. */ /* public void setImageFile(String name) { m_imageFileName = name; } */ /** * Set the file name containing the name definitions. * * @param name * the file name. */ /* public void setNameFile(String name) { m_nameFileName = name; } */ /** * Set the file name containing the extension definitions. * * @param name * the file name. */ /* public void setExtensionFile(String name) { m_extensionFileName = name; } */ /********************************************************************************************************************************************************************************************************************************************************** * Init and Destroy *********************************************************************************************************************************************************************************************************************************************************/ /** * Final initialization, once all dependencies are set. */ public void init() { String resourceClass = serverConfigurationService.getString(RESOURCECLASS, DEFAULT_RESOURCECLASS); String extensionFileBundle = serverConfigurationService.getString(EXTENSIONFILEBUNDLE, DEFAULT_EXTENSIONFILEBUNDLE); String imageFileBundle = serverConfigurationService.getString(IMAGEFILEBUNDLE, DEFAULT_IMAGEFILEBUNDLE); String nameFileBundle = serverConfigurationService.getString(NAMEFILEBUNDLE, DEFAULT_NAMEFILEBUNDLE); m_contentTypeExtensions = new Resource().getLoader(resourceClass, extensionFileBundle); m_contentTypeImages = new Resource().getLoader(resourceClass, imageFileBundle); m_contentTypeDisplayNames = new Resource().getLoader(resourceClass, nameFileBundle); // read the content type extensions file, using extension as the key if (m_contentTypeExtensions != null) { m_contentTypes = new Properties(); m_mimetypes = new TreeMap<String, SortedSet<String>>(); Set<?> set = m_contentTypeExtensions.entrySet(); Iterator<?> it = set.iterator(); while (it.hasNext()) { Map.Entry<?,?> entry = (Map.Entry<?,?>) it.next(); // MIME type is the string before the equal sign String type = entry.getKey().toString(); //String type = key.substring(0, key.indexOf("=")); if (!(type.startsWith("#"))) { // update the list of mime subtypes for the mime category int index = type.indexOf("/"); if (index > 0 && (index + 1) < type.length()) { String category = type.substring(0, index).trim(); String subtype = type.substring(index + 1).trim(); SortedSet<String> subtypes = (SortedSet<String>) m_mimetypes.get(category); if (subtypes == null) { subtypes = new TreeSet<String>(); } subtypes.add(subtype); m_mimetypes.put(category, subtypes); } // extension string is after the equal sign // parse the extension string by space String tokens = entry.getValue().toString(); //String tokens = value.substring(value.indexOf("=") + 1); StringTokenizer st = new StringTokenizer(tokens, " ", false); if (!st.hasMoreTokens()) continue; while (st.hasMoreTokens()) { String ext = st.nextToken(); m_contentTypes.put(ext, type); } } // Debug M_log.debug(entry.getKey() + " : " + entry.getValue()); } } else { M_log.warn("init(): Resource loader failed to load content type extensions bundle"); } } // init /** * Returns to uninitialized state. */ public void destroy() { m_contentTypeImages = null; m_contentTypeDisplayNames = null; m_contentTypeExtensions = null; m_contentTypes.clear(); m_contentTypes = null; m_mimetypes.clear(); m_mimetypes = null; M_log.info("destroy()"); } // shutdown /********************************************************************************************************************************************************************************************************************************************************** * ContentTypeImageService implementation *********************************************************************************************************************************************************************************************************************************************************/ /** * Get the image file name based on the content type. * * @param contentType * The content type string. * @return The image file name based on the content type. */ public String getContentTypeImage(String contentType) { String image = DEFAULT_IMAGE; if (contentType != null && m_contentTypeImages.getIsValid(contentType.toLowerCase())) { image = m_contentTypeImages.getString(contentType.toLowerCase()); } return image; } // getContentTypeImage /** * Get the display name of the content type. * * @param contentType * The content type string. * @return The display name of the content type. */ public String getContentTypeDisplayName(String contentType) { String name = m_contentTypeDisplayNames.getString("contenttype.name.default"); if (contentType != null && m_contentTypeDisplayNames.getIsValid(contentType.toLowerCase())) { name = m_contentTypeDisplayNames.getString(contentType.toLowerCase()); } if (name == null || name.equals("")) { name = DEFAULT_DISPLAY_NAME; } return name; } // getContentTypeDisplayName /** * Get the file extension value of the content type. * * @param contentType * The content type string. * @return The file extension value of the content type. */ public String getContentTypeExtension(String contentType) { String extension = DEFAULT_EXTENSION; if (contentType != null && m_contentTypeExtensions.getIsValid(contentType.toLowerCase())) { extension = m_contentTypeExtensions.getString(contentType.toLowerCase()); if (extension.indexOf(" ") != -1) { // possibility of multiple extensions for this MIME type, get one listed first extension = extension.substring(0, extension.indexOf(" ")); } } return extension; } // getContentTypeExtension // public String getContentTypeExtension(String contentType) // { // String extension = m_contentTypeExtensions.getString(contentType.toLowerCase()); // String extension = m_contentTypeExtensions.getProperty(contentType.toLowerCase()); // if not there, use empty String // if (extension == null) // { // extension = ""; // } // else // { // if (extension.indexOf(" ") != -1) // { // there might be more than one extension for this MIME type, get one listed first // extension = extension.substring(0, extension.indexOf(" ")); // } // } // return extension; // } // getContentTypeExtension /** * Get the content type string that is used for this file extension. * * @param extension * The file extension (to the right of the dot, not including the dot). * @return The content type string that is used for this file extension. */ public String getContentType(String extension) { String type = m_contentTypes.getProperty(extension.toLowerCase()); // if not there, use the UNKNOWN_TYPE if (type == null) type = UNKNOWN_TYPE; return type; } // getContentTypeDisplayName /** * Is the type one of the known types used when the file type is unknown? * * @param contentType * The content type string to test. * @return true if the type is a type used for unknown file types, false if not. */ public boolean isUnknownType(String contentType) { if (contentType.equals(UNKNOWN_TYPE)) return true; // if (contentType.equals(UNKNOWN_TYPE_II)) return true; return false; } // isUnknownType /** * Access an ordered list of all mimetype categories. * * @return The list of mimetype categories in alphabetic order. */ public List<String> getMimeCategories() { List<String> rv = new Vector<String>(); Set<String> categories = m_mimetypes.keySet(); if (categories != null) { rv.addAll(categories); } return rv; } /** * Access an ordered list of all mimetype subtypes for a particular category. * * @param category * The category. * @return The list of mimetype subtypes in alphabetic order. */ public List<String> getMimeSubtypes(String category) { List<String> rv = new Vector<String>(); Set<String> subtypes = (Set<String>) m_mimetypes.get(category); if (subtypes != null) { rv.addAll(subtypes); } return rv; } } // BasicContentTypeImage