History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/datatransfer (36 of 18352 files). Show all

Unified · Split

36 files
  1. java/pkg/java/awt/datatransfer/Clipboard$1.class +0 −0
  2. java/pkg/java/awt/datatransfer/Clipboard$2.class +0 −0
  3. java/pkg/java/awt/datatransfer/Clipboard.class +0 −0
  4. java/pkg/java/awt/datatransfer/Clipboard.java +354 −0
  5. java/pkg/java/awt/datatransfer/ClipboardOwner.class +0 −0
  6. java/pkg/java/awt/datatransfer/ClipboardOwner.java +56 −0
  7. java/pkg/java/awt/datatransfer/DataFlavor$1.class +0 −0
  8. java/pkg/java/awt/datatransfer/DataFlavor$TextFlavorComparator.class +0 −0
  9. java/pkg/java/awt/datatransfer/DataFlavor.class +0 −0
  10. java/pkg/java/awt/datatransfer/DataFlavor.java +1381 −0
  11. java/pkg/java/awt/datatransfer/FlavorEvent.class +0 −0
  12. java/pkg/java/awt/datatransfer/FlavorEvent.java +51 −0
  13. java/pkg/java/awt/datatransfer/FlavorListener.class +0 −0
  14. java/pkg/java/awt/datatransfer/FlavorListener.java +55 −0
  15. java/pkg/java/awt/datatransfer/FlavorMap.class +0 −0
  16. java/pkg/java/awt/datatransfer/FlavorMap.java +75 −0
  17. java/pkg/java/awt/datatransfer/FlavorTable.class +0 −0
  18. java/pkg/java/awt/datatransfer/FlavorTable.java +82 −0
  19. java/pkg/java/awt/datatransfer/MimeType.class +0 −0
  20. java/pkg/java/awt/datatransfer/MimeType.java +393 −0
  21. java/pkg/java/awt/datatransfer/MimeTypeParameterList.class +0 −0
  22. java/pkg/java/awt/datatransfer/MimeTypeParameterList.java +404 −0
  23. java/pkg/java/awt/datatransfer/MimeTypeParseException.class +0 −0
  24. java/pkg/java/awt/datatransfer/MimeTypeParseException.java +55 −0
  25. java/pkg/java/awt/datatransfer/StringSelection.class +0 −0
  26. java/pkg/java/awt/datatransfer/StringSelection.java +140 −0
  27. java/pkg/java/awt/datatransfer/SystemFlavorMap$1.class +0 −0
  28. java/pkg/java/awt/datatransfer/SystemFlavorMap$2.class +0 −0
  29. java/pkg/java/awt/datatransfer/SystemFlavorMap.class +0 −0
  30. java/pkg/java/awt/datatransfer/SystemFlavorMap.java +1299 −0
  31. java/pkg/java/awt/datatransfer/Transferable.class +0 −0
  32. java/pkg/java/awt/datatransfer/Transferable.java +73 −0
  33. java/pkg/java/awt/datatransfer/UnsupportedFlavorException.class +0 −0
  34. java/pkg/java/awt/datatransfer/UnsupportedFlavorException.java +50 −0
  35. java/pkg/java/awt/datatransfer/mkfile +21 −0
  36. java/pkg/java/awt/datatransfer/package.html +63 −0
java/pkg/java/awt/datatransfer/Clipboard$1.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/Clipboard$2.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/Clipboard.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/Clipboard.java+354−0
@@ -0,0 +1,354 @@
1+/*
2+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.awt.EventQueue;
29+
30+import java.util.Set;
31+import java.util.HashSet;
32+import java.util.Arrays;
33+
34+import java.io.IOException;
35+
36+import sun.awt.EventListenerAggregate;
37+
38+
39+/**
40+ * A class that implements a mechanism to transfer data using
41+ * cut/copy/paste operations.
42+ * <p>
43+ * {@link FlavorListener}s may be registered on an instance of the
44+ * Clipboard class to be notified about changes to the set of
45+ * {@link DataFlavor}s available on this clipboard (see
46+ * {@link #addFlavorListener}).
47+ *
48+ * @see java.awt.Toolkit#getSystemClipboard
49+ * @see java.awt.Toolkit#getSystemSelection
50+ *
51+ * @author Amy Fowler
52+ * @author Alexander Gerasimov
53+ */
54+public class Clipboard {
55+
56+ String name;
57+
58+ protected ClipboardOwner owner;
59+ protected Transferable contents;
60+
61+ /**
62+ * An aggregate of flavor listeners registered on this local clipboard.
63+ *
64+ * @since 1.5
65+ */
66+ private EventListenerAggregate flavorListeners;
67+
68+ /**
69+ * A set of <code>DataFlavor</code>s that is available on
70+ * this local clipboard. It is used for tracking changes
71+ * of <code>DataFlavor</code>s available on this clipboard.
72+ *
73+ * @since 1.5
74+ */
75+ private Set currentDataFlavors;
76+
77+ /**
78+ * Creates a clipboard object.
79+ *
80+ * @see java.awt.Toolkit#getSystemClipboard
81+ */
82+ public Clipboard(String name) {
83+ this.name = name;
84+ }
85+
86+ /**
87+ * Returns the name of this clipboard object.
88+ *
89+ * @see java.awt.Toolkit#getSystemClipboard
90+ */
91+ public String getName() {
92+ return name;
93+ }
94+
95+ /**
96+ * Sets the current contents of the clipboard to the specified
97+ * transferable object and registers the specified clipboard owner
98+ * as the owner of the new contents.
99+ * <p>
100+ * If there is an existing owner different from the argument
101+ * <code>owner</code>, that owner is notified that it no longer
102+ * holds ownership of the clipboard contents via an invocation
103+ * of <code>ClipboardOwner.lostOwnership()</code> on that owner.
104+ * An implementation of <code>setContents()</code> is free not
105+ * to invoke <code>lostOwnership()</code> directly from this method.
106+ * For example, <code>lostOwnership()</code> may be invoked later on
107+ * a different thread. The same applies to <code>FlavorListener</code>s
108+ * registered on this clipboard.
109+ * <p>
110+ * The method throws <code>IllegalStateException</code> if the clipboard
111+ * is currently unavailable. For example, on some platforms, the system
112+ * clipboard is unavailable while it is accessed by another application.
113+ *
114+ * @param contents the transferable object representing the
115+ * clipboard content
116+ * @param owner the object which owns the clipboard content
117+ * @throws IllegalStateException if the clipboard is currently unavailable
118+ * @see java.awt.Toolkit#getSystemClipboard
119+ */
120+ public synchronized void setContents(Transferable contents, ClipboardOwner owner) {
121+ final ClipboardOwner oldOwner = this.owner;
122+ final Transferable oldContents = this.contents;
123+
124+ this.owner = owner;
125+ this.contents = contents;
126+
127+ if (oldOwner != null && oldOwner != owner) {
128+ EventQueue.invokeLater(new Runnable() {
129+ public void run() {
130+ oldOwner.lostOwnership(Clipboard.this, oldContents);
131+ }
132+ });
133+ }
134+ fireFlavorsChanged();
135+ }
136+
137+ /**
138+ * Returns a transferable object representing the current contents
139+ * of the clipboard. If the clipboard currently has no contents,
140+ * it returns <code>null</code>. The parameter Object requestor is
141+ * not currently used. The method throws
142+ * <code>IllegalStateException</code> if the clipboard is currently
143+ * unavailable. For example, on some platforms, the system clipboard is
144+ * unavailable while it is accessed by another application.
145+ *
146+ * @param requestor the object requesting the clip data (not used)
147+ * @return the current transferable object on the clipboard
148+ * @throws IllegalStateException if the clipboard is currently unavailable
149+ * @see java.awt.Toolkit#getSystemClipboard
150+ */
151+ public synchronized Transferable getContents(Object requestor) {
152+ return contents;
153+ }
154+
155+
156+ /**
157+ * Returns an array of <code>DataFlavor</code>s in which the current
158+ * contents of this clipboard can be provided. If there are no
159+ * <code>DataFlavor</code>s available, this method returns a zero-length
160+ * array.
161+ *
162+ * @return an array of <code>DataFlavor</code>s in which the current
163+ * contents of this clipboard can be provided
164+ *
165+ * @throws IllegalStateException if this clipboard is currently unavailable
166+ *
167+ * @since 1.5
168+ */
169+ public DataFlavor[] getAvailableDataFlavors() {
170+ Transferable cntnts = getContents(null);
171+ if (cntnts == null) {
172+ return new DataFlavor[0];
173+ }
174+ return cntnts.getTransferDataFlavors();
175+ }
176+
177+ /**
178+ * Returns whether or not the current contents of this clipboard can be
179+ * provided in the specified <code>DataFlavor</code>.
180+ *
181+ * @param flavor the requested <code>DataFlavor</code> for the contents
182+ *
183+ * @return <code>true</code> if the current contents of this clipboard
184+ * can be provided in the specified <code>DataFlavor</code>;
185+ * <code>false</code> otherwise
186+ *
187+ * @throws NullPointerException if <code>flavor</code> is <code>null</code>
188+ * @throws IllegalStateException if this clipboard is currently unavailable
189+ *
190+ * @since 1.5
191+ */
192+ public boolean isDataFlavorAvailable(DataFlavor flavor) {
193+ if (flavor == null) {
194+ throw new NullPointerException("flavor");
195+ }
196+
197+ Transferable cntnts = getContents(null);
198+ if (cntnts == null) {
199+ return false;
200+ }
201+ return cntnts.isDataFlavorSupported(flavor);
202+ }
203+
204+ /**
205+ * Returns an object representing the current contents of this clipboard
206+ * in the specified <code>DataFlavor</code>.
207+ * The class of the object returned is defined by the representation
208+ * class of <code>flavor</code>.
209+ *
210+ * @param flavor the requested <code>DataFlavor</code> for the contents
211+ *
212+ * @return an object representing the current contents of this clipboard
213+ * in the specified <code>DataFlavor</code>
214+ *
215+ * @throws NullPointerException if <code>flavor</code> is <code>null</code>
216+ * @throws IllegalStateException if this clipboard is currently unavailable
217+ * @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
218+ * is not available
219+ * @throws IOException if the data in the requested <code>DataFlavor</code>
220+ * can not be retrieved
221+ *
222+ * @see DataFlavor#getRepresentationClass
223+ *
224+ * @since 1.5
225+ */
226+ public Object getData(DataFlavor flavor)
227+ throws UnsupportedFlavorException, IOException {
228+ if (flavor == null) {
229+ throw new NullPointerException("flavor");
230+ }
231+
232+ Transferable cntnts = getContents(null);
233+ if (cntnts == null) {
234+ throw new UnsupportedFlavorException(flavor);
235+ }
236+ return cntnts.getTransferData(flavor);
237+ }
238+
239+
240+ /**
241+ * Registers the specified <code>FlavorListener</code> to receive
242+ * <code>FlavorEvent</code>s from this clipboard.
243+ * If <code>listener</code> is <code>null</code>, no exception
244+ * is thrown and no action is performed.
245+ *
246+ * @param listener the listener to be added
247+ *
248+ * @see #removeFlavorListener
249+ * @see #getFlavorListeners
250+ * @see FlavorListener
251+ * @see FlavorEvent
252+ * @since 1.5
253+ */
254+ public synchronized void addFlavorListener(FlavorListener listener) {
255+ if (listener == null) {
256+ return;
257+ }
258+ if (flavorListeners == null) {
259+ currentDataFlavors = getAvailableDataFlavorSet();
260+ flavorListeners = new EventListenerAggregate(FlavorListener.class);
261+ }
262+ flavorListeners.add(listener);
263+ }
264+
265+ /**
266+ * Removes the specified <code>FlavorListener</code> so that it no longer
267+ * receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
268+ * This method performs no function, nor does it throw an exception, if
269+ * the listener specified by the argument was not previously added to this
270+ * <code>Clipboard</code>.
271+ * If <code>listener</code> is <code>null</code>, no exception
272+ * is thrown and no action is performed.
273+ *
274+ * @param listener the listener to be removed
275+ *
276+ * @see #addFlavorListener
277+ * @see #getFlavorListeners
278+ * @see FlavorListener
279+ * @see FlavorEvent
280+ * @since 1.5
281+ */
282+ public synchronized void removeFlavorListener(FlavorListener listener) {
283+ if (listener == null || flavorListeners == null) {
284+ return;
285+ }
286+ flavorListeners.remove(listener);
287+ }
288+
289+ /**
290+ * Returns an array of all the <code>FlavorListener</code>s currently
291+ * registered on this <code>Clipboard</code>.
292+ *
293+ * @return all of this clipboard's <code>FlavorListener</code>s or an empty
294+ * array if no listeners are currently registered
295+ * @see #addFlavorListener
296+ * @see #removeFlavorListener
297+ * @see FlavorListener
298+ * @see FlavorEvent
299+ * @since 1.5
300+ */
301+ public synchronized FlavorListener[] getFlavorListeners() {
302+ return flavorListeners == null ? new FlavorListener[0] :
303+ (FlavorListener[])flavorListeners.getListenersCopy();
304+ }
305+
306+ /**
307+ * Checks change of the <code>DataFlavor</code>s and, if necessary,
308+ * notifies all listeners that have registered interest for notification
309+ * on <code>FlavorEvent</code>s.
310+ *
311+ * @since 1.5
312+ */
313+ private void fireFlavorsChanged() {
314+ if (flavorListeners == null) {
315+ return;
316+ }
317+ Set prevDataFlavors = currentDataFlavors;
318+ currentDataFlavors = getAvailableDataFlavorSet();
319+ if (prevDataFlavors.equals(currentDataFlavors)) {
320+ return;
321+ }
322+ FlavorListener[] flavorListenerArray =
323+ (FlavorListener[])flavorListeners.getListenersInternal();
324+ for (int i = 0; i < flavorListenerArray.length; i++) {
325+ final FlavorListener listener = flavorListenerArray[i];
326+ EventQueue.invokeLater(new Runnable() {
327+ public void run() {
328+ listener.flavorsChanged(new FlavorEvent(Clipboard.this));
329+ }
330+ });
331+ }
332+ }
333+
334+ /**
335+ * Returns a set of <code>DataFlavor</code>s currently available
336+ * on this clipboard.
337+ *
338+ * @return a set of <code>DataFlavor</code>s currently available
339+ * on this clipboard
340+ *
341+ * @since 1.5
342+ */
343+ private Set getAvailableDataFlavorSet() {
344+ Set set = new HashSet();
345+ Transferable contents = getContents(null);
346+ if (contents != null) {
347+ DataFlavor[] flavors = contents.getTransferDataFlavors();
348+ if (flavors != null) {
349+ set.addAll(Arrays.asList(flavors));
350+ }
351+ }
352+ return set;
353+ }
354+}
java/pkg/java/awt/datatransfer/ClipboardOwner.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/ClipboardOwner.java+56−0
@@ -0,0 +1,56 @@
1+/*
2+ * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+/**
29+ * Defines the interface for classes that will provide data to
30+ * a clipboard. An instance of this interface becomes the owner
31+ * of the contents of a clipboard (clipboard owner) if it is
32+ * passed as an argument to
33+ * {@link java.awt.datatransfer.Clipboard#setContents} method of
34+ * the clipboard and this method returns successfully.
35+ * The instance remains the clipboard owner until another application
36+ * or another object within this application asserts ownership
37+ * of this clipboard.
38+ *
39+ * @see java.awt.datatransfer.Clipboard
40+ *
41+ * @author Amy Fowler
42+ */
43+
44+public interface ClipboardOwner {
45+
46+ /**
47+ * Notifies this object that it is no longer the clipboard owner.
48+ * This method will be called when another application or another
49+ * object within this application asserts ownership of the clipboard.
50+ *
51+ * @param clipboard the clipboard that is no longer owned
52+ * @param contents the contents which this owner had placed on the clipboard
53+ */
54+ public void lostOwnership(Clipboard clipboard, Transferable contents);
55+
56+}
java/pkg/java/awt/datatransfer/DataFlavor$1.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/DataFlavor$TextFlavorComparator.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/DataFlavor.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/DataFlavor.java+1381−0
@@ -0,0 +1,1381 @@
1+/*
2+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.awt.Toolkit;
29+import java.io.*;
30+import java.nio.*;
31+import java.util.*;
32+
33+import sun.awt.datatransfer.DataTransferer;
34+
35+/**
36+ * A {@code DataFlavor} provides meta information about data. {@code DataFlavor}
37+ * is typically used to access data on the clipboard, or during
38+ * a drag and drop operation.
39+ * <p>
40+ * An instance of {@code DataFlavor} encapsulates a content type as
41+ * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
42+ * and <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>.
43+ * A content type is typically referred to as a MIME type.
44+ * <p>
45+ * A content type consists of a media type (referred
46+ * to as the primary type), a subtype, and optional parameters. See
47+ * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
48+ * for details on the syntax of a MIME type.
49+ * <p>
50+ * The JRE data transfer implementation interprets the parameter &quot;class&quot;
51+ * of a MIME type as <B>a representation class</b>.
52+ * The representation class reflects the class of the object being
53+ * transferred. In other words, the representation class is the type of
54+ * object returned by {@link Transferable#getTransferData}.
55+ * For example, the MIME type of {@link #imageFlavor} is
56+ * {@code "image/x-java-image;class=java.awt.Image"},
57+ * the primary type is {@code image}, the subtype is
58+ * {@code x-java-image}, and the representation class is
59+ * {@code java.awt.Image}. When {@code getTransferData} is invoked
60+ * with a {@code DataFlavor} of {@code imageFlavor}, an instance of
61+ * {@code java.awt.Image} is returned.
62+ * It's important to note that {@code DataFlavor} does no error checking
63+ * against the representation class. It is up to consumers of
64+ * {@code DataFlavor}, such as {@code Transferable}, to honor the representation
65+ * class.
66+ * <br>
67+ * Note, if you do not specify a representation class when
68+ * creating a {@code DataFlavor}, the default
69+ * representation class is used. See appropriate documentation for
70+ * {@code DataFlavor}'s constructors.
71+ * <p>
72+ * Also, {@code DataFlavor} instances with the &quot;text&quot; primary
73+ * MIME type may have a &quot;charset&quot; parameter. Refer to
74+ * <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a> and
75+ * {@link #selectBestTextFlavor} for details on &quot;text&quot; MIME types
76+ * and the &quot;charset&quot; parameter.
77+ * <p>
78+ * Equality of {@code DataFlavors} is determined by the primary type,
79+ * subtype, and representation class. Refer to {@link #equals(DataFlavor)} for
80+ * details. When determining equality, any optional parameters are ignored.
81+ * For example, the following produces two {@code DataFlavors} that
82+ * are considered identical:
83+ * <pre>
84+ * DataFlavor flavor1 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; foo=bar&quot;);
85+ * DataFlavor flavor2 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; x=y&quot;);
86+ * // The following returns true.
87+ * flavor1.equals(flavor2);
88+ * </pre>
89+ * As mentioned, {@code flavor1} and {@code flavor2} are considered identical.
90+ * As such, asking a {@code Transferable} for either {@code DataFlavor} returns
91+ * the same results.
92+ * <p>
93+ * For more information on the using data transfer with Swing see
94+ * the <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
95+ * How to Use Drag and Drop and Data Transfer</a>,
96+ * section in <em>Java Tutorial</em>.
97+ *
98+ * @author Blake Sullivan
99+ * @author Laurence P. G. Cable
100+ * @author Jeff Dunn
101+ */
102+public class DataFlavor implements Externalizable, Cloneable {
103+
104+ private static final long serialVersionUID = 8367026044764648243L;
105+ private static final Class ioInputStreamClass = java.io.InputStream.class;
106+
107+ /**
108+ * Tries to load a class from: the bootstrap loader, the system loader,
109+ * the context loader (if one is present) and finally the loader specified.
110+ *
111+ * @param className the name of the class to be loaded
112+ * @param fallback the fallback loader
113+ * @return the class loaded
114+ * @exception ClassNotFoundException if class is not found
115+ */
116+ protected final static Class<?> tryToLoadClass(String className,
117+ ClassLoader fallback)
118+ throws ClassNotFoundException
119+ {
120+ ClassLoader systemClassLoader = (ClassLoader)
121+ java.security.AccessController.doPrivileged(
122+ new java.security.PrivilegedAction() {
123+ public Object run() {
124+ ClassLoader cl = Thread.currentThread().
125+ getContextClassLoader();
126+ return (cl != null)
127+ ? cl
128+ : ClassLoader.getSystemClassLoader();
129+ }
130+ });
131+
132+ try {
133+ return Class.forName(className, true, systemClassLoader);
134+ } catch (ClassNotFoundException e2) {
135+ if (fallback != null) {
136+ return Class.forName(className, true, fallback);
137+ } else {
138+ throw new ClassNotFoundException(className);
139+ }
140+ }
141+ }
142+
143+ /*
144+ * private initializer
145+ */
146+ static private DataFlavor createConstant(Class rc, String prn) {
147+ try {
148+ return new DataFlavor(rc, prn);
149+ } catch (Exception e) {
150+ return null;
151+ }
152+ }
153+
154+ /*
155+ * private initializer
156+ */
157+ static private DataFlavor createConstant(String mt, String prn) {
158+ try {
159+ return new DataFlavor(mt, prn);
160+ } catch (Exception e) {
161+ return null;
162+ }
163+ }
164+
165+ /**
166+ * The <code>DataFlavor</code> representing a Java Unicode String class,
167+ * where:
168+ * <pre>
169+ * representationClass = java.lang.String
170+ * mimeType = "application/x-java-serialized-object"
171+ * </pre>
172+ */
173+ public static final DataFlavor stringFlavor = createConstant(java.lang.String.class, "Unicode String");
174+
175+ /**
176+ * The <code>DataFlavor</code> representing a Java Image class,
177+ * where:
178+ * <pre>
179+ * representationClass = java.awt.Image
180+ * mimeType = "image/x-java-image"
181+ * </pre>
182+ */
183+ public static final DataFlavor imageFlavor = createConstant("image/x-java-image; class=java.awt.Image", "Image");
184+
185+ /**
186+ * The <code>DataFlavor</code> representing plain text with Unicode
187+ * encoding, where:
188+ * <pre>
189+ * representationClass = InputStream
190+ * mimeType = "text/plain; charset=unicode"
191+ * </pre>
192+ * This <code>DataFlavor</code> has been <b>deprecated</b> because
193+ * (1) Its representation is an InputStream, an 8-bit based representation,
194+ * while Unicode is a 16-bit character set; and (2) The charset "unicode"
195+ * is not well-defined. "unicode" implies a particular platform's
196+ * implementation of Unicode, not a cross-platform implementation.
197+ *
198+ * @deprecated as of 1.3. Use <code>DataFlavor.getReaderForText(Transferable)</code>
199+ * instead of <code>Transferable.getTransferData(DataFlavor.plainTextFlavor)</code>.
200+ */
201+ @Deprecated
202+ public static final DataFlavor plainTextFlavor = createConstant("text/plain; charset=unicode; class=java.io.InputStream", "Plain Text");
203+
204+ /**
205+ * A MIME Content-Type of application/x-java-serialized-object represents
206+ * a graph of Java object(s) that have been made persistent.
207+ *
208+ * The representation class associated with this <code>DataFlavor</code>
209+ * identifies the Java type of an object returned as a reference
210+ * from an invocation <code>java.awt.datatransfer.getTransferData</code>.
211+ */
212+ public static final String javaSerializedObjectMimeType = "application/x-java-serialized-object";
213+
214+ /**
215+ * To transfer a list of files to/from Java (and the underlying
216+ * platform) a <code>DataFlavor</code> of this type/subtype and
217+ * representation class of <code>java.util.List</code> is used.
218+ * Each element of the list is required/guaranteed to be of type
219+ * <code>java.io.File</code>.
220+ */
221+ public static final DataFlavor javaFileListFlavor = createConstant("application/x-java-file-list;class=java.util.List", null);
222+
223+ /**
224+ * To transfer a reference to an arbitrary Java object reference that
225+ * has no associated MIME Content-type, across a <code>Transferable</code>
226+ * interface WITHIN THE SAME JVM, a <code>DataFlavor</code>
227+ * with this type/subtype is used, with a <code>representationClass</code>
228+ * equal to the type of the class/interface being passed across the
229+ * <code>Transferable</code>.
230+ * <p>
231+ * The object reference returned from
232+ * <code>Transferable.getTransferData</code> for a <code>DataFlavor</code>
233+ * with this MIME Content-Type is required to be
234+ * an instance of the representation Class of the <code>DataFlavor</code>.
235+ */
236+ public static final String javaJVMLocalObjectMimeType = "application/x-java-jvm-local-objectref";
237+
238+ /**
239+ * In order to pass a live link to a Remote object via a Drag and Drop
240+ * <code>ACTION_LINK</code> operation a Mime Content Type of
241+ * application/x-java-remote-object should be used,
242+ * where the representation class of the <code>DataFlavor</code>
243+ * represents the type of the <code>Remote</code> interface to be
244+ * transferred.
245+ */
246+ public static final String javaRemoteObjectMimeType = "application/x-java-remote-object";
247+
248+ /**
249+ * Constructs a new <code>DataFlavor</code>. This constructor is
250+ * provided only for the purpose of supporting the
251+ * <code>Externalizable</code> interface. It is not
252+ * intended for public (client) use.
253+ *
254+ * @since 1.2
255+ */
256+ public DataFlavor() {
257+ super();
258+ }
259+
260+ /**
261+ * Constructs a fully specified <code>DataFlavor</code>.
262+ *
263+ * @exception NullPointerException if either <code>primaryType</code>,
264+ * <code>subType</code> or <code>representationClass</code> is null
265+ */
266+ private DataFlavor(String primaryType, String subType, MimeTypeParameterList params, Class representationClass, String humanPresentableName) {
267+ super();
268+ if (primaryType == null) {
269+ throw new NullPointerException("primaryType");
270+ }
271+ if (subType == null) {
272+ throw new NullPointerException("subType");
273+ }
274+ if (representationClass == null) {
275+ throw new NullPointerException("representationClass");
276+ }
277+
278+ if (params == null) params = new MimeTypeParameterList();
279+
280+ params.set("class", representationClass.getName());
281+
282+ if (humanPresentableName == null) {
283+ humanPresentableName = (String)params.get("humanPresentableName");
284+
285+ if (humanPresentableName == null)
286+ humanPresentableName = primaryType + "/" + subType;
287+ }
288+
289+ try {
290+ mimeType = new MimeType(primaryType, subType, params);
291+ } catch (MimeTypeParseException mtpe) {
292+ throw new IllegalArgumentException("MimeType Parse Exception: " + mtpe.getMessage());
293+ }
294+
295+ this.representationClass = representationClass;
296+ this.humanPresentableName = humanPresentableName;
297+
298+ mimeType.removeParameter("humanPresentableName");
299+ }
300+
301+ /**
302+ * Constructs a <code>DataFlavor</code> that represents a Java class.
303+ * <p>
304+ * The returned <code>DataFlavor</code> will have the following
305+ * characteristics:
306+ * <pre>
307+ * representationClass = representationClass
308+ * mimeType = application/x-java-serialized-object
309+ * </pre>
310+ * @param representationClass the class used to transfer data in this flavor
311+ * @param humanPresentableName the human-readable string used to identify
312+ * this flavor; if this parameter is <code>null</code>
313+ * then the value of the the MIME Content Type is used
314+ * @exception NullPointerException if <code>representationClass</code> is null
315+ */
316+ public DataFlavor(Class<?> representationClass, String humanPresentableName) {
317+ this("application", "x-java-serialized-object", null, representationClass, humanPresentableName);
318+ if (representationClass == null) {
319+ throw new NullPointerException("representationClass");
320+ }
321+ }
322+
323+ /**
324+ * Constructs a <code>DataFlavor</code> that represents a
325+ * <code>MimeType</code>.
326+ * <p>
327+ * The returned <code>DataFlavor</code> will have the following
328+ * characteristics:
329+ * <p>
330+ * If the <code>mimeType</code> is
331+ * "application/x-java-serialized-object; class=&lt;representation class&gt;",
332+ * the result is the same as calling
333+ * <code>new DataFlavor(Class:forName(&lt;representation class&gt;)</code>.
334+ * <p>
335+ * Otherwise:
336+ * <pre>
337+ * representationClass = InputStream
338+ * mimeType = mimeType
339+ * </pre>
340+ * @param mimeType the string used to identify the MIME type for this flavor;
341+ * if the the <code>mimeType</code> does not specify a
342+ * "class=" parameter, or if the class is not successfully
343+ * loaded, then an <code>IllegalArgumentException</code>
344+ * is thrown
345+ * @param humanPresentableName the human-readable string used to identify
346+ * this flavor; if this parameter is <code>null</code>
347+ * then the value of the the MIME Content Type is used
348+ * @exception IllegalArgumentException if <code>mimeType</code> is
349+ * invalid or if the class is not successfully loaded
350+ * @exception NullPointerException if <code>mimeType</code> is null
351+ */
352+ public DataFlavor(String mimeType, String humanPresentableName) {
353+ super();
354+ if (mimeType == null) {
355+ throw new NullPointerException("mimeType");
356+ }
357+ try {
358+ initialize(mimeType, humanPresentableName, this.getClass().getClassLoader());
359+ } catch (MimeTypeParseException mtpe) {
360+ throw new IllegalArgumentException("failed to parse:" + mimeType);
361+ } catch (ClassNotFoundException cnfe) {
362+ throw new IllegalArgumentException("can't find specified class: " + cnfe.getMessage());
363+ }
364+ }
365+
366+ /**
367+ * Constructs a <code>DataFlavor</code> that represents a
368+ * <code>MimeType</code>.
369+ * <p>
370+ * The returned <code>DataFlavor</code> will have the following
371+ * characteristics:
372+ * <p>
373+ * If the mimeType is
374+ * "application/x-java-serialized-object; class=&lt;representation class&gt;",
375+ * the result is the same as calling
376+ * <code>new DataFlavor(Class:forName(&lt;representation class&gt;)</code>.
377+ * <p>
378+ * Otherwise:
379+ * <pre>
380+ * representationClass = InputStream
381+ * mimeType = mimeType
382+ * </pre>
383+ * @param mimeType the string used to identify the MIME type for this flavor
384+ * @param humanPresentableName the human-readable string used to
385+ * identify this flavor
386+ * @param classLoader the class loader to use
387+ * @exception ClassNotFoundException if the class is not loaded
388+ * @exception IllegalArgumentException if <code>mimeType</code> is
389+ * invalid
390+ * @exception NullPointerException if <code>mimeType</code> is null
391+ */
392+ public DataFlavor(String mimeType, String humanPresentableName, ClassLoader classLoader) throws ClassNotFoundException {
393+ super();
394+ if (mimeType == null) {
395+ throw new NullPointerException("mimeType");
396+ }
397+ try {
398+ initialize(mimeType, humanPresentableName, classLoader);
399+ } catch (MimeTypeParseException mtpe) {
400+ throw new IllegalArgumentException("failed to parse:" + mimeType);
401+ }
402+ }
403+
404+ /**
405+ * Constructs a <code>DataFlavor</code> from a <code>mimeType</code> string.
406+ * The string can specify a "class=<fully specified Java class name>"
407+ * parameter to create a <code>DataFlavor</code> with the desired
408+ * representation class. If the string does not contain "class=" parameter,
409+ * <code>java.io.InputStream</code> is used as default.
410+ *
411+ * @param mimeType the string used to identify the MIME type for this flavor;
412+ * if the class specified by "class=" parameter is not
413+ * successfully loaded, then an
414+ * <code>ClassNotFoundException</code> is thrown
415+ * @exception ClassNotFoundException if the class is not loaded
416+ * @exception IllegalArgumentException if <code>mimeType</code> is
417+ * invalid
418+ * @exception NullPointerException if <code>mimeType</code> is null
419+ */
420+ public DataFlavor(String mimeType) throws ClassNotFoundException {
421+ super();
422+ if (mimeType == null) {
423+ throw new NullPointerException("mimeType");
424+ }
425+ try {
426+ initialize(mimeType, null, this.getClass().getClassLoader());
427+ } catch (MimeTypeParseException mtpe) {
428+ throw new IllegalArgumentException("failed to parse:" + mimeType);
429+ }
430+ }
431+
432+ /**
433+ * Common initialization code called from various constructors.
434+ *
435+ * @param mimeType the MIME Content Type (must have a class= param)
436+ * @param humanPresentableName the human Presentable Name or
437+ * <code>null</code>
438+ * @param classLoader the fallback class loader to resolve against
439+ *
440+ * @throws MimeTypeParseException
441+ * @throws ClassNotFoundException
442+ * @throws NullPointerException if <code>mimeType</code> is null
443+ *
444+ * @see tryToLoadClass
445+ */
446+ private void initialize(String mimeType, String humanPresentableName, ClassLoader classLoader) throws MimeTypeParseException, ClassNotFoundException {
447+ if (mimeType == null) {
448+ throw new NullPointerException("mimeType");
449+ }
450+
451+ this.mimeType = new MimeType(mimeType); // throws
452+
453+ String rcn = getParameter("class");
454+
455+ if (rcn == null) {
456+ if ("application/x-java-serialized-object".equals(this.mimeType.getBaseType()))
457+
458+ throw new IllegalArgumentException("no representation class specified for:" + mimeType);
459+ else
460+ representationClass = java.io.InputStream.class; // default
461+ } else { // got a class name
462+ representationClass = DataFlavor.tryToLoadClass(rcn, classLoader);
463+ }
464+
465+ this.mimeType.setParameter("class", representationClass.getName());
466+
467+ if (humanPresentableName == null) {
468+ humanPresentableName = this.mimeType.getParameter("humanPresentableName");
469+ if (humanPresentableName == null)
470+ humanPresentableName = this.mimeType.getPrimaryType() + "/" + this.mimeType.getSubType();
471+ }
472+
473+ this.humanPresentableName = humanPresentableName; // set it.
474+
475+ this.mimeType.removeParameter("humanPresentableName"); // just in case
476+ }
477+
478+ /**
479+ * String representation of this <code>DataFlavor</code> and its
480+ * parameters. The resulting <code>String</code> contains the name of
481+ * the <code>DataFlavor</code> class, this flavor's MIME type, and its
482+ * representation class. If this flavor has a primary MIME type of "text",
483+ * supports the charset parameter, and has an encoded representation, the
484+ * flavor's charset is also included. See <code>selectBestTextFlavor</code>
485+ * for a list of text flavors which support the charset parameter.
486+ *
487+ * @return string representation of this <code>DataFlavor</code>
488+ * @see #selectBestTextFlavor
489+ */
490+ public String toString() {
491+ String string = getClass().getName();
492+ string += "["+paramString()+"]";
493+ return string;
494+ }
495+
496+ private String paramString() {
497+ String params = "";
498+ params += "mimetype=";
499+ if (mimeType == null) {
500+ params += "null";
501+ } else {
502+ params += mimeType.getBaseType();
503+ }
504+ params += ";representationclass=";
505+ if (representationClass == null) {
506+ params += "null";
507+ } else {
508+ params += representationClass.getName();
509+ }
510+ if (DataTransferer.isFlavorCharsetTextType(this) &&
511+ (isRepresentationClassInputStream() ||
512+ isRepresentationClassByteBuffer() ||
513+ DataTransferer.byteArrayClass.equals(representationClass)))
514+ {
515+ params += ";charset=" + DataTransferer.getTextCharset(this);
516+ }
517+ return params;
518+ }
519+
520+ /**
521+ * Returns a <code>DataFlavor</code> representing plain text with Unicode
522+ * encoding, where:
523+ * <pre>
524+ * representationClass = java.io.InputStream
525+ * mimeType = "text/plain;
526+ * charset=&lt;platform default Unicode encoding&gt;"
527+ * </pre>
528+ * Sun's implementation for Microsoft Windows uses the encoding <code>utf-16le</code>.
529+ * Sun's implementation for Solaris and Linux uses the encoding
530+ * <code>iso-10646-ucs-2</code>.
531+ *
532+ * @return a <code>DataFlavor</code> representing plain text
533+ * with Unicode encoding
534+ * @since 1.3
535+ */
536+ public static final DataFlavor getTextPlainUnicodeFlavor() {
537+ String encoding = null;
538+ DataTransferer transferer = DataTransferer.getInstance();
539+ if (transferer != null) {
540+ encoding = transferer.getDefaultUnicodeEncoding();
541+ }
542+ return new DataFlavor(
543+ "text/plain;charset="+encoding
544+ +";class=java.io.InputStream", "Plain Text");
545+ }
546+
547+ /**
548+ * Selects the best text <code>DataFlavor</code> from an array of <code>
549+ * DataFlavor</code>s. Only <code>DataFlavor.stringFlavor</code>, and
550+ * equivalent flavors, and flavors that have a primary MIME type of "text",
551+ * are considered for selection.
552+ * <p>
553+ * Flavors are first sorted by their MIME types in the following order:
554+ * <ul>
555+ * <li>"text/sgml"
556+ * <li>"text/xml"
557+ * <li>"text/html"
558+ * <li>"text/rtf"
559+ * <li>"text/enriched"
560+ * <li>"text/richtext"
561+ * <li>"text/uri-list"
562+ * <li>"text/tab-separated-values"
563+ * <li>"text/t140"
564+ * <li>"text/rfc822-headers"
565+ * <li>"text/parityfec"
566+ * <li>"text/directory"
567+ * <li>"text/css"
568+ * <li>"text/calendar"
569+ * <li>"application/x-java-serialized-object"
570+ * <li>"text/plain"
571+ * <li>"text/&lt;other&gt;"
572+ * </ul>
573+ * <p>For example, "text/sgml" will be selected over
574+ * "text/html", and <code>DataFlavor.stringFlavor</code> will be chosen
575+ * over <code>DataFlavor.plainTextFlavor</code>.
576+ * <p>
577+ * If two or more flavors share the best MIME type in the array, then that
578+ * MIME type will be checked to see if it supports the charset parameter.
579+ * <p>
580+ * The following MIME types support, or are treated as though they support,
581+ * the charset parameter:
582+ * <ul>
583+ * <li>"text/sgml"
584+ * <li>"text/xml"
585+ * <li>"text/html"
586+ * <li>"text/enriched"
587+ * <li>"text/richtext"
588+ * <li>"text/uri-list"
589+ * <li>"text/directory"
590+ * <li>"text/css"
591+ * <li>"text/calendar"
592+ * <li>"application/x-java-serialized-object"
593+ * <li>"text/plain"
594+ * </ul>
595+ * The following MIME types do not support, or are treated as though they
596+ * do not support, the charset parameter:
597+ * <ul>
598+ * <li>"text/rtf"
599+ * <li>"text/tab-separated-values"
600+ * <li>"text/t140"
601+ * <li>"text/rfc822-headers"
602+ * <li>"text/parityfec"
603+ * </ul>
604+ * For "text/&lt;other&gt;" MIME types, the first time the JRE needs to
605+ * determine whether the MIME type supports the charset parameter, it will
606+ * check whether the parameter is explicitly listed in an arbitrarily
607+ * chosen <code>DataFlavor</code> which uses that MIME type. If so, the JRE
608+ * will assume from that point on that the MIME type supports the charset
609+ * parameter and will not check again. If the parameter is not explicitly
610+ * listed, the JRE will assume from that point on that the MIME type does
611+ * not support the charset parameter and will not check again. Because
612+ * this check is performed on an arbitrarily chosen
613+ * <code>DataFlavor</code>, developers must ensure that all
614+ * <code>DataFlavor</code>s with a "text/&lt;other&gt;" MIME type specify
615+ * the charset parameter if it is supported by that MIME type. Developers
616+ * should never rely on the JRE to substitute the platform's default
617+ * charset for a "text/&lt;other&gt;" DataFlavor. Failure to adhere to this
618+ * restriction will lead to undefined behavior.
619+ * <p>
620+ * If the best MIME type in the array does not support the charset
621+ * parameter, the flavors which share that MIME type will then be sorted by
622+ * their representation classes in the following order:
623+ * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
624+ * <code>[B</code>, &lt;all others&gt;.
625+ * <p>
626+ * If two or more flavors share the best representation class, or if no
627+ * flavor has one of the three specified representations, then one of those
628+ * flavors will be chosen non-deterministically.
629+ * <p>
630+ * If the best MIME type in the array does support the charset parameter,
631+ * the flavors which share that MIME type will then be sorted by their
632+ * representation classes in the following order:
633+ * <code>java.io.Reader</code>, <code>java.lang.String</code>,
634+ * <code>java.nio.CharBuffer</code>, <code>[C</code>, &lt;all others&gt;.
635+ * <p>
636+ * If two or more flavors share the best representation class, and that
637+ * representation is one of the four explicitly listed, then one of those
638+ * flavors will be chosen non-deterministically. If, however, no flavor has
639+ * one of the four specified representations, the flavors will then be
640+ * sorted by their charsets. Unicode charsets, such as "UTF-16", "UTF-8",
641+ * "UTF-16BE", "UTF-16LE", and their aliases, are considered best. After
642+ * them, the platform default charset and its aliases are selected.
643+ * "US-ASCII" and its aliases are worst. All other charsets are chosen in
644+ * alphabetical order, but only charsets supported by this implementation
645+ * of the Java platform will be considered.
646+ * <p>
647+ * If two or more flavors share the best charset, the flavors will then
648+ * again be sorted by their representation classes in the following order:
649+ * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
650+ * <code>[B</code>, &lt;all others&gt;.
651+ * <p>
652+ * If two or more flavors share the best representation class, or if no
653+ * flavor has one of the three specified representations, then one of those
654+ * flavors will be chosen non-deterministically.
655+ *
656+ * @param availableFlavors an array of available <code>DataFlavor</code>s
657+ * @return the best (highest fidelity) flavor according to the rules
658+ * specified above, or <code>null</code>,
659+ * if <code>availableFlavors</code> is <code>null</code>,
660+ * has zero length, or contains no text flavors
661+ * @since 1.3
662+ */
663+ public static final DataFlavor selectBestTextFlavor(
664+ DataFlavor[] availableFlavors) {
665+ if (availableFlavors == null || availableFlavors.length == 0) {
666+ return null;
667+ }
668+
669+ if (textFlavorComparator == null) {
670+ textFlavorComparator = new TextFlavorComparator();
671+ }
672+
673+ DataFlavor bestFlavor =
674+ (DataFlavor)Collections.max(Arrays.asList(availableFlavors),
675+ textFlavorComparator);
676+
677+ if (!bestFlavor.isFlavorTextType()) {
678+ return null;
679+ }
680+
681+ return bestFlavor;
682+ }
683+
684+ private static Comparator textFlavorComparator;
685+
686+ static class TextFlavorComparator
687+ extends DataTransferer.DataFlavorComparator {
688+
689+ /**
690+ * Compares two <code>DataFlavor</code> objects. Returns a negative
691+ * integer, zero, or a positive integer as the first
692+ * <code>DataFlavor</code> is worse than, equal to, or better than the
693+ * second.
694+ * <p>
695+ * <code>DataFlavor</code>s are ordered according to the rules outlined
696+ * for <code>selectBestTextFlavor</code>.
697+ *
698+ * @param obj1 the first <code>DataFlavor</code> to be compared
699+ * @param obj2 the second <code>DataFlavor</code> to be compared
700+ * @return a negative integer, zero, or a positive integer as the first
701+ * argument is worse, equal to, or better than the second
702+ * @throws ClassCastException if either of the arguments is not an
703+ * instance of <code>DataFlavor</code>
704+ * @throws NullPointerException if either of the arguments is
705+ * <code>null</code>
706+ *
707+ * @see #selectBestTextFlavor
708+ */
709+ public int compare(Object obj1, Object obj2) {
710+ DataFlavor flavor1 = (DataFlavor)obj1;
711+ DataFlavor flavor2 = (DataFlavor)obj2;
712+
713+ if (flavor1.isFlavorTextType()) {
714+ if (flavor2.isFlavorTextType()) {
715+ return super.compare(obj1, obj2);
716+ } else {
717+ return 1;
718+ }
719+ } else if (flavor2.isFlavorTextType()) {
720+ return -1;
721+ } else {
722+ return 0;
723+ }
724+ }
725+ }
726+
727+ /**
728+ * Gets a Reader for a text flavor, decoded, if necessary, for the expected
729+ * charset (encoding). The supported representation classes are
730+ * <code>java.io.Reader</code>, <code>java.lang.String</code>,
731+ * <code>java.nio.CharBuffer</code>, <code>[C</code>,
732+ * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
733+ * and <code>[B</code>.
734+ * <p>
735+ * Because text flavors which do not support the charset parameter are
736+ * encoded in a non-standard format, this method should not be called for
737+ * such flavors. However, in order to maintain backward-compatibility,
738+ * if this method is called for such a flavor, this method will treat the
739+ * flavor as though it supports the charset parameter and attempt to
740+ * decode it accordingly. See <code>selectBestTextFlavor</code> for a list
741+ * of text flavors which do not support the charset parameter.
742+ *
743+ * @param transferable the <code>Transferable</code> whose data will be
744+ * requested in this flavor
745+ *
746+ * @return a <code>Reader</code> to read the <code>Transferable</code>'s
747+ * data
748+ *
749+ * @exception IllegalArgumentException if the representation class
750+ * is not one of the seven listed above
751+ * @exception IllegalArgumentException if the <code>Transferable</code>
752+ * has <code>null</code> data
753+ * @exception NullPointerException if the <code>Transferable</code> is
754+ * <code>null</code>
755+ * @exception UnsupportedEncodingException if this flavor's representation
756+ * is <code>java.io.InputStream</code>,
757+ * <code>java.nio.ByteBuffer</code>, or <code>[B</code> and
758+ * this flavor's encoding is not supported by this
759+ * implementation of the Java platform
760+ * @exception UnsupportedFlavorException if the <code>Transferable</code>
761+ * does not support this flavor
762+ * @exception IOException if the data cannot be read because of an
763+ * I/O error
764+ * @see #selectBestTextFlavor
765+ * @since 1.3
766+ */
767+ public Reader getReaderForText(Transferable transferable)
768+ throws UnsupportedFlavorException, IOException
769+ {
770+ Object transferObject = transferable.getTransferData(this);
771+ if (transferObject == null) {
772+ throw new IllegalArgumentException
773+ ("getTransferData() returned null");
774+ }
775+
776+ if (transferObject instanceof Reader) {
777+ return (Reader)transferObject;
778+ } else if (transferObject instanceof String) {
779+ return new StringReader((String)transferObject);
780+ } else if (transferObject instanceof CharBuffer) {
781+ CharBuffer buffer = (CharBuffer)transferObject;
782+ int size = buffer.remaining();
783+ char[] chars = new char[size];
784+ buffer.get(chars, 0, size);
785+ return new CharArrayReader(chars);
786+ } else if (transferObject instanceof char[]) {
787+ return new CharArrayReader((char[])transferObject);
788+ }
789+
790+ InputStream stream = null;
791+
792+ if (transferObject instanceof InputStream) {
793+ stream = (InputStream)transferObject;
794+ } else if (transferObject instanceof ByteBuffer) {
795+ ByteBuffer buffer = (ByteBuffer)transferObject;
796+ int size = buffer.remaining();
797+ byte[] bytes = new byte[size];
798+ buffer.get(bytes, 0, size);
799+ stream = new ByteArrayInputStream(bytes);
800+ } else if (transferObject instanceof byte[]) {
801+ stream = new ByteArrayInputStream((byte[])transferObject);
802+ }
803+
804+ if (stream == null) {
805+ throw new IllegalArgumentException("transfer data is not Reader, String, CharBuffer, char array, InputStream, ByteBuffer, or byte array");
806+ }
807+
808+ String encoding = getParameter("charset");
809+ return (encoding == null)
810+ ? new InputStreamReader(stream)
811+ : new InputStreamReader(stream, encoding);
812+ }
813+
814+ /**
815+ * Returns the MIME type string for this <code>DataFlavor</code>.
816+ * @return the MIME type string for this flavor
817+ */
818+ public String getMimeType() {
819+ return (mimeType != null) ? mimeType.toString() : null;
820+ }
821+
822+ /**
823+ * Returns the <code>Class</code> which objects supporting this
824+ * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
825+ * is requested.
826+ * @return the <code>Class</code> which objects supporting this
827+ * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
828+ * is requested
829+ */
830+ public Class<?> getRepresentationClass() {
831+ return representationClass;
832+ }
833+
834+ /**
835+ * Returns the human presentable name for the data format that this
836+ * <code>DataFlavor</code> represents. This name would be localized
837+ * for different countries.
838+ * @return the human presentable name for the data format that this
839+ * <code>DataFlavor</code> represents
840+ */
841+ public String getHumanPresentableName() {
842+ return humanPresentableName;
843+ }
844+
845+ /**
846+ * Returns the primary MIME type for this <code>DataFlavor</code>.
847+ * @return the primary MIME type of this <code>DataFlavor</code>
848+ */
849+ public String getPrimaryType() {
850+ return (mimeType != null) ? mimeType.getPrimaryType() : null;
851+ }
852+
853+ /**
854+ * Returns the sub MIME type of this <code>DataFlavor</code>.
855+ * @return the Sub MIME type of this <code>DataFlavor</code>
856+ */
857+ public String getSubType() {
858+ return (mimeType != null) ? mimeType.getSubType() : null;
859+ }
860+
861+ /**
862+ * Returns the human presentable name for this <code>DataFlavor</code>
863+ * if <code>paramName</code> equals "humanPresentableName". Otherwise
864+ * returns the MIME type value associated with <code>paramName</code>.
865+ *
866+ * @param paramName the parameter name requested
867+ * @return the value of the name parameter, or <code>null</code>
868+ * if there is no associated value
869+ */
870+ public String getParameter(String paramName) {
871+ if (paramName.equals("humanPresentableName")) {
872+ return humanPresentableName;
873+ } else {
874+ return (mimeType != null)
875+ ? mimeType.getParameter(paramName) : null;
876+ }
877+ }
878+
879+ /**
880+ * Sets the human presentable name for the data format that this
881+ * <code>DataFlavor</code> represents. This name would be localized
882+ * for different countries.
883+ * @param humanPresentableName the new human presentable name
884+ */
885+ public void setHumanPresentableName(String humanPresentableName) {
886+ this.humanPresentableName = humanPresentableName;
887+ }
888+
889+ /**
890+ * {@inheritDoc}
891+ * <p>
892+ * The equals comparison for the {@code DataFlavor} class is implemented
893+ * as follows: Two <code>DataFlavor</code>s are considered equal if and
894+ * only if their MIME primary type and subtype and representation class are
895+ * equal. Additionally, if the primary type is "text", the subtype denotes
896+ * a text flavor which supports the charset parameter, and the
897+ * representation class is not <code>java.io.Reader</code>,
898+ * <code>java.lang.String</code>, <code>java.nio.CharBuffer</code>, or
899+ * <code>[C</code>, the <code>charset</code> parameter must also be equal.
900+ * If a charset is not explicitly specified for one or both
901+ * <code>DataFlavor</code>s, the platform default encoding is assumed. See
902+ * <code>selectBestTextFlavor</code> for a list of text flavors which
903+ * support the charset parameter.
904+ *
905+ * @param o the <code>Object</code> to compare with <code>this</code>
906+ * @return <code>true</code> if <code>that</code> is equivalent to this
907+ * <code>DataFlavor</code>; <code>false</code> otherwise
908+ * @see #selectBestTextFlavor
909+ */
910+ public boolean equals(Object o) {
911+ return ((o instanceof DataFlavor) && equals((DataFlavor)o));
912+ }
913+
914+ /**
915+ * This method has the same behavior as {@link #equals(Object)}.
916+ * The only difference being that it takes a {@code DataFlavor} instance
917+ * as a parameter.
918+ *
919+ * @param that the <code>DataFlavor</code> to compare with
920+ * <code>this</code>
921+ * @return <code>true</code> if <code>that</code> is equivalent to this
922+ * <code>DataFlavor</code>; <code>false</code> otherwise
923+ * @see #selectBestTextFlavor
924+ */
925+ public boolean equals(DataFlavor that) {
926+ if (that == null) {
927+ return false;
928+ }
929+ if (this == that) {
930+ return true;
931+ }
932+
933+ if (representationClass == null) {
934+ if (that.getRepresentationClass() != null) {
935+ return false;
936+ }
937+ } else {
938+ if (!representationClass.equals(that.getRepresentationClass())) {
939+ return false;
940+ }
941+ }
942+
943+ if (mimeType == null) {
944+ if (that.mimeType != null) {
945+ return false;
946+ }
947+ } else {
948+ if (!mimeType.match(that.mimeType)) {
949+ return false;
950+ }
951+
952+ if ("text".equals(getPrimaryType()) &&
953+ DataTransferer.doesSubtypeSupportCharset(this) &&
954+ representationClass != null &&
955+ !(isRepresentationClassReader() ||
956+ String.class.equals(representationClass) ||
957+ isRepresentationClassCharBuffer() ||
958+ DataTransferer.charArrayClass.equals(representationClass)))
959+ {
960+ String thisCharset =
961+ DataTransferer.canonicalName(getParameter("charset"));
962+ String thatCharset =
963+ DataTransferer.canonicalName(that.getParameter("charset"));
964+ if (thisCharset == null) {
965+ if (thatCharset != null) {
966+ return false;
967+ }
968+ } else {
969+ if (!thisCharset.equals(thatCharset)) {
970+ return false;
971+ }
972+ }
973+ }
974+ }
975+
976+ return true;
977+ }
978+
979+ /**
980+ * Compares only the <code>mimeType</code> against the passed in
981+ * <code>String</code> and <code>representationClass</code> is
982+ * not considered in the comparison.
983+ *
984+ * If <code>representationClass</code> needs to be compared, then
985+ * <code>equals(new DataFlavor(s))</code> may be used.
986+ * @deprecated As inconsistent with <code>hashCode()</code> contract,
987+ * use <code>isMimeTypeEqual(String)</code> instead.
988+ * @param s the {@code mimeType} to compare.
989+ * @return true if the String (MimeType) is equal; false otherwise or if
990+ * {@code s} is {@code null}
991+ */
992+ @Deprecated
993+ public boolean equals(String s) {
994+ if (s == null || mimeType == null)
995+ return false;
996+ return isMimeTypeEqual(s);
997+ }
998+
999+ /**
1000+ * Returns hash code for this <code>DataFlavor</code>.
1001+ * For two equal <code>DataFlavor</code>s, hash codes are equal.
1002+ * For the <code>String</code>
1003+ * that matches <code>DataFlavor.equals(String)</code>, it is not
1004+ * guaranteed that <code>DataFlavor</code>'s hash code is equal
1005+ * to the hash code of the <code>String</code>.
1006+ *
1007+ * @return a hash code for this <code>DataFlavor</code>
1008+ */
1009+ public int hashCode() {
1010+ int total = 0;
1011+
1012+ if (representationClass != null) {
1013+ total += representationClass.hashCode();
1014+ }
1015+
1016+ if (mimeType != null) {
1017+ String primaryType = mimeType.getPrimaryType();
1018+ if (primaryType != null) {
1019+ total += primaryType.hashCode();
1020+ }
1021+
1022+ // Do not add subType.hashCode() to the total. equals uses
1023+ // MimeType.match which reports a match if one or both of the
1024+ // subTypes is '*', regardless of the other subType.
1025+
1026+ if ("text".equals(primaryType) &&
1027+ DataTransferer.doesSubtypeSupportCharset(this) &&
1028+ representationClass != null &&
1029+ !(isRepresentationClassReader() ||
1030+ String.class.equals(representationClass) ||
1031+ isRepresentationClassCharBuffer() ||
1032+ DataTransferer.charArrayClass.equals
1033+ (representationClass)))
1034+ {
1035+ String charset =
1036+ DataTransferer.canonicalName(getParameter("charset"));
1037+ if (charset != null) {
1038+ total += charset.hashCode();
1039+ }
1040+ }
1041+ }
1042+
1043+ return total;
1044+ }
1045+
1046+ /**
1047+ * Identical to {@link #equals(DataFlavor)}.
1048+ *
1049+ * @param that the <code>DataFlavor</code> to compare with
1050+ * <code>this</code>
1051+ * @return <code>true</code> if <code>that</code> is equivalent to this
1052+ * <code>DataFlavor</code>; <code>false</code> otherwise
1053+ * @see #selectBestTextFlavor
1054+ * @since 1.3
1055+ */
1056+ public boolean match(DataFlavor that) {
1057+ return equals(that);
1058+ }
1059+
1060+ /**
1061+ * Returns whether the string representation of the MIME type passed in
1062+ * is equivalent to the MIME type of this <code>DataFlavor</code>.
1063+ * Parameters are not included in the comparison.
1064+ *
1065+ * @param mimeType the string representation of the MIME type
1066+ * @return true if the string representation of the MIME type passed in is
1067+ * equivalent to the MIME type of this <code>DataFlavor</code>;
1068+ * false otherwise
1069+ * @throws NullPointerException if mimeType is <code>null</code>
1070+ */
1071+ public boolean isMimeTypeEqual(String mimeType) {
1072+ // JCK Test DataFlavor0117: if 'mimeType' is null, throw NPE
1073+ if (mimeType == null) {
1074+ throw new NullPointerException("mimeType");
1075+ }
1076+ if (this.mimeType == null) {
1077+ return false;
1078+ }
1079+ try {
1080+ return this.mimeType.match(new MimeType(mimeType));
1081+ } catch (MimeTypeParseException mtpe) {
1082+ return false;
1083+ }
1084+ }
1085+
1086+ /**
1087+ * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
1088+ * objects. No parameters are considered.
1089+ *
1090+ * @param dataFlavor the <code>DataFlavor</code> to be compared
1091+ * @return true if the <code>MimeType</code>s are equal,
1092+ * otherwise false
1093+ */
1094+
1095+ public final boolean isMimeTypeEqual(DataFlavor dataFlavor) {
1096+ return isMimeTypeEqual(dataFlavor.mimeType);
1097+ }
1098+
1099+ /**
1100+ * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
1101+ * objects. No parameters are considered.
1102+ *
1103+ * @return true if the <code>MimeType</code>s are equal,
1104+ * otherwise false
1105+ */
1106+
1107+ private boolean isMimeTypeEqual(MimeType mtype) {
1108+ if (this.mimeType == null) {
1109+ return (mtype == null);
1110+ }
1111+ return mimeType.match(mtype);
1112+ }
1113+
1114+ /**
1115+ * Does the <code>DataFlavor</code> represent a serialized object?
1116+ */
1117+
1118+ public boolean isMimeTypeSerializedObject() {
1119+ return isMimeTypeEqual(javaSerializedObjectMimeType);
1120+ }
1121+
1122+ public final Class<?> getDefaultRepresentationClass() {
1123+ return ioInputStreamClass;
1124+ }
1125+
1126+ public final String getDefaultRepresentationClassAsString() {
1127+ return getDefaultRepresentationClass().getName();
1128+ }
1129+
1130+ /**
1131+ * Does the <code>DataFlavor</code> represent a
1132+ * <code>java.io.InputStream</code>?
1133+ */
1134+
1135+ public boolean isRepresentationClassInputStream() {
1136+ return ioInputStreamClass.isAssignableFrom(representationClass);
1137+ }
1138+
1139+ /**
1140+ * Returns whether the representation class for this
1141+ * <code>DataFlavor</code> is <code>java.io.Reader</code> or a subclass
1142+ * thereof.
1143+ *
1144+ * @since 1.4
1145+ */
1146+ public boolean isRepresentationClassReader() {
1147+ return java.io.Reader.class.isAssignableFrom(representationClass);
1148+ }
1149+
1150+ /**
1151+ * Returns whether the representation class for this
1152+ * <code>DataFlavor</code> is <code>java.nio.CharBuffer</code> or a
1153+ * subclass thereof.
1154+ *
1155+ * @since 1.4
1156+ */
1157+ public boolean isRepresentationClassCharBuffer() {
1158+ return java.nio.CharBuffer.class.isAssignableFrom(representationClass);
1159+ }
1160+
1161+ /**
1162+ * Returns whether the representation class for this
1163+ * <code>DataFlavor</code> is <code>java.nio.ByteBuffer</code> or a
1164+ * subclass thereof.
1165+ *
1166+ * @since 1.4
1167+ */
1168+ public boolean isRepresentationClassByteBuffer() {
1169+ return java.nio.ByteBuffer.class.isAssignableFrom(representationClass);
1170+ }
1171+
1172+ /**
1173+ * Returns true if the representation class can be serialized.
1174+ * @return true if the representation class can be serialized
1175+ */
1176+
1177+ public boolean isRepresentationClassSerializable() {
1178+ return java.io.Serializable.class.isAssignableFrom(representationClass);
1179+ }
1180+
1181+ /**
1182+ * Returns true if the representation class is <code>Remote</code>.
1183+ * @return true if the representation class is <code>Remote</code>
1184+ */
1185+
1186+ public boolean isRepresentationClassRemote() {
1187+ return DataTransferer.isRemote(representationClass);
1188+ }
1189+
1190+ /**
1191+ * Returns true if the <code>DataFlavor</code> specified represents
1192+ * a serialized object.
1193+ * @return true if the <code>DataFlavor</code> specified represents
1194+ * a Serialized Object
1195+ */
1196+
1197+ public boolean isFlavorSerializedObjectType() {
1198+ return isRepresentationClassSerializable() && isMimeTypeEqual(javaSerializedObjectMimeType);
1199+ }
1200+
1201+ /**
1202+ * Returns true if the <code>DataFlavor</code> specified represents
1203+ * a remote object.
1204+ * @return true if the <code>DataFlavor</code> specified represents
1205+ * a Remote Object
1206+ */
1207+
1208+ public boolean isFlavorRemoteObjectType() {
1209+ return isRepresentationClassRemote()
1210+ && isRepresentationClassSerializable()
1211+ && isMimeTypeEqual(javaRemoteObjectMimeType);
1212+ }
1213+
1214+
1215+ /**
1216+ * Returns true if the <code>DataFlavor</code> specified represents
1217+ * a list of file objects.
1218+ * @return true if the <code>DataFlavor</code> specified represents
1219+ * a List of File objects
1220+ */
1221+
1222+ public boolean isFlavorJavaFileListType() {
1223+ if (mimeType == null || representationClass == null)
1224+ return false;
1225+ return java.util.List.class.isAssignableFrom(representationClass) &&
1226+ mimeType.match(javaFileListFlavor.mimeType);
1227+
1228+ }
1229+
1230+ /**
1231+ * Returns whether this <code>DataFlavor</code> is a valid text flavor for
1232+ * this implementation of the Java platform. Only flavors equivalent to
1233+ * <code>DataFlavor.stringFlavor</code> and <code>DataFlavor</code>s with
1234+ * a primary MIME type of "text" can be valid text flavors.
1235+ * <p>
1236+ * If this flavor supports the charset parameter, it must be equivalent to
1237+ * <code>DataFlavor.stringFlavor</code>, or its representation must be
1238+ * <code>java.io.Reader</code>, <code>java.lang.String</code>,
1239+ * <code>java.nio.CharBuffer</code>, <code>[C</code>,
1240+ * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
1241+ * <code>[B</code>. If the representation is
1242+ * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
1243+ * <code>[B</code>, then this flavor's <code>charset</code> parameter must
1244+ * be supported by this implementation of the Java platform. If a charset
1245+ * is not specified, then the platform default charset, which is always
1246+ * supported, is assumed.
1247+ * <p>
1248+ * If this flavor does not support the charset parameter, its
1249+ * representation must be <code>java.io.InputStream</code>,
1250+ * <code>java.nio.ByteBuffer</code>, or <code>[B</code>.
1251+ * <p>
1252+ * See <code>selectBestTextFlavor</code> for a list of text flavors which
1253+ * support the charset parameter.
1254+ *
1255+ * @return <code>true</code> if this <code>DataFlavor</code> is a valid
1256+ * text flavor as described above; <code>false</code> otherwise
1257+ * @see #selectBestTextFlavor
1258+ * @since 1.4
1259+ */
1260+ public boolean isFlavorTextType() {
1261+ return (DataTransferer.isFlavorCharsetTextType(this) ||
1262+ DataTransferer.isFlavorNoncharsetTextType(this));
1263+ }
1264+
1265+ /**
1266+ * Serializes this <code>DataFlavor</code>.
1267+ */
1268+
1269+ public synchronized void writeExternal(ObjectOutput os) throws IOException {
1270+ if (mimeType != null) {
1271+ mimeType.setParameter("humanPresentableName", humanPresentableName);
1272+ os.writeObject(mimeType);
1273+ mimeType.removeParameter("humanPresentableName");
1274+ } else {
1275+ os.writeObject(null);
1276+ }
1277+
1278+ os.writeObject(representationClass);
1279+ }
1280+
1281+ /**
1282+ * Restores this <code>DataFlavor</code> from a Serialized state.
1283+ */
1284+
1285+ public synchronized void readExternal(ObjectInput is) throws IOException , ClassNotFoundException {
1286+ String rcn = null;
1287+ mimeType = (MimeType)is.readObject();
1288+
1289+ if (mimeType != null) {
1290+ humanPresentableName =
1291+ mimeType.getParameter("humanPresentableName");
1292+ mimeType.removeParameter("humanPresentableName");
1293+ rcn = mimeType.getParameter("class");
1294+ if (rcn == null) {
1295+ throw new IOException("no class parameter specified in: " +
1296+ mimeType);
1297+ }
1298+ }
1299+
1300+ try {
1301+ representationClass = (Class)is.readObject();
1302+ } catch (OptionalDataException ode) {
1303+ if (!ode.eof || ode.length != 0) {
1304+ throw ode;
1305+ }
1306+ // Ensure backward compatibility.
1307+ // Old versions didn't write the representation class to the stream.
1308+ if (rcn != null) {
1309+ representationClass =
1310+ DataFlavor.tryToLoadClass(rcn, getClass().getClassLoader());
1311+ }
1312+ }
1313+ }
1314+
1315+ /**
1316+ * Returns a clone of this <code>DataFlavor</code>.
1317+ * @return a clone of this <code>DataFlavor</code>
1318+ */
1319+
1320+ public Object clone() throws CloneNotSupportedException {
1321+ Object newObj = super.clone();
1322+ if (mimeType != null) {
1323+ ((DataFlavor)newObj).mimeType = (MimeType)mimeType.clone();
1324+ }
1325+ return newObj;
1326+ } // clone()
1327+
1328+ /**
1329+ * Called on <code>DataFlavor</code> for every MIME Type parameter
1330+ * to allow <code>DataFlavor</code> subclasses to handle special
1331+ * parameters like the text/plain <code>charset</code>
1332+ * parameters, whose values are case insensitive. (MIME type parameter
1333+ * values are supposed to be case sensitive.
1334+ * <p>
1335+ * This method is called for each parameter name/value pair and should
1336+ * return the normalized representation of the <code>parameterValue</code>.
1337+ *
1338+ * This method is never invoked by this implementation from 1.1 onwards.
1339+ *
1340+ * @deprecated
1341+ */
1342+ @Deprecated
1343+ protected String normalizeMimeTypeParameter(String parameterName, String parameterValue) {
1344+ return parameterValue;
1345+ }
1346+
1347+ /**
1348+ * Called for each MIME type string to give <code>DataFlavor</code> subtypes
1349+ * the opportunity to change how the normalization of MIME types is
1350+ * accomplished. One possible use would be to add default
1351+ * parameter/value pairs in cases where none are present in the MIME
1352+ * type string passed in.
1353+ *
1354+ * This method is never invoked by this implementation from 1.1 onwards.
1355+ *
1356+ * @deprecated
1357+ */
1358+ @Deprecated
1359+ protected String normalizeMimeType(String mimeType) {
1360+ return mimeType;
1361+ }
1362+
1363+ /*
1364+ * fields
1365+ */
1366+
1367+ /* placeholder for caching any platform-specific data for flavor */
1368+
1369+ transient int atom;
1370+
1371+ /* Mime Type of DataFlavor */
1372+
1373+ MimeType mimeType;
1374+
1375+ private String humanPresentableName;
1376+
1377+ /** Java class of objects this DataFlavor represents **/
1378+
1379+ private Class representationClass;
1380+
1381+} // class DataFlavor
java/pkg/java/awt/datatransfer/FlavorEvent.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/FlavorEvent.java+51−0
@@ -0,0 +1,51 @@
1+/*
2+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package java.awt.datatransfer;
26+
27+import java.util.EventObject;
28+
29+
30+/**
31+ * <code>FlavorEvent</code> is used to notify interested parties
32+ * that available {@link DataFlavor}s have changed in the
33+ * {@link Clipboard} (the event source).
34+ *
35+ * @see FlavorListener
36+ *
37+ * @author Alexander Gerasimov
38+ * @since 1.5
39+ */
40+public class FlavorEvent extends EventObject {
41+ /**
42+ * Constructs a <code>FlavorEvent</code> object.
43+ *
44+ * @param source the <code>Clipboard</code> that is the source of the event
45+ *
46+ * @throws IllegalArgumentException if the {@code source} is {@code null}
47+ */
48+ public FlavorEvent(Clipboard source) {
49+ super(source);
50+ }
51+}
java/pkg/java/awt/datatransfer/FlavorListener.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/FlavorListener.java+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package java.awt.datatransfer;
26+
27+import java.util.EventListener;
28+
29+
30+/**
31+ * Defines an object which listens for {@link FlavorEvent}s.
32+ *
33+ * @author Alexander Gerasimov
34+ * @since 1.5
35+ */
36+public interface FlavorListener extends EventListener {
37+ /**
38+ * Invoked when the target {@link Clipboard} of the listener
39+ * has changed its available {@link DataFlavor}s.
40+ * <p>
41+ * Some notifications may be redundant &#151; they are not
42+ * caused by a change of the set of DataFlavors available
43+ * on the clipboard.
44+ * For example, if the clipboard subsystem supposes that
45+ * the system clipboard's contents has been changed but it
46+ * can't ascertain whether its DataFlavors have been changed
47+ * because of some exceptional condition when accessing the
48+ * clipboard, the notification is sent to ensure from omitting
49+ * a significant notification. Ordinarily, those redundant
50+ * notifications should be occasional.
51+ *
52+ * @param e a <code>FlavorEvent</code> object
53+ */
54+ void flavorsChanged(FlavorEvent e);
55+}
java/pkg/java/awt/datatransfer/FlavorMap.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/FlavorMap.java+75−0
@@ -0,0 +1,75 @@
1+/*
2+ * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.util.Map;
29+
30+
31+/**
32+ * A two-way Map between "natives" (Strings), which correspond to platform-
33+ * specfic data formats, and "flavors" (DataFlavors), which corerspond to
34+ * platform-independent MIME types. FlavorMaps need not be symmetric, but
35+ * typically are.
36+ *
37+ *
38+ * @since 1.2
39+ */
40+public interface FlavorMap {
41+
42+ /**
43+ * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
44+ * their corresponding <code>String</code> native. The returned
45+ * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
46+ * internal data. Client code is free to modify the <code>Map</code>
47+ * without affecting this object.
48+ *
49+ * @param flavors an array of <code>DataFlavor</code>s which will be the
50+ * key set of the returned <code>Map</code>. If <code>null</code> is
51+ * specified, a mapping of all <code>DataFlavor</code>s currently
52+ * known to this <code>FlavorMap</code> to their corresponding
53+ * <code>String</code> natives will be returned.
54+ * @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
55+ * <code>String</code> natives
56+ */
57+ Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors);
58+
59+ /**
60+ * Returns a <code>Map</code> of the specified <code>String</code> natives
61+ * to their corresponding <code>DataFlavor</code>. The returned
62+ * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
63+ * internal data. Client code is free to modify the <code>Map</code>
64+ * without affecting this object.
65+ *
66+ * @param natives an array of <code>String</code>s which will be the
67+ * key set of the returned <code>Map</code>. If <code>null</code> is
68+ * specified, a mapping of all <code>String</code> natives currently
69+ * known to this <code>FlavorMap</code> to their corresponding
70+ * <code>DataFlavor</code>s will be returned.
71+ * @return a <code>java.util.Map</code> of <code>String</code> natives to
72+ * <code>DataFlavor</code>s
73+ */
74+ Map<String,DataFlavor> getFlavorsForNatives(String[] natives);
75+}
java/pkg/java/awt/datatransfer/FlavorTable.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/FlavorTable.java+82−0
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.util.List;
29+
30+
31+/**
32+ * A FlavorMap which relaxes the traditional 1-to-1 restriction of a Map. A
33+ * flavor is permitted to map to any number of natives, and likewise a native
34+ * is permitted to map to any number of flavors. FlavorTables need not be
35+ * symmetric, but typically are.
36+ *
37+ * @author David Mendenhall
38+ *
39+ * @since 1.4
40+ */
41+public interface FlavorTable extends FlavorMap {
42+
43+ /**
44+ * Returns a <code>List</code> of <code>String</code> natives to which the
45+ * specified <code>DataFlavor</code> corresponds. The <code>List</code>
46+ * will be sorted from best native to worst. That is, the first native will
47+ * best reflect data in the specified flavor to the underlying native
48+ * platform. The returned <code>List</code> is a modifiable copy of this
49+ * <code>FlavorTable</code>'s internal data. Client code is free to modify
50+ * the <code>List</code> without affecting this object.
51+ *
52+ * @param flav the <code>DataFlavor</code> whose corresponding natives
53+ * should be returned. If <code>null</code> is specified, all
54+ * natives currently known to this <code>FlavorTable</code> are
55+ * returned in a non-deterministic order.
56+ * @return a <code>java.util.List</code> of <code>java.lang.String</code>
57+ * objects which are platform-specific representations of platform-
58+ * specific data formats
59+ */
60+ List<String> getNativesForFlavor(DataFlavor flav);
61+
62+ /**
63+ * Returns a <code>List</code> of <code>DataFlavor</code>s to which the
64+ * specified <code>String</code> corresponds. The <code>List</code> will be
65+ * sorted from best <code>DataFlavor</code> to worst. That is, the first
66+ * <code>DataFlavor</code> will best reflect data in the specified
67+ * native to a Java application. The returned <code>List</code> is a
68+ * modifiable copy of this <code>FlavorTable</code>'s internal data.
69+ * Client code is free to modify the <code>List</code> without affecting
70+ * this object.
71+ *
72+ * @param nat the native whose corresponding <code>DataFlavor</code>s
73+ * should be returned. If <code>null</code> is specified, all
74+ * <code>DataFlavor</code>s currently known to this
75+ * <code>FlavorTable</code> are returned in a non-deterministic
76+ * order.
77+ * @return a <code>java.util.List</code> of <code>DataFlavor</code>
78+ * objects into which platform-specific data in the specified,
79+ * platform-specific native can be translated
80+ */
81+ List<DataFlavor> getFlavorsForNative(String nat);
82+}
java/pkg/java/awt/datatransfer/MimeType.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/MimeType.java+393−0
@@ -0,0 +1,393 @@
1+/*
2+ * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.io.Externalizable;
29+import java.io.ObjectOutput;
30+import java.io.ObjectInput;
31+import java.io.IOException;
32+import java.util.Enumeration;
33+
34+
35+/**
36+ * A Multipurpose Internet Mail Extension (MIME) type, as defined
37+ * in RFC 2045 and 2046.
38+ *
39+ * THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS
40+ * THE PUBLIC INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE***
41+ * (THAT IS AS IN *NOT* PUBLIC) HELPER CLASS!
42+ */
43+class MimeType implements Externalizable, Cloneable {
44+
45+ /*
46+ * serialization support
47+ */
48+
49+ static final long serialVersionUID = -6568722458793895906L;
50+
51+ /**
52+ * Constructor for externalization; this constructor should not be
53+ * called directly by an application, since the result will be an
54+ * uninitialized, immutable <code>MimeType</code> object.
55+ */
56+ public MimeType() {
57+ }
58+
59+ /**
60+ * Builds a <code>MimeType</code> from a <code>String</code>.
61+ *
62+ * @param rawdata text used to initialize the <code>MimeType</code>
63+ * @throws NullPointerException if <code>rawdata</code> is null
64+ */
65+ public MimeType(String rawdata) throws MimeTypeParseException {
66+ parse(rawdata);
67+ }
68+
69+ /**
70+ * Builds a <code>MimeType</code> with the given primary and sub
71+ * type but has an empty parameter list.
72+ *
73+ * @param primary the primary type of this <code>MimeType</code>
74+ * @param sub the subtype of this <code>MimeType</code>
75+ * @throws NullPointerException if either <code>primary</code> or
76+ * <code>sub</code> is null
77+ */
78+ public MimeType(String primary, String sub) throws MimeTypeParseException {
79+ this(primary, sub, new MimeTypeParameterList());
80+ }
81+
82+ /**
83+ * Builds a <code>MimeType</code> with a pre-defined
84+ * and valid (or empty) parameter list.
85+ *
86+ * @param primary the primary type of this <code>MimeType</code>
87+ * @param sub the subtype of this <code>MimeType</code>
88+ * @param mtpl the requested parameter list
89+ * @throws NullPointerException if either <code>primary</code>,
90+ * <code>sub</code> or <code>mtpl</code> is null
91+ */
92+ public MimeType(String primary, String sub, MimeTypeParameterList mtpl) throws
93+MimeTypeParseException {
94+ // check to see if primary is valid
95+ if(isValidToken(primary)) {
96+ primaryType = primary.toLowerCase();
97+ } else {
98+ throw new MimeTypeParseException("Primary type is invalid.");
99+ }
100+
101+ // check to see if sub is valid
102+ if(isValidToken(sub)) {
103+ subType = sub.toLowerCase();
104+ } else {
105+ throw new MimeTypeParseException("Sub type is invalid.");
106+ }
107+
108+ parameters = (MimeTypeParameterList)mtpl.clone();
109+ }
110+
111+ public int hashCode() {
112+
113+ // We sum up the hash codes for all of the strings. This
114+ // way, the order of the strings is irrelevant
115+ int code = 0;
116+ code += primaryType.hashCode();
117+ code += subType.hashCode();
118+ code += parameters.hashCode();
119+ return code;
120+ } // hashCode()
121+
122+ /**
123+ * <code>MimeType</code>s are equal if their primary types,
124+ * subtypes, and parameters are all equal. No default values
125+ * are taken into account.
126+ * @param thatObject the object to be evaluated as a
127+ * <code>MimeType</code>
128+ * @return <code>true</code> if <code>thatObject</code> is
129+ * a <code>MimeType</code>; otherwise returns <code>false</code>
130+ */
131+ public boolean equals(Object thatObject) {
132+ if (!(thatObject instanceof MimeType)) {
133+ return false;
134+ }
135+ MimeType that = (MimeType)thatObject;
136+ boolean isIt =
137+ ((this.primaryType.equals(that.primaryType)) &&
138+ (this.subType.equals(that.subType)) &&
139+ (this.parameters.equals(that.parameters)));
140+ return isIt;
141+ } // equals()
142+
143+ /**
144+ * A routine for parsing the MIME type out of a String.
145+ *
146+ * @throws NullPointerException if <code>rawdata</code> is null
147+ */
148+ private void parse(String rawdata) throws MimeTypeParseException {
149+ int slashIndex = rawdata.indexOf('/');
150+ int semIndex = rawdata.indexOf(';');
151+ if((slashIndex < 0) && (semIndex < 0)) {
152+ // neither character is present, so treat it
153+ // as an error
154+ throw new MimeTypeParseException("Unable to find a sub type.");
155+ } else if((slashIndex < 0) && (semIndex >= 0)) {
156+ // we have a ';' (and therefore a parameter list),
157+ // but no '/' indicating a sub type is present
158+ throw new MimeTypeParseException("Unable to find a sub type.");
159+ } else if((slashIndex >= 0) && (semIndex < 0)) {
160+ // we have a primary and sub type but no parameter list
161+ primaryType = rawdata.substring(0,
162+slashIndex).trim().toLowerCase();
163+ subType = rawdata.substring(slashIndex +
164+1).trim().toLowerCase();
165+ parameters = new MimeTypeParameterList();
166+ } else if (slashIndex < semIndex) {
167+ // we have all three items in the proper sequence
168+ primaryType = rawdata.substring(0,
169+slashIndex).trim().toLowerCase();
170+ subType = rawdata.substring(slashIndex + 1,
171+semIndex).trim().toLowerCase();
172+ parameters = new
173+MimeTypeParameterList(rawdata.substring(semIndex));
174+ } else {
175+ // we have a ';' lexically before a '/' which means we have a primary type
176+ // & a parameter list but no sub type
177+ throw new MimeTypeParseException("Unable to find a sub type.");
178+ }
179+
180+ // now validate the primary and sub types
181+
182+ // check to see if primary is valid
183+ if(!isValidToken(primaryType)) {
184+ throw new MimeTypeParseException("Primary type is invalid.");
185+ }
186+
187+ // check to see if sub is valid
188+ if(!isValidToken(subType)) {
189+ throw new MimeTypeParseException("Sub type is invalid.");
190+ }
191+ }
192+
193+ /**
194+ * Retrieve the primary type of this object.
195+ */
196+ public String getPrimaryType() {
197+ return primaryType;
198+ }
199+
200+ /**
201+ * Retrieve the sub type of this object.
202+ */
203+ public String getSubType() {
204+ return subType;
205+ }
206+
207+ /**
208+ * Retrieve a copy of this object's parameter list.
209+ */
210+ public MimeTypeParameterList getParameters() {
211+ return (MimeTypeParameterList)parameters.clone();
212+ }
213+
214+ /**
215+ * Retrieve the value associated with the given name, or null if there
216+ * is no current association.
217+ */
218+ public String getParameter(String name) {
219+ return parameters.get(name);
220+ }
221+
222+ /**
223+ * Set the value to be associated with the given name, replacing
224+ * any previous association.
225+ *
226+ * @throw IllegalArgumentException if parameter or value is illegal
227+ */
228+ public void setParameter(String name, String value) {
229+ parameters.set(name, value);
230+ }
231+
232+ /**
233+ * Remove any value associated with the given name.
234+ *
235+ * @throw IllegalArgumentExcpetion if parameter may not be deleted
236+ */
237+ public void removeParameter(String name) {
238+ parameters.remove(name);
239+ }
240+
241+ /**
242+ * Return the String representation of this object.
243+ */
244+ public String toString() {
245+ return getBaseType() + parameters.toString();
246+ }
247+
248+ /**
249+ * Return a String representation of this object
250+ * without the parameter list.
251+ */
252+ public String getBaseType() {
253+ return primaryType + "/" + subType;
254+ }
255+
256+ /**
257+ * Returns <code>true</code> if the primary type and the
258+ * subtype of this object are the same as the specified
259+ * <code>type</code>; otherwise returns <code>false</code>.
260+ *
261+ * @param type the type to compare to <code>this</code>'s type
262+ * @return <code>true</code> if the primary type and the
263+ * subtype of this object are the same as the
264+ * specified <code>type</code>; otherwise returns
265+ * <code>false</code>
266+ */
267+ public boolean match(MimeType type) {
268+ if (type == null)
269+ return false;
270+ return primaryType.equals(type.getPrimaryType())
271+ && (subType.equals("*")
272+ || type.getSubType().equals("*")
273+ || (subType.equals(type.getSubType())));
274+ }
275+
276+ /**
277+ * Returns <code>true</code> if the primary type and the
278+ * subtype of this object are the same as the content type
279+ * described in <code>rawdata</code>; otherwise returns
280+ * <code>false</code>.
281+ *
282+ * @param rawdata the raw data to be examined
283+ * @return <code>true</code> if the primary type and the
284+ * subtype of this object are the same as the content type
285+ * described in <code>rawdata</code>; otherwise returns
286+ * <code>false</code>; if <code>rawdata</code> is
287+ * <code>null</code>, returns <code>false</code>
288+ */
289+ public boolean match(String rawdata) throws MimeTypeParseException {
290+ if (rawdata == null)
291+ return false;
292+ return match(new MimeType(rawdata));
293+ }
294+
295+ /**
296+ * The object implements the writeExternal method to save its contents
297+ * by calling the methods of DataOutput for its primitive values or
298+ * calling the writeObject method of ObjectOutput for objects, strings
299+ * and arrays.
300+ * @exception IOException Includes any I/O exceptions that may occur
301+ */
302+ public void writeExternal(ObjectOutput out) throws IOException {
303+ String s = toString(); // contains ASCII chars only
304+ // one-to-one correspondence between ASCII char and byte in UTF string
305+ if (s.length() <= 65535) { // 65535 is max length of UTF string
306+ out.writeUTF(s);
307+ } else {
308+ out.writeByte(0);
309+ out.writeByte(0);
310+ out.writeInt(s.length());
311+ out.write(s.getBytes());
312+ }
313+ }
314+
315+ /**
316+ * The object implements the readExternal method to restore its
317+ * contents by calling the methods of DataInput for primitive
318+ * types and readObject for objects, strings and arrays. The
319+ * readExternal method must read the values in the same sequence
320+ * and with the same types as were written by writeExternal.
321+ * @exception ClassNotFoundException If the class for an object being
322+ * restored cannot be found.
323+ */
324+ public void readExternal(ObjectInput in) throws IOException,
325+ClassNotFoundException {
326+ String s = in.readUTF();
327+ if (s == null || s.length() == 0) { // long mime type
328+ byte[] ba = new byte[in.readInt()];
329+ in.readFully(ba);
330+ s = new String(ba);
331+ }
332+ try {
333+ parse(s);
334+ } catch(MimeTypeParseException e) {
335+ throw new IOException(e.toString());
336+ }
337+ }
338+
339+ /**
340+ * Returns a clone of this object.
341+ * @return a clone of this object
342+ */
343+
344+ public Object clone() {
345+ MimeType newObj = null;
346+ try {
347+ newObj = (MimeType)super.clone();
348+ } catch (CloneNotSupportedException cannotHappen) {
349+ }
350+ newObj.parameters = (MimeTypeParameterList)parameters.clone();
351+ return newObj;
352+ }
353+
354+ private String primaryType;
355+ private String subType;
356+ private MimeTypeParameterList parameters;
357+
358+ // below here be scary parsing related things
359+
360+ /**
361+ * Determines whether or not a given character belongs to a legal token.
362+ */
363+ private static boolean isTokenChar(char c) {
364+ return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
365+ }
366+
367+ /**
368+ * Determines whether or not a given string is a legal token.
369+ *
370+ * @throws NullPointerException if <code>s</code> is null
371+ */
372+ private boolean isValidToken(String s) {
373+ int len = s.length();
374+ if(len > 0) {
375+ for (int i = 0; i < len; ++i) {
376+ char c = s.charAt(i);
377+ if (!isTokenChar(c)) {
378+ return false;
379+ }
380+ }
381+ return true;
382+ } else {
383+ return false;
384+ }
385+ }
386+
387+ /**
388+ * A string that holds all the special chars.
389+ */
390+
391+ private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
392+
393+} // class MimeType
java/pkg/java/awt/datatransfer/MimeTypeParameterList.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/MimeTypeParameterList.java+404−0
@@ -0,0 +1,404 @@
1+/*
2+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.util.Enumeration;
29+import java.util.Hashtable;
30+import java.util.Iterator;
31+import java.util.Map;
32+import java.util.Set;
33+
34+
35+/**
36+ * An object that encapsualtes the parameter list of a MimeType
37+ * as defined in RFC 2045 and 2046.
38+ *
39+ * @author jeff.dunn@eng.sun.com
40+ */
41+class MimeTypeParameterList implements Cloneable {
42+
43+ /**
44+ * Default constructor.
45+ */
46+ public MimeTypeParameterList() {
47+ parameters = new Hashtable();
48+ }
49+
50+ public MimeTypeParameterList(String rawdata)
51+ throws MimeTypeParseException
52+ {
53+ parameters = new Hashtable();
54+
55+ // now parse rawdata
56+ parse(rawdata);
57+ }
58+
59+ public int hashCode() {
60+ int code = Integer.MAX_VALUE/45; // "random" value for empty lists
61+ String paramName = null;
62+ Enumeration enum_ = this.getNames();
63+
64+ while (enum_.hasMoreElements()) {
65+ paramName = (String)enum_.nextElement();
66+ code += paramName.hashCode();
67+ code += this.get(paramName).hashCode();
68+ }
69+
70+ return code;
71+ } // hashCode()
72+
73+ /**
74+ * Two parameter lists are considered equal if they have exactly
75+ * the same set of parameter names and associated values. The
76+ * order of the parameters is not considered.
77+ */
78+ public boolean equals(Object thatObject) {
79+ //System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")");
80+ if (!(thatObject instanceof MimeTypeParameterList)) {
81+ return false;
82+ }
83+ MimeTypeParameterList that = (MimeTypeParameterList)thatObject;
84+ if (this.size() != that.size()) {
85+ return false;
86+ }
87+ String name = null;
88+ String thisValue = null;
89+ String thatValue = null;
90+ Set entries = parameters.entrySet();
91+ Iterator iterator = entries.iterator();
92+ Map.Entry entry = null;
93+ while (iterator.hasNext()) {
94+ entry = (Map.Entry)iterator.next();
95+ name = (String)entry.getKey();
96+ thisValue = (String)entry.getValue();
97+ thatValue = (String)that.parameters.get(name);
98+ if ((thisValue == null) || (thatValue == null)) {
99+ // both null -> equal, only one null -> not equal
100+ if (thisValue != thatValue) {
101+ return false;
102+ }
103+ } else if (!thisValue.equals(thatValue)) {
104+ return false;
105+ }
106+ } // while iterator
107+
108+ return true;
109+ } // equals()
110+
111+ /**
112+ * A routine for parsing the parameter list out of a String.
113+ */
114+ protected void parse(String rawdata) throws MimeTypeParseException {
115+ int length = rawdata.length();
116+ if(length > 0) {
117+ int currentIndex = skipWhiteSpace(rawdata, 0);
118+ int lastIndex = 0;
119+
120+ if(currentIndex < length) {
121+ char currentChar = rawdata.charAt(currentIndex);
122+ while ((currentIndex < length) && (currentChar == ';')) {
123+ String name;
124+ String value;
125+ boolean foundit;
126+
127+ // eat the ';'
128+ ++currentIndex;
129+
130+ // now parse the parameter name
131+
132+ // skip whitespace
133+ currentIndex = skipWhiteSpace(rawdata, currentIndex);
134+
135+ if(currentIndex < length) {
136+ // find the end of the token char run
137+ lastIndex = currentIndex;
138+ currentChar = rawdata.charAt(currentIndex);
139+ while((currentIndex < length) && isTokenChar(currentChar)) {
140+ ++currentIndex;
141+ currentChar = rawdata.charAt(currentIndex);
142+ }
143+ name = rawdata.substring(lastIndex, currentIndex).toLowerCase();
144+
145+ // now parse the '=' that separates the name from the value
146+
147+ // skip whitespace
148+ currentIndex = skipWhiteSpace(rawdata, currentIndex);
149+
150+ if((currentIndex < length) && (rawdata.charAt(currentIndex) == '=')) {
151+ // eat it and parse the parameter value
152+ ++currentIndex;
153+
154+ // skip whitespace
155+ currentIndex = skipWhiteSpace(rawdata, currentIndex);
156+
157+ if(currentIndex < length) {
158+ // now find out whether or not we have a quoted value
159+ currentChar = rawdata.charAt(currentIndex);
160+ if(currentChar == '"') {
161+ // yup it's quoted so eat it and capture the quoted string
162+ ++currentIndex;
163+ lastIndex = currentIndex;
164+
165+ if(currentIndex < length) {
166+ // find the next unescqped quote
167+ foundit = false;
168+ while((currentIndex < length) && !foundit) {
169+ currentChar = rawdata.charAt(currentIndex);
170+ if(currentChar == '\\') {
171+ // found an escape sequence so pass this and the next character
172+ currentIndex += 2;
173+ } else if(currentChar == '"') {
174+ // foundit!
175+ foundit = true;
176+ } else {
177+ ++currentIndex;
178+ }
179+ }
180+ if(currentChar == '"') {
181+ value = unquote(rawdata.substring(lastIndex, currentIndex));
182+ // eat the quote
183+ ++currentIndex;
184+ } else {
185+ throw new MimeTypeParseException("Encountered unterminated quoted parameter value.");
186+ }
187+ } else {
188+ throw new MimeTypeParseException("Encountered unterminated quoted parameter value.");
189+ }
190+ } else if(isTokenChar(currentChar)) {
191+ // nope it's an ordinary token so it ends with a non-token char
192+ lastIndex = currentIndex;
193+ foundit = false;
194+ while((currentIndex < length) && !foundit) {
195+ currentChar = rawdata.charAt(currentIndex);
196+
197+ if(isTokenChar(currentChar)) {
198+ ++currentIndex;
199+ } else {
200+ foundit = true;
201+ }
202+ }
203+ value = rawdata.substring(lastIndex, currentIndex);
204+ } else {
205+ // it ain't a value
206+ throw new MimeTypeParseException("Unexpected character encountered at index " + currentIndex);
207+ }
208+
209+ // now put the data into the hashtable
210+ parameters.put(name, value);
211+ } else {
212+ throw new MimeTypeParseException("Couldn't find a value for parameter named " + name);
213+ }
214+ } else {
215+ throw new MimeTypeParseException("Couldn't find the '=' that separates a parameter name from its value.");
216+ }
217+ } else {
218+ throw new MimeTypeParseException("Couldn't find parameter name");
219+ }
220+
221+ // setup the next iteration
222+ currentIndex = skipWhiteSpace(rawdata, currentIndex);
223+ if(currentIndex < length) {
224+ currentChar = rawdata.charAt(currentIndex);
225+ }
226+ }
227+ if(currentIndex < length) {
228+ throw new MimeTypeParseException("More characters encountered in input than expected.");
229+ }
230+ }
231+ }
232+ }
233+
234+ /**
235+ * return the number of name-value pairs in this list.
236+ */
237+ public int size() {
238+ return parameters.size();
239+ }
240+
241+ /**
242+ * Determine whether or not this list is empty.
243+ */
244+ public boolean isEmpty() {
245+ return parameters.isEmpty();
246+ }
247+
248+ /**
249+ * Retrieve the value associated with the given name, or null if there
250+ * is no current association.
251+ */
252+ public String get(String name) {
253+ return (String)parameters.get(name.trim().toLowerCase());
254+ }
255+
256+ /**
257+ * Set the value to be associated with the given name, replacing
258+ * any previous association.
259+ */
260+ public void set(String name, String value) {
261+ parameters.put(name.trim().toLowerCase(), value);
262+ }
263+
264+ /**
265+ * Remove any value associated with the given name.
266+ */
267+ public void remove(String name) {
268+ parameters.remove(name.trim().toLowerCase());
269+ }
270+
271+ /**
272+ * Retrieve an enumeration of all the names in this list.
273+ */
274+ public Enumeration getNames() {
275+ return parameters.keys();
276+ }
277+
278+ public String toString() {
279+ // Heuristic: 8 characters per field
280+ StringBuilder buffer = new StringBuilder(parameters.size() * 16);
281+
282+ Enumeration keys = parameters.keys();
283+ while(keys.hasMoreElements())
284+ {
285+ buffer.append("; ");
286+
287+ String key = (String)keys.nextElement();
288+ buffer.append(key);
289+ buffer.append('=');
290+ buffer.append(quote((String)parameters.get(key)));
291+ }
292+
293+ return buffer.toString();
294+ }
295+
296+ /**
297+ * @return a clone of this object
298+ */
299+
300+ public Object clone() {
301+ MimeTypeParameterList newObj = null;
302+ try {
303+ newObj = (MimeTypeParameterList)super.clone();
304+ } catch (CloneNotSupportedException cannotHappen) {
305+ }
306+ newObj.parameters = (Hashtable)parameters.clone();
307+ return newObj;
308+ }
309+
310+ private Hashtable parameters;
311+
312+ // below here be scary parsing related things
313+
314+ /**
315+ * Determine whether or not a given character belongs to a legal token.
316+ */
317+ private static boolean isTokenChar(char c) {
318+ return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
319+ }
320+
321+ /**
322+ * return the index of the first non white space character in
323+ * rawdata at or after index i.
324+ */
325+ private static int skipWhiteSpace(String rawdata, int i) {
326+ int length = rawdata.length();
327+ if (i < length) {
328+ char c = rawdata.charAt(i);
329+ while ((i < length) && Character.isWhitespace(c)) {
330+ ++i;
331+ c = rawdata.charAt(i);
332+ }
333+ }
334+
335+ return i;
336+ }
337+
338+ /**
339+ * A routine that knows how and when to quote and escape the given value.
340+ */
341+ private static String quote(String value) {
342+ boolean needsQuotes = false;
343+
344+ // check to see if we actually have to quote this thing
345+ int length = value.length();
346+ for(int i = 0; (i < length) && !needsQuotes; ++i) {
347+ needsQuotes = !isTokenChar(value.charAt(i));
348+ }
349+
350+ if(needsQuotes) {
351+ StringBuilder buffer = new StringBuilder((int)(length * 1.5));
352+
353+ // add the initial quote
354+ buffer.append('"');
355+
356+ // add the properly escaped text
357+ for(int i = 0; i < length; ++i) {
358+ char c = value.charAt(i);
359+ if((c == '\\') || (c == '"')) {
360+ buffer.append('\\');
361+ }
362+ buffer.append(c);
363+ }
364+
365+ // add the closing quote
366+ buffer.append('"');
367+
368+ return buffer.toString();
369+ }
370+ else
371+ {
372+ return value;
373+ }
374+ }
375+
376+ /**
377+ * A routine that knows how to strip the quotes and escape sequences from the given value.
378+ */
379+ private static String unquote(String value) {
380+ int valueLength = value.length();
381+ StringBuilder buffer = new StringBuilder(valueLength);
382+
383+ boolean escaped = false;
384+ for(int i = 0; i < valueLength; ++i) {
385+ char currentChar = value.charAt(i);
386+ if(!escaped && (currentChar != '\\')) {
387+ buffer.append(currentChar);
388+ } else if(escaped) {
389+ buffer.append(currentChar);
390+ escaped = false;
391+ } else {
392+ escaped = true;
393+ }
394+ }
395+
396+ return buffer.toString();
397+ }
398+
399+ /**
400+ * A string that holds all the special chars.
401+ */
402+ private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
403+
404+}
java/pkg/java/awt/datatransfer/MimeTypeParseException.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/MimeTypeParseException.java+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+
29+/**
30+ * A class to encapsulate MimeType parsing related exceptions
31+ *
32+ * @serial exclude
33+ * @since 1.3
34+ */
35+public class MimeTypeParseException extends Exception {
36+
37+ // use serialVersionUID from JDK 1.2.2 for interoperability
38+ private static final long serialVersionUID = -5604407764691570741L;
39+
40+ /**
41+ * Constructs a MimeTypeParseException with no specified detail message.
42+ */
43+ public MimeTypeParseException() {
44+ super();
45+ }
46+
47+ /**
48+ * Constructs a MimeTypeParseException with the specified detail message.
49+ *
50+ * @param s the detail message.
51+ */
52+ public MimeTypeParseException(String s) {
53+ super(s);
54+ }
55+} // class MimeTypeParseException
java/pkg/java/awt/datatransfer/StringSelection.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/StringSelection.java+140−0
@@ -0,0 +1,140 @@
1+/*
2+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.io.*;
29+
30+/**
31+ * A <code>Transferable</code> which implements the capability required
32+ * to transfer a <code>String</code>.
33+ *
34+ * This <code>Transferable</code> properly supports
35+ * <code>DataFlavor.stringFlavor</code>
36+ * and all equivalent flavors. Support for
37+ * <code>DataFlavor.plainTextFlavor</code>
38+ * and all equivalent flavors is <b>deprecated</b>. No other
39+ * <code>DataFlavor</code>s are supported.
40+ *
41+ * @see java.awt.datatransfer.DataFlavor#stringFlavor
42+ * @see java.awt.datatransfer.DataFlavor#plainTextFlavor
43+ */
44+public class StringSelection implements Transferable, ClipboardOwner {
45+
46+ private static final int STRING = 0;
47+ private static final int PLAIN_TEXT = 1;
48+
49+ private static final DataFlavor[] flavors = {
50+ DataFlavor.stringFlavor,
51+ DataFlavor.plainTextFlavor // deprecated
52+ };
53+
54+ private String data;
55+
56+ /**
57+ * Creates a <code>Transferable</code> capable of transferring
58+ * the specified <code>String</code>.
59+ */
60+ public StringSelection(String data) {
61+ this.data = data;
62+ }
63+
64+ /**
65+ * Returns an array of flavors in which this <code>Transferable</code>
66+ * can provide the data. <code>DataFlavor.stringFlavor</code>
67+ * is properly supported.
68+ * Support for <code>DataFlavor.plainTextFlavor</code> is
69+ * <b>deprecated</b>.
70+ *
71+ * @return an array of length two, whose elements are <code>DataFlavor.
72+ * stringFlavor</code> and <code>DataFlavor.plainTextFlavor</code>
73+ */
74+ public DataFlavor[] getTransferDataFlavors() {
75+ // returning flavors itself would allow client code to modify
76+ // our internal behavior
77+ return (DataFlavor[])flavors.clone();
78+ }
79+
80+ /**
81+ * Returns whether the requested flavor is supported by this
82+ * <code>Transferable</code>.
83+ *
84+ * @param flavor the requested flavor for the data
85+ * @return true if <code>flavor</code> is equal to
86+ * <code>DataFlavor.stringFlavor</code> or
87+ * <code>DataFlavor.plainTextFlavor</code>; false if <code>flavor</code>
88+ * is not one of the above flavors
89+ * @throws NullPointerException if flavor is <code>null</code>
90+ */
91+ public boolean isDataFlavorSupported(DataFlavor flavor) {
92+ // JCK Test StringSelection0003: if 'flavor' is null, throw NPE
93+ for (int i = 0; i < flavors.length; i++) {
94+ if (flavor.equals(flavors[i])) {
95+ return true;
96+ }
97+ }
98+ return false;
99+ }
100+
101+ /**
102+ * Returns the <code>Transferable</code>'s data in the requested
103+ * <code>DataFlavor</code> if possible. If the desired flavor is
104+ * <code>DataFlavor.stringFlavor</code>, or an equivalent flavor,
105+ * the <code>String</code> representing the selection is
106+ * returned. If the desired flavor is
107+ * <code>DataFlavor.plainTextFlavor</code>,
108+ * or an equivalent flavor, a <code>Reader</code> is returned.
109+ * <b>Note:</b> The behavior of this method for
110+ * <code>DataFlavor.plainTextFlavor</code>
111+ * and equivalent <code>DataFlavor</code>s is inconsistent with the
112+ * definition of <code>DataFlavor.plainTextFlavor</code>.
113+ *
114+ * @param flavor the requested flavor for the data
115+ * @return the data in the requested flavor, as outlined above
116+ * @throws UnsupportedFlavorException if the requested data flavor is
117+ * not equivalent to either <code>DataFlavor.stringFlavor</code>
118+ * or <code>DataFlavor.plainTextFlavor</code>
119+ * @throws IOException if an IOException occurs while retrieving the data.
120+ * By default, StringSelection never throws this exception, but a
121+ * subclass may.
122+ * @throws NullPointerException if flavor is <code>null</code>
123+ * @see java.io.Reader
124+ */
125+ public Object getTransferData(DataFlavor flavor)
126+ throws UnsupportedFlavorException, IOException
127+ {
128+ // JCK Test StringSelection0007: if 'flavor' is null, throw NPE
129+ if (flavor.equals(flavors[STRING])) {
130+ return (Object)data;
131+ } else if (flavor.equals(flavors[PLAIN_TEXT])) {
132+ return new StringReader(data == null ? "" : data);
133+ } else {
134+ throw new UnsupportedFlavorException(flavor);
135+ }
136+ }
137+
138+ public void lostOwnership(Clipboard clipboard, Transferable contents) {
139+ }
140+}
java/pkg/java/awt/datatransfer/SystemFlavorMap$1.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/SystemFlavorMap$2.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/SystemFlavorMap.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/SystemFlavorMap.java+1299−0
@@ -0,0 +1,1299 @@
1+/*
2+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.awt.Toolkit;
29+
30+import java.lang.ref.SoftReference;
31+
32+import java.io.BufferedReader;
33+import java.io.File;
34+import java.io.InputStreamReader;
35+import java.io.IOException;
36+
37+import java.net.URL;
38+import java.net.MalformedURLException;
39+
40+import java.util.ArrayList;
41+import java.util.HashMap;
42+import java.util.HashSet;
43+import java.util.Iterator;
44+import java.util.LinkedList;
45+import java.util.List;
46+import java.util.Map;
47+import java.util.Set;
48+import java.util.WeakHashMap;
49+
50+import sun.awt.datatransfer.DataTransferer;
51+
52+/**
53+ * The SystemFlavorMap is a configurable map between "natives" (Strings), which
54+ * correspond to platform-specific data formats, and "flavors" (DataFlavors),
55+ * which correspond to platform-independent MIME types. This mapping is used
56+ * by the data transfer subsystem to transfer data between Java and native
57+ * applications, and between Java applications in separate VMs.
58+ * <p>
59+ * In the Sun reference implementation, the default SystemFlavorMap is
60+ * initialized by the file <code>jre/lib/flavormap.properties</code> and the
61+ * contents of the URL referenced by the AWT property
62+ * <code>AWT.DnD.flavorMapFileURL</code>. See <code>flavormap.properties</code>
63+ * for details.
64+ *
65+ * @since 1.2
66+ */
67+public final class SystemFlavorMap implements FlavorMap, FlavorTable {
68+
69+ /**
70+ * Constant prefix used to tag Java types converted to native platform
71+ * type.
72+ */
73+ private static String JavaMIME = "JAVA_DATAFLAVOR:";
74+
75+ /**
76+ * System singleton which maps a thread's ClassLoader to a SystemFlavorMap.
77+ */
78+ private static final WeakHashMap flavorMaps = new WeakHashMap();
79+
80+ /**
81+ * Copied from java.util.Properties.
82+ */
83+ private static final String keyValueSeparators = "=: \t\r\n\f";
84+ private static final String strictKeyValueSeparators = "=:";
85+ private static final String whiteSpaceChars = " \t\r\n\f";
86+
87+ /**
88+ * The list of valid, decoded text flavor representation classes, in order
89+ * from best to worst.
90+ */
91+ private static final String[] UNICODE_TEXT_CLASSES = {
92+ "java.io.Reader", "java.lang.String", "java.nio.CharBuffer", "\"[C\""
93+ };
94+
95+ /**
96+ * The list of valid, encoded text flavor representation classes, in order
97+ * from best to worst.
98+ */
99+ private static final String[] ENCODED_TEXT_CLASSES = {
100+ "java.io.InputStream", "java.nio.ByteBuffer", "\"[B\""
101+ };
102+
103+ /**
104+ * A String representing text/plain MIME type.
105+ */
106+ private static final String TEXT_PLAIN_BASE_TYPE = "text/plain";
107+
108+ /**
109+ * This constant is passed to flavorToNativeLookup() to indicate that a
110+ * a native should be synthesized, stored, and returned by encoding the
111+ * DataFlavor's MIME type in case if the DataFlavor is not found in
112+ * 'flavorToNative' map.
113+ */
114+ private static final boolean SYNTHESIZE_IF_NOT_FOUND = true;
115+
116+ /**
117+ * Maps native Strings to Lists of DataFlavors (or base type Strings for
118+ * text DataFlavors).
119+ * Do not use the field directly, use getNativeToFlavor() instead.
120+ */
121+ private Map nativeToFlavor = new HashMap();
122+
123+ /**
124+ * Accessor to nativeToFlavor map. Since we use lazy initialization we must
125+ * use this accessor instead of direct access to the field which may not be
126+ * initialized yet. This method will initialize the field if needed.
127+ *
128+ * @return nativeToFlavor
129+ */
130+ private Map getNativeToFlavor() {
131+ if (!isMapInitialized) {
132+ initSystemFlavorMap();
133+ }
134+ return nativeToFlavor;
135+ }
136+
137+ /**
138+ * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
139+ * native Strings.
140+ * Do not use the field directly, use getFlavorToNative() instead.
141+ */
142+ private Map flavorToNative = new HashMap();
143+
144+ /**
145+ * Accessor to flavorToNative map. Since we use lazy initialization we must
146+ * use this accessor instead of direct access to the field which may not be
147+ * initialized yet. This method will initialize the field if needed.
148+ *
149+ * @return flavorToNative
150+ */
151+ private synchronized Map getFlavorToNative() {
152+ if (!isMapInitialized) {
153+ initSystemFlavorMap();
154+ }
155+ return flavorToNative;
156+ }
157+
158+ /**
159+ * Shows if the object has been initialized.
160+ */
161+ private boolean isMapInitialized = false;
162+
163+ /**
164+ * Caches the result of getNativesForFlavor(). Maps DataFlavors to
165+ * SoftReferences which reference Lists of String natives.
166+ */
167+ private Map getNativesForFlavorCache = new HashMap();
168+
169+ /**
170+ * Caches the result getFlavorsForNative(). Maps String natives to
171+ * SoftReferences which reference Lists of DataFlavors.
172+ */
173+ private Map getFlavorsForNativeCache = new HashMap();
174+
175+ /**
176+ * Dynamic mapping generation used for text mappings should not be applied
177+ * to the DataFlavors and String natives for which the mappings have been
178+ * explicitly specified with setFlavorsForNative() or
179+ * setNativesForFlavor(). This keeps all such keys.
180+ */
181+ private Set disabledMappingGenerationKeys = new HashSet();
182+
183+ /**
184+ * Returns the default FlavorMap for this thread's ClassLoader.
185+ */
186+ public static FlavorMap getDefaultFlavorMap() {
187+ ClassLoader contextClassLoader =
188+ Thread.currentThread().getContextClassLoader();
189+ if (contextClassLoader == null) {
190+ contextClassLoader = ClassLoader.getSystemClassLoader();
191+ }
192+
193+ FlavorMap fm;
194+
195+ synchronized(flavorMaps) {
196+ fm = (FlavorMap)flavorMaps.get(contextClassLoader);
197+ if (fm == null) {
198+ fm = new SystemFlavorMap();
199+ flavorMaps.put(contextClassLoader, fm);
200+ }
201+ }
202+
203+ return fm;
204+ }
205+
206+ private SystemFlavorMap() {
207+ }
208+
209+ /**
210+ * Initializes a SystemFlavorMap by reading flavormap.properties and
211+ * AWT.DnD.flavorMapFileURL.
212+ * For thread-safety must be called under lock on this.
213+ */
214+ private void initSystemFlavorMap() {
215+ if (isMapInitialized) {
216+ return;
217+ }
218+
219+ isMapInitialized = true;
220+ BufferedReader flavormapDotProperties =
221+ java.security.AccessController.doPrivileged(
222+ new java.security.PrivilegedAction<BufferedReader>() {
223+ public BufferedReader run() {
224+ String fileName =
225+ System.getProperty("java.home") +
226+ File.separator +
227+ "lib" +
228+ File.separator +
229+ "flavormap.properties";
230+ try {
231+ return new BufferedReader
232+ (new InputStreamReader
233+ (new File(fileName).toURI().toURL().openStream(), "ISO-8859-1"));
234+ } catch (MalformedURLException e) {
235+ System.err.println("MalformedURLException:" + e + " while loading default flavormap.properties file:" + fileName);
236+ } catch (IOException e) {
237+ System.err.println("IOException:" + e + " while loading default flavormap.properties file:" + fileName);
238+ }
239+ return null;
240+ }
241+ });
242+
243+ BufferedReader flavormapURL =
244+ java.security.AccessController.doPrivileged(
245+ new java.security.PrivilegedAction<BufferedReader>() {
246+ public BufferedReader run() {
247+ String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
248+
249+ if (url == null) {
250+ return null;
251+ }
252+
253+ try {
254+ return new BufferedReader
255+ (new InputStreamReader
256+ (new URL(url).openStream(), "ISO-8859-1"));
257+ } catch (MalformedURLException e) {
258+ System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
259+ } catch (IOException e) {
260+ System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
261+ }
262+ return null;
263+ }
264+ });
265+
266+ if (flavormapDotProperties != null) {
267+ try {
268+ parseAndStoreReader(flavormapDotProperties);
269+ } catch (IOException e) {
270+ System.err.println("IOException:" + e + " while parsing default flavormap.properties file");
271+ }
272+ }
273+
274+ if (flavormapURL != null) {
275+ try {
276+ parseAndStoreReader(flavormapURL);
277+ } catch (IOException e) {
278+ System.err.println("IOException:" + e + " while parsing AWT.DnD.flavorMapFileURL");
279+ }
280+ }
281+ }
282+ /**
283+ * Copied code from java.util.Properties. Parsing the data ourselves is the
284+ * only way to handle duplicate keys and values.
285+ */
286+ private void parseAndStoreReader(BufferedReader in) throws IOException {
287+ while (true) {
288+ // Get next line
289+ String line = in.readLine();
290+ if (line == null) {
291+ return;
292+ }
293+
294+ if (line.length() > 0) {
295+ // Continue lines that end in slashes if they are not comments
296+ char firstChar = line.charAt(0);
297+ if (firstChar != '#' && firstChar != '!') {
298+ while (continueLine(line)) {
299+ String nextLine = in.readLine();
300+ if (nextLine == null) {
301+ nextLine = "";
302+ }
303+ String loppedLine =
304+ line.substring(0, line.length() - 1);
305+ // Advance beyond whitespace on new line
306+ int startIndex = 0;
307+ for(; startIndex < nextLine.length(); startIndex++) {
308+ if (whiteSpaceChars.
309+ indexOf(nextLine.charAt(startIndex)) == -1)
310+ {
311+ break;
312+ }
313+ }
314+ nextLine = nextLine.substring(startIndex,
315+ nextLine.length());
316+ line = loppedLine+nextLine;
317+ }
318+
319+ // Find start of key
320+ int len = line.length();
321+ int keyStart = 0;
322+ for(; keyStart < len; keyStart++) {
323+ if(whiteSpaceChars.
324+ indexOf(line.charAt(keyStart)) == -1) {
325+ break;
326+ }
327+ }
328+
329+ // Blank lines are ignored
330+ if (keyStart == len) {
331+ continue;
332+ }
333+
334+ // Find separation between key and value
335+ int separatorIndex = keyStart;
336+ for(; separatorIndex < len; separatorIndex++) {
337+ char currentChar = line.charAt(separatorIndex);
338+ if (currentChar == '\\') {
339+ separatorIndex++;
340+ } else if (keyValueSeparators.
341+ indexOf(currentChar) != -1) {
342+ break;
343+ }
344+ }
345+
346+ // Skip over whitespace after key if any
347+ int valueIndex = separatorIndex;
348+ for (; valueIndex < len; valueIndex++) {
349+ if (whiteSpaceChars.
350+ indexOf(line.charAt(valueIndex)) == -1) {
351+ break;
352+ }
353+ }
354+
355+ // Skip over one non whitespace key value separators if any
356+ if (valueIndex < len) {
357+ if (strictKeyValueSeparators.
358+ indexOf(line.charAt(valueIndex)) != -1) {
359+ valueIndex++;
360+ }
361+ }
362+
363+ // Skip over white space after other separators if any
364+ while (valueIndex < len) {
365+ if (whiteSpaceChars.
366+ indexOf(line.charAt(valueIndex)) == -1) {
367+ break;
368+ }
369+ valueIndex++;
370+ }
371+
372+ String key = line.substring(keyStart, separatorIndex);
373+ String value = (separatorIndex < len)
374+ ? line.substring(valueIndex, len)
375+ : "";
376+
377+ // Convert then store key and value
378+ key = loadConvert(key);
379+ value = loadConvert(value);
380+
381+ try {
382+ MimeType mime = new MimeType(value);
383+ if ("text".equals(mime.getPrimaryType())) {
384+ String charset = mime.getParameter("charset");
385+ if (DataTransferer.doesSubtypeSupportCharset
386+ (mime.getSubType(), charset))
387+ {
388+ // We need to store the charset and eoln
389+ // parameters, if any, so that the
390+ // DataTransferer will have this information
391+ // for conversion into the native format.
392+ DataTransferer transferer =
393+ DataTransferer.getInstance();
394+ if (transferer != null) {
395+ transferer.registerTextFlavorProperties
396+ (key, charset,
397+ mime.getParameter("eoln"),
398+ mime.getParameter("terminators"));
399+ }
400+ }
401+
402+ // But don't store any of these parameters in the
403+ // DataFlavor itself for any text natives (even
404+ // non-charset ones). The SystemFlavorMap will
405+ // synthesize the appropriate mappings later.
406+ mime.removeParameter("charset");
407+ mime.removeParameter("class");
408+ mime.removeParameter("eoln");
409+ mime.removeParameter("terminators");
410+ value = mime.toString();
411+ }
412+ } catch (MimeTypeParseException e) {
413+ e.printStackTrace();
414+ continue;
415+ }
416+
417+ DataFlavor flavor;
418+ try {
419+ flavor = new DataFlavor(value);
420+ } catch (Exception e) {
421+ try {
422+ flavor = new DataFlavor(value, (String)null);
423+ } catch (Exception ee) {
424+ ee.printStackTrace();
425+ continue;
426+ }
427+ }
428+
429+ // For text/* flavors, store mappings in separate maps to
430+ // enable dynamic mapping generation at a run-time.
431+ if ("text".equals(flavor.getPrimaryType())) {
432+ store(value, key, getFlavorToNative());
433+ store(key, value, getNativeToFlavor());
434+ } else {
435+ store(flavor, key, getFlavorToNative());
436+ store(key, flavor, getNativeToFlavor());
437+ }
438+ }
439+ }
440+ }
441+ }
442+
443+ /**
444+ * Copied from java.util.Properties.
445+ */
446+ private boolean continueLine (String line) {
447+ int slashCount = 0;
448+ int index = line.length() - 1;
449+ while((index >= 0) && (line.charAt(index--) == '\\')) {
450+ slashCount++;
451+ }
452+ return (slashCount % 2 == 1);
453+ }
454+
455+ /**
456+ * Copied from java.util.Properties.
457+ */
458+ private String loadConvert(String theString) {
459+ char aChar;
460+ int len = theString.length();
461+ StringBuilder outBuffer = new StringBuilder(len);
462+
463+ for (int x = 0; x < len; ) {
464+ aChar = theString.charAt(x++);
465+ if (aChar == '\\') {
466+ aChar = theString.charAt(x++);
467+ if (aChar == 'u') {
468+ // Read the xxxx
469+ int value = 0;
470+ for (int i = 0; i < 4; i++) {
471+ aChar = theString.charAt(x++);
472+ switch (aChar) {
473+ case '0': case '1': case '2': case '3': case '4':
474+ case '5': case '6': case '7': case '8': case '9': {
475+ value = (value << 4) + aChar - '0';
476+ break;
477+ }
478+ case 'a': case 'b': case 'c':
479+ case 'd': case 'e': case 'f': {
480+ value = (value << 4) + 10 + aChar - 'a';
481+ break;
482+ }
483+ case 'A': case 'B': case 'C':
484+ case 'D': case 'E': case 'F': {
485+ value = (value << 4) + 10 + aChar - 'A';
486+ break;
487+ }
488+ default: {
489+ throw new IllegalArgumentException(
490+ "Malformed \\uxxxx encoding.");
491+ }
492+ }
493+ }
494+ outBuffer.append((char)value);
495+ } else {
496+ if (aChar == 't') {
497+ aChar = '\t';
498+ } else if (aChar == 'r') {
499+ aChar = '\r';
500+ } else if (aChar == 'n') {
501+ aChar = '\n';
502+ } else if (aChar == 'f') {
503+ aChar = '\f';
504+ }
505+ outBuffer.append(aChar);
506+ }
507+ } else {
508+ outBuffer.append(aChar);
509+ }
510+ }
511+ return outBuffer.toString();
512+ }
513+
514+ /**
515+ * Stores the listed object under the specified hash key in map. Unlike a
516+ * standard map, the listed object will not replace any object already at
517+ * the appropriate Map location, but rather will be appended to a List
518+ * stored in that location.
519+ */
520+ private void store(Object hashed, Object listed, Map map) {
521+ List list = (List)map.get(hashed);
522+ if (list == null) {
523+ list = new ArrayList(1);
524+ map.put(hashed, list);
525+ }
526+ if (!list.contains(listed)) {
527+ list.add(listed);
528+ }
529+ }
530+
531+ /**
532+ * Semantically equivalent to 'nativeToFlavor.get(nat)'. This method
533+ * handles the case where 'nat' is not found in 'nativeToFlavor'. In that
534+ * case, a new DataFlavor is synthesized, stored, and returned, if and
535+ * only if the specified native is encoded as a Java MIME type.
536+ */
537+ private List nativeToFlavorLookup(String nat) {
538+ List flavors = (List)getNativeToFlavor().get(nat);
539+
540+ if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
541+ DataTransferer transferer = DataTransferer.getInstance();
542+ if (transferer != null) {
543+ List platformFlavors =
544+ transferer.getPlatformMappingsForNative(nat);
545+ if (!platformFlavors.isEmpty()) {
546+ if (flavors != null) {
547+ platformFlavors.removeAll(new HashSet(flavors));
548+ // Prepending the platform-specific mappings ensures
549+ // that the flavors added with
550+ // addFlavorForUnencodedNative() are at the end of
551+ // list.
552+ platformFlavors.addAll(flavors);
553+ }
554+ flavors = platformFlavors;
555+ }
556+ }
557+ }
558+
559+ if (flavors == null && isJavaMIMEType(nat)) {
560+ String decoded = decodeJavaMIMEType(nat);
561+ DataFlavor flavor = null;
562+
563+ try {
564+ flavor = new DataFlavor(decoded);
565+ } catch (Exception e) {
566+ System.err.println("Exception \"" + e.getClass().getName() +
567+ ": " + e.getMessage() +
568+ "\"while constructing DataFlavor for: " +
569+ decoded);
570+ }
571+
572+ if (flavor != null) {
573+ flavors = new ArrayList(1);
574+ getNativeToFlavor().put(nat, flavors);
575+ flavors.add(flavor);
576+ getFlavorsForNativeCache.remove(nat);
577+ getFlavorsForNativeCache.remove(null);
578+
579+ List natives = (List)getFlavorToNative().get(flavor);
580+ if (natives == null) {
581+ natives = new ArrayList(1);
582+ getFlavorToNative().put(flavor, natives);
583+ }
584+ natives.add(nat);
585+ getNativesForFlavorCache.remove(flavor);
586+ getNativesForFlavorCache.remove(null);
587+ }
588+ }
589+
590+ return (flavors != null) ? flavors : new ArrayList(0);
591+ }
592+
593+ /**
594+ * Semantically equivalent to 'flavorToNative.get(flav)'. This method
595+ * handles the case where 'flav' is not found in 'flavorToNative' depending
596+ * on the value of passes 'synthesize' parameter. If 'synthesize' is
597+ * SYNTHESIZE_IF_NOT_FOUND a native is synthesized, stored, and returned by
598+ * encoding the DataFlavor's MIME type. Otherwise an empty List is returned
599+ * and 'flavorToNative' remains unaffected.
600+ */
601+ private List flavorToNativeLookup(final DataFlavor flav,
602+ final boolean synthesize) {
603+ List natives = (List)getFlavorToNative().get(flav);
604+
605+ if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
606+ DataTransferer transferer = DataTransferer.getInstance();
607+ if (transferer != null) {
608+ List platformNatives =
609+ transferer.getPlatformMappingsForFlavor(flav);
610+ if (!platformNatives.isEmpty()) {
611+ if (natives != null) {
612+ platformNatives.removeAll(new HashSet(natives));
613+ // Prepend the platform-specific mappings to ensure
614+ // that the natives added with
615+ // addUnencodedNativeForFlavor() are at the end of
616+ // list.
617+ platformNatives.addAll(natives);
618+ }
619+ natives = platformNatives;
620+ }
621+ }
622+ }
623+
624+ if (natives == null) {
625+ if (synthesize) {
626+ String encoded = encodeDataFlavor(flav);
627+ natives = new ArrayList(1);
628+ getFlavorToNative().put(flav, natives);
629+ natives.add(encoded);
630+ getNativesForFlavorCache.remove(flav);
631+ getNativesForFlavorCache.remove(null);
632+
633+ List flavors = (List)getNativeToFlavor().get(encoded);
634+ if (flavors == null) {
635+ flavors = new ArrayList(1);
636+ getNativeToFlavor().put(encoded, flavors);
637+ }
638+ flavors.add(flav);
639+ getFlavorsForNativeCache.remove(encoded);
640+ getFlavorsForNativeCache.remove(null);
641+ } else {
642+ natives = new ArrayList(0);
643+ }
644+ }
645+
646+ return natives;
647+ }
648+
649+ /**
650+ * Returns a <code>List</code> of <code>String</code> natives to which the
651+ * specified <code>DataFlavor</code> can be translated by the data transfer
652+ * subsystem. The <code>List</code> will be sorted from best native to
653+ * worst. That is, the first native will best reflect data in the specified
654+ * flavor to the underlying native platform.
655+ * <p>
656+ * If the specified <code>DataFlavor</code> is previously unknown to the
657+ * data transfer subsystem and the data transfer subsystem is unable to
658+ * translate this <code>DataFlavor</code> to any existing native, then
659+ * invoking this method will establish a
660+ * mapping in both directions between the specified <code>DataFlavor</code>
661+ * and an encoded version of its MIME type as its native.
662+ *
663+ * @param flav the <code>DataFlavor</code> whose corresponding natives
664+ * should be returned. If <code>null</code> is specified, all
665+ * natives currently known to the data transfer subsystem are
666+ * returned in a non-deterministic order.
667+ * @return a <code>java.util.List</code> of <code>java.lang.String</code>
668+ * objects which are platform-specific representations of platform-
669+ * specific data formats
670+ *
671+ * @see #encodeDataFlavor
672+ * @since 1.4
673+ */
674+ public synchronized List<String> getNativesForFlavor(DataFlavor flav) {
675+ List retval = null;
676+
677+ // Check cache, even for null flav
678+ SoftReference ref = (SoftReference)getNativesForFlavorCache.get(flav);
679+ if (ref != null) {
680+ retval = (List)ref.get();
681+ if (retval != null) {
682+ // Create a copy, because client code can modify the returned
683+ // list.
684+ return new ArrayList(retval);
685+ }
686+ }
687+
688+ if (flav == null) {
689+ retval = new ArrayList(getNativeToFlavor().keySet());
690+ } else if (disabledMappingGenerationKeys.contains(flav)) {
691+ // In this case we shouldn't synthesize a native for this flavor,
692+ // since its mappings were explicitly specified.
693+ retval = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
694+ } else if (DataTransferer.isFlavorCharsetTextType(flav)) {
695+
696+ // For text/* flavors, flavor-to-native mappings specified in
697+ // flavormap.properties are stored per flavor's base type.
698+ if ("text".equals(flav.getPrimaryType())) {
699+ retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
700+ if (retval != null) {
701+ // To prevent the List stored in the map from modification.
702+ retval = new ArrayList(retval);
703+ }
704+ }
705+
706+ // Also include text/plain natives, but don't duplicate Strings
707+ List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
708+
709+ if (textPlainList != null && !textPlainList.isEmpty()) {
710+ // To prevent the List stored in the map from modification.
711+ // This also guarantees that removeAll() is supported.
712+ textPlainList = new ArrayList(textPlainList);
713+ if (retval != null && !retval.isEmpty()) {
714+ // Use HashSet to get constant-time performance for search.
715+ textPlainList.removeAll(new HashSet(retval));
716+ retval.addAll(textPlainList);
717+ } else {
718+ retval = textPlainList;
719+ }
720+ }
721+
722+ if (retval == null || retval.isEmpty()) {
723+ retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
724+ } else {
725+ // In this branch it is guaranteed that natives explicitly
726+ // listed for flav's MIME type were added with
727+ // addUnencodedNativeForFlavor(), so they have lower priority.
728+ List explicitList =
729+ flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
730+
731+ // flavorToNativeLookup() never returns null.
732+ // It can return an empty List, however.
733+ if (!explicitList.isEmpty()) {
734+ // To prevent the List stored in the map from modification.
735+ // This also guarantees that removeAll() is supported.
736+ explicitList = new ArrayList(explicitList);
737+ // Use HashSet to get constant-time performance for search.
738+ explicitList.removeAll(new HashSet(retval));
739+ retval.addAll(explicitList);
740+ }
741+ }
742+ } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
743+ retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
744+
745+ if (retval == null || retval.isEmpty()) {
746+ retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
747+ } else {
748+ // In this branch it is guaranteed that natives explicitly
749+ // listed for flav's MIME type were added with
750+ // addUnencodedNativeForFlavor(), so they have lower priority.
751+ List explicitList =
752+ flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
753+
754+ // flavorToNativeLookup() never returns null.
755+ // It can return an empty List, however.
756+ if (!explicitList.isEmpty()) {
757+ // To prevent the List stored in the map from modification.
758+ // This also guarantees that add/removeAll() are supported.
759+ retval = new ArrayList(retval);
760+ explicitList = new ArrayList(explicitList);
761+ // Use HashSet to get constant-time performance for search.
762+ explicitList.removeAll(new HashSet(retval));
763+ retval.addAll(explicitList);
764+ }
765+ }
766+ } else {
767+ retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
768+ }
769+
770+ getNativesForFlavorCache.put(flav, new SoftReference(retval));
771+ // Create a copy, because client code can modify the returned list.
772+ return new ArrayList(retval);
773+ }
774+
775+ /**
776+ * Returns a <code>List</code> of <code>DataFlavor</code>s to which the
777+ * specified <code>String</code> native can be translated by the data
778+ * transfer subsystem. The <code>List</code> will be sorted from best
779+ * <code>DataFlavor</code> to worst. That is, the first
780+ * <code>DataFlavor</code> will best reflect data in the specified
781+ * native to a Java application.
782+ * <p>
783+ * If the specified native is previously unknown to the data transfer
784+ * subsystem, and that native has been properly encoded, then invoking this
785+ * method will establish a mapping in both directions between the specified
786+ * native and a <code>DataFlavor</code> whose MIME type is a decoded
787+ * version of the native.
788+ * <p>
789+ * If the specified native is not a properly encoded native and the
790+ * mappings for this native have not been altered with
791+ * <code>setFlavorsForNative</code>, then the contents of the
792+ * <code>List</code> is platform dependent, but <code>null</code>
793+ * cannot be returned.
794+ *
795+ * @param nat the native whose corresponding <code>DataFlavor</code>s
796+ * should be returned. If <code>null</code> is specified, all
797+ * <code>DataFlavor</code>s currently known to the data transfer
798+ * subsystem are returned in a non-deterministic order.
799+ * @return a <code>java.util.List</code> of <code>DataFlavor</code>
800+ * objects into which platform-specific data in the specified,
801+ * platform-specific native can be translated
802+ *
803+ * @see #encodeJavaMIMEType
804+ * @since 1.4
805+ */
806+ public synchronized List<DataFlavor> getFlavorsForNative(String nat) {
807+
808+ // Check cache, even for null nat
809+ SoftReference ref = (SoftReference)getFlavorsForNativeCache.get(nat);
810+ if (ref != null) {
811+ ArrayList retval = (ArrayList)ref.get();
812+ if (retval != null) {
813+ return (List)retval.clone();
814+ }
815+ }
816+
817+ LinkedList retval = new LinkedList();
818+
819+ if (nat == null) {
820+ List natives = getNativesForFlavor(null);
821+ HashSet dups = new HashSet(natives.size());
822+
823+ for (Iterator natives_iter = natives.iterator();
824+ natives_iter.hasNext(); )
825+ {
826+ List flavors =
827+ getFlavorsForNative((String)natives_iter.next());
828+ for (Iterator flavors_iter = flavors.iterator();
829+ flavors_iter.hasNext(); )
830+ {
831+ Object flavor = flavors_iter.next();
832+ if (dups.add(flavor)) {
833+ retval.add(flavor);
834+ }
835+ }
836+ }
837+ } else {
838+ List flavors = nativeToFlavorLookup(nat);
839+
840+ if (disabledMappingGenerationKeys.contains(nat)) {
841+ return flavors;
842+ }
843+
844+ HashSet dups = new HashSet(flavors.size());
845+
846+ List flavorsAndbaseTypes = nativeToFlavorLookup(nat);
847+
848+ for (Iterator flavorsAndbaseTypes_iter =
849+ flavorsAndbaseTypes.iterator();
850+ flavorsAndbaseTypes_iter.hasNext(); )
851+ {
852+ Object value = flavorsAndbaseTypes_iter.next();
853+ if (value instanceof String) {
854+ String baseType = (String)value;
855+ String subType = null;
856+ try {
857+ MimeType mimeType = new MimeType(baseType);
858+ subType = mimeType.getSubType();
859+ } catch (MimeTypeParseException mtpe) {
860+ // Cannot happen, since we checked all mappings
861+ // on load from flavormap.properties.
862+ assert(false);
863+ }
864+ if (DataTransferer.doesSubtypeSupportCharset(subType,
865+ null)) {
866+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
867+ dups.add(DataFlavor.stringFlavor))
868+ {
869+ retval.add(DataFlavor.stringFlavor);
870+ }
871+
872+ for (int i = 0; i < UNICODE_TEXT_CLASSES.length; i++) {
873+ DataFlavor toAdd = null;
874+ try {
875+ toAdd = new DataFlavor
876+ (baseType + ";charset=Unicode;class=" +
877+ UNICODE_TEXT_CLASSES[i]);
878+ } catch (ClassNotFoundException cannotHappen) {
879+ }
880+ if (dups.add(toAdd)) {
881+ retval.add(toAdd);
882+ }
883+ }
884+
885+ for (Iterator charset_iter =
886+ DataTransferer.standardEncodings();
887+ charset_iter.hasNext(); )
888+ {
889+ String charset = (String)charset_iter.next();
890+
891+ for (int i = 0; i < ENCODED_TEXT_CLASSES.length;
892+ i++)
893+ {
894+ DataFlavor toAdd = null;
895+ try {
896+ toAdd = new DataFlavor
897+ (baseType + ";charset=" + charset +
898+ ";class=" + ENCODED_TEXT_CLASSES[i]);
899+ } catch (ClassNotFoundException cannotHappen) {
900+ }
901+
902+ // Check for equality to plainTextFlavor so
903+ // that we can ensure that the exact charset of
904+ // plainTextFlavor, not the canonical charset
905+ // or another equivalent charset with a
906+ // different name, is used.
907+ if (toAdd.equals(DataFlavor.plainTextFlavor)) {
908+ toAdd = DataFlavor.plainTextFlavor;
909+ }
910+
911+ if (dups.add(toAdd)) {
912+ retval.add(toAdd);
913+ }
914+ }
915+ }
916+
917+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
918+ dups.add(DataFlavor.plainTextFlavor))
919+ {
920+ retval.add(DataFlavor.plainTextFlavor);
921+ }
922+ } else {
923+ // Non-charset text natives should be treated as
924+ // opaque, 8-bit data in any of its various
925+ // representations.
926+ for (int i = 0; i < ENCODED_TEXT_CLASSES.length; i++) {
927+ DataFlavor toAdd = null;
928+ try {
929+ toAdd = new DataFlavor(baseType +
930+ ";class=" + ENCODED_TEXT_CLASSES[i]);
931+ } catch (ClassNotFoundException cannotHappen) {
932+ }
933+
934+ if (dups.add(toAdd)) {
935+ retval.add(toAdd);
936+ }
937+ }
938+ }
939+ } else {
940+ DataFlavor flavor = (DataFlavor)value;
941+ if (dups.add(flavor)) {
942+ retval.add(flavor);
943+ }
944+ }
945+ }
946+ }
947+
948+ ArrayList arrayList = new ArrayList(retval);
949+ getFlavorsForNativeCache.put(nat, new SoftReference(arrayList));
950+ return (List)arrayList.clone();
951+ }
952+
953+ /**
954+ * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
955+ * their most preferred <code>String</code> native. Each native value will
956+ * be the same as the first native in the List returned by
957+ * <code>getNativesForFlavor</code> for the specified flavor.
958+ * <p>
959+ * If a specified <code>DataFlavor</code> is previously unknown to the
960+ * data transfer subsystem, then invoking this method will establish a
961+ * mapping in both directions between the specified <code>DataFlavor</code>
962+ * and an encoded version of its MIME type as its native.
963+ *
964+ * @param flavors an array of <code>DataFlavor</code>s which will be the
965+ * key set of the returned <code>Map</code>. If <code>null</code> is
966+ * specified, a mapping of all <code>DataFlavor</code>s known to the
967+ * data transfer subsystem to their most preferred
968+ * <code>String</code> natives will be returned.
969+ * @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
970+ * <code>String</code> natives
971+ *
972+ * @see #getNativesForFlavor
973+ * @see #encodeDataFlavor
974+ */
975+ public synchronized Map<DataFlavor,String>
976+ getNativesForFlavors(DataFlavor[] flavors)
977+ {
978+ // Use getNativesForFlavor to generate extra natives for text flavors
979+ // and stringFlavor
980+
981+ if (flavors == null) {
982+ List flavor_list = getFlavorsForNative(null);
983+ flavors = new DataFlavor[flavor_list.size()];
984+ flavor_list.toArray(flavors);
985+ }
986+
987+ HashMap retval = new HashMap(flavors.length, 1.0f);
988+ for (int i = 0; i < flavors.length; i++) {
989+ List natives = getNativesForFlavor(flavors[i]);
990+ String nat = (natives.isEmpty()) ? null : (String)natives.get(0);
991+ retval.put(flavors[i], nat);
992+ }
993+
994+ return retval;
995+ }
996+
997+ /**
998+ * Returns a <code>Map</code> of the specified <code>String</code> natives
999+ * to their most preferred <code>DataFlavor</code>. Each
1000+ * <code>DataFlavor</code> value will be the same as the first
1001+ * <code>DataFlavor</code> in the List returned by
1002+ * <code>getFlavorsForNative</code> for the specified native.
1003+ * <p>
1004+ * If a specified native is previously unknown to the data transfer
1005+ * subsystem, and that native has been properly encoded, then invoking this
1006+ * method will establish a mapping in both directions between the specified
1007+ * native and a <code>DataFlavor</code> whose MIME type is a decoded
1008+ * version of the native.
1009+ *
1010+ * @param natives an array of <code>String</code>s which will be the
1011+ * key set of the returned <code>Map</code>. If <code>null</code> is
1012+ * specified, a mapping of all supported <code>String</code> natives
1013+ * to their most preferred <code>DataFlavor</code>s will be
1014+ * returned.
1015+ * @return a <code>java.util.Map</code> of <code>String</code> natives to
1016+ * <code>DataFlavor</code>s
1017+ *
1018+ * @see #getFlavorsForNative
1019+ * @see #encodeJavaMIMEType
1020+ */
1021+ public synchronized Map<String,DataFlavor>
1022+ getFlavorsForNatives(String[] natives)
1023+ {
1024+ // Use getFlavorsForNative to generate extra flavors for text natives
1025+
1026+ if (natives == null) {
1027+ List native_list = getNativesForFlavor(null);
1028+ natives = new String[native_list.size()];
1029+ native_list.toArray(natives);
1030+ }
1031+
1032+ HashMap retval = new HashMap(natives.length, 1.0f);
1033+ for (int i = 0; i < natives.length; i++) {
1034+ List flavors = getFlavorsForNative(natives[i]);
1035+ DataFlavor flav = (flavors.isEmpty())
1036+ ? null : (DataFlavor)flavors.get(0);
1037+ retval.put(natives[i], flav);
1038+ }
1039+
1040+ return retval;
1041+ }
1042+
1043+ /**
1044+ * Adds a mapping from the specified <code>DataFlavor</code> (and all
1045+ * <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>)
1046+ * to the specified <code>String</code> native.
1047+ * Unlike <code>getNativesForFlavor</code>, the mapping will only be
1048+ * established in one direction, and the native will not be encoded. To
1049+ * establish a two-way mapping, call
1050+ * <code>addFlavorForUnencodedNative</code> as well. The new mapping will
1051+ * be of lower priority than any existing mapping.
1052+ * This method has no effect if a mapping from the specified or equal
1053+ * <code>DataFlavor</code> to the specified <code>String</code> native
1054+ * already exists.
1055+ *
1056+ * @param flav the <code>DataFlavor</code> key for the mapping
1057+ * @param nat the <code>String</code> native value for the mapping
1058+ * @throws NullPointerException if flav or nat is <code>null</code>
1059+ *
1060+ * @see #addFlavorForUnencodedNative
1061+ * @since 1.4
1062+ */
1063+ public synchronized void addUnencodedNativeForFlavor(DataFlavor flav,
1064+ String nat) {
1065+ if (flav == null || nat == null) {
1066+ throw new NullPointerException("null arguments not permitted");
1067+ }
1068+
1069+ List natives = (List)getFlavorToNative().get(flav);
1070+ if (natives == null) {
1071+ natives = new ArrayList(1);
1072+ getFlavorToNative().put(flav, natives);
1073+ } else if (natives.contains(nat)) {
1074+ return;
1075+ }
1076+ natives.add(nat);
1077+ getNativesForFlavorCache.remove(flav);
1078+ getNativesForFlavorCache.remove(null);
1079+ }
1080+
1081+ /**
1082+ * Discards the current mappings for the specified <code>DataFlavor</code>
1083+ * and all <code>DataFlavor</code>s equal to the specified
1084+ * <code>DataFlavor</code>, and creates new mappings to the
1085+ * specified <code>String</code> natives.
1086+ * Unlike <code>getNativesForFlavor</code>, the mappings will only be
1087+ * established in one direction, and the natives will not be encoded. To
1088+ * establish two-way mappings, call <code>setFlavorsForNative</code>
1089+ * as well. The first native in the array will represent the highest
1090+ * priority mapping. Subsequent natives will represent mappings of
1091+ * decreasing priority.
1092+ * <p>
1093+ * If the array contains several elements that reference equal
1094+ * <code>String</code> natives, this method will establish new mappings
1095+ * for the first of those elements and ignore the rest of them.
1096+ * <p>
1097+ * It is recommended that client code not reset mappings established by the
1098+ * data transfer subsystem. This method should only be used for
1099+ * application-level mappings.
1100+ *
1101+ * @param flav the <code>DataFlavor</code> key for the mappings
1102+ * @param natives the <code>String</code> native values for the mappings
1103+ * @throws NullPointerException if flav or natives is <code>null</code>
1104+ * or if natives contains <code>null</code> elements
1105+ *
1106+ * @see #setFlavorsForNative
1107+ * @since 1.4
1108+ */
1109+ public synchronized void setNativesForFlavor(DataFlavor flav,
1110+ String[] natives) {
1111+ if (flav == null || natives == null) {
1112+ throw new NullPointerException("null arguments not permitted");
1113+ }
1114+
1115+ getFlavorToNative().remove(flav);
1116+ for (int i = 0; i < natives.length; i++) {
1117+ addUnencodedNativeForFlavor(flav, natives[i]);
1118+ }
1119+ disabledMappingGenerationKeys.add(flav);
1120+ // Clear the cache to handle the case of empty natives.
1121+ getNativesForFlavorCache.remove(flav);
1122+ getNativesForFlavorCache.remove(null);
1123+ }
1124+
1125+ /**
1126+ * Adds a mapping from a single <code>String</code> native to a single
1127+ * <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the
1128+ * mapping will only be established in one direction, and the native will
1129+ * not be encoded. To establish a two-way mapping, call
1130+ * <code>addUnencodedNativeForFlavor</code> as well. The new mapping will
1131+ * be of lower priority than any existing mapping.
1132+ * This method has no effect if a mapping from the specified
1133+ * <code>String</code> native to the specified or equal
1134+ * <code>DataFlavor</code> already exists.
1135+ *
1136+ * @param nat the <code>String</code> native key for the mapping
1137+ * @param flav the <code>DataFlavor</code> value for the mapping
1138+ * @throws NullPointerException if nat or flav is <code>null</code>
1139+ *
1140+ * @see #addUnencodedNativeForFlavor
1141+ * @since 1.4
1142+ */
1143+ public synchronized void addFlavorForUnencodedNative(String nat,
1144+ DataFlavor flav) {
1145+ if (nat == null || flav == null) {
1146+ throw new NullPointerException("null arguments not permitted");
1147+ }
1148+
1149+ List flavors = (List)getNativeToFlavor().get(nat);
1150+ if (flavors == null) {
1151+ flavors = new ArrayList(1);
1152+ getNativeToFlavor().put(nat, flavors);
1153+ } else if (flavors.contains(flav)) {
1154+ return;
1155+ }
1156+ flavors.add(flav);
1157+ getFlavorsForNativeCache.remove(nat);
1158+ getFlavorsForNativeCache.remove(null);
1159+ }
1160+
1161+ /**
1162+ * Discards the current mappings for the specified <code>String</code>
1163+ * native, and creates new mappings to the specified
1164+ * <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the
1165+ * mappings will only be established in one direction, and the natives need
1166+ * not be encoded. To establish two-way mappings, call
1167+ * <code>setNativesForFlavor</code> as well. The first
1168+ * <code>DataFlavor</code> in the array will represent the highest priority
1169+ * mapping. Subsequent <code>DataFlavor</code>s will represent mappings of
1170+ * decreasing priority.
1171+ * <p>
1172+ * If the array contains several elements that reference equal
1173+ * <code>DataFlavor</code>s, this method will establish new mappings
1174+ * for the first of those elements and ignore the rest of them.
1175+ * <p>
1176+ * It is recommended that client code not reset mappings established by the
1177+ * data transfer subsystem. This method should only be used for
1178+ * application-level mappings.
1179+ *
1180+ * @param nat the <code>String</code> native key for the mappings
1181+ * @param flavors the <code>DataFlavor</code> values for the mappings
1182+ * @throws NullPointerException if nat or flavors is <code>null</code>
1183+ * or if flavors contains <code>null</code> elements
1184+ *
1185+ * @see #setNativesForFlavor
1186+ * @since 1.4
1187+ */
1188+ public synchronized void setFlavorsForNative(String nat,
1189+ DataFlavor[] flavors) {
1190+ if (nat == null || flavors == null) {
1191+ throw new NullPointerException("null arguments not permitted");
1192+ }
1193+
1194+ getNativeToFlavor().remove(nat);
1195+ for (int i = 0; i < flavors.length; i++) {
1196+ addFlavorForUnencodedNative(nat, flavors[i]);
1197+ }
1198+ disabledMappingGenerationKeys.add(nat);
1199+ // Clear the cache to handle the case of empty flavors.
1200+ getFlavorsForNativeCache.remove(nat);
1201+ getFlavorsForNativeCache.remove(null);
1202+ }
1203+
1204+ /**
1205+ * Encodes a MIME type for use as a <code>String</code> native. The format
1206+ * of an encoded representation of a MIME type is implementation-dependent.
1207+ * The only restrictions are:
1208+ * <ul>
1209+ * <li>The encoded representation is <code>null</code> if and only if the
1210+ * MIME type <code>String</code> is <code>null</code>.</li>
1211+ * <li>The encoded representations for two non-<code>null</code> MIME type
1212+ * <code>String</code>s are equal if and only if these <code>String</code>s
1213+ * are equal according to <code>String.equals(Object)</code>.</li>
1214+ * </ul>
1215+ * <p>
1216+ * Sun's reference implementation of this method returns the specified MIME
1217+ * type <code>String</code> prefixed with <code>JAVA_DATAFLAVOR:</code>.
1218+ *
1219+ * @param mimeType the MIME type to encode
1220+ * @return the encoded <code>String</code>, or <code>null</code> if
1221+ * mimeType is <code>null</code>
1222+ */
1223+ public static String encodeJavaMIMEType(String mimeType) {
1224+ return (mimeType != null)
1225+ ? JavaMIME + mimeType
1226+ : null;
1227+ }
1228+
1229+ /**
1230+ * Encodes a <code>DataFlavor</code> for use as a <code>String</code>
1231+ * native. The format of an encoded <code>DataFlavor</code> is
1232+ * implementation-dependent. The only restrictions are:
1233+ * <ul>
1234+ * <li>The encoded representation is <code>null</code> if and only if the
1235+ * specified <code>DataFlavor</code> is <code>null</code> or its MIME type
1236+ * <code>String</code> is <code>null</code>.</li>
1237+ * <li>The encoded representations for two non-<code>null</code>
1238+ * <code>DataFlavor</code>s with non-<code>null</code> MIME type
1239+ * <code>String</code>s are equal if and only if the MIME type
1240+ * <code>String</code>s of these <code>DataFlavor</code>s are equal
1241+ * according to <code>String.equals(Object)</code>.</li>
1242+ * </ul>
1243+ * <p>
1244+ * Sun's reference implementation of this method returns the MIME type
1245+ * <code>String</code> of the specified <code>DataFlavor</code> prefixed
1246+ * with <code>JAVA_DATAFLAVOR:</code>.
1247+ *
1248+ * @param flav the <code>DataFlavor</code> to encode
1249+ * @return the encoded <code>String</code>, or <code>null</code> if
1250+ * flav is <code>null</code> or has a <code>null</code> MIME type
1251+ */
1252+ public static String encodeDataFlavor(DataFlavor flav) {
1253+ return (flav != null)
1254+ ? SystemFlavorMap.encodeJavaMIMEType(flav.getMimeType())
1255+ : null;
1256+ }
1257+
1258+ /**
1259+ * Returns whether the specified <code>String</code> is an encoded Java
1260+ * MIME type.
1261+ *
1262+ * @param str the <code>String</code> to test
1263+ * @return <code>true</code> if the <code>String</code> is encoded;
1264+ * <code>false</code> otherwise
1265+ */
1266+ public static boolean isJavaMIMEType(String str) {
1267+ return (str != null && str.startsWith(JavaMIME, 0));
1268+ }
1269+
1270+ /**
1271+ * Decodes a <code>String</code> native for use as a Java MIME type.
1272+ *
1273+ * @param nat the <code>String</code> to decode
1274+ * @return the decoded Java MIME type, or <code>null</code> if nat is not
1275+ * an encoded <code>String</code> native
1276+ */
1277+ public static String decodeJavaMIMEType(String nat) {
1278+ return (isJavaMIMEType(nat))
1279+ ? nat.substring(JavaMIME.length(), nat.length()).trim()
1280+ : null;
1281+ }
1282+
1283+ /**
1284+ * Decodes a <code>String</code> native for use as a
1285+ * <code>DataFlavor</code>.
1286+ *
1287+ * @param nat the <code>String</code> to decode
1288+ * @return the decoded <code>DataFlavor</code>, or <code>null</code> if
1289+ * nat is not an encoded <code>String</code> native
1290+ */
1291+ public static DataFlavor decodeDataFlavor(String nat)
1292+ throws ClassNotFoundException
1293+ {
1294+ String retval_str = SystemFlavorMap.decodeJavaMIMEType(nat);
1295+ return (retval_str != null)
1296+ ? new DataFlavor(retval_str)
1297+ : null;
1298+ }
1299+}
java/pkg/java/awt/datatransfer/Transferable.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/Transferable.java+73−0
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+import java.io.IOException;
29+
30+/**
31+ * Defines the interface for classes that can be used to provide data
32+ * for a transfer operation.
33+ * <p>
34+ * For information on using data transfer with Swing, see
35+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
36+ * How to Use Drag and Drop and Data Transfer</a>,
37+ * a section in <em>The Java Tutorial</em>, for more information.
38+ *
39+ * @author Amy Fowler
40+ */
41+
42+public interface Transferable {
43+
44+ /**
45+ * Returns an array of DataFlavor objects indicating the flavors the data
46+ * can be provided in. The array should be ordered according to preference
47+ * for providing the data (from most richly descriptive to least descriptive).
48+ * @return an array of data flavors in which this data can be transferred
49+ */
50+ public DataFlavor[] getTransferDataFlavors();
51+
52+ /**
53+ * Returns whether or not the specified data flavor is supported for
54+ * this object.
55+ * @param flavor the requested flavor for the data
56+ * @return boolean indicating whether or not the data flavor is supported
57+ */
58+ public boolean isDataFlavorSupported(DataFlavor flavor);
59+
60+ /**
61+ * Returns an object which represents the data to be transferred. The class
62+ * of the object returned is defined by the representation class of the flavor.
63+ *
64+ * @param flavor the requested flavor for the data
65+ * @see DataFlavor#getRepresentationClass
66+ * @exception IOException if the data is no longer available
67+ * in the requested flavor.
68+ * @exception UnsupportedFlavorException if the requested data flavor is
69+ * not supported.
70+ */
71+ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException;
72+
73+}
java/pkg/java/awt/datatransfer/UnsupportedFlavorException.class+0−0

Binary file not shown.

java/pkg/java/awt/datatransfer/UnsupportedFlavorException.java+50−0
@@ -0,0 +1,50 @@
1+/*
2+ * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.datatransfer;
27+
28+/**
29+ * Signals that the requested data is not supported in this flavor.
30+ * @see Transferable#getTransferData
31+ *
32+ * @author Amy Fowler
33+ */
34+public class UnsupportedFlavorException extends Exception {
35+
36+ /*
37+ * JDK 1.1 serialVersionUID
38+ */
39+ private static final long serialVersionUID = 5383814944251665601L;
40+
41+ /**
42+ * Constructs an UnsupportedFlavorException.
43+ *
44+ * @param flavor the flavor object which caused the exception. May
45+ * be <code>null</code>.
46+ */
47+ public UnsupportedFlavorException(DataFlavor flavor) {
48+ super((flavor != null) ? flavor.getHumanPresentableName() : null);
49+ }
50+}
java/pkg/java/awt/datatransfer/mkfile+21−0
@@ -0,0 +1,21 @@
1+<../../../../../mkconfig
2+
3+TARG=\
4+ Clipboard.dis\
5+ ClipboardOwner.dis\
6+ DataFlavor.dis\
7+ FlavorEvent.dis\
8+ FlavorListener.dis\
9+ FlavorMap.dis\
10+ FlavorTable.dis\
11+ MimeType.dis\
12+ MimeTypeParameterList.dis\
13+ MimeTypeParseException.dis\
14+ StringSelection.dis\
15+ SystemFlavorMap.dis\
16+ Transferable.dis\
17+ UnsupportedFlavorException.dis\
18+
19+DISBIN=$ROOT/java/dis/java/java/java/awt/datatransfer
20+
21+<$ROOT/mkfiles/mkjava
java/pkg/java/awt/datatransfer/package.html+63−0
@@ -0,0 +1,63 @@
1+<!--
2+ Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
3+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
5+ This code is free software; you can redistribute it and/or modify it
6+ under the terms of the GNU General Public License version 2 only, as
7+ published by the Free Software Foundation. Oracle designates this
8+ particular file as subject to the "Classpath" exception as provided
9+ by Oracle in the LICENSE file that accompanied this code.
10+
11+ This code is distributed in the hope that it will be useful, but WITHOUT
12+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ version 2 for more details (a copy is included in the LICENSE file that
15+ accompanied this code).
16+
17+ You should have received a copy of the GNU General Public License version
18+ 2 along with this work; if not, write to the Free Software Foundation,
19+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
21+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ or visit www.oracle.com if you need additional information or have any
23+ questions.
24+-->
25+
26+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
27+<html>
28+<body bgcolor="white">
29+
30+Provides interfaces and classes for transferring data
31+between and within applications. It defines the notion of a
32+"transferable" object, which is an object capable of being
33+transferred between or within applications. An object identifies
34+itself as being transferable by implementing the Transferable
35+interface.
36+<p>
37+It also provides a clipboard mechanism, which is an object that
38+temporarily holds a transferable object that can be transferred
39+between or within an application. The clipboard is typically used
40+for copy and paste operations. Although it is possible to create
41+a clipboard to use within an application, most applications will
42+use the system clipboard to ensure the data can be transferred
43+across applications running on the platform.
44+
45+<!--
46+<h2>Package Specification</h2>
47+
48+##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
49+<ul>
50+ <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
51+</ul>
52+
53+<h2>Related Documentation</h2>
54+
55+For overviews, tutorials, examples, guides, and tool documentation, please see:
56+<ul>
57+ <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
58+</ul>
59+-->
60+
61+@since JDK1.1
62+</body>
63+</html>