8136763: [macosx] java always returns only one value for "text/uri-list" dataflavor even if several files were copied

Reviewed-by: alexsch, serb
This commit is contained in:
Mikhail Cherkasov 2015-10-21 18:58:19 +03:00
parent b96af1d249
commit d9ebc2b4c2
3 changed files with 75 additions and 59 deletions

View File

@ -72,6 +72,7 @@ JFIF=image/x-java-image;class=java.awt.Image
TIFF=image/x-java-image;class=java.awt.Image
RICH_TEXT=text/rtf
HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
URL=application/x-java-url;class=java.net.URL,\
text/uri-list;eoln="\r\n";terminators=1
URL=application/x-java-url;class=java.net.URL
FILE_NAME=text/uri-list;eoln="\r\n";terminators=1
URL=text/uri-list;eoln="\r\n";terminators=1
XPICT=image/x-pict;class=java.io.InputStream

View File

@ -1,3 +1,4 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -28,12 +29,13 @@ package sun.lwawt.macosx;
import java.awt.*;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.*;
import java.util.regex.*;
import java.awt.datatransfer.*;
import sun.awt.datatransfer.*;
@ -127,51 +129,33 @@ public class CDataTransferer extends DataTransferer {
long format, Transferable transferable) throws IOException {
if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) {
String charset = Charset.defaultCharset().name();
if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
try {
charset = new String((byte[]) transferable.getTransferData(javaTextEncodingFlavor), "UTF-8");
} catch (UnsupportedFlavorException cannotHappen) {
}
String[] strings = dragQueryFile(bytes);
if(strings == null || strings.length == 0) {
return null;
}
String xml = new String(bytes, charset);
// macosx pasteboard returns a property list that consists of one URL
// let's extract it.
return new URL(extractURL(xml));
}
if (format == CF_STRING) {
return new URL(strings[0]);
} else if(isUriListFlavor(flavor)) {
// dragQueryFile works fine with files and url,
// it parses and extracts values from property list.
// maxosx always returns property list for
// CF_URL and CF_FILE
String[] strings = dragQueryFile(bytes);
if(strings == null) {
return null;
}
bytes = String.join(System.getProperty("line.separator"),
strings).getBytes();
// now we extracted uri from xml, now we should treat it as
// regular string that allows to translate data to target represantation
// class by base method
format = CF_STRING;
} else if (format == CF_STRING) {
bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8");
}
return super.translateBytes(bytes, flavor, format, transferable);
}
/**
* Macosx pasteboard returns xml document that contains one URL, for exmple:
* <pre>
* {@code
* <?xml version=\"1.0\" encoding=\"UTF-8\"?>
* <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
* <plist version=\"1.0\">
* <array>
* <string>file:///path_to_file</string>
* <string></string>
* </array>
* </plist>
* }
* </pre>
*/
private String extractURL(String xml) {
Pattern urlExtractorPattern = Pattern.compile("<string>(.*)</string>");
Matcher matcher = urlExtractorPattern.matcher(xml);
if (matcher.find()) {
return matcher.group(1);
} else {
return null;
}
}
@Override
protected synchronized Long getFormatForNativeAsLong(String str) {
Long format = predefinedClipboardNameMap.get(str);
@ -247,6 +231,7 @@ public class CDataTransferer extends DataTransferer {
return nativeDragQueryFile(bytes);
}
@Override
protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
return CImage.getCreator().createImageFromPlatformImageBytes(bytes);
@ -271,7 +256,7 @@ public class CDataTransferer extends DataTransferer {
}
try {
DataFlavor df = new DataFlavor(nat);
if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
if (isUriListFlavor(df)) {
return true;
}
} catch (Exception e) {
@ -279,4 +264,11 @@ public class CDataTransferer extends DataTransferer {
}
return false;
}
private boolean isUriListFlavor(DataFlavor df) {
if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
return true;
}
return false;
}
}

View File

@ -23,10 +23,9 @@
/*
@test
@bug 8081787
@summary MalformedURLException is thrown during reading data for application/x-java-url;class=java.net.URL flavor
@bug 8081787 8136763
@author Mikhail Cherkasov
@run main/manual XJavaUrlDataFlavorTest
@run main/manual MacOsXFileAndMultipleFileCopingTest
*/
import javax.swing.*;
@ -36,17 +35,24 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
public class XJavaUrlDataFlavorTest {
public class MacOsXFileAndMultipleFileCopingTest {
private static void init() {
String[] instructions =
{"Test for MacOS X only:",
"1. The aim is to test that java works fine with \"application/" +
"x-java-url;class=java.net.URL\"falvor.",
"x-java-url;class=java.net.URL\"falvor and support coping of multiple files",
"2. Open finder and select any file.",
"3. Press CMD+C or press \"Copy\" in context menu",
"4. Focus window with \"Test\" Button.",
"4. Focus window with \"Test URL\" Button.",
"5. If you see URL for selected file, then test PASSED,",
"otherwise test FAILED."
"otherwise test FAILED.",
"6. Open finder again and select several files.",
"7. Press CMD+C or press \"Copy\" in context menu",
"8. Focus window with \"Test multiple files coping\" Button.",
"9. If you see list of selected files, then test PASSED,",
"otherwise test FAILED.",
};
Sysout.createDialog();
@ -57,22 +63,36 @@ public class XJavaUrlDataFlavorTest {
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
frame.add(panel);
Button testButton = new Button("Test");
final TextField textField = new TextField(40);
testButton.addActionListener(new AbstractAction() {
Button testUrlBtn = new Button("Test URL");
final TextArea textArea = new TextArea(5, 80);
testUrlBtn.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard();
URL url = (URL)board.getData(new DataFlavor("application/x-java-url;class=java.net.URL"));
textField.setText(url.toString());
URL url = (URL) board.getData(new DataFlavor("application/x-java-url;class=java.net.URL"));
textArea.setText(url.toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
panel.add(testButton);
panel.add(textField);
panel.add(testUrlBtn);
Button testUriList = new Button("Test multiple files coping");
testUriList.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard();
String files = (String) board.getData(new DataFlavor("text/uri-list;class=java.lang.String"));
textArea.setText(files);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
panel.add(testUriList);
panel.add(textArea);
frame.setBounds(200, 200, 400, 400);
frame.setVisible(true);
@ -100,6 +120,9 @@ public class XJavaUrlDataFlavorTest {
private static int sleepTime = 300000;
public static void main(String args[]) throws InterruptedException {
if (!System.getProperty("os.name").startsWith("Mac")) {
return;
}
mainThread = Thread.currentThread();
try {
init();
@ -336,10 +359,10 @@ class TestDialog extends Dialog implements ActionListener {
//ManualMainTest
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "pass") {
XJavaUrlDataFlavorTest.pass();
MacOsXFileAndMultipleFileCopingTest.pass();
} else {
XJavaUrlDataFlavorTest.fail();
MacOsXFileAndMultipleFileCopingTest.fail();
}
}
}// TestDialog class
}// TestDialog class