Hi,

A while ago I made some updates to java.awt.datatransfer to bring them
up to date with 1.3. They are not yet finished and/or completely tested
but I am busy with other things. I hope it will help someone that wants
to hack some more on them. Note that a couple of new methods appeared in
1.3 for DataFlavor without any documentation. Sigh...

    * java/awt/datatransfer/Clibboard.java:
    (getContents, setContents): synchronized, add comment
    * java/awt/datatransfer/DataFlavor.java:
    (DataFlavor constructor): refactored,
    if null set humanPresentable name to mimeType
    (getParameter): renamed from getParamter
    (equals(String)): deprecated
    (hashCode): new method
    (match): new method, XXX implemented as equals
    (toString): new method
    (getTextPlainUnicodeFlavor): new method, XXX returns plainTextFlavor
    (getDefaultRepresentationClass): new method, XXX returns InputStream
    (getDefaultRepresentationClassAsString): new method, XXX
    (selectBestTextFlavor): new method
    (getReaderForText): new method
    * java/awt/datatransfer/FlavorMap.java: update comments
    * java/awt/datatransfer/MimeTypeParseException.java: new class
    * java/awt/datatransfer/SystemFlavorMap.java: new class XXX 

Cheers,

Mark
Index: java/awt/datatransfer/Clipboard.java
===================================================================
RCS file: /cvs/classpath/java/awt/datatransfer/Clipboard.java,v
retrieving revision 1.2
diff -u -u -r1.2 Clipboard.java
--- java/awt/datatransfer/Clipboard.java        2000/03/17 23:50:10     1.2
+++ java/awt/datatransfer/Clipboard.java        2001/01/12 13:42:28
@@ -1,5 +1,5 @@
 /* Clipboard.java -- Class for transferring data via cut and paste.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001 Free Software Foundation, Inc.
 
 This file is part of the non-peer AWT libraries of GNU Classpath.
 
@@ -86,7 +86,7 @@
   *
   * @param requestor The object requesting the contents.
   */
-public Transferable
+public synchronized Transferable
 getContents(Object requestor)
 {
   return(contents);
@@ -96,11 +96,14 @@
 
 /**
   * Sets the content and owner of this clipboard.
+  * If the given owner is different from the current owner
+  * then lostOwnership is called on the current owner.
+  * XXX - is this called with the old or new contents.
   *
   * @param contents The new clipboard contents.
   * @param owner The new clipboard owner
   */
-public void
+public synchronized void
 setContents(Transferable contents, ClipboardOwner owner)
 {
   if (this.owner != owner)
Index: java/awt/datatransfer/DataFlavor.java
===================================================================
RCS file: /cvs/classpath/java/awt/datatransfer/DataFlavor.java,v
retrieving revision 1.3
diff -u -u -r1.3 DataFlavor.java
--- java/awt/datatransfer/DataFlavor.java       2000/03/17 23:50:11     1.3
+++ java/awt/datatransfer/DataFlavor.java       2001/01/12 13:42:28
@@ -1,5 +1,5 @@
 /* DataFlavor.java -- A type of data to transfer via the clipboard.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001 Free Software Foundation, Inc.
 
 This file is part of the non-peer AWT libraries of GNU Classpath.
 
@@ -24,6 +24,9 @@
 import java.io.ObjectOutput;
 import java.io.ObjectInput;
 import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
 
 /**
   * This class represents a particular data format used for transferring
@@ -40,12 +43,13 @@
  * Static Variables
  */
 
-private static DataFlavor _tmp = null;
-
 /**
   * 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;
 
@@ -87,31 +91,23 @@
 
 static
 {
-  try
-    {
-      _tmp = new DataFlavor("text/plain; charset=unicode", 
-                                       "java.io.InputStream");
-    }
-  catch(Exception e) { _tmp = null; }
-  plainTextFlavor = _tmp;
-
-  try
-    {
-      _tmp = new DataFlavor("application/x-java-serialized-object",
-                                    "java.lang.String");
-    }
-  catch(Exception e) { _tmp = null; }
-  stringFlavor = _tmp;
+  plainTextFlavor = new DataFlavor();
+  plainTextFlavor.representationClass = java.io.InputStream.class;
+  plainTextFlavor.mimeType = "text/plain; charset=unicode";
+  plainTextFlavor.humanPresentableName = "plain unicode text";
+
+  stringFlavor = new DataFlavor();
+  stringFlavor.representationClass = java.lang.String.class;
+  stringFlavor.mimeType = javaSerializedObjectMIMEType
+                          + "; class=java.lang.String";
+  stringFlavor.humanPresentableName = "Java Unicode String";
+
+  javaFileListFlavor = new DataFlavor();
+  javaFileListFlavor.representationClass = java.util.List.class;
+  javaFileListFlavor.mimeType = javaSerializedObjectMIMEType
+                                + "; class=java.util.list";
+  // javaFileListFlavor.mimeType = "application/x-java-file-list";
 
-  try
-    {
-      _tmp = new DataFlavor("application/x-java-file-list", 
-                                          "java.util.List");
-    }
-  catch(Exception e) { _tmp = null; }
-  javaFileListFlavor = _tmp;
-}
-
 /*************************************************************************/
 
 /*
@@ -119,10 +115,10 @@
  */
 
 // The MIME type for this flavor
-private String mimeType;
+private final String mimeType;
 
 // The representation class for this flavor
-private Class representationClass;
+private final Class representationClass;
 
 // The human readable name of this flavor
 private String humanPresentableName;
@@ -190,7 +186,8 @@
  */
 
 /**
-  * // FIXME: What does this do?
+  * Empty public constructor needed for externalization.
+  * Should not be used for normal instantiation.
   */
 public
 DataFlavor()
@@ -202,7 +199,9 @@
 /**
   * 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".
+  * "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.
@@ -212,18 +211,23 @@
 {
   this.representationClass = representationClass;
   this.humanPresentableName = humanPresentableName;
-  mimeType = "application/x-java-serialized-object";
+  mimeType = "application/x-java-serialized-object"
+             + "; class="
+             + representationClass.getName();
+  if (this.humanPresentableName == null)
+    this.humanPresentableName = mimeType;
 }
 
 /*************************************************************************/
 
 /**
   * Initializes a new instance of <code>DataFlavor</code> with the
-  * specified MIME type and description.  If the MIME type is
-  * "application/x-java-serialized-object; class=<rep class>" then the
-  * representation class will be the class name specified as the 
-  * parameter to the MIME type.  Otherwise the class defaults to
-  * <code>java.io.InputStream</code>.
+  * specified MIME type and description.  If the MIME type has a
+  * "class=<rep class>" 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.
@@ -237,9 +241,17 @@
 DataFlavor(String mimeType, String humanPresentableName, 
            ClassLoader classLoader) throws ClassNotFoundException
 {
-  if (mimeType.startsWith("application/x-java-serialized-object; class="))
+  this.mimeType = mimeType;
+  if (humanPresentableName != null)
+    this.humanPresentableName = humanPresentableName;
+  else
+    this.humanPresentableName = mimeType;
+
+  String classname = getParameter("class");
+  if (className == null)
+    representationClass = java.io.InputStream.class;
+  else
     {
-      String classname = mimeType.substring(mimeType.indexOf("=")+1);
       try
         {
           representationClass = tryToLoadClass(classname, classLoader);
@@ -249,24 +261,19 @@
           throw new IllegalArgumentException("classname: " + e.getMessage());
         }
     }
-  else
-    {
-      representationClass = tryToLoadClass("java.io.InputStream", null);
-    }
-
-  this.mimeType = mimeType;
-  this.humanPresentableName = humanPresentableName;
 }
 
 /*************************************************************************/
 
 /**
   * Initializes a new instance of <code>DataFlavor</code> with the
-  * specified MIME type and description.  If the MIME type is
-  * "application/x-java-serialized-object; class=<rep class>" then the
-  * representation class will be the class name specified as the 
-  * parameter to the MIME type.  Otherwise the class defaults to
-  * <code>java.io.InputStream</code>.
+  * specified MIME type and description.  If the MIME type has a
+  * "class=<rep class>" 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.
@@ -286,8 +293,11 @@
 
 /**
   * Initializes a new instance of <code>DataFlavor</code> with the specified
-  * MIME type.  This type must have a "class=" parameter, and that
-  * class specified must exist or an exception will be thrown.
+  * 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.
   *
@@ -298,13 +308,7 @@
 public
 DataFlavor(String mimeType) throws ClassNotFoundException
 {
-  if (mimeType.indexOf("class=") == -1)
-    throw new IllegalArgumentException(mimeType);
-
-  String classname = mimeType.substring(mimeType.indexOf("=")+1);
-  representationClass = tryToLoadClass(classname, null);
-  this.mimeType = mimeType;
-  this.humanPresentableName = mimeType;
+  this(mimeType, null);
 }
 
 /*************************************************************************/
@@ -397,7 +401,7 @@
   * @return The value of the parameter.
   */
 public String
-getParamter(String paramName)
+getParameter(String paramName)
 {
   int idx = mimeType.indexOf(paramName + "=");
   if (idx == -1)
@@ -665,6 +669,9 @@
   *
   * @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)
@@ -675,6 +682,32 @@
 /*************************************************************************/
 
 /**
+  * 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.
   *
@@ -733,6 +766,148 @@
 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>.
+  */
+public static final Class
+getDefaultRepresentationClass()
+{
+  return(java.io.InputStream.class);
+}
+/*************************************************************************/
+
+/**
+  * XXX - Currently returns <code>java.io.InputStream</code>.
+  */
+public static 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;
+      if ((c instanceof Reader) || (c instanceof String))
+        return df;
+      if ((c instanceof InputStream) && ("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) { /* 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 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,
+                                                   UnsupportedEncodingException
+{
+    if (!transferable.isDataFlavorSupported(this)
+        throw UnsupportedFlavorException(this);
+
+    if (representationClass instanceof Reader)
+        return((Reader)transferable.getTransferData(this));
+
+    if (representationClass instanceof String)
+        return(StringReader((String)transferable.getTransferData(this)));
+
+    if ((representationClass instanceof InputStream)
+        && "text".equals(getPrimaryType())
+      {
+        InputStream in = (InputStream)transferable.getTransferData(this);
+        String encoding = getParameter("charset");
+        if (encoding == null)
+            encoding = "us-ascii";
+        return(InputStreamReader(in, encoding));
+      }
+
+    throw UnsupportedFlavorException(this);
 }
 
 } // class DataFlavor
Index: java/awt/datatransfer/FlavorMap.java
===================================================================
RCS file: /cvs/classpath/java/awt/datatransfer/FlavorMap.java,v
retrieving revision 1.2
diff -u -u -r1.2 FlavorMap.java
--- java/awt/datatransfer/FlavorMap.java        2000/03/17 23:50:12     1.2
+++ java/awt/datatransfer/FlavorMap.java        2001/01/12 13:42:28
@@ -1,5 +1,5 @@
 /* FlavorMap.java -- Maps between flavor names and MIME types.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001 Free Software Foundation, Inc.
 
 This file is part of the non-peer AWT libraries of GNU Classpath.
 
@@ -23,7 +23,7 @@
 import java.util.Map;
 
 /**
-  * This interface maps between data flavor names and MIME types.
+  * This interface maps between native platform type names and DataFlavors.
   *
   * @author Aaron M. Renn ([EMAIL PROTECTED])
   */
@@ -36,7 +36,8 @@
   * the data flavors and values that are strings.  The returned map
   * may be modified.  This can be useful for implementing nested mappings.
   *
-  * @param flavors An array of data flavors to map.
+  * @param flavors An array of data flavors to map
+  *                or null for all data flavors.
   *
   * @return A <code>Map</code> of native data types.
   */
@@ -51,7 +52,8 @@
   * that are <code>DataFlavor</code>'s.  The returned map may be
   * modified.  This can be useful for implementing nested mappings.
   *
-  * @param natives An array of native types to map.
+  * @param natives An array of native types to map
+  *                or null for all native types.
   *
   * @return A <code>Map</code> of data flavors.
   */
Index: java/awt/datatransfer/MimeTypeParseException.java
===================================================================
RCS file: MimeTypeParseException.java
diff -N MimeTypeParseException.java
--- /dev/null   Tue Aug 29 07:25:14 2000
+++ MimeTypeParseException.java Fri Jan 12 05:42:28 2001
@@ -0,0 +1,52 @@
+/* MimeTypeParseException.java -- Thrown when MIME string couldn't be parsed.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of the non-peer AWT libraries of GNU Classpath.
+
+This library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published 
+by the Free Software Foundation, either version 2 of the License, or
+(at your option) any later verion.
+
+This library 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 Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this library; if not, write to the Free Software Foundation
+Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA. */
+
+
+package java.awt.datatransfer;
+
+/**
+  * MIME string couldn't be parsed correctly.
+  *
+  * @author Mark Wielaard ([EMAIL PROTECTED])
+  */
+public class MimeTypeParseException extends Exception 
+{
+
+/**
+  * Initializes a new instance of <code>MimeTypeParseException</code>
+  * without any message.
+  */
+public
+MimeTypeParseException()
+{
+  super();
+}
+
+/**
+  * Initializes a new instance of <code>MimeTypeParseException</code>
+  * with a specified detailed error message.
+  */
+public
+MimeTypeParseException(String message)
+{
+  super(message);
+}
+
+} // class MimeTypeParseException
+
Index: java/awt/datatransfer/SystemFlavorMap.java
===================================================================
RCS file: SystemFlavorMap.java
diff -N SystemFlavorMap.java
--- /dev/null   Tue Aug 29 07:25:14 2000
+++ SystemFlavorMap.java        Fri Jan 12 05:42:28 2001
@@ -0,0 +1,162 @@
+/* SystemFlavorMap.java -- Maps between native flavor names and MIME types.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of the non-peer AWT libraries of GNU Classpath.
+
+This library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published 
+by the Free Software Foundation, either version 2 of the License, or
+(at your option) any later verion.
+
+This library 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 Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this library; if not, write to the Free Software Foundation
+Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA. */
+
+
+package java.awt.datatransfer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+  * This class maps between native platform type names and DataFlavors.
+  *
+  * XXX - The current implementation does no mapping at all.
+  *
+  * @author Mark Wielaard ([EMAIL PROTECTED])
+  */
+public final class SystemFlavorMap implements FlavorMap
+{
+
+/**
+  * The default (instance) flavor map.
+  */
+private static FlavorMap defaultFlavorMap;
+
+/**
+  * Private constructor.
+  */
+private SystemFlavorMap()
+{
+}
+
+/*************************************************************************/
+
+/**
+  * Maps the specified <code>DataFlavor</code> objects to the native
+  * data type name.  The returned <code>Map</code> has keys that are
+  * the data flavors and values that are strings.  The returned map
+  * may be modified.  This can be useful for implementing nested mappings.
+  *
+  * @param flavors An array of data flavors to map
+  *                or null for all data flavors.
+  *
+  * @return A <code>Map</code> of native data types to data flavors.
+  */
+public Map
+getNativesForFlavors(DataFlavor[] flavors)
+{
+  return(new HashMap());
+}
+
+/*************************************************************************/
+
+/**
+  * Maps the specified native type names to <code>DataFlavor</code>'s.
+  * The returned <code>Map</code> has keys that are strings and values
+  * that are <code>DataFlavor</code>'s.  The returned map may be
+  * modified.  This can be useful for implementing nested mappings.
+  *
+  * @param natives An array of native types to map
+  *                or null for all native types.
+  *
+  * @return A <code>Map</code> of data flavors to native type names.
+  */
+public Map
+getFlavorsForNatives(String[] natives)
+{
+  return(new HashMap());
+}
+
+/*************************************************************************/
+
+/**
+  * Returns the default (instance) (System)FlavorMap.
+  */
+public static FlavorMap
+getDefaultFlavorMap()
+{
+  if (defaultFlavorMap == null)
+    defaultFlavorMap = new SystemFlavorMap();
+
+  return(defaultFlavorMap);
+}
+
+/*************************************************************************/
+
+/**
+  * Returns the native type name for the given java mime type.
+  */
+public static String
+encodeJavaMIMEType(String mime)
+{
+  return null;
+}
+
+/*************************************************************************/
+
+/**
+  * Returns the native type name for the given data flavor.
+  */
+public static String
+encodeDataFlavor(DataFlavor df)
+{
+  return null;
+}
+
+/*************************************************************************/
+
+/**
+  * Returns true if the native type name can be represented as
+  * a java mime type.
+  */
+public static boolean
+isJavaMIMEType(String name)
+{
+  return(false);
+}
+
+/*************************************************************************/
+
+/**
+  * Returns the java mime type for the given the native type name.
+  */
+public static String
+decodeJavaMIMEType(String name)
+{
+  return null;
+}
+
+/*************************************************************************/
+
+/**
+  * Returns the data flavor given the native type name
+  * or null when no such data flavor exists.
+  */
+public static DataFlavor
+decodeDataFlavor(String name) throws ClassNotFoundException
+{
+  String javaMIMEType = decodeJavaMIMEType(name);
+  if (javaMIMEType != null)
+    return(new DataFlavor(javaMIMEType));
+  else
+    return(null);
+}
+
+} // class SystemFlavorMap
+

Reply via email to