/* DataFlavor.java -- A type of data to transfer via the clipboard.
   Copyright (C) 1999, 2001, 2004 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

/**
 * 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;

/**
 * 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;

/**
 * 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;

/**
 * This is an image flavor used for transferring images.  The
 * representation type is a <code>java.awt.Image</code>.
 */
public static final DataFlavor imageFlavor;

/**
 * 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";

static
{
  plainTextFlavor
      = new DataFlavor(java.io.InputStream.class,
		       "text/plain; charset=unicode",
		       "plain unicode text");

  stringFlavor
      = new DataFlavor(java.lang.String.class,
		       "Java Unicode String");

  javaFileListFlavor
      = new DataFlavor(java.util.List.class,
		       "Java File List");

  // javaFileListFlavor.mimeType = "application/x-java-file-list";

  imageFlavor
      = new DataFlavor(java.awt.Image.class,
                       "Java Image");
}

/*************************************************************************/

/*
 * Instance Variables
 */

// The MIME type for this flavor
private final String mimeType;

// The representation class for this flavor
private final 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
{
  try
    {
      return(Class.forName(className));
    }
  catch(Exception e) { ; }
  // Commented out for Java 1.1
  /*
  try
    {
      return(className.getClass().getClassLoader().findClass(className));
    }
  catch(Exception e) { ; }

  try
    {
      return(ClassLoader.getSystemClassLoader().findClass(className));
    }
  catch(Exception e) { ; }
  */

  // FIXME: What is the context class loader?
  /*
  try
    {
    }
  catch(Exception e) { ; }
  */

  if (classLoader != null)
    return(classLoader.loadClass(className));
  else
    throw new ClassNotFoundException(className);
}

/*************************************************************************/

/*
 * Constructors
 */

/**
 * Empty public constructor needed for externalization.
 * Should not be used for normal instantiation.
 */
public
DataFlavor()
{
    mimeType = null;
    representationClass = null;
    humanPresentableName = null;
}

/*************************************************************************/

/**
 * Private constructor.
 */
private
DataFlavor(Class representationClass,
	   String mimeType,
	   String humanPresentableName)
{
    this.representationClass = representationClass;
    this.mimeType = mimeType;
    if (humanPresentableName != null)
	this.humanPresentableName = humanPresentableName;
    else
	this.humanPresentableName = mimeType;
}

/*************************************************************************/

/**
 * 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)
{
    this(representationClass,
       "application/x-java-serialized-object"
       + "; class="
       + representationClass.getName(),
       humanPresentableName);
}

/*************************************************************************/

/**
 * 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
{
  this(getRepresentationClassFromMime(mimeType, classLoader),
       mimeType, humanPresentableName);
}

private static Class
getRepresentationClassFromMime(String mimeString, ClassLoader classLoader)
{
  String classname = getParameter("class", mimeString);
  if (classname != null)
    {
      try
        {
          return tryToLoadClass(classname, classLoader);
        }
      catch(Exception e)
        {
          throw new IllegalArgumentException("classname: " + e.getMessage());
        }
    }
  else
    {
      return java.io.InputStream.class;
    }
}

/*************************************************************************/

/**
 * 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)
{
  this (getRepresentationClassFromMime (mimeType, null), humanPresentableName);
}

/*************************************************************************/

/**
 * 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
{
  this(mimeType, null);
}

/*************************************************************************/

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

/*************************************************************************/

/**
 * 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()
{
  int idx = mimeType.indexOf("/");
  if (idx == -1)
    return(mimeType);

  return(mimeType.substring(0, idx));
}

/*************************************************************************/

/**
 * Returns the MIME subtype for this flavor.
 *
 * @return The MIME subtype for this flavor.
 */
public String
getSubType()
{
  int idx = mimeType.indexOf("/");
  if (idx == -1)
    return("");

  String subtype = mimeType.substring(idx + 1);

  idx = subtype.indexOf(" ");
  if (idx == -1)
    return(subtype);
  else
    return(subtype.substring(0, idx));
}

/*************************************************************************/

/**
 * Returns the value of the named MIME type parameter, or <code>null</code>
 * if the parameter does not exist. Given the parameter name and the mime
 * string.
 *
 * @param paramName The name of the parameter.
 * @param mimeString The mime string from where the name should be found.
 *
 * @return The value of the parameter or null.
 */
private static String
getParameter(String paramName, String mimeString)
{
  int idx = mimeString.indexOf(paramName + "=");
  if (idx == -1)
    return(null);

  String value = mimeString.substring(idx + paramName.length() + 1);

  idx = value.indexOf(" ");
  if (idx == -1)
    return(value);
  else
    return(value.substring(0, idx));
}

/*************************************************************************/

/**
 * 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)
{
  return getParameter(paramName, mimeType);
}

/*************************************************************************/

/**
 * 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.
 *
 * @param mimeType The MIME type to test against.
 *
 * @return <code>true</code> if the MIME type is equal to this object's
 * MIME type, <code>false</code> otherwise.
 *
 * @exception NullPointerException If mimeType is null.
 */
public boolean
isMimeTypeEqual(String mimeType)
{
  // FIXME: Need to handle default attributes and parameters

  return(this.mimeType.equals(mimeType));
}

/*************************************************************************/

/**
 * 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(mimeType.startsWith(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(representationClass.getName().equals("java.io.InputStream"));
}

/*************************************************************************/

/**
 * 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()
{
  Class[] interfaces = representationClass.getInterfaces();

  int i = 0;
  while (i < interfaces.length)
    {
      if (interfaces[i].getName().equals("java.io.Serializable"))
        return(true);
      ++i;
    }

  return(false);
}

/*************************************************************************/

/**
 * 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()
{
  // FIXME: Implement
  throw new RuntimeException("Not implemented");
}

/*************************************************************************/

/**
 * 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()
{
  // FIXME: What is the diff between this and isMimeTypeSerializedObject?
  return(mimeType.startsWith(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(mimeType.startsWith(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 (this.mimeType.equals(javaFileListFlavor.mimeType) &&
      this.representationClass.equals(javaFileListFlavor.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
{
  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 type are the equal.
 *
 * @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);

  if (!this.mimeType.toLowerCase().equals(flavor.mimeType.toLowerCase()))
    return(false);

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

  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.toLowerCase().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
{
  // FIXME: Implement me
}

/*************************************************************************/

/**
 * 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
{
  // FIXME: Implement me
}

/*************************************************************************/

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

/*************************************************************************/

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

/*************************************************************************/

/**
 * 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());
}

/*************************************************************************/

/**
 * 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);
}

/*************************************************************************/

/**
 * 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);
  }

} // class DataFlavor

