From d9ebc2b4c2c47e16b264648bee8dda5fc80d90ee Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Wed, 21 Oct 2015 18:58:19 +0300 Subject: [PATCH] 8136763: [macosx] java always returns only one value for "text/uri-list" dataflavor even if several files were copied Reviewed-by: alexsch, serb --- .../resources/flavormap.properties | 5 +- .../sun/lwawt/macosx/CDataTransferer.java | 72 +++++++++---------- .../MacOsXFileAndMultipleFileCopingTest.java} | 57 ++++++++++----- 3 files changed, 75 insertions(+), 59 deletions(-) rename jdk/test/java/awt/datatransfer/DataFlavor/{XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java => MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java} (85%) diff --git a/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties b/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties index 10d625fc494..370c7de21fb 100644 --- a/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties +++ b/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties @@ -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 diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java index ae1d4446c05..3f05185c091 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java @@ -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: - *
-     *     {@code
-     * 
-     * 
-     * 
-     *      
-     *          file:///path_to_file
-     *          
-     *      
-     * 
-     *     }
-     * 
- */ - private String extractURL(String xml) { - Pattern urlExtractorPattern = Pattern.compile("(.*)"); - 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; + } } diff --git a/jdk/test/java/awt/datatransfer/DataFlavor/XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java b/jdk/test/java/awt/datatransfer/DataFlavor/MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java similarity index 85% rename from jdk/test/java/awt/datatransfer/DataFlavor/XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java rename to jdk/test/java/awt/datatransfer/DataFlavor/MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java index 7e86b92e192..18b70121aab 100644 --- a/jdk/test/java/awt/datatransfer/DataFlavor/XJavaUrlDataFlavorTest/XJavaUrlDataFlavorTest.java +++ b/jdk/test/java/awt/datatransfer/DataFlavor/MacOsXFileAndMultipleFileCopingTest/MacOsXFileAndMultipleFileCopingTest.java @@ -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 \ No newline at end of file