package com.limegroup.gnutella.gui.search; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Locale; import java.util.MissingResourceException; import java.awt.Component; import java.awt.Graphics; import javax.swing.Icon; import javax.swing.ImageIcon; import com.limegroup.gnutella.MediaType; import com.limegroup.gnutella.gui.GUIMediator; import com.limegroup.gnutella.gui.tables.IconAndNameHolder; import com.limegroup.gnutella.gui.xml.XMLUtils; import com.limegroup.gnutella.xml.LimeXMLProperties; import com.limegroup.gnutella.xml.LimeXMLSchema; import com.limegroup.gnutella.xml.LimeXMLSchemaRepository; /** * Associates a MediaType with a LimeXMLSchema. * * Also contains factory methods for retrieving all media types, * and retrieving the media type associated with a specific TableLine. */ public class NamedMediaType implements IconAndNameHolder, Comparable { /** * The cached mapping of description -> media type, * for easy looking up from incoming results. */ private static final Map /* String -> NamedMediaType */ CACHED_TYPES = new HashMap(); /** * The MediaType this is describing. */ private final MediaType _mediaType; /** * The name used to describe this MediaType/LimeXMLSchema. */ private final String _name; /** * The icon used to display this mediaType/LimeXMLSchema. */ private final Icon _icon; /** * The (possibly null) LimeXMLSchema. */ private final LimeXMLSchema _schema; /** * Constructs a new NamedMediaType, associating the MediaType with the * LimeXMLSchema. */ public NamedMediaType(MediaType mt, LimeXMLSchema schema) { if(mt == null) throw new NullPointerException("Null media type."); this._mediaType = mt; this._schema = schema; this._name = constructName(_mediaType, _schema); this._icon = getIcon(_mediaType, _schema); } /** * Compares this NamedMediaType to another. */ public int compareTo(Object o) { NamedMediaType other = (NamedMediaType)o; return _name.compareTo(other._name); } /** * Returns the name of this NamedMediaType. */ public String getName() { return _name; } /** * Returns the icon representing this NamedMediaType. */ public Icon getIcon() { return _icon; } /** * Returns the description of this NamedMediaType. */ public String toString() { return _name; } /** * Returns the media type this is wrapping. */ public MediaType getMediaType() { return _mediaType; } /** * Returns the schema this is wrapping. */ public LimeXMLSchema getSchema() { return _schema; } /** * Retrieves the named media type for the specified schema uri. * * This should only be used if you are positive that the media type * is already cached for this description OR it is not a default * type. */ public static NamedMediaType getFromDescription(String description) { NamedMediaType type = (NamedMediaType)CACHED_TYPES.get(description); if(type != null) return type; type = new NamedMediaType(new MediaType(description), null); CACHED_TYPES.put(description, type); return type; } /** * Retrieves the named media type from the specified extension. * * This should only be used if you are positive that the media type * is already cached for this extension. */ public static NamedMediaType getFromExtension(String extension) { MediaType mt = MediaType.getMediaTypeForExtension(extension); if(mt == null) return null; String description = mt.getMimeType(); return getFromDescription(description); } /** * Retrieves all possible media types, wrapped in a NamedMediaType. */ public static List getAllNamedMediaTypes() { List allSchemas = new LinkedList(); //Add all our schemas to the list. for(Iterator i = LimeXMLSchemaRepository.instance(). getAvailableSchemas().iterator(); i.hasNext(); ) { LimeXMLSchema schema = (LimeXMLSchema)i.next(); allSchemas.add(getFromSchema(schema)); } //Add any default media types that haven't been added already. MediaType allTypes[] = MediaType.getDefaultMediaTypes(); for(int i = 0; i < allTypes.length; i++) { if(!containsMediaType(allSchemas, allTypes[i])) allSchemas.add(getFromMediaType(allTypes[i])); } return allSchemas; } /** * Retrieves the named media type for the specified schema. */ private static NamedMediaType getFromSchema(LimeXMLSchema schema) { String description = schema.getDescription(); NamedMediaType type = (NamedMediaType)CACHED_TYPES.get(description); if(type != null) return type; MediaType mt; // If it's not a default type, the MediaType is constructed. if(!MediaType.isDefaultType(description)) { mt = new MediaType(description); } else { // Otherwise, the default MediaType is used. mt = MediaType.getMediaTypeForSchema(description); } type = new NamedMediaType(mt, schema); CACHED_TYPES.put(description, type); return type; } /** * Retrieves the named media type for the specified media type. */ public static NamedMediaType getFromMediaType(MediaType media) { String description = media.getMimeType(); NamedMediaType type = (NamedMediaType)CACHED_TYPES.get(description); if(type != null) return type; type = new NamedMediaType(media, null); CACHED_TYPES.put(description, type); return type; } /** * Determines whether or not the specified MediaType is in a list of * NamedMediaTypes. */ private static boolean containsMediaType(List named, MediaType type) { for(Iterator i = named.iterator(); i.hasNext(); ) if(((NamedMediaType)i.next()).getMediaType().equals(type)) return true; return false; } /** * Retrieves the icon representing the MediaType/Schema. */ private Icon getIcon(MediaType type, LimeXMLSchema schema) { final ImageIcon icon; if(type == MediaType.getAnyTypeMediaType()) icon = GUIMediator.getThemeImage("lime"); else { String location = LimeXMLProperties.instance().getXMLImagesDir() + type.getMimeType(); icon = GUIMediator.getImageFromPath(location); if(icon == null) { return new EmptyIcon(getName(), 16, 16); } } icon.setDescription(getName()); return icon; } /** * Returns the human-readable description of this MediaType/Schema. */ private static String constructName(MediaType type, LimeXMLSchema schema) { // If we can act off the MediaType. String name = null; if(type.isDefault()) { String key = type.getDescriptionKey(); try { if(key != null) name = GUIMediator.getStringResource(key); } catch(MissingResourceException mre) { // oh well, will capitalize the mime-type } // If still no name, capitalize the mime-type. if(name == null) { name = type.getMimeType(); name = name.substring(0, 1).toUpperCase(Locale.US) + name.substring(1); } } else { name = XMLUtils.getTitleForSchema(schema); } return name; } private static class EmptyIcon implements Icon { private final String name; private final int width; private final int height; public EmptyIcon(String name, int width, int height) { this.name = name; this.width = width; this.height = height; } public void paintIcon(Component c, Graphics g, int x, int y) {} public int getIconWidth() { return width; } public int getIconHeight() { return height; } public String toString() { return name; } } }