diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-17 18:09:40 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-17 18:09:40 +0000 |
commit | 2d8cf20d0d5ca6b1fbdefc22229d4b7cf1497ede (patch) | |
tree | c976ca91e3ef0bda3b34b37c0195145638d8d08e /libjava/classpath/java/awt | |
parent | a3ef37ddfeddcc5b0f1c5068d8fdeb25a302d5cd (diff) | |
download | gcc-2d8cf20d0d5ca6b1fbdefc22229d4b7cf1497ede.tar.gz |
Imported GNU Classpath 0.20
* Makefile.am (AM_CPPFLAGS): Add classpath/include.
* java/nio/charset/spi/CharsetProvider.java: New override file.
* java/security/Security.java: Likewise.
* sources.am: Regenerated.
* Makefile.in: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109831 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java/awt')
-rw-r--r-- | libjava/classpath/java/awt/BorderLayout.java | 2 | ||||
-rw-r--r-- | libjava/classpath/java/awt/Component.java | 42 | ||||
-rw-r--r-- | libjava/classpath/java/awt/Container.java | 59 | ||||
-rw-r--r-- | libjava/classpath/java/awt/GridBagLayout.java | 24 | ||||
-rw-r--r-- | libjava/classpath/java/awt/datatransfer/DataFlavor.java | 1702 | ||||
-rw-r--r-- | libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java | 292 |
6 files changed, 1165 insertions, 956 deletions
diff --git a/libjava/classpath/java/awt/BorderLayout.java b/libjava/classpath/java/awt/BorderLayout.java index 1b67c01cfcb..7c8c582a96b 100644 --- a/libjava/classpath/java/awt/BorderLayout.java +++ b/libjava/classpath/java/awt/BorderLayout.java @@ -415,7 +415,7 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable */ public Dimension maximumLayoutSize(Container target) { - return calcSize(target, MAX); + return new Dimension (Integer.MAX_VALUE, Integer.MAX_VALUE); } /** diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java index ec03d631dcf..bd22ea3c984 100644 --- a/libjava/classpath/java/awt/Component.java +++ b/libjava/classpath/java/awt/Component.java @@ -1038,14 +1038,10 @@ public abstract class Component if ((c != null) && c.equals(background)) return; - // If c is null, inherit from closest ancestor whose bg is set. - if (c == null && parent != null) - c = parent.getBackground(); - if (peer != null && c != null) - peer.setBackground(c); - Color previous = background; background = c; + if (peer != null && c != null) + peer.setBackground(c); firePropertyChange("background", previous, c); } @@ -2642,7 +2638,7 @@ public abstract class Component { mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener); if (mouseMotionListener != null) - enableEvents(AWTEvent.MOUSE_EVENT_MASK); + enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK); } /** @@ -2775,10 +2771,19 @@ public abstract class Component } /** - * Returns all registered EventListers of the given listenerType. + * Returns all registered {@link EventListener}s of the given + * <code>listenerType</code>. * - * @param listenerType the class of listeners to filter - * @return an array of registered listeners + * @param listenerType the class of listeners to filter (<code>null</code> + * not permitted). + * + * @return An array of registered listeners. + * + * @throws ClassCastException if <code>listenerType</code> does not implement + * the {@link EventListener} interface. + * @throws NullPointerException if <code>listenerType</code> is + * <code>null</code>. + * * @see #getComponentListeners() * @see #getFocusListeners() * @see #getHierarchyListeners() @@ -4786,7 +4791,12 @@ p * <li>the set of backward traversal keys void dispatchEventImpl(AWTEvent e) { Event oldEvent = translateEvent (e); - + // This boolean tells us not to process focus events when the focus + // opposite component is the same as the focus component. + boolean ignoreFocus = + (e instanceof FocusEvent && + ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent()); + if (oldEvent != null) postEvent (oldEvent); @@ -4817,7 +4827,8 @@ p * <li>the set of backward traversal keys break; } } - if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE) + if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE + && !ignoreFocus) processEvent(e); } @@ -4853,11 +4864,12 @@ p * <li>the set of backward traversal keys case MouseEvent.MOUSE_EXITED: case MouseEvent.MOUSE_PRESSED: case MouseEvent.MOUSE_RELEASED: - case MouseEvent.MOUSE_MOVED: - case MouseEvent.MOUSE_DRAGGED: return (mouseListener != null - || mouseMotionListener != null || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0); + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + return (mouseMotionListener != null + || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0); case FocusEvent.FOCUS_GAINED: case FocusEvent.FOCUS_LOST: diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java index ed791dc8b88..67f0ed184d4 100644 --- a/libjava/classpath/java/awt/Container.java +++ b/libjava/classpath/java/awt/Container.java @@ -449,9 +449,6 @@ public class Container extends Component ContainerEvent.COMPONENT_REMOVED, r); getToolkit().getSystemEventQueue().postEvent(ce); - - // Repaint this container. - repaint(); } } } @@ -896,13 +893,21 @@ public class Container extends Component } /** - * Returns an array of all the objects currently registered as FooListeners - * upon this Container. FooListeners are registered using the addFooListener - * method. - * - * @exception ClassCastException If listenerType doesn't specify a class or - * interface that implements @see java.util.EventListener. + * Returns all registered {@link EventListener}s of the given + * <code>listenerType</code>. * + * @param listenerType the class of listeners to filter (<code>null</code> + * not permitted). + * + * @return An array of registered listeners. + * + * @throws ClassCastException if <code>listenerType</code> does not implement + * the {@link EventListener} interface. + * @throws NullPointerException if <code>listenerType</code> is + * <code>null</code>. + * + * @see #getContainerListeners() + * * @since 1.3 */ public EventListener[] getListeners(Class listenerType) @@ -1094,7 +1099,7 @@ public class Container extends Component { if (!contains(x, y)) return null; - + for (int i = 0; i < ncomponents; ++i) { // Ignore invisible children... @@ -1117,7 +1122,8 @@ public class Container extends Component } //don't return transparent components with no MouseListeners - if (this.getMouseListeners().length == 0) + if (getMouseListeners().length == 0 + && getMouseMotionListeners().length == 0) return null; return this; } @@ -1625,30 +1631,19 @@ public class Container extends Component Component comp) { Rectangle bounds = comp.getBounds(); - Rectangle oldClip = gfx.getClipBounds(); - if (oldClip == null) - oldClip = bounds; - - Rectangle clip = oldClip.intersection(bounds); - if (clip.isEmpty()) return; + if(!gfx.hitClip(bounds.x,bounds.y, bounds.width, bounds.height)) + return; - boolean clipped = false; - boolean translated = false; + Graphics g2 = gfx.create(bounds.x, bounds.y, bounds.width, + bounds.height); try { - gfx.setClip(clip.x, clip.y, clip.width, clip.height); - clipped = true; - gfx.translate(bounds.x, bounds.y); - translated = true; - visitor.visit(comp, gfx); + visitor.visit(comp, g2); } finally { - if (translated) - gfx.translate (-bounds.x, -bounds.y); - if (clipped) - gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height); + g2.dispose(); } } @@ -2148,12 +2143,18 @@ class LightweightDispatcher implements Serializable break; } - if (me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0 + if (me.getID() == MouseEvent.MOUSE_RELEASED + || me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0 || me.getID() == MouseEvent.MOUSE_DRAGGED) { // If any of the following events occur while a button is held down, // they should be dispatched to the same component to which the // original MOUSE_PRESSED event was dispatched: + // - MOUSE_RELEASED: This is important for correct dragging + // behaviour, otherwise the release goes to an arbitrary component + // outside of the dragged component. OTOH, if there is no mouse + // drag while the mouse is pressed, the component under the mouse + // is the same as the previously pressed component anyway. // - MOUSE_PRESSED: another button pressed while the first is held // down // - MOUSE_DRAGGED diff --git a/libjava/classpath/java/awt/GridBagLayout.java b/libjava/classpath/java/awt/GridBagLayout.java index 083c0b7a7a3..714e080d7b2 100644 --- a/libjava/classpath/java/awt/GridBagLayout.java +++ b/libjava/classpath/java/awt/GridBagLayout.java @@ -341,11 +341,14 @@ public class GridBagLayout GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE); if (info.cols == 0 && info.rows == 0) return; - layoutInfo = info; // DEBUG - //dumpLayoutInfo (layoutInfo); - + //dumpLayoutInfo (info); + + // Calling setBounds on these components causes this layout to + // be invalidated, clearing the layout information cache, + // layoutInfo. So we wait until after this for loop to set + // layoutInfo. for(int i = 0; i < components.length; i++) { Component component = components [i]; @@ -357,11 +360,11 @@ public class GridBagLayout GridBagConstraints constraints = lookupInternalConstraints(component); - int cellx = sumIntArray(layoutInfo.colWidths, constraints.gridx); - int celly = sumIntArray(layoutInfo.rowHeights, constraints.gridy); - int cellw = sumIntArray(layoutInfo.colWidths, + int cellx = sumIntArray(info.colWidths, constraints.gridx); + int celly = sumIntArray(info.rowHeights, constraints.gridy); + int cellw = sumIntArray(info.colWidths, constraints.gridx + constraints.gridwidth) - cellx; - int cellh = sumIntArray(layoutInfo.rowHeights, + int cellh = sumIntArray(info.rowHeights, constraints.gridy + constraints.gridheight) - celly; Insets insets = constraints.insets; @@ -438,11 +441,14 @@ public class GridBagLayout break; } - component.setBounds(layoutInfo.pos_x + x, layoutInfo.pos_y + y, dim.width, dim.height); + component.setBounds(info.pos_x + x, info.pos_y + y, dim.width, dim.height); } // DEBUG - //dumpLayoutInfo (layoutInfo); + //dumpLayoutInfo (info); + + // Cache layout information. + layoutInfo = getLayoutInfo (parent, PREFERREDSIZE); } /** diff --git a/libjava/classpath/java/awt/datatransfer/DataFlavor.java b/libjava/classpath/java/awt/datatransfer/DataFlavor.java index 38f415b7526..32bf4d6cf37 100644 --- a/libjava/classpath/java/awt/datatransfer/DataFlavor.java +++ b/libjava/classpath/java/awt/datatransfer/DataFlavor.java @@ -1,5 +1,5 @@ /* DataFlavor.java -- A type of data to transfer via the clipboard. - Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -49,6 +49,7 @@ 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; /** @@ -63,946 +64,818 @@ public class DataFlavor implements java.io.Externalizable, Cloneable // 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, - "application/x-java-file-list; class=java.util.List", - "Java File List"); - - imageFlavor - = new DataFlavor(java.awt.Image.class, - "Java Image"); -} - -/*************************************************************************/ + /** + * 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(java.io.InputStream.class, + "text/plain; charset=unicode", + "plain unicode text"); -/* - * Instance Variables - */ + /** + * 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"); -// The MIME type for this flavor -private final String mimeType; + /** + * 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(java.util.List.class, + "application/x-java-file-list; class=java.util.List", + "Java File List"); -// The representation class for this flavor -private final Class representationClass; + /** + * 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"); -// The human readable name of this flavor -private String humanPresentableName; + /** + * 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"; -/* - * Static Methods - */ + /** + * 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"; -/** - * 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) { ; } - */ + * 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; - // FIXME: What is the context class loader? /* - try + * 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); + } + + 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; } - catch(Exception e) { ; } - */ - - if (classLoader != null) - return(classLoader.loadClass(className)); - else - throw new ClassNotFoundException(className); -} - -/*************************************************************************/ + + /** + * 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>. + */ + 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() -{ + /* + * 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) -{ + /** + * Private constructor. + */ + private DataFlavor(Class representationClass, + String mimeType, + String humanPresentableName) + { this.representationClass = representationClass; this.mimeType = mimeType; if (humanPresentableName != null) - this.humanPresentableName = humanPresentableName; + this.humanPresentableName = humanPresentableName; else - this.humanPresentableName = mimeType; -} - -/*************************************************************************/ + 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) -{ + /** + * 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=<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. - * @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=<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. - * - * @exception IllegalArgumentException If the representation class - * specified cannot be loaded. - */ -public -DataFlavor(String mimeType, String humanPresentableName) -{ - this (getRepresentationClassFromMime (mimeType, null), - mimeType, 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); -} + "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=<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. + * @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); + } -/** - * Returns the human presentable name for this flavor. - * - * @return The human presentable name for this flavor. - */ -public String -getHumanPresentableName() -{ - return(humanPresentableName); -} + /** + * Initializes a new instance of <code>DataFlavor</code> with the + * 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. + * + * @exception IllegalArgumentException If the representation class + * specified cannot be loaded. + */ + public DataFlavor(String mimeType, String humanPresentableName) + { + this(getRepresentationClassFromMime (mimeType, null), + mimeType, 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 primary MIME type for this flavor. - * - * @return The primary MIME type for this flavor. - */ -public String -getPrimaryType() -{ - int idx = mimeType.indexOf("/"); - if (idx == -1) + /** + * Returns the MIME type of this flavor. + * + * @return The MIME type for this flavor. + */ + public String getMimeType() + { 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 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); -} - -/*************************************************************************/ - -/** - * 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) -{ - if ("humanPresentableName".equals(paramName)) - return getHumanPresentableName(); - - 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. 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) -{ - 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); -} - -/*************************************************************************/ - -/** - * 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() -{ - 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() -{ - // 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); + /** + * Returns the representation class for this flavor. + * + * @return The representation class for this flavor. + */ + public Class getRepresentationClass() + { + return(representationClass); + } - return(true); -} + /** + * 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)); + } -/** - * 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); + /** + * Returns the MIME subtype for this flavor. + * + * @return The MIME subtype for this flavor. + */ + 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(equals((DataFlavor)obj)); -} + /** + * 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 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 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)); -} + /** + * 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) + { + 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); + } -/*************************************************************************/ + /** + * 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()); + } -/** - * 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()); -} + /** + * 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"); + } -/** - * 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)); -} + /** + * 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() + { + return Remote.class.isAssignableFrom (representationClass); + } -/** - * 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); -} + /** + * 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)); + } -/** - * 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); -} + /** + * 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 (mimeType.equals(javaFileListFlavor.mimeType) + && 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 + { + // FIXME - This cannot be right. + try + { + return super.clone(); + } + catch(Exception e) + { + return null; + } + } -/** - * 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 -} + /** + * 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); + } -/** - * 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 -} + /** + * 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 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() - + "]"); -} + /** + * 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; + } -/** - * XXX - Currently returns <code>plainTextFlavor</code>. - */ -public static final DataFlavor -getTextPlainUnicodeFlavor() -{ - return(plainTextFlavor); -} + /** + * 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 + } -/** - * 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()); -} + /** + * 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 (getClass().getName() + + "[representationClass=" + getRepresentationClass().getName() + + ",mimeType=" + getMimeType() + + ",humanPresentableName=" + getHumanPresentableName() + + "]"); + } -/** - * 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; + /** + * XXX - Currently returns <code>java.io.InputStream</code>. + * + * @since 1.3 + */ + public final Class getDefaultRepresentationClass() + { + return java.io.InputStream.class; + } - // A Reader or String is good. - if ((Reader.class.isAssignableFrom(c)) - || (String.class.isAssignableFrom(c))) - { - return df; - } + /** + * XXX - Currently returns <code>java.io.InputStream</code>. + */ + public final String getDefaultRepresentationClassAsString() + { + return getDefaultRepresentationClass().getName(); + } - // A InputStream is good if the mime primary type is "text" - if ((InputStream.class.isAssignableFrom(c)) - && ("text".equals(df.getPrimaryType()))) + /** + * 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())) { - String encoding = availableFlavors[i].getParameter("charset"); + InputStream in = (InputStream)transferable.getTransferData(this); + String encoding = 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; + encoding = "us-ascii"; + return new InputStreamReader(in, encoding); } - } - - // 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); -} + + throw new UnsupportedFlavorException(this); + } /** * Returns whether the representation class for this DataFlavor is @@ -1010,9 +883,9 @@ public Reader getReaderForText(Transferable transferable) * * @since 1.4 */ - public boolean isRepresentationClassByteBuffer () + public boolean isRepresentationClassByteBuffer() { - return ByteBuffer.class.isAssignableFrom (representationClass); + return ByteBuffer.class.isAssignableFrom(representationClass); } /** @@ -1021,9 +894,9 @@ public Reader getReaderForText(Transferable transferable) * * @since 1.4 */ - public boolean isRepresentationClassCharBuffer () + public boolean isRepresentationClassCharBuffer() { - return CharBuffer.class.isAssignableFrom (representationClass); + return CharBuffer.class.isAssignableFrom(representationClass); } /** @@ -1032,10 +905,67 @@ public Reader getReaderForText(Transferable transferable) * * @since 1.4 */ - public boolean isRepresentationClassReader () + public boolean isRepresentationClassReader() { - return Reader.class.isAssignableFrom (representationClass); + 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 diff --git a/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java b/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java index f6530f5117c..7b4d2fbd38f 100644 --- a/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java +++ b/libjava/classpath/java/awt/datatransfer/SystemFlavorMap.java @@ -38,9 +38,11 @@ exception statement from your version. */ package java.awt.datatransfer; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.WeakHashMap; /** * This class maps between native platform type names and DataFlavors. @@ -54,10 +56,28 @@ import java.util.Map; public final class SystemFlavorMap implements FlavorMap, FlavorTable { /** - * The default (instance) flavor map. + * The map which maps the thread's <code>ClassLoaders</code> to + * <code>SystemFlavorMaps</code>. */ - private static FlavorMap defaultFlavorMap; - + private static final Map systemFlavorMaps = new WeakHashMap(); + + /** + * Constant which is used to prefix encode Java MIME types. + */ + private static final String GNU_JAVA_MIME_PREFIX = "gnu.java:"; + + /** + * This map maps native <code>String</code>s to lists of + * <code>DataFlavor</code>s + */ + private HashMap nativeToFlavorMap = new HashMap(); + + /** + * This map maps <code>DataFlavor</code>s to lists of native + * <code>String</code>s + */ + private HashMap flavorToNativeMap = new HashMap(); + /** * Private constructor. */ @@ -98,47 +118,118 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable } /** - * Returns the default (instance) (System)FlavorMap. + * Returns the (System)FlavorMap for the current thread's + * ClassLoader. */ public static FlavorMap getDefaultFlavorMap () { - if (defaultFlavorMap == null) - defaultFlavorMap = new SystemFlavorMap (); - - return defaultFlavorMap; + ClassLoader classLoader = Thread.currentThread() + .getContextClassLoader(); + + //if ContextClassLoader not set, use system default + if (classLoader == null) + { + classLoader = ClassLoader.getSystemClassLoader(); + } + + synchronized(systemFlavorMaps) + { + FlavorMap map = (FlavorMap) + systemFlavorMaps.get(classLoader); + if (map == null) + { + map = new SystemFlavorMap(); + systemFlavorMaps.put(classLoader, map); + } + return map; + } } /** - * Returns the native type name for the given java mime type. + * Encodes a MIME type for use as a <code>String</code> native. The format + * of an encoded representation of a MIME type is implementation-dependent. + * The only restrictions are: + * <ul> + * <li>The encoded representation is <code>null</code> if and only if the + * MIME type <code>String</code> is <code>null</code>.</li> + * <li>The encoded representations for two non-<code>null</code> MIME type + * <code>String</code>s are equal if and only if these <code>String</code>s + * are equal according to <code>String.equals(Object)</code>.</li> + * </ul> + * <p> + * The present implementation of this method returns the specified MIME + * type <code>String</code> prefixed with <code>gnu.java:</code>. + * + * @param mime the MIME type to encode + * @return the encoded <code>String</code>, or <code>null</code> if + * mimeType is <code>null</code> */ public static String encodeJavaMIMEType (String mime) { - return null; + if (mime != null) + return GNU_JAVA_MIME_PREFIX + mime; + else + return null; } /** - * Returns the native type name for the given data flavor. + * Encodes a <code>DataFlavor</code> for use as a <code>String</code> + * native. The format of an encoded <code>DataFlavor</code> is + * implementation-dependent. The only restrictions are: + * <ul> + * <li>The encoded representation is <code>null</code> if and only if the + * specified <code>DataFlavor</code> is <code>null</code> or its MIME type + * <code>String</code> is <code>null</code>.</li> + * <li>The encoded representations for two non-<code>null</code> + * <code>DataFlavor</code>s with non-<code>null</code> MIME type + * <code>String</code>s are equal if and only if the MIME type + * <code>String</code>s of these <code>DataFlavor</code>s are equal + * according to <code>String.equals(Object)</code>.</li> + * </ul> + * <p> + * The present implementation of this method returns the MIME type + * <code>String</code> of the specified <code>DataFlavor</code> prefixed + * with <code>gnu.java:</code>. + * + * @param df the <code>DataFlavor</code> to encode + * @return the encoded <code>String</code>, or <code>null</code> if + * flav is <code>null</code> or has a <code>null</code> MIME type */ public static String encodeDataFlavor (DataFlavor df) { - return null; + if (df != null) + { + return encodeJavaMIMEType(df.getMimeType()); + } + else + return null; } /** * Returns true if the native type name can be represented as - * a java mime type. + * a java mime type. Returns <code>false</code> if parameter is + * <code>null</code>. */ public static boolean isJavaMIMEType (String name) { - return false; + return (name != null && name.startsWith(GNU_JAVA_MIME_PREFIX)); } /** - * Returns the java mime type for the given the native type name. + * Decodes a <code>String</code> native for use as a Java MIME type. + * + * @param name the <code>String</code> to decode + * @return the decoded Java MIME type, or <code>null</code> if nat + * is not an encoded <code>String</code> native */ public static String decodeJavaMIMEType (String name) { - return null; + if (isJavaMIMEType(name)) + { + return name.substring(GNU_JAVA_MIME_PREFIX.length()); + } + else + return null; } /** @@ -156,6 +247,20 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable return null; } + /** + * Returns a List of <code>DataFlavors</code> to which the specified + * <code>String</code> native can be translated by the data transfer + * subsystem. The <code>List</code> will be sorted from best + * <code>DataFlavor</code> to worst. That is, the first <code>DataFlavor + * </code> will best reflect data in the specified native to a Java + * application. + * <p> + * If the specified native is previously unknown to the data transfer + * subsystem, and that native has been properly encoded, then invoking + * this method will establish a mapping in both directions between the + * specified native and a DataFlavor whose MIME type is a decoded + * version of the native. + */ public List getFlavorsForNative (String nat) { throw new Error ("Not implemented"); @@ -165,5 +270,160 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new Error ("Not implemented"); } + + /** + * Adds a mapping from a single <code>String</code> native to a single + * <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the + * mapping will only be established in one direction, and the native will + * not be encoded. To establish a two-way mapping, call + * <code>addUnencodedNativeForFlavor</code> as well. The new mapping will + * be of lower priority than any existing mapping. + * This method has no effect if a mapping from the specified + * <code>String</code> native to the specified or equal + * <code>DataFlavor</code> already exists. + * + * @param nativeStr the <code>String</code> native key for the mapping + * @param flavor the <code>DataFlavor</code> value for the mapping + * @throws NullPointerException if nat or flav is <code>null</code> + * + * @see #addUnencodedNativeForFlavor + * @since 1.4 + */ + public synchronized void addFlavorForUnencodedNative(String nativeStr, + DataFlavor flavor) + { + if ((nativeStr == null) || (flavor == null)) + throw new NullPointerException(); + List flavors = (List) nativeToFlavorMap.get(nativeStr); + if (flavors == null) + { + flavors = new ArrayList(); + nativeToFlavorMap.put(nativeStr, flavors); + } + else + { + if (! flavors.contains(flavor)) + flavors.add(flavor); + } + } + + /** + * Adds a mapping from the specified <code>DataFlavor</code> (and all + * <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>) + * to the specified <code>String</code> native. + * Unlike <code>getNativesForFlavor</code>, the mapping will only be + * established in one direction, and the native will not be encoded. To + * establish a two-way mapping, call + * <code>addFlavorForUnencodedNative</code> as well. The new mapping will + * be of lower priority than any existing mapping. + * This method has no effect if a mapping from the specified or equal + * <code>DataFlavor</code> to the specified <code>String</code> native + * already exists. + * + * @param flavor the <code>DataFlavor</code> key for the mapping + * @param nativeStr the <code>String</code> native value for the mapping + * @throws NullPointerException if flav or nat is <code>null</code> + * + * @see #addFlavorForUnencodedNative + * @since 1.4 + */ + public synchronized void addUnencodedNativeForFlavor(DataFlavor flavor, + String nativeStr) + { + if ((nativeStr == null) || (flavor == null)) + throw new NullPointerException(); + List natives = (List) flavorToNativeMap.get(flavor); + if (natives == null) + { + natives = new ArrayList(); + flavorToNativeMap.put(flavor, natives); + } + else + { + if (! natives.contains(nativeStr)) + natives.add(nativeStr); + } + } + + /** + * Discards the current mappings for the specified <code>DataFlavor</code> + * and all <code>DataFlavor</code>s equal to the specified + * <code>DataFlavor</code>, and creates new mappings to the + * specified <code>String</code> natives. + * Unlike <code>getNativesForFlavor</code>, the mappings will only be + * established in one direction, and the natives will not be encoded. To + * establish two-way mappings, call <code>setFlavorsForNative</code> + * as well. The first native in the array will represent the highest + * priority mapping. Subsequent natives will represent mappings of + * decreasing priority. + * <p> + * If the array contains several elements that reference equal + * <code>String</code> natives, this method will establish new mappings + * for the first of those elements and ignore the rest of them. + * <p> + * It is recommended that client code not reset mappings established by the + * data transfer subsystem. This method should only be used for + * application-level mappings. + * + * @param flavor the <code>DataFlavor</code> key for the mappings + * @param natives the <code>String</code> native values for the mappings + * @throws NullPointerException if flav or natives is <code>null</code> + * or if natives contains <code>null</code> elements + * + * @see #setFlavorsForNative + * @since 1.4 + */ + public synchronized void setNativesForFlavor(DataFlavor flavor, + String[] natives) + { + if ((natives == null) || (flavor == null)) + throw new NullPointerException(); + + flavorToNativeMap.remove(flavor); + for (int i = 0; i < natives.length; i++) + { + addUnencodedNativeForFlavor(flavor, natives[i]); + } + } + + /** + * Discards the current mappings for the specified <code>String</code> + * native, and creates new mappings to the specified + * <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the + * mappings will only be established in one direction, and the natives need + * not be encoded. To establish two-way mappings, call + * <code>setNativesForFlavor</code> as well. The first + * <code>DataFlavor</code> in the array will represent the highest priority + * mapping. Subsequent <code>DataFlavor</code>s will represent mappings of + * decreasing priority. + * <p> + * If the array contains several elements that reference equal + * <code>DataFlavor</code>s, this method will establish new mappings + * for the first of those elements and ignore the rest of them. + * <p> + * It is recommended that client code not reset mappings established by the + * data transfer subsystem. This method should only be used for + * application-level mappings. + * + * @param nativeStr the <code>String</code> native key for the mappings + * @param flavors the <code>DataFlavor</code> values for the mappings + * @throws NullPointerException if nat or flavors is <code>null</code> + * or if flavors contains <code>null</code> elements + * + * @see #setNativesForFlavor + * @since 1.4 + */ + public synchronized void setFlavorsForNative(String nativeStr, + DataFlavor[] flavors) + { + if ((nativeStr == null) || (flavors == null)) + throw new NullPointerException(); + + nativeToFlavorMap.remove(nativeStr); + for (int i = 0; i < flavors.length; i++) + { + addFlavorForUnencodedNative(nativeStr, flavors[i]); + } + } } // class SystemFlavorMap |