提交 1b72cf45 编写于 作者: P pchelko

8029565: java.awt.dnd.InvalidDnDOperationException: data translation failed on file drop

Reviewed-by: anthony, serb
上级 eefca52d
......@@ -1598,6 +1598,30 @@ search:
// Turn the list of Files into a List and return
theObject = Arrays.asList(files);
// Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
// where possible.
} else if (isURIListFormat(format)
&& DataFlavor.javaFileListFlavor.equals(flavor)) {
try (ByteArrayInputStream str = new ByteArrayInputStream(bytes)) {
URI uris[] = dragQueryURIs(str, format, localeTransferable);
if (uris == null) {
return null;
}
List<File> 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.
}
}
theObject = files;
}
// Target data is a String. Strip terminating NUL bytes. Decode bytes
// into characters. Search-and-replace EOLN.
} else if (String.class.equals(flavor.getRepresentationClass()) &&
......
......@@ -242,6 +242,7 @@ public class XDataTransferer extends DataTransferer {
}
}
@Override
protected String[] dragQueryFile(byte[] bytes) {
XToolkit.awtLock();
try {
......@@ -252,8 +253,8 @@ public class XDataTransferer extends DataTransferer {
}
}
@Override
protected URI[] dragQueryURIs(InputStream stream,
byte[] bytes,
long format,
Transferable localeTransferable)
throws IOException {
......
/*
* Copyright (c) 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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;
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import test.java.awt.regtesthelpers.Util;
import java.awt.*;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.io.File;
import java.net.URI;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class SourceFileListFrame extends Frame implements DragGestureListener {
private final static int SOURCE_POINT_SHIFT = 3;
private List list = new List(URIListToFileListBetweenJVMsTest.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) {
java.util.List<URI> uriList = Stream.of(list.getItems())
.map(File::new)
.map(File::toURI)
.collect(Collectors.toList());
dge.startDrag(null, new URIListTransferable(uriList));
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
class TargetFileListFrame extends Frame implements DropTargetListener {
private List list = new List(URIListToFileListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST);
private int expectationTransferredFilesNumber;
TargetFileListFrame(Point location, int expectationTransferredFilesNumber) {
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(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
}
}
public void dragOver(DropTargetDragEvent dtde) {
if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
}
}
public void dropActionChanged(DropTargetDragEvent dtde) {
if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) {
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) {
java.util.List<File> fileList = null;
try {
fileList = (java.util.List<File>)dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
return fileList;
}
Point getDropTargetPoint() {
return new Point((int)list.getLocationOnScreen().getX()+(list.getWidth()/2),
(int)list.getLocationOnScreen().getY()+(list.getHeight()/2));
}
}
<!--
Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<html>
<!--
@test
@bug 8029565
@summary Conversion of a URI list to File list fails
@author Petr Pchelko <petr.pchelko@oracle.com>
@library ../../regtesthelpers
@library ../../regtesthelpers/process
@build Util
@build ProcessResults ProcessCommunicator
@run applet/othervm URIListToFileListBetweenJVMsTest.html
-->
<head>
<title> DnD of File-List across JVM </title>
</head>
<body>
<h1>URIListToFileListBetweenJVMsTest<br>Bug ID: 5079469</h1>
<p> This is an AUTOMATIC test, simply wait for completion </p>
<APPLET CODE="URIListToFileListBetweenJVMsTest.class" WIDTH=200 HEIGHT=200></APPLET>
</body>
</html>
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
test
@bug 8029565
@summary Conversion of a URI list to File list fails
@author Petr Pchelko <petr.pchelko@oracle.com>
@library ../../regtesthelpers
@library ../../regtesthelpers/process
@build Util
@build ProcessResults ProcessCommunicator
@run applet/othervm URIListToFileListBetweenJVMsTest.html
*/
/**
* URIListToFileListBetweenJVMsTest.java
*
* summary: DnD of File-List across JVM adds two empty items to the list
*/
import test.java.awt.regtesthelpers.Util;
import test.java.awt.regtesthelpers.process.ProcessCommunicator;
import test.java.awt.regtesthelpers.process.ProcessResults;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.InputEvent;
import static java.lang.Thread.sleep;
public class URIListToFileListBetweenJVMsTest extends Applet {
// information related to the test in common
static int VISIBLE_RAWS_IN_LIST=15;
public void init() {
setLayout(new BorderLayout());
}
public void start() {
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())
};
ProcessResults processResults = ProcessCommunicator.executeChildProcess(this.getClass(), args);
verifyTestResults(processResults);
}
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 URIListToFileListBetweenJVMsTest() {
super();
}
//We need in this constructor to pass frame position between JVMs
public URIListToFileListBetweenJVMsTest(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) throws Exception {
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);
new URIListToFileListBetweenJVMsTest(targetFrameLocation, dragSourcePoint, transferredFilesNumber);
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.net.URI;
import java.util.List;
class URIListTransferable implements Transferable {
private final DataFlavor supportedFlavor;
private List<URI> list;
public URIListTransferable(List<URI> list) {
try {
this.supportedFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
} catch (ClassNotFoundException e) {
throw new RuntimeException("FAILED: could not create a DataFlavor");
}
this.list = list;
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { supportedFlavor };
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return supportedFlavor.equals(flavor);
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (supportedFlavor.equals(flavor)) {
return list.stream()
.map(URI::toASCIIString)
.collect(StringBuilder::new,
(builder, uri)-> { builder.append(uri).append("\r\n"); },
StringBuilder::append).toString();
}
throw new UnsupportedFlavorException(flavor);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册