summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-10-30 13:19:49 +0000
committerRoman Kennke <roman@kennke.org>2006-10-30 13:19:49 +0000
commitd562f9f0a899608bb155799a61300675cb0fd85f (patch)
treecae7433abb03fcadda7431a8588496eeb2c89ec8
parentdcc21101715f16a696c6d9715308d40ce6934693 (diff)
downloadclasspath-d562f9f0a899608bb155799a61300675cb0fd85f.tar.gz
2006-10-30 Roman Kennke <kennke@aicas.com>
* java/awt/datatransfer/DataFlavor.java (javaFileListFlavor): Don't explicitly specify class. (plainTextFlavor): Don't explicitly specify class. (mimeType): Changed to type MimeType. Remove final. (representationClass): Remove final. (DataFlavor): Don't do anything here. (DataFlavor(Class,String,String)): Removed. (DataFlavor(Class,String)): Initialize here. (DataFlavor(String,String,ClassLoader)): Initialize in init(). (DataFlavor(String,String)): Initialize in init(). (DataFlavor(String)): Initialize in init(). (init): New initialization method. (getMimeType): Delegate to MimeType.toString(). (getParameter(String,String)): Removed. Is now done in MimeType. (getParameter(String)): Delegate to MimeType. (getPrimaryType): Delegate to MimeType. (getRepresentationClassFromMime): Removed. (getRepresentationClassFromMimeThrows): Removed. (getSubType): Delegate to MimeType. (hashCode): Take MimeType.toString() for the hashCode. (isFlavorRemoveObjectType): Return true only when representation class is remove and serializable and the mime type is remote. (isFlavorSerializedObjectType): Return true only when representation class is serializable and the mime type is serialized. (isMimeTypeEqual): Rewritten to delegate to MimeType.matches(). (isMimeTypeSerializedObject): Delegate to isMimeTypeEqual(). (readExternal): Implemented stub method. (writeExternal): Implemented stub method. * java/awt/datatransfer/MimeType.java: New helper class.
-rw-r--r--ChangeLog32
-rw-r--r--java/awt/datatransfer/DataFlavor.java276
-rw-r--r--java/awt/datatransfer/MimeType.java281
3 files changed, 457 insertions, 132 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b89ab850..bc8c09fe6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2006-10-30 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/datatransfer/DataFlavor.java
+ (javaFileListFlavor): Don't explicitly specify class.
+ (plainTextFlavor): Don't explicitly specify class.
+ (mimeType): Changed to type MimeType. Remove final.
+ (representationClass): Remove final.
+ (DataFlavor): Don't do anything here.
+ (DataFlavor(Class,String,String)): Removed.
+ (DataFlavor(Class,String)): Initialize here.
+ (DataFlavor(String,String,ClassLoader)): Initialize in init().
+ (DataFlavor(String,String)): Initialize in init().
+ (DataFlavor(String)): Initialize in init().
+ (init): New initialization method.
+ (getMimeType): Delegate to MimeType.toString().
+ (getParameter(String,String)): Removed. Is now done in MimeType.
+ (getParameter(String)): Delegate to MimeType.
+ (getPrimaryType): Delegate to MimeType.
+ (getRepresentationClassFromMime): Removed.
+ (getRepresentationClassFromMimeThrows): Removed.
+ (getSubType): Delegate to MimeType.
+ (hashCode): Take MimeType.toString() for the hashCode.
+ (isFlavorRemoveObjectType): Return true only when representation
+ class is remove and serializable and the mime type is remote.
+ (isFlavorSerializedObjectType): Return true only when representation
+ class is serializable and the mime type is serialized.
+ (isMimeTypeEqual): Rewritten to delegate to MimeType.matches().
+ (isMimeTypeSerializedObject): Delegate to isMimeTypeEqual().
+ (readExternal): Implemented stub method.
+ (writeExternal): Implemented stub method.
+ * java/awt/datatransfer/MimeType.java: New helper class.
+
2006-10-28 Roman Kennke <kennke@aicas.com>
* javax/swing/TransferHandler.java
diff --git a/java/awt/datatransfer/DataFlavor.java b/java/awt/datatransfer/DataFlavor.java
index 9178c925a..58ff49f2d 100644
--- a/java/awt/datatransfer/DataFlavor.java
+++ b/java/awt/datatransfer/DataFlavor.java
@@ -46,6 +46,7 @@ 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;
@@ -76,8 +77,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
* deals with bytes not chars. Use <code>getRederForText()</code>.
*/
public static final DataFlavor plainTextFlavor =
- new DataFlavor(java.io.InputStream.class,
- "text/plain; charset=unicode",
+ new DataFlavor("text/plain; charset=unicode; class=java.io.InputStream",
"plain unicode text");
/**
@@ -94,8 +94,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
* element of the list being a <code>java.io.File</code>.
*/
public static final DataFlavor javaFileListFlavor =
- new DataFlavor(java.util.List.class,
- "application/x-java-file-list; class=java.util.List",
+ new DataFlavor("application/x-java-file-list; class=java.util.List",
"Java File List");
/**
@@ -132,10 +131,10 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
// The MIME type for this flavor
- private final String mimeType;
+ private MimeType mimeType;
// The representation class for this flavor
- private final Class representationClass;
+ private Class representationClass;
// The human readable name of this flavor
private String humanPresentableName;
@@ -198,62 +197,6 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
throw new ClassNotFoundException(className);
}
- private static Class getRepresentationClassFromMimeThrows(String mimeString,
- ClassLoader classLoader)
- throws ClassNotFoundException
- {
- String classname = getParameter("class", mimeString);
- if (classname != null)
- return tryToLoadClass(classname, classLoader);
- else
- return java.io.InputStream.class;
- }
-
- // Same as above, but wraps any ClassNotFoundExceptions
- private static Class getRepresentationClassFromMime(String mimeString,
- ClassLoader classLoader)
- {
- try
- {
- return getRepresentationClassFromMimeThrows(mimeString, classLoader);
- }
- catch(ClassNotFoundException cnfe)
- {
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("mimeString: "
- + mimeString
- + " classLoader: "
- + classLoader);
- iae.initCause(cnfe);
- throw iae;
- }
- }
-
- /**
- * 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));
- }
-
/**
* XXX - Currently returns <code>plainTextFlavor</code>.
*/
@@ -321,31 +264,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor()
{
- mimeType = null;
- representationClass = null;
- humanPresentableName = null;
- }
-
- /**
- * Private constructor.
- */
- private DataFlavor(Class representationClass,
- String mimeType,
- String humanPresentableName)
- {
- this.representationClass = representationClass;
- this.mimeType = mimeType;
-
- // Do some simple validity checks
- String type = getPrimaryType() + "/" + getSubType();
- if (type.indexOf('=') != -1
- || type.indexOf(';') != -1)
- throw new IllegalArgumentException(mimeType);
-
- if (humanPresentableName != null)
- this.humanPresentableName = humanPresentableName;
- else
- this.humanPresentableName = mimeType;
+ // Used for deserialization only, nothing to do here.
}
/**
@@ -360,11 +279,21 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor(Class representationClass, String humanPresentableName)
{
- this(representationClass,
- "application/x-java-serialized-object"
- + "; class="
- + representationClass.getName(),
- 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;
}
/**
@@ -389,8 +318,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
ClassLoader classLoader)
throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, classLoader),
- mimeType, humanPresentableName);
+ init(mimeType, humanPresentableName, classLoader);
}
/**
@@ -411,8 +339,17 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor(String mimeType, String humanPresentableName)
{
- this(getRepresentationClassFromMime (mimeType, null),
- mimeType, humanPresentableName);
+ try
+ {
+ init(mimeType, humanPresentableName, getClass().getClassLoader());
+ }
+ catch (ClassNotFoundException ex)
+ {
+ IllegalArgumentException iae =
+ new IllegalArgumentException("Class not found: " + ex.getMessage());
+ iae.initCause(ex);
+ throw iae;
+ }
}
/**
@@ -431,8 +368,54 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor(String mimeType) throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, null),
- mimeType, null);
+ 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;
}
/**
@@ -442,7 +425,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public String getMimeType()
{
- return(mimeType);
+ return(mimeType.toString());
}
/**
@@ -472,11 +455,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public String getPrimaryType()
{
- int idx = mimeType.indexOf("/");
- if (idx == -1)
- return(mimeType);
-
- return(mimeType.substring(0, idx));
+ return(mimeType.getPrimaryType());
}
/**
@@ -486,15 +465,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public String getSubType()
{
- int start = mimeType.indexOf("/");
- if (start == -1)
- return "";
-
- int end = mimeType.indexOf(";", start + 1);
- if (end == -1)
- return mimeType.substring(start + 1);
- else
- return mimeType.substring(start + 1, end);
+ return mimeType.getSubType();
}
/**
@@ -510,7 +481,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
if ("humanPresentableName".equals(paramName))
return getHumanPresentableName();
- return getParameter(paramName, mimeType);
+ return mimeType.getParameter(paramName);
}
/**
@@ -536,16 +507,22 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isMimeTypeEqual(String mimeType)
{
- String mime = getMimeType();
- int i = mime.indexOf(";");
- if (i != -1)
- mime = mime.substring(0, i);
-
- i = mimeType.indexOf(";");
- if (i != -1)
- mimeType = mimeType.substring(0, i);
-
- return mime.equals(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;
}
/**
@@ -570,7 +547,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isMimeTypeSerializedObject()
{
- return mimeType.startsWith(javaSerializedObjectMimeType);
+ return isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -616,8 +593,8 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isFlavorSerializedObjectType()
{
- // FIXME: What is the diff between this and isMimeTypeSerializedObject?
- return(mimeType.startsWith(javaSerializedObjectMimeType));
+ return isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -628,7 +605,9 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isFlavorRemoteObjectType()
{
- return(mimeType.startsWith(javaRemoteObjectMimeType));
+ return isRepresentationClassRemote()
+ && isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaRemoteObjectMimeType);
}
/**
@@ -769,7 +748,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public int hashCode()
{
- return mimeType.toLowerCase().hashCode() ^ representationClass.hashCode();
+ return mimeType.toString().hashCode() ^ representationClass.hashCode();
}
/**
@@ -823,7 +802,15 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
public void writeExternal(ObjectOutput stream)
throws IOException, NotImplementedException
{
- // FIXME: Implement me
+ if (mimeType != null)
+ {
+ mimeType.addParameter("humanPresentableName", humanPresentableName);
+ stream.writeObject(mimeType);
+ mimeType.removeParameter("humanPresentableName");
+ }
+ else
+ stream.writeObject(null);
+ stream.writeObject(representationClass);
}
@@ -837,9 +824,34 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
* cannot be found.
*/
public void readExternal(ObjectInput stream)
- throws IOException, ClassNotFoundException, NotImplementedException
+ throws IOException, ClassNotFoundException
{
- // FIXME: Implement me
+ 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;
+ }
}
/**
diff --git a/java/awt/datatransfer/MimeType.java b/java/awt/datatransfer/MimeType.java
new file mode 100644
index 000000000..438d78e9e
--- /dev/null
+++ b/java/awt/datatransfer/MimeType.java
@@ -0,0 +1,281 @@
+/* MimeType.java -- A helper class for mime handling in DataFlavor
+ Copyright (C) 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.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * A helper class for mime handling in DataFlavor.
+ *
+ * A Mauve test for DataFlavor.writeExternal() shows that a non-public
+ * class java.awt.datatransfer.MimeType gets serialized. This class
+ * is mainly here for serialization compatibility. Of course,
+ * now that we have it here, we can just as well implement some
+ * mime handling facility here.
+ */
+class MimeType
+ implements Externalizable
+{
+
+ /**
+ * The primary type.
+ */
+ private String primaryType;
+
+ /**
+ * The subtype.
+ */
+ private String subType;
+
+ /**
+ * Additional parameters to be appended to the mime string.
+ */
+ private HashMap parameters;
+
+ /**
+ * This is only here for deserialization.
+ */
+ public MimeType()
+ {
+ parameters = new HashMap();
+ }
+
+ /**
+ * Creates a new MimeType object.
+ *
+ * @param mime the mime type
+ */
+ MimeType(String mime)
+ throws MimeTypeParseException
+ {
+ this();
+ parse(mime);
+ }
+
+ /**
+ * Adds a mime parameter.
+ *
+ * @param param the parameter key
+ * @param value the parameter value
+ */
+ void addParameter(String param, String value)
+ {
+ parameters.put(param, value);
+ }
+
+ /**
+ * Removes the parameter with the specified key.
+ *
+ * @param param the parameter to remove
+ */
+ void removeParameter(String param)
+ {
+ parameters.remove(param);
+ }
+
+ /**
+ * Returns the parameter for the <code>key</code>.
+ *
+ * @param key the parameter key
+ *
+ * @return the parameter for the <code>key</code>
+ */
+ String getParameter(String key)
+ {
+ return (String) parameters.get(key);
+ }
+
+ /**
+ * Returns the primary type.
+ *
+ * @return the primary type
+ */
+ String getPrimaryType()
+ {
+ return primaryType;
+ }
+
+ String getSubType()
+ {
+ return subType;
+ }
+
+ /**
+ * Returns the base type of this mime type. This is the primary
+ * type plus the subtype, separated by '/'.
+ *
+ * @return the base type of this mime type
+ */
+ String getBaseType()
+ {
+ return primaryType + '/' + subType;
+ }
+
+ /**
+ * Returns <code>true</code> if this mime type and another mime type
+ * match. This will be true when their primary types are equal, and their
+ * subtypes are equal (or when either subtype is * ).
+ *
+ * @param other the other mime type
+ *
+ * @return <code>true</code> if the mime types match, <code>false</code>
+ * otherwise
+ */
+ boolean matches(MimeType other)
+ {
+ boolean match = false;
+ if (other != null)
+ {
+ match = primaryType.equals(other.primaryType)
+ && (subType.equals("*") || other.subType.equals("*")
+ || subType.equals(other.subType));
+ }
+ return match;
+ }
+
+ /**
+ * Serializes the mime type.
+ *
+ * @param in the input stream to read from
+ *
+ * @throws ClassNotFoundException not thrown here
+ * @throws IOException when something goes wrong on the input stream,
+ * or when the mime type can't be parsed
+ */
+ public void readExternal(ObjectInput in)
+ throws ClassNotFoundException, IOException
+ {
+ String mime = in.readUTF();
+ parameters.clear();
+ try
+ {
+ parse(mime);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ IOException ioEx = new IOException();
+ ioEx.initCause(ex);
+ throw ioEx;
+ }
+ }
+
+ /**
+ * Serializes this mime type.
+ *
+ * @param out the output stream
+ *
+ * @throws IOException when something goes wrong on the output stream
+ */
+ public void writeExternal(ObjectOutput out)
+ throws IOException
+ {
+ out.writeUTF(toString());
+ }
+
+ /**
+ * Creates a string representation of this mime type.
+ *
+ * @return a string representation of this mime type
+ */
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append(primaryType);
+ s.append('/');
+ s.append(subType);
+ if (parameters.size() > 0)
+ {
+ Set entries = parameters.entrySet();
+ for (Iterator i = entries.iterator(); i.hasNext();)
+ {
+ s.append("; ");
+ Map.Entry entry = (Map.Entry) i.next();
+ s.append(entry.getKey());
+ s.append('=');
+ s.append(entry.getValue());
+ }
+ }
+ return s.toString();
+ }
+
+ /**
+ * Parses the specified mime type string and initializes the fields
+ * of this object.
+ *
+ * @param mime the mime type string
+ */
+ private void parse(String mime)
+ throws MimeTypeParseException
+ {
+ // FIXME: Maybe implement more sophisticated mime string parsing according
+ // to RFC 2045 and 2046.
+ StringTokenizer tokenizer = new StringTokenizer(mime);
+ try
+ {
+ primaryType = tokenizer.nextToken("/");
+ subType = tokenizer.nextToken("/;");
+ }
+ catch (NoSuchElementException ex)
+ {
+ throw new MimeTypeParseException("Expected / separator");
+ }
+
+ // Add any parameters.
+ while (tokenizer.hasMoreTokens())
+ {
+ String keyValuePair = tokenizer.nextToken(";");
+ int i = keyValuePair.indexOf('=');
+ if (i == -1)
+ throw new MimeTypeParseException("Expected = as parameter separator");
+ String key = keyValuePair.substring(0, i).trim();
+ String value = keyValuePair.substring(i + 1).trim();
+ parameters.put(key, value);
+ }
+ }
+
+}