--- old/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java 2016-08-15 00:56:34.000000000 +0530 +++ new/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java 2016-08-15 00:56:34.000000000 +0530 @@ -36,6 +36,7 @@ import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.*; +import java.util.regex.*; import java.awt.datatransfer.*; import sun.awt.datatransfer.*; @@ -129,12 +130,21 @@ long format, Transferable transferable) throws IOException { if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) { - String[] strings = dragQueryFile(bytes); - if(strings == null || strings.length == 0) { - return null; + String charset = Charset.defaultCharset().name(); + if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) { + try { + charset = new String((byte[]) transferable.getTransferData(javaTextEncodingFlavor), "UTF-8"); + } catch (UnsupportedFlavorException cannotHappen) { + } } - return new URL(strings[0]); - } else if(isUriListFlavor(flavor)) { + + 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(isUriListFlavor(flavor) && format == CF_FILE) { // dragQueryFile works fine with files and url, // it parses and extracts values from property list. // maxosx always returns property list for @@ -151,11 +161,21 @@ 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); } + 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); --- /dev/null 2016-08-15 00:56:35.000000000 +0530 +++ new/test/java/awt/dnd/URLDragTest/DragLinkFromBrowser.java 2016-08-15 00:56:35.000000000 +0530 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2016, 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 8156099 + @summary Drag and drop of link from web browser, DataFlavor types + application/x-java-url and text/uri-list, getTransferData returns null + @run main/manual DragLinkFromBrowser + */ + +import java.awt.Frame; +import java.awt.Button; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.TransferHandler; +import javax.swing.SwingUtilities; +import javax.swing.JOptionPane; + +public class DragLinkFromBrowser implements ActionListener { + + private static GridBagLayout layout; + private static Panel mainControlPanel; + private static Panel resultButtonPanel; + private static TextArea instructionTextArea; + private static Button passButton; + private static Button failButton; + private static Frame mainFrame; + private static Thread mainThread = null; + private static volatile boolean testPassed = false; + private static volatile boolean isInterrupted = false; + private static volatile String failMessage; + private static final int testTimeOut = 300000; + private static JFrame urlFrame; + private static JPanel urlPanel; + + public static void dragLinkFromWebBrowser() { + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + + urlFrame = new JFrame(); + urlPanel = new JPanel(); + failMessage = "Dragging link from web browser Failed. " + + "getTransferData returns null"; + urlFrame.getContentPane().add(urlPanel); + urlPanel.setTransferHandler(new TransferHandler() { + @Override + public boolean canImport(final TransferSupport support) { + return true; + } + + @Override + public boolean importData(final TransferSupport support) { + final Transferable transferable = + support.getTransferable(); + final DataFlavor[] flavors + = transferable.getTransferDataFlavors(); + + for (final DataFlavor flavor : flavors) { + try { + final Object transferData + = transferable.getTransferData(flavor); + + if (transferData == null) { + JOptionPane.showMessageDialog(urlPanel, + failMessage); + break; + } else { + String flavorMessage = flavor.toString(); + String transferDataMessage = + transferData.toString(); + if (flavorMessage.contains("error") + || transferDataMessage.contains("null")) { + JOptionPane.showMessageDialog(urlPanel, + failMessage); + break; + } + } + } catch (UnsupportedFlavorException e) { + testFailed("UnsupportedFlavorException - " + + "test Failed"); + } catch (IOException e) { + testFailed("IOException - test Failed"); + } + } + + return true; + } + }); + + urlFrame.setBounds(500, 10, 200, 200); + urlFrame.setVisible(true); + } + }); + } + + private void createInstructionUI() { + mainFrame = new Frame("Updating TrayIcon Popup Menu Item Test"); + layout = new GridBagLayout(); + mainControlPanel = new Panel(layout); + resultButtonPanel = new Panel(layout); + + GridBagConstraints gbc = new GridBagConstraints(); + String instructions + = "INSTRUCTIONS:" + + "\n 1. Open any browser." + + "\n 2. Select and drag URL from the browser page and " + + "drop it on the panel" + + "\n 3. If test fails, then a popup message will be displayed," + + " click Ok and \n click Fail button." + + "\n 5. Otherwise test passed. Click Pass button."; + + instructionTextArea = new TextArea(); + instructionTextArea.setText(instructions); + instructionTextArea.setEnabled(false); + instructionTextArea.setBackground(Color.white); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.HORIZONTAL; + mainControlPanel.add(instructionTextArea, gbc); + + passButton = new Button("Pass"); + passButton.setName("Pass"); + passButton.addActionListener(this); + + failButton = new Button("Fail"); + failButton.setName("Fail"); + failButton.addActionListener(this); + + gbc.gridx = 0; + gbc.gridy = 0; + resultButtonPanel.add(passButton, gbc); + gbc.gridx = 1; + gbc.gridy = 0; + resultButtonPanel.add(failButton, gbc); + gbc.gridx = 0; + gbc.gridy = 1; + mainControlPanel.add(resultButtonPanel, gbc); + + mainFrame.add(mainControlPanel); + mainFrame.pack(); + mainFrame.setVisible(true); + } + + @Override + public void actionPerformed(ActionEvent ae) { + if (ae.getSource() instanceof Button) { + Button btn = (Button) ae.getSource(); + switch (btn.getName()) { + case "Pass": + testPassed = true; + isInterrupted = true; + mainThread.interrupt(); + break; + + case "Fail": + testFailed("Dragging link from web browser Failed"); + break; + } + } + } + + public static void cleanUp() { + urlFrame.dispose(); + mainFrame.dispose(); + } + + public static void testFailed(String message) { + testPassed = false; + isInterrupted = true; + failMessage = message; + mainThread.interrupt(); + } + + public static void main(final String[] args) throws Exception { + + DragLinkFromBrowser linkFromBrowser = new DragLinkFromBrowser(); + linkFromBrowser.createInstructionUI(); + linkFromBrowser.dragLinkFromWebBrowser(); + + mainThread = Thread.currentThread(); + try { + mainThread.sleep(testTimeOut); + } catch (InterruptedException ex) { + if (!testPassed) { + throw new RuntimeException(failMessage); + } + } finally { + cleanUp(); + } + + if (!isInterrupted) { + throw new RuntimeException("Test Timed out after " + + testTimeOut / 1000 + " seconds"); + } + } +}