4899516: Transferable has no DataFlavors when dragging from Gnome window to Swing
Reviewed-by: uta, dav
Contributed-by: Damjan Jovanovic <damjan.jov@gmail.com>
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Tue Nov 24 18:46:17 2009 +0300
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Nov 25 21:27:06 2009 +0300
@@ -51,6 +51,9 @@
import java.io.SequenceInputStream;
import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
@@ -203,8 +206,6 @@
private static final Map nativeEOLNs =
Collections.synchronizedMap(new HashMap());
- private static final byte [] UNICODE_NULL_TERMINATOR = new byte [] {0,0};
-
/**
* The number of terminating NUL bytes for the Set of textNatives.
*/
@@ -628,6 +629,14 @@
public abstract boolean isImageFormat(long format);
/**
+ * Determines whether the format is a URI list we can convert to
+ * a DataFlavor.javaFileListFlavor.
+ */
+ protected boolean isURIListFormat(long format) {
+ return false;
+ }
+
+ /**
* Returns a Map whose keys are all of the possible formats into which the
* Transferable's transfer data flavors can be translated. The value of
* each key is the DataFlavor in which the Transferable's data should be
@@ -1299,58 +1308,55 @@
if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
throw new IOException("data translation failed");
}
+
final List list = (List)obj;
- final ArrayList <String> fileList = new ArrayList<String>();
-
final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
- int nFiles = 0;
- for (int i = 0; i < list.size(); i++) {
- Object o = list.get(i);
- if (o instanceof File || o instanceof String) {
- nFiles++;
+ final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
+
+ bos = convertFileListToBytes(fileList);
+
+
+ // Target data is a URI list. Source data must be a
+ // java.util.List which contains java.io.File or String instances.
+ } else if (isURIListFormat(format)) {
+ if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
+ throw new IOException("data translation failed");
+ }
+ String nat = getNativeForFormat(format);
+ String targetCharset = null;
+ if (nat != null) {
+ try {
+ targetCharset = new DataFlavor(nat).getParameter("charset");
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException(cnfe);
}
}
-
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws IOException {
- for (Object fileObject : list)
- {
- File file = castToFile(fileObject);
- if (null == System.getSecurityManager() ||
- !(isFileInWebstartedCache(file) ||
- isForbiddenToRead(file, userProtectionDomain)))
- {
- fileList.add(file.getCanonicalPath());
- }
- }
- return null;
- }
- });
- } catch (PrivilegedActionException pae) {
- throw new IOException(pae.getMessage());
+ if (targetCharset == null) {
+ targetCharset = "UTF-8";
}
-
- if(fileList.isEmpty()) {
- //store empty unicode string (null terminator)
- bos.write(UNICODE_NULL_TERMINATOR);
- } else {
- for (int i = 0; i < fileList.size(); i++) {
- byte[] bytes = fileList.get(i).getBytes(getDefaultUnicodeEncoding());
- //store unicode string with null terminator
- bos.write(bytes, 0, bytes.length);
- bos.write(UNICODE_NULL_TERMINATOR);
- }
+ final List list = (List)obj;
+ final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
+ final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
+ final ArrayList<String> uriList = new ArrayList<String>(fileList.size());
+ for (String fileObject : fileList) {
+ final URI uri = new File(fileObject).toURI();
+ // Some implementations are fussy about the number of slashes (file:///path/to/file is best)
+ try {
+ uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString());
+ } catch (URISyntaxException uriSyntaxException) {
+ throw new IOException(uriSyntaxException);
+ }
+ }
+
+ byte[] eoln = "\r\n".getBytes(targetCharset);
+ for (int i = 0; i < uriList.size(); i++) {
+ byte[] bytes = uriList.get(i).getBytes(targetCharset);
+ bos.write(bytes, 0, bytes.length);
+ bos.write(eoln, 0, eoln.length);
}
- // According to MSDN the byte array have to be double NULL-terminated.
- // The array contains Unicode characters, so each NULL-terminator is
- // a pair of bytes
-
- bos.write(UNICODE_NULL_TERMINATOR);
-
// Source data is an InputStream. For arbitrary flavors, just grab the
// bytes and dump them into a byte array. For text flavors, decode back
// to a String and recur to reencode according to the requested format.
@@ -1398,6 +1404,8 @@
return ret;
}
+ protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException;
+
private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str)
throws IOException
{
@@ -1465,6 +1473,33 @@
return true;
}
+ private ArrayList<String> castToFiles(final List files,
+ final ProtectionDomain userProtectionDomain) throws IOException
+ {
+ final ArrayList<String> fileList = new ArrayList<String>();
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws IOException {
+ for (Object fileObject : files)
+ {
+ File file = castToFile(fileObject);
+ if (file != null &&
+ (null == System.getSecurityManager() ||
+ !(isFileInWebstartedCache(file) ||
+ isForbiddenToRead(file, userProtectionDomain))))
+ {
+ fileList.add(file.getCanonicalPath());
+ }
+ }
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ throw new IOException(pae.getMessage());
+ }
+ return fileList;
+ }
+
// It is important do not use user's successors
// of File class.
private File castToFile(Object fileObject) throws IOException {
@@ -1473,6 +1508,8 @@
filePath = ((File)fileObject).getCanonicalPath();
} else if (fileObject instanceof String) {
filePath = (String) fileObject;
+ } else {
+ return null;
}
return new File(filePath);
}
@@ -1578,6 +1615,29 @@
// Turn the list of Files into a List and return
return Arrays.asList(files);
+ // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
+ // where possible.
+ } else if (isURIListFormat(format) && DataFlavor.javaFileListFlavor.equals(flavor)) {
+ try {
+ URI uris[] = dragQueryURIs(str, bytes, format, localeTransferable);
+ if (uris == null) {
+ return null;
+ }
+ ArrayList files = new ArrayList();
+ for (URI uri : uris) {
+ try {
+ files.add(new File(uri));
+ } catch (IllegalArgumentException illegalArg) {
+ // When converting from URIs to less generic files,
+ // common practice (Wine, SWT) seems to be to
+ // silently drop the URIs that aren't local files.
+ }
+ }
+ return files;
+ } finally {
+ str.close();
+ }
+
// Target data is a String. Strip terminating NUL bytes. Decode bytes
// into characters. Search-and-replace EOLN.
} else if (String.class.equals(flavor.getRepresentationClass()) &&
@@ -1963,6 +2023,19 @@
protected abstract String[] dragQueryFile(byte[] bytes);
/**
+ * Decodes URIs from either a byte array or a stream.
+ */
+ protected URI[] dragQueryURIs(InputStream stream,
+ byte[] bytes,
+ long format,
+ Transferable localeTransferable)
+ throws IOException
+ {
+ throw new IOException(
+ new UnsupportedOperationException("not implemented on this platform"));
+ }
+
+ /**
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
*/
--- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Tue Nov 24 18:46:17 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Nov 25 21:27:06 2009 +0300
@@ -28,14 +28,21 @@
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
+import java.io.BufferedReader;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -48,6 +55,8 @@
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
+import java.io.ByteArrayOutputStream;
+
/**
* Platform-specific support for the data transfer subsystem.
*/
@@ -108,6 +117,22 @@
return super.getCharsetForTextFormat(lFormat);
}
+ protected boolean isURIListFormat(long format) {
+ String nat = getNativeForFormat(format);
+ if (nat == null) {
+ return false;
+ }
+ try {
+ DataFlavor df = new DataFlavor(nat);
+ if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
+ return true;
+ }
+ } catch (Exception e) {
+ // Not a MIME format.
+ }
+ return false;
+ }
+
public boolean isFileFormat(long format) {
return format == FILE_NAME_ATOM.getAtom() ||
format == DT_NET_FILE_ATOM.getAtom();
@@ -170,6 +195,19 @@
}
}
+ protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
+ throws IOException
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ for (int i = 0; i < fileList.size(); i++)
+ {
+ byte[] bytes = fileList.get(i).getBytes();
+ if (i != 0) bos.write(0);
+ bos.write(bytes, 0, bytes.length);
+ }
+ return bos;
+ }
+
/**
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
@@ -215,6 +253,52 @@
}
}
+ protected URI[] dragQueryURIs(InputStream stream,
+ byte[] bytes,
+ long format,
+ Transferable localeTransferable)
+ throws IOException {
+
+ String charset = null;
+ if (localeTransferable != null &&
+ isLocaleDependentTextFormat(format) &&
+ localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
+ try {
+ charset = new String(
+ (byte[])localeTransferable.getTransferData(javaTextEncodingFlavor),
+ "UTF-8"
+ );
+ } catch (UnsupportedFlavorException cannotHappen) {
+ }
+ } else {
+ charset = getCharsetForTextFormat(format);
+ }
+ if (charset == null) {
+ // Only happens when we have a custom text type.
+ charset = getDefaultTextCharset();
+ }
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(stream, charset));
+ String line;
+ ArrayList<URI> uriList = new ArrayList<URI>();
+ URI uri;
+ while ((line = reader.readLine()) != null) {
+ try {
+ uri = new URI(line);
+ } catch (URISyntaxException uriSyntaxException) {
+ throw new IOException(uriSyntaxException);
+ }
+ uriList.add(uri);
+ }
+ return uriList.toArray(new URI[uriList.size()]);
+ } finally {
+ if (reader != null)
+ reader.close();
+ }
+ }
+
/**
* Returns true if and only if the name of the specified format Atom
* constitutes a valid MIME type with the specified primary type.
--- a/jdk/src/solaris/lib/flavormap.properties Tue Nov 24 18:46:17 2009 +0300
+++ b/jdk/src/solaris/lib/flavormap.properties Wed Nov 25 21:27:06 2009 +0300
@@ -73,5 +73,6 @@
TEXT=text/plain;eoln="\n";terminators=0
STRING=text/plain;charset=iso8859-1;eoln="\n";terminators=0
FILE_NAME=application/x-java-file-list;class=java.util.List
+text/uri-list=application/x-java-file-list;class=java.util.List
PNG=image/x-java-image;class=java.awt.Image
JFIF=image/x-java-image;class=java.awt.Image
--- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Tue Nov 24 18:46:17 2009 +0300
+++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Wed Nov 25 21:27:06 2009 +0300
@@ -72,6 +72,10 @@
import sun.awt.image.ImageRepresentation;
import sun.awt.image.ToolkitImage;
+import java.util.ArrayList;
+
+import java.io.ByteArrayOutputStream;
+
/**
* Platform-specific support for the data transfer subsystem.
*
@@ -342,6 +346,33 @@
return imageDataToPlatformImageBytes(imageData, width, height, format);
}
+ private static final byte [] UNICODE_NULL_TERMINATOR = new byte [] {0,0};
+
+ protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
+ throws IOException
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ if(fileList.isEmpty()) {
+ //store empty unicode string (null terminator)
+ bos.write(UNICODE_NULL_TERMINATOR);
+ } else {
+ for (int i = 0; i < fileList.size(); i++) {
+ byte[] bytes = fileList.get(i).getBytes(getDefaultUnicodeEncoding());
+ //store unicode string with null terminator
+ bos.write(bytes, 0, bytes.length);
+ bos.write(UNICODE_NULL_TERMINATOR);
+ }
+ }
+
+ // According to MSDN the byte array have to be double NULL-terminated.
+ // The array contains Unicode characters, so each NULL-terminator is
+ // a pair of bytes
+
+ bos.write(UNICODE_NULL_TERMINATOR);
+ return bos;
+ }
+
/**
* Returns a byte array which contains data special for the given format
* and for the given image data.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/FileListTransferable.java Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.File;
+import java.io.IOException;
+
+class FileListTransferable implements Transferable {
+
+ final private DataFlavor[] supportedFlavors =
+ {DataFlavor.javaFileListFlavor};
+
+ private java.util.List<File> list;
+
+ public FileListTransferable(java.util.List<File> list) {
+ this.list = list;
+ }
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return supportedFlavors;
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ for (DataFlavor df:supportedFlavors) {
+ if (df.equals(flavor)) return true;
+ }
+ return false;
+ }
+
+ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+ if (flavor.equals(DataFlavor.javaFileListFlavor)) {
+ return list;
+ }
+ throw new UnsupportedFlavorException(flavor);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/InterprocessMessages.java Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+public interface InterprocessMessages {
+ final static int EXECUTION_IS_SUCCESSFULL = 0;
+ final static int WRONG_FILES_NUMBER_ON_TARGET = 212;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/SourceFileListFrame.java Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+import test.java.awt.regtesthelpers.Util;
+
+import java.awt.*;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.io.File;
+import java.util.Arrays;
+
+
+class SourceFileListFrame extends Frame implements DragGestureListener {
+
+ private final static int SOURCE_POINT_SHIFT = 3;
+
+ private List list = new List(URIListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST);
+ private File[] files;
+
+ SourceFileListFrame() {
+ super("Source File List Frame");
+ extractFilesFromTheWorkingDirectory();
+ initList();
+ initGUI();
+ new DragSource().createDefaultDragGestureRecognizer(list,
+ DnDConstants.ACTION_COPY,this);
+ }
+
+ private void extractFilesFromTheWorkingDirectory() {
+ files = new File(System.getProperty("java.home", "")).listFiles();
+ }
+
+ private void initList() {
+ for (File currFile:files) {
+ list.add(currFile.getName());
+ }
+ }
+
+ private void initGUI() {
+ this.addWindowListener(Util.getClosingWindowAdapter());
+ this.setLocation(300,250);
+ this.add(new Panel().add(list));
+ this.pack();
+ this.setVisible(true);
+ }
+
+ int getNextLocationX() {
+ return getX()+getWidth();
+ }
+
+ int getNextLocationY() {
+ return getY();
+ }
+
+ int getDragSourcePointX() {
+ return (int)list.getLocationOnScreen().getX()+(list.getWidth()/2);
+ }
+
+ int getDragSourcePointY() {
+ return (int)list.getLocationOnScreen().getY()+ SOURCE_POINT_SHIFT;
+ }
+
+ int getSourceFilesNumber() {
+ return files.length;
+ }
+
+ public void dragGestureRecognized(DragGestureEvent dge) {
+ String [] filesAsStringArray = list.getItems();
+ File [] files = new File[filesAsStringArray.length];
+ for (int fileNumber=0; fileNumber<filesAsStringArray.length ; fileNumber++ ) {
+ files[fileNumber]=new File(filesAsStringArray[fileNumber]);
+ }
+ dge.startDrag(null, new FileListTransferable(Arrays.asList(files)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/TargetFileListFrame.java Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+import test.java.awt.regtesthelpers.Util;
+
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.dnd.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+class TargetFileListFrame extends Frame implements DropTargetListener {
+
+ private List list = new List(URIListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST);
+ private int expectationTransferredFilesNumber;
+ private DataFlavor dropFlavor;
+
+ TargetFileListFrame(Point location, int expectationTransferredFilesNumber) {
+ try {
+ dropFlavor = new DataFlavor("text/uri-list;class=java.io.Reader");
+ } catch (Exception ex) {
+ }
+ this.expectationTransferredFilesNumber = expectationTransferredFilesNumber;
+ initGUI(location);
+ setDropTarget(new DropTarget(list, DnDConstants.ACTION_COPY,
+ this));
+ }
+
+ private void initGUI(Point location) {
+ this.setLocation(location);
+ this.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ TargetFileListFrame.this.dispose();
+ }
+ });
+ this.add(new Panel().add(list));
+ this.pack();
+ this.setVisible(true);
+ }
+
+ public void dragEnter(DropTargetDragEvent dtde) {
+ if (dtde.getCurrentDataFlavorsAsList().contains(dropFlavor)) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+ }
+
+ public void dragOver(DropTargetDragEvent dtde) {
+ if (dtde.getCurrentDataFlavorsAsList().contains(dropFlavor)) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+ }
+
+ public void dropActionChanged(DropTargetDragEvent dtde) {
+ if (dtde.getCurrentDataFlavorsAsList().contains(dropFlavor)) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+ }
+
+ public void dragExit(DropTargetEvent dte) {}
+
+ public void drop(DropTargetDropEvent dtde) {
+ list.removeAll();
+ dtde.acceptDrop(DnDConstants.ACTION_COPY);
+ java.util.List<File> fileList = extractListOfFiles(dtde);
+ for (File file:fileList) {
+ list.add(file.getName());
+ }
+
+ if (fileList.size() != expectationTransferredFilesNumber)
+ {
+ System.err.println("ERROR: Expected file number:"
+ + expectationTransferredFilesNumber
+ + "; Received file number: "
+ + fileList.size());
+ TargetFileListFrame.this.dispose();
+ System.exit(InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET);
+ }
+
+ TargetFileListFrame.this.dispose();
+
+ }
+
+ private java.util.List<File> extractListOfFiles(DropTargetDropEvent dtde) {
+ BufferedReader reader = null;
+ ArrayList<File> files = new ArrayList<File>();
+ try {
+ reader = new BufferedReader((Reader)dtde.getTransferable().
+ getTransferData(dropFlavor));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ files.add(new File(new URI(line)));
+ }
+ } catch (UnsupportedFlavorException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ return files;
+ }
+
+ Point getDropTargetPoint() {
+ return new Point((int)list.getLocationOnScreen().getX()+(list.getWidth()/2),
+ (int)list.getLocationOnScreen().getY()+(list.getHeight()/2));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,25 @@
+<html>
+<!--
+ @test
+ @bug 4899516
+ @summary Transferable has no DataFlavors when dragging from Gnome window to Swing
+ @author : area=dnd
+ @library ../../regtesthelpers
+ @library ../../regtesthelpers/process
+ @build Util
+ @build ProcessResults ProcessCommunicator
+ @run applet/othervm URIListBetweenJVMsTest.html
+
+-->
+<head>
+<title> DnD of URI-List across JVM </title>
+</head>
+<body>
+
+<h1>URIListBetweenJVMsTest<br>Bug ID: 4899516</h1>
+
+<p> This is an AUTOMATIC test, simply wait for completion </p>
+
+<APPLET CODE="URIListBetweenJVMsTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java Wed Nov 25 21:27:06 2009 +0300
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2009 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.
+ *
+ * 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.
+ */
+
+/*
+ test
+ @bug 4899516
+ @summary Transferable has no DataFlavors when dragging from Gnome window to Swing
+ @author : area=dnd
+ @run applet URIListBetweenJVMsTest.html
+*/
+
+/**
+ * URIListBetweenJVMsTest.java
+ *
+ * summary: Transferable has no DataFlavors when dragging from Gnome window to Swing
+ */
+
+import static java.lang.Thread.sleep;
+
+import test.java.awt.regtesthelpers.process.ProcessCommunicator;
+import test.java.awt.regtesthelpers.process.ProcessResults;
+import test.java.awt.regtesthelpers.Util;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.io.*;
+
+public class URIListBetweenJVMsTest extends Applet {
+
+ // information related to the test in common
+ static int VISIBLE_RAWS_IN_LIST=15;
+
+ public void init() {
+ setLayout(new BorderLayout());
+
+ }//End init()
+
+ public void start() {
+
+ String toolkit = Toolkit.getDefaultToolkit().getClass().getName();
+ if (toolkit.equals("sun.awt.windows.WToolkit")){
+ System.out.println("This test is not for the Windows platform. Passed.");
+ return;
+ } else {
+ System.out.println("Toolkit = " + toolkit);
+ }
+
+ SourceFileListFrame sourceFrame = new SourceFileListFrame();
+
+ Util.waitForIdle(null);
+
+ String [] args = new String [] {
+ String.valueOf(sourceFrame.getNextLocationX()),
+ String.valueOf(sourceFrame.getNextLocationY()),
+ String.valueOf(sourceFrame.getDragSourcePointX()),
+ String.valueOf(sourceFrame.getDragSourcePointY()),
+ String.valueOf(sourceFrame.getSourceFilesNumber())
+ };
+
+ String classpath = System.getProperty("java.class.path");
+ ProcessResults processResults =
+ ProcessCommunicator.executeChildProcess(this.getClass(), classpath, args);
+
+ verifyTestResults(processResults);
+
+ }// start()
+
+ private static void verifyTestResults(ProcessResults processResults) {
+ if ( InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET ==
+ processResults.getExitValue())
+ {
+ processResults.printProcessErrorOutput(System.err);
+ throw new RuntimeException("TEST IS FAILED: Target has recieved" +
+ " wrong number of files.");
+ }
+ processResults.verifyStdErr(System.err);
+ processResults.verifyProcessExitValue(System.err);
+ processResults.printProcessStandartOutput(System.out);
+ }
+
+ //We cannot make an instance of the applet without the default constructor
+ public URIListBetweenJVMsTest () {
+ super();
+ }
+
+ //We need in this constructor to pass frame position between JVMs
+ public URIListBetweenJVMsTest (Point targetFrameLocation, Point dragSourcePoint,
+ int transferredFilesNumber)
+ throws InterruptedException
+ {
+ TargetFileListFrame targetFrame = new TargetFileListFrame(targetFrameLocation,
+ transferredFilesNumber);
+
+ Util.waitForIdle(null);
+
+ final Robot robot = Util.createRobot();
+
+ robot.mouseMove((int)dragSourcePoint.getX(),(int)dragSourcePoint.getY());
+ sleep(100);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ sleep(100);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ sleep(100);
+
+ Util.drag(robot, dragSourcePoint, targetFrame.getDropTargetPoint(),
+ InputEvent.BUTTON1_MASK);
+
+ }
+
+ enum InterprocessArguments {
+ TARGET_FRAME_X_POSITION_ARGUMENT,
+ TARGET_FRAME_Y_POSITION_ARGUMENT,
+ DRAG_SOURCE_POINT_X_ARGUMENT,
+ DRAG_SOURCE_POINT_Y_ARGUMENT,
+ FILES_IN_THE_LIST_NUMBER_ARGUMENT;
+
+ int extract (String [] args) {
+ return Integer.parseInt(args[this.ordinal()]);
+ }
+ }
+
+ public static void main (String [] args) {
+ Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extract(args),
+ InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extract(args));
+ Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extract(args),
+ InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extract(args));
+ int transferredFilesNumber = InterprocessArguments.FILES_IN_THE_LIST_NUMBER_ARGUMENT.extract(args);
+
+ try {
+ new URIListBetweenJVMsTest(targetFrameLocation, dragSourcePoint, transferredFilesNumber);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+}// class URIListBetweenJVMsTest
--- a/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java Tue Nov 24 18:46:17 2009 +0300
+++ b/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java Wed Nov 25 21:27:06 2009 +0300
@@ -146,7 +146,15 @@
final String classPathArguments, final String [] args)
{
StringBuilder commandBuilder = new StringBuilder();
- commandBuilder.append(javaPath).append(classPathArguments).append(classToExecute.getName());
+ commandBuilder.append(javaPath).append(" ");
+ commandBuilder.append("-cp ").append(System.getProperty("test.classes", ".")).append(File.pathSeparatorChar);
+
+ if (classPathArguments.trim().length() > 0) {
+ commandBuilder.append(classPathArguments).append(" ");
+ }
+
+ commandBuilder.append(" ");
+ commandBuilder.append(classToExecute.getName());
for (String argument:args) {
commandBuilder.append(" ").append(argument);
}