/* DataFlavor.java -- A type of data to transfer via the clipboard.
   Copyright (C) 1999, 2001, 2004, 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.datatransfer;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OptionalDataException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.rmi.Remote;

/**
 * This class represents a particular data format used for transferring
 * data via the clipboard.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public class DataFlavor implements java.io.Externalizable, Cloneable
{
  static final long serialVersionUID = 8367026044764648243L;

  // FIXME: Serialization: Need to write methods for.

  /**
   * This is the data flavor used for tranferring plain text.  The MIME
   * type is "text/plain; charset=unicode".  The representation class
   * is <code>java.io.InputStream</code>.
   *
   * @deprecated The charset unicode is platform specific and InputStream
   * deals with bytes not chars. Use <code>getRederForText()</code>.
   */
  public static final DataFlavor plainTextFlavor =
    new DataFlavor("text/plain; charset=unicode; class=java.io.InputStream",
                   "plain unicode text");

  /**
   * This is the data flavor used for transferring Java strings.  The
   * MIME type is "application/x-java-serialized-object" and the
   * representation class is <code>java.lang.String</code>.
   */
  public static final DataFlavor stringFlavor =
    new DataFlavor(java.lang.String.class, "Java Unicode String");

  /**
   * This is a data flavor used for transferring lists of files.  The
   * representation type is a <code>java.util.List</code>, with each
   * element of the list being a <code>java.io.File</code>.
   */
  public static final DataFlavor javaFileListFlavor =
    new DataFlavor("application/x-java-file-list; class=java.util.List",
                   "Java File List");

  /**
   * This is an image flavor used for transferring images.  The
   * representation type is a <code>java.awt.Image</code>.
   */
  public static final DataFlavor imageFlavor =
    new DataFlavor(java.awt.Image.class, "Java Image");

  /**
   * This is the MIME type used for transferring a serialized object.
   * The representation class is the type of object be deserialized.
   */
  public static final String javaSerializedObjectMimeType =
    "application/x-java-serialized-object";

  /**
   * This is the MIME type used to transfer a Java object reference within
   * the same JVM.  The representation class is the class of the object
   * being transferred.
   */
  public static final String javaJVMLocalObjectMimeType =
    "application/x-java-jvm-local-objectref";

  /**
   * This is the MIME type used to transfer a link to a remote object.
   * The representation class is the type of object being linked to.
   */
  public static final String javaRemoteObjectMimeType =
    "application/x-java-remote-object";

  /*
   * Instance Variables
   */

  // The MIME type for this flavor
  private MimeType mimeType;

  // The representation class for this flavor
  private Class<?> representationClass;

  // The human readable name of this flavor
  private String humanPresentableName;

  /*
   * Static Methods
   */

  /**
   * This method attempts to load the named class.  The following class
   * loaders are searched in order: the bootstrap class loader, the
   * system class loader, the context class loader (if it exists), and
   * the specified fallback class loader.
   *
   * @param className The name of the class to load.
   * @param classLoader The class loader to use if all others fail, which
   * may be <code>null</code>.
   *
   * @exception ClassNotFoundException If the class cannot be loaded.
   */
  protected static final Class<?> tryToLoadClass(String className,
                                                 ClassLoader classLoader)
    throws ClassNotFoundException
  {
    // Bootstrap
    try
      {
        return Class.forName(className);
      }
    catch(ClassNotFoundException cnfe)
      {
        // Ignored.
      }

    // System
    try
      {
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        return Class.forName(className, true, loader);
      }
    catch(ClassNotFoundException cnfe)
      {
        // Ignored.
      }

    // Context
    try
      {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        return Class.forName(className, true, loader);
      }
    catch(ClassNotFoundException cnfe)
      {
        // Ignored.
      }

    if (classLoader != null)
      return Class.forName(className, true, classLoader);

    throw new ClassNotFoundException(className);
  }

  /**
   * XXX - Currently returns <code>plainTextFlavor</code>.
   */
  public static final DataFlavor getTextPlainUnicodeFlavor()
  {
    return plainTextFlavor;
  }

  /**
   * Selects the best supported text flavor on this implementation.
   * Returns <code>null</code> when none of the given flavors is liked.
   *
   * The <code>DataFlavor</code> returned the first data flavor in the
   * array that has either a representation class which is (a subclass of)
   * <code>Reader</code> or <code>String</code>, or has a representation
   * class which is (a subclass of) <code>InputStream</code> and has a
   * primary MIME type of "text" and has an supported encoding.
   */
  public static final DataFlavor
    selectBestTextFlavor(DataFlavor[] availableFlavors)
  {
    for(int i = 0; i < availableFlavors.length; i++)
      {
        DataFlavor df = availableFlavors[i];
        Class c = df.representationClass;

        // A Reader or String is good.
        if ((Reader.class.isAssignableFrom(c))
           || (String.class.isAssignableFrom(c)))
      return df;

        // A InputStream is good if the mime primary type is "text"
        if ((InputStream.class.isAssignableFrom(c))
           && ("text".equals(df.getPrimaryType())))
          {
            String encoding = availableFlavors[i].getParameter("charset");
            if (encoding == null)
              encoding = "us-ascii";
            Reader r = null;
            try
              {
                // Try to construct a dummy reader with the found encoding
                r = new InputStreamReader
                      (new ByteArrayInputStream(new byte[0]), encoding);
              }
            catch(UnsupportedEncodingException uee) { /* ignore */ }

            if (r != null)
              return df;
          }
      }

    // Nothing found
    return null;
  }


  /*
   * Constructors
   */

  /**
   * Empty public constructor needed for externalization.
   * Should not be used for normal instantiation.
   */
  public DataFlavor()
  {
    // Used for deserialization only, nothing to do here.
  }

  /**
   * Initializes a new instance of <code>DataFlavor</code>.  The class
   * and human readable name are specified, the MIME type will be
   * "application/x-java-serialized-object". If the human readable name
   * is not specified (<code>null</code>) then the human readable name
   * will be the same as the MIME type.
   *
   * @param representationClass The representation class for this object.
   * @param humanPresentableName The display name of the object.
   */
  public DataFlavor(Class<?> representationClass, String humanPresentableName)
  {
    if (representationClass == null)
      throw new NullPointerException("representationClass must not be null");
    try
      {
        mimeType = new MimeType(javaSerializedObjectMimeType);
      }
    catch (MimeTypeParseException ex)
      {
        // Must not happen as we use a constant string.
        assert false;
      }
    if (humanPresentableName == null)
      humanPresentableName = javaSerializedObjectMimeType;
    this.humanPresentableName = humanPresentableName;
    this.representationClass = representationClass;
  }

  /**
   * Initializes a new instance of <code>DataFlavor</code> with the
   * specified MIME type and description.  If the MIME type has a
   * "class=&lt;rep class&gt;" parameter then the representation class will
   * be the class name specified. Otherwise the class defaults to
   * <code>java.io.InputStream</code>. If the human readable name
   * is not specified (<code>null</code>) then the human readable name
   * will be the same as the MIME type.
   *
   * @param mimeType The MIME type for this flavor.
   * @param humanPresentableName The display name of this flavor.
   * @param classLoader The class loader for finding classes if the default
   * class loaders do not work.
   *
   * @exception IllegalArgumentException If the representation class
   * specified cannot be loaded.
   * @exception ClassNotFoundException If the class is not loaded.
   */
  public DataFlavor(String mimeType, String humanPresentableName,
                   ClassLoader classLoader)
    throws ClassNotFoundException
  {
    init(mimeType, humanPresentableName, classLoader);
  }

  /**
   * Initializes a new instance of <code>DataFlavor</code> with the
   * specified MIME type and description.  If the MIME type has a
   * "class=&lt;rep class&gt;" parameter then the representation class will
   * be the class name specified. Otherwise the class defaults to
   * <code>java.io.InputStream</code>. If the human readable name
   * is not specified (<code>null</code>) then the human readable name
   * will be the same as the MIME type. This is the same as calling
   * <code>new DataFlavor(mimeType, humanPresentableName, null)</code>.
   *
   * @param mimeType The MIME type for this flavor.
   * @param humanPresentableName The display name of this flavor.
   *
   * @exception IllegalArgumentException If the representation class
   * specified cannot be loaded.
   */
  public DataFlavor(String mimeType, String humanPresentableName)
  {
    try
      {
        init(mimeType, humanPresentableName, getClass().getClassLoader());
      }
    catch (ClassNotFoundException ex)
      {
        IllegalArgumentException iae =
          new IllegalArgumentException("Class not found: " + ex.getMessage());
        iae.initCause(ex);
        throw iae;
      }
  }

  /**
   * Initializes a new instance of <code>DataFlavor</code> with the specified
   * MIME type.  This type can have a "class=" parameter to specify the
   * representation class, and then the class must exist or an exception will
   * be thrown. If there is no "class=" parameter then the representation class
   * will be <code>java.io.InputStream</code>. This is the same as calling
   * <code>new DataFlavor(mimeType, null)</code>.
   *
   * @param mimeType The MIME type for this flavor.
   *
   * @exception IllegalArgumentException If a class is not specified in
   * the MIME type.
   * @exception ClassNotFoundException If the class cannot be loaded.
   */
  public DataFlavor(String mimeType) throws ClassNotFoundException
  {
    init(mimeType, null, getClass().getClassLoader());
  }

  /**
   * Called by various constructors to initialize this object.
   *
   * @param mime the mime string
   * @param humanPresentableName the human presentable name
   * @param loader the class loader to use for loading the representation
   *        class
   */
  private void init(String mime, String humanPresentableName,
                    ClassLoader loader)
    throws ClassNotFoundException
  {
    if (mime == null)
      throw new NullPointerException("The mime type must not be null");
    try
      {
        mimeType = new MimeType(mime);
      }
    catch (MimeTypeParseException ex)
      {
        IllegalArgumentException iae =
          new IllegalArgumentException("Invalid mime type");
        iae.initCause(ex);
        throw iae;
      }
    String className = mimeType.getParameter("class");
    if (className == null)
      {
        if (mimeType.getBaseType().equals(javaSerializedObjectMimeType))
          throw new IllegalArgumentException("Serialized object type must have"
                                        + " a representation class parameter");
        else
          representationClass = java.io.InputStream.class;
      }
    else
      representationClass = tryToLoadClass(className, loader);
    mimeType.addParameter("class", representationClass.getName());

    if (humanPresentableName == null)
      {
        humanPresentableName = mimeType.getParameter("humanPresentableName");
        if (humanPresentableName == null)
          humanPresentableName = mimeType.getBaseType();
      }
    this.humanPresentableName = humanPresentableName;
  }

  /**
   * Returns the MIME type of this flavor.
   *
   * @return The MIME type for this flavor.
   */
  public String getMimeType()
  {
    return(mimeType.toString());
  }

  /**
   * Returns the representation class for this flavor.
   *
   * @return The representation class for this flavor.
   */
  public Class<?> getRepresentationClass()
  {
    return(representationClass);
  }

  /**
   * Returns the human presentable name for this flavor.
   *
   * @return The human presentable name for this flavor.
   */
  public String getHumanPresentableName()
  {
    return(humanPresentableName);
  }

  /**
   * Returns the primary MIME type for this flavor.
   *
   * @return The primary MIME type for this flavor.
   */
  public String getPrimaryType()
  {
    return(mimeType.getPrimaryType());
  }

  /**
   * Returns the MIME subtype for this flavor.
   *
   * @return The MIME subtype for this flavor.
   */
  public String getSubType()
  {
    return mimeType.getSubType();
  }

  /**
   * Returns the value of the named MIME type parameter, or <code>null</code>
   * if the parameter does not exist.
   *
   * @param paramName The name of the paramter.
   *
   * @return The value of the parameter.
   */
  public String getParameter(String paramName)
  {
    if ("humanPresentableName".equals(paramName))
      return getHumanPresentableName();

    return mimeType.getParameter(paramName);
  }

  /**
   * Sets the human presentable name to the specified value.
   *
   * @param humanPresentableName The new display name.
   */
  public void setHumanPresentableName(String humanPresentableName)
  {
    this.humanPresentableName = humanPresentableName;
  }

  /**
   * Tests the MIME type of this object for equality against the specified
   * MIME type. Ignores parameters.
   *
   * @param mimeType The MIME type to test against.
   *
   * @return <code>true</code> if the MIME type is equal to this object's
   * MIME type (ignoring parameters), <code>false</code> otherwise.
   *
   * @exception NullPointerException If mimeType is null.
   */
  public boolean isMimeTypeEqual(String mimeType)
  {
    if (mimeType == null)
      throw new NullPointerException("mimeType must not be null");
    boolean equal = false;
    try
      {
        if (this.mimeType != null)
          {
            MimeType other = new MimeType(mimeType);
            equal = this.mimeType.matches(other);
          }
      }
    catch (MimeTypeParseException ex)
      {
        // Return false in this case.
      }
    return equal;
  }

  /**
   * Tests the MIME type of this object for equality against the specified
   * data flavor's MIME type
   *
   * @param flavor The flavor to test against.
   *
   * @return <code>true</code> if the flavor's MIME type is equal to this
   * object's MIME type, <code>false</code> otherwise.
   */
  public final boolean isMimeTypeEqual(DataFlavor flavor)
  {
    return isMimeTypeEqual(flavor.getMimeType());
  }

  /**
   * Tests whether or not this flavor represents a serialized object.
   *
   * @return <code>true</code> if this flavor represents a serialized
   * object, <code>false</code> otherwise.
   */
  public boolean isMimeTypeSerializedObject()
  {
    return isMimeTypeEqual(javaSerializedObjectMimeType);
  }

  /**
   * Tests whether or not this flavor has a representation class of
   * <code>java.io.InputStream</code>.
   *
   * @return <code>true</code> if the representation class of this flavor
   * is <code>java.io.InputStream</code>, <code>false</code> otherwise.
   */
  public boolean isRepresentationClassInputStream()
  {
    return InputStream.class.isAssignableFrom(representationClass);
  }

  /**
   * Tests whether the representation class for this flavor is
   * serializable.
   *
   * @return <code>true</code> if the representation class is serializable,
   * <code>false</code> otherwise.
   */
  public boolean isRepresentationClassSerializable()
  {
    return Serializable.class.isAssignableFrom(representationClass);
  }

  /**
   * Tests whether the representation class for his flavor is remote.
   *
   * @return <code>true</code> if the representation class is remote,
   * <code>false</code> otherwise.
   */
  public boolean isRepresentationClassRemote()
  {
    return Remote.class.isAssignableFrom (representationClass);
  }

  /**
   * Tests whether or not this flavor represents a serialized object.
   *
   * @return <code>true</code> if this flavor represents a serialized
   * object, <code>false</code> otherwise.
   */
  public boolean isFlavorSerializedObjectType()
  {
    return isRepresentationClassSerializable()
           && isMimeTypeEqual(javaSerializedObjectMimeType);
  }

  /**
   * Tests whether or not this flavor represents a remote object.
   *
   * @return <code>true</code> if this flavor represents a remote object,
   * <code>false</code> otherwise.
   */
  public boolean isFlavorRemoteObjectType()
  {
    return isRepresentationClassRemote()
           && isRepresentationClassSerializable()
           && isMimeTypeEqual(javaRemoteObjectMimeType);
  }

  /**
   * Tests whether or not this flavor represents a list of files.
   *
   * @return <code>true</code> if this flavor represents a list of files,
   * <code>false</code> otherwise.
   */
  public boolean isFlavorJavaFileListType()
  {
    if (getPrimaryType().equals(javaFileListFlavor.getPrimaryType())
        && getSubType().equals(javaFileListFlavor.getSubType())
        && javaFileListFlavor.representationClass
           .isAssignableFrom(representationClass))
      return true;

    return false ;
  }

  /**
   * Returns a copy of this object.
   *
   * @return A copy of this object.
   *
   * @exception CloneNotSupportedException If the object's class does not support
   * the Cloneable interface. Subclasses that override the clone method can also
   * throw this exception to indicate that an instance cannot be cloned.
   */
  public Object clone () throws CloneNotSupportedException
  {
    // FIXME - This cannot be right.
    try
      {
        return super.clone();
      }
    catch(Exception e)
      {
        return null;
      }
  }

  /**
   * This method test the specified <code>DataFlavor</code> for equality
   * against this object.  This will be true if the MIME type and
   * representation class are the equal. If the primary type is 'text'
   * then also the value of the charset parameter is compared. In such a
   * case when the charset parameter isn't given then the charset is
   * assumed to be equal to the default charset of the platform.  All
   * other parameters are ignored.
   *
   * @param flavor The <code>DataFlavor</code> to test against.
   *
   * @return <code>true</code> if the flavor is equal to this object,
   * <code>false</code> otherwise.
   */
  public boolean equals(DataFlavor flavor)
  {
    if (flavor == null)
      return false;

    String primary = getPrimaryType();
    if (! primary.equals(flavor.getPrimaryType()))
      return false;

    String sub = getSubType();
    if (! sub.equals(flavor.getSubType()))
      return false;

    if (! this.representationClass.equals(flavor.representationClass))
      return false;

    if (primary.equals("text"))
      if (! isRepresentationClassCharBuffer()
          && ! isRepresentationClassReader()
          && representationClass != java.lang.String.class
          && ! (representationClass.isArray()
                && representationClass.getComponentType() == Character.TYPE))
        {
          String charset = getParameter("charset");
          String otherset = flavor.getParameter("charset");
          String defaultset = Charset.defaultCharset().name();

          if (charset == null || charset.equals(defaultset))
            return (otherset == null || otherset.equals(defaultset));

          return charset.equals(otherset);
        }

    return true;
  }

  /**
   * This method test the specified <code>Object</code> for equality
   * against this object.  This will be true if the following conditions
   * are met:
   * <p>
   * <ul>
   * <li>The object is not <code>null</code>.</li>
   * <li>The object is an instance of <code>DataFlavor</code>.</li>
   * <li>The object's MIME type and representation class are equal to
   * this object's.</li>
   * </ul>
   *
   * @param obj The <code>Object</code> to test against.
   *
   * @return <code>true</code> if the flavor is equal to this object,
   * <code>false</code> otherwise.
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof DataFlavor))
      return false;

    return equals((DataFlavor) obj);
  }

  /**
   * Tests whether or not the specified string is equal to the MIME type
   * of this object.
   *
   * @param str The string to test against.
   *
   * @return <code>true</code> if the string is equal to this object's MIME
   * type, <code>false</code> otherwise.
   *
   * @deprecated Not compatible with <code>hashCode()</code>.
   *             Use <code>isMimeTypeEqual()</code>
   */
  public boolean equals(String str)
  {
    return isMimeTypeEqual(str);
  }

  /**
   * Returns the hash code for this data flavor.
   * The hash code is based on the (lower case) mime type and the
   * representation class.
   */
  public int hashCode()
  {
    return mimeType.toString().hashCode() ^ representationClass.hashCode();
  }

  /**
   * Returns <code>true</code> when the given <code>DataFlavor</code>
   * matches this one.
   */
  public boolean match(DataFlavor dataFlavor)
  {
    // XXX - How is this different from equals?
    return equals(dataFlavor);
  }

  /**
   * This method exists for backward compatibility.  It simply returns
   * the same name/value pair passed in.
   *
   * @param name The parameter name.
   * @param value The parameter value.
   *
   * @return The name/value pair.
   *
   * @deprecated
   */
  protected String normalizeMimeTypeParameter(String name, String value)
  {
    return name + "=" + value;
  }

  /**
   * This method exists for backward compatibility.  It simply returns
   * the MIME type string unchanged.
   *
   * @param type The MIME type.
   *
   * @return The MIME type.
   *
   * @deprecated
   */
  protected String normalizeMimeType(String type)
  {
    return type;
  }

  /**
   * Serialize this class.
   *
   * @param stream The <code>ObjectOutput</code> stream to serialize to.
   *
   * @exception IOException If an error occurs.
   */
  public void writeExternal(ObjectOutput stream)
    throws IOException
  {
    if (mimeType != null)
      {
        mimeType.addParameter("humanPresentableName", humanPresentableName);
        stream.writeObject(mimeType);
        mimeType.removeParameter("humanPresentableName");
      }
    else
      stream.writeObject(null);
    stream.writeObject(representationClass);
  }


  /**
   * De-serialize this class.
   *
   * @param stream The <code>ObjectInput</code> stream to deserialize from.
   *
   * @exception IOException If an error ocurs.
   * @exception ClassNotFoundException If the class for an object being restored
   * cannot be found.
   */
  public void readExternal(ObjectInput stream)
    throws IOException, ClassNotFoundException
  {
    mimeType = (MimeType) stream.readObject();
    String className = null;
    if (mimeType != null)
      {
        humanPresentableName =
          mimeType.getParameter("humanPresentableName");
        mimeType.removeParameter("humanPresentableName");
        className = mimeType.getParameter("class");
        if (className == null)
          throw new IOException("No class in mime type");
      }
    try
      {
        representationClass = (Class) stream.readObject();
      }
    catch (OptionalDataException ex)
      {
        if (ex.eof && ex.length == 0)
          {
            if (className != null)
              representationClass = tryToLoadClass(className,
                                                  getClass().getClassLoader());
          }
        else
          throw ex;
      }
  }

  /**
   * Returns a string representation of this DataFlavor. Including the
   * representation class name, MIME type and human presentable name.
   */
  public String toString()
  {
    return (getClass().getName()
           + "[representationClass=" + getRepresentationClass().getName()
           + ",mimeType=" + getMimeType()
           + ",humanPresentableName=" + getHumanPresentableName()
           + "]");
  }

  /**
   * XXX - Currently returns <code>java.io.InputStream</code>.
   *
   * @since 1.3
   */
  public final Class<?> getDefaultRepresentationClass()
  {
    return java.io.InputStream.class;
  }

  /**
   * XXX - Currently returns <code>java.io.InputStream</code>.
   */
  public final String getDefaultRepresentationClassAsString()
  {
    return getDefaultRepresentationClass().getName();
  }

  /**
   * Creates a <code>Reader</code> for a given <code>Transferable</code>.
   *
   * If the representation class is a (subclass of) <code>Reader</code>
   * then an instance of the representation class is returned. If the
   * representatation class is a <code>String</code> then a
   * <code>StringReader</code> is returned. And if the representation class
   * is a (subclass of) <code>InputStream</code> and the primary MIME type
   * is "text" then a <code>InputStreamReader</code> for the correct charset
   * encoding is returned.
   *
   * @param transferable The <code>Transferable</code> for which a text
   *                     <code>Reader</code> is requested.
   *
   * @exception IllegalArgumentException If the representation class is not one
   * of the seven listed above or the Transferable has null data.
   * @exception NullPointerException If the Transferable is null.
   * @exception UnsupportedFlavorException when the transferable doesn't
   * support this <code>DataFlavor</code>. Or if the representable class
   * isn't a (subclass of) <code>Reader</code>, <code>String</code>,
   * <code>InputStream</code> and/or the primary MIME type isn't "text".
   * @exception IOException when any IOException occurs.
   * @exception UnsupportedEncodingException if the "charset" isn't supported
   * on this platform.
   */
  public Reader getReaderForText(Transferable transferable)
    throws UnsupportedFlavorException, IOException
  {
      if (!transferable.isDataFlavorSupported(this))
          throw new UnsupportedFlavorException(this);

      if (Reader.class.isAssignableFrom(representationClass))
          return (Reader)transferable.getTransferData(this);

      if (String.class.isAssignableFrom(representationClass))
          return new StringReader((String)transferable.getTransferData(this));

      if (InputStream.class.isAssignableFrom(representationClass)
          && "text".equals(getPrimaryType()))
        {
          InputStream in = (InputStream)transferable.getTransferData(this);
          String encoding = getParameter("charset");
          if (encoding == null)
              encoding = "us-ascii";
          return new InputStreamReader(in, encoding);
        }

      throw new UnsupportedFlavorException(this);
  }

  /**
   * Returns whether the representation class for this DataFlavor is
   * @see java.nio.ByteBuffer or a subclass thereof.
   *
   * @since 1.4
   */
  public boolean isRepresentationClassByteBuffer()
  {
    return ByteBuffer.class.isAssignableFrom(representationClass);
  }

  /**
   * Returns whether the representation class for this DataFlavor is
   * @see java.nio.CharBuffer or a subclass thereof.
   *
   * @since 1.4
   */
  public boolean isRepresentationClassCharBuffer()
  {
    return CharBuffer.class.isAssignableFrom(representationClass);
  }

  /**
   * Returns whether the representation class for this DataFlavor is
   * @see java.io.Reader or a subclass thereof.
   *
   * @since 1.4
   */
  public boolean isRepresentationClassReader()
  {
    return Reader.class.isAssignableFrom(representationClass);
  }

  /**
   * Returns whether this <code>DataFlavor</code> is a valid text flavor for
   * this implementation of the Java platform. Only flavors equivalent to
   * <code>DataFlavor.stringFlavor</code> and <code>DataFlavor</code>s with
   * a primary MIME type of "text" can be valid text flavors.
   * <p>
   * If this flavor supports the charset parameter, it must be equivalent to
   * <code>DataFlavor.stringFlavor</code>, or its representation must be
   * <code>java.io.Reader</code>, <code>java.lang.String</code>,
   * <code>java.nio.CharBuffer</code>, <code>java.io.InputStream</code> or
   * <code>java.nio.ByteBuffer</code>,
   * If the representation is <code>java.io.InputStream</code> or
   * <code>java.nio.ByteBuffer</code>, then this flavor's <code>charset</code>
   * parameter must be supported by this implementation of the Java platform.
   * If a charset is not specified, then the platform default charset, which
   * is always supported, is assumed.
   * <p>
   * If this flavor does not support the charset parameter, its
   * representation must be <code>java.io.InputStream</code>,
   * <code>java.nio.ByteBuffer</code>.
   * <p>
   * See <code>selectBestTextFlavor</code> for a list of text flavors which
   * support the charset parameter.
   *
   * @return <code>true</code> if this <code>DataFlavor</code> is a valid
   *         text flavor as described above; <code>false</code> otherwise
   * @see #selectBestTextFlavor
   * @since 1.4
   */
  public boolean isFlavorTextType() {
    // FIXME: I'm not 100% sure if this implementation does the same like sun's does
    if(equals(DataFlavor.stringFlavor) || getPrimaryType().equals("text"))
      {
        String charset = getParameter("charset");
        Class c = getRepresentationClass();
        if(charset != null)
          {
            if(Reader.class.isAssignableFrom(c)
                || CharBuffer.class.isAssignableFrom(c)
                || String.class.isAssignableFrom(c))
              {
                return true;
              }
            else if(InputStream.class.isAssignableFrom(c)
                    || ByteBuffer.class.isAssignableFrom(c))
              {
                return Charset.isSupported(charset);
              }
          }
        else if(InputStream.class.isAssignableFrom(c)
            || ByteBuffer.class.isAssignableFrom(c))
          {
            return true;
          }
      }
    return false;
  }
} // class DataFlavor
