--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.awt.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * Reads all of the data from the system Clipboard which the data transfer
+ * subsystem knows how to translate. This includes all text data, File Lists,
+ * Serializable objects, Remote objects, and properly registered, arbitrary
+ * data as InputStreams. The data is stored in byte format until requested
+ * by client code. At that point, the data is converted, if necessary, into
+ * the proper format to deliver to the application.
+ *
+ * This hybrid pre-fetch/delayed-rendering approach allows us to circumvent
+ * the API restriction that client code cannot lock the Clipboard to discover
+ * its formats before requesting data in a particular format, while avoiding
+ * the overhead of fully rendering all data ahead of time.
+ *
+ * @author David Mendenhall
+ * @author Danila Sinopalnikov
+ *
+ * @since 1.4 (appeared in modified form as FullyRenderedTransferable in 1.3.1)
+ */
+public class ClipboardTransferable implements Transferable {
+ private final HashMap flavorsToData = new HashMap();
+ private DataFlavor[] flavors = new DataFlavor[0];
+
+ private final class DataFactory {
+ final long format;
+ final byte[] data;
+ DataFactory(long format, byte[] data) {
+ this.format = format;
+ this.data = data;
+ }
+
+ public Object getTransferData(DataFlavor flavor) throws IOException {
+ return DataTransferer.getInstance().
+ translateBytes(data, flavor, format,
+ ClipboardTransferable.this);
+ }
+ }
+
+ public ClipboardTransferable(SunClipboard clipboard) {
+
+ clipboard.openClipboard(null);
+
+ try {
+ long[] formats = clipboard.getClipboardFormats();
+
+ if (formats != null && formats.length > 0) {
+ // Since the SystemFlavorMap will specify many DataFlavors
+ // which map to the same format, we should cache data as we
+ // read it.
+ HashMap cached_data = new HashMap(formats.length, 1.0f);
+
+ Map flavorsForFormats = DataTransferer.getInstance().
+ getFlavorsForFormats(formats, SunClipboard.flavorMap);
+ for (Iterator iter = flavorsForFormats.keySet().iterator();
+ iter.hasNext(); )
+ {
+ DataFlavor flavor = (DataFlavor)iter.next();
+ Long lFormat = (Long)flavorsForFormats.get(flavor);
+
+ fetchOneFlavor(clipboard, flavor, lFormat, cached_data);
+ }
+
+ flavors = DataTransferer.getInstance().
+ setToSortedDataFlavorArray(flavorsToData.keySet(),
+ flavorsForFormats);
+ }
+ } finally {
+ clipboard.closeClipboard();
+ }
+ }
+
+ private boolean fetchOneFlavor(SunClipboard clipboard, DataFlavor flavor,
+ Long lFormat, HashMap cached_data)
+ {
+ if (!flavorsToData.containsKey(flavor)) {
+ long format = lFormat.longValue();
+ Object data = null;
+
+ if (!cached_data.containsKey(lFormat)) {
+ try {
+ data = clipboard.getClipboardData(format);
+ } catch (IOException e) {
+ data = e;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ // Cache this data, even if it's null, so we don't have to go
+ // to native code again for this format.
+ cached_data.put(lFormat, data);
+ } else {
+ data = cached_data.get(lFormat);
+ }
+
+ // Casting IOException to byte array causes ClassCastException.
+ // We should handle IOException separately - do not wrap them into
+ // DataFactory and report failure.
+ if (data instanceof IOException) {
+ flavorsToData.put(flavor, data);
+ return false;
+ } else if (data != null) {
+ flavorsToData.put(flavor, new DataFactory(format,
+ (byte[])data));
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return (DataFlavor[])flavors.clone();
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return flavorsToData.containsKey(flavor);
+ }
+
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException
+ {
+ if (!isDataFlavorSupported(flavor)) {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ Object ret = flavorsToData.get(flavor);
+ if (ret instanceof IOException) {
+ // rethrow IOExceptions generated while fetching data
+ throw (IOException)ret;
+ } else if (ret instanceof DataFactory) {
+ // Now we can render the data
+ DataFactory factory = (DataFactory)ret;
+ ret = factory.getTransferData(flavor);
+ }
+ return ret;
+ }
+
+}