1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @bug 8081787 27 @summary MalformedURLException is thrown during reading data for application/x-java-url;class=java.net.URL flavor 28 @author Mikhail Cherkasov 29 @run main/manual XJavaUrlDataFlavorTest 30 */ 31 32 import javax.swing.*; 33 import java.awt.*; 34 import java.awt.datatransfer.*; 35 import java.awt.event.ActionEvent; 36 import java.awt.event.ActionListener; 37 import java.net.URL; 38 39 public class XJavaUrlDataFlavorTest { 40 private static void init() { 41 String[] instructions = 42 {"Test for MacOS X only:", 43 "1. The aim is to test that java works fine with \"application/" + 44 "x-java-url;class=java.net.URL\"falvor.", 45 "2. Open finder and select any file.", 46 "3. Press CMD+C or press \"Copy\" in context menu", 47 "4. Focus window with \"Test\" Button.", 48 "5. If you see URL for selected file, then test PASSED,", 49 "otherwise test FAILED." 50 }; 51 52 Sysout.createDialog(); 53 Sysout.printInstructions(instructions); 54 55 final Frame frame = new Frame(); 56 Panel panel = new Panel(); 57 panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); 58 59 frame.add(panel); 60 Button testButton = new Button("Test"); 61 final TextField textField = new TextField(40); 62 testButton.addActionListener(new AbstractAction() { 63 @Override 64 public void actionPerformed(ActionEvent ae) { 65 try { 66 Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); 67 URL url = (URL)board.getData(new DataFlavor("application/x-java-url;class=java.net.URL")); 68 textField.setText(url.toString()); 69 } catch (Exception e) { 70 throw new RuntimeException(e); 71 } 72 } 73 }); 74 panel.add(testButton); 75 panel.add(textField); 76 frame.setBounds(200, 200, 400, 400); 77 frame.setVisible(true); 78 79 }//End init() 80 81 82 /***************************************************** 83 * Standard Test Machinery Section 84 * DO NOT modify anything in this section -- it's a 85 * standard chunk of code which has all of the 86 * synchronisation necessary for the test harness. 87 * By keeping it the same in all tests, it is easier 88 * to read and understand someone else's test, as 89 * well as insuring that all tests behave correctly 90 * with the test harness. 91 * There is a section following this for test-defined 92 * classes 93 ******************************************************/ 94 private static boolean theTestPassed = false; 95 private static boolean testGeneratedInterrupt = false; 96 private static String failureMessage = ""; 97 98 private static Thread mainThread = null; 99 100 private static int sleepTime = 300000; 101 102 public static void main(String args[]) throws InterruptedException { 103 mainThread = Thread.currentThread(); 104 try { 105 init(); 106 } catch (TestPassedException e) { 107 //The test passed, so just return from main and harness will 108 // interepret this return as a pass 109 return; 110 } 111 //At this point, neither test passed nor test failed has been 112 // called -- either would have thrown an exception and ended the 113 // test, so we know we have multiple threads. 114 115 //Test involves other threads, so sleep and wait for them to 116 // called pass() or fail() 117 try { 118 Thread.sleep(sleepTime); 119 //Timed out, so fail the test 120 throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds"); 121 } catch (InterruptedException e) { 122 if (!testGeneratedInterrupt) throw e; 123 124 //reset flag in case hit this code more than once for some reason (just safety) 125 testGeneratedInterrupt = false; 126 if (theTestPassed == false) { 127 throw new RuntimeException(failureMessage); 128 } 129 } 130 131 }//main 132 133 public static synchronized void setTimeoutTo(int seconds) { 134 sleepTime = seconds * 1000; 135 } 136 137 public static synchronized void pass() { 138 Sysout.println("The test passed."); 139 Sysout.println("The test is over, hit Ctl-C to stop Java VM"); 140 //first check if this is executing in main thread 141 if (mainThread == Thread.currentThread()) { 142 //Still in the main thread, so set the flag just for kicks, 143 // and throw a test passed exception which will be caught 144 // and end the test. 145 theTestPassed = true; 146 throw new TestPassedException(); 147 } 148 //pass was called from a different thread, so set the flag and interrupt 149 // the main thead. 150 theTestPassed = true; 151 testGeneratedInterrupt = true; 152 if (mainThread != null) { 153 mainThread.interrupt(); 154 } 155 }//pass() 156 157 public static synchronized void fail() { 158 //test writer didn't specify why test failed, so give generic 159 fail("it just plain failed! :-)"); 160 } 161 162 public static synchronized void fail(String whyFailed) { 163 Sysout.println("The test failed: " + whyFailed); 164 Sysout.println("The test is over, hit Ctl-C to stop Java VM"); 165 //check if this called from main thread 166 if (mainThread == Thread.currentThread()) { 167 //If main thread, fail now 'cause not sleeping 168 throw new RuntimeException(whyFailed); 169 } 170 theTestPassed = false; 171 testGeneratedInterrupt = true; 172 failureMessage = whyFailed; 173 mainThread.interrupt(); 174 }//fail() 175 176 }// class ManualMainTest 177 178 //This exception is used to exit from any level of call nesting 179 // when it's determined that the test has passed, and immediately 180 // end the test. 181 class TestPassedException extends RuntimeException { 182 } 183 184 //*********** End Standard Test Machinery Section ********** 185 186 187 /**************************************************** 188 * Standard Test Machinery 189 * DO NOT modify anything below -- it's a standard 190 * chunk of code whose purpose is to make user 191 * interaction uniform, and thereby make it simpler 192 * to read and understand someone else's test. 193 ****************************************************/ 194 195 /** 196 This is part of the standard test machinery. 197 It creates a dialog (with the instructions), and is the interface 198 for sending text messages to the user. 199 To print the instructions, send an array of strings to Sysout.createDialog 200 WithInstructions method. Put one line of instructions per array entry. 201 To display a message for the tester to see, simply call Sysout.println 202 with the string to be displayed. 203 This mimics System.out.println but works within the test harness as well 204 as standalone. 205 */ 206 207 class Sysout { 208 private static TestDialog dialog; 209 private static boolean numbering = false; 210 private static int messageNumber = 0; 211 212 public static void createDialogWithInstructions(String[] instructions) { 213 dialog = new TestDialog(new Frame(), "Instructions"); 214 dialog.printInstructions(instructions); 215 dialog.setVisible(true); 216 println("Any messages for the tester will display here."); 217 } 218 219 public static void createDialog() { 220 dialog = new TestDialog(new Frame(), "Instructions"); 221 String[] defInstr = {"Instructions will appear here. ", ""}; 222 dialog.printInstructions(defInstr); 223 dialog.setVisible(true); 224 println("Any messages for the tester will display here."); 225 } 226 227 228 /* Enables message counting for the tester. */ 229 public static void enableNumbering(boolean enable) { 230 numbering = enable; 231 } 232 233 public static void printInstructions(String[] instructions) { 234 dialog.printInstructions(instructions); 235 } 236 237 238 public static void println(String messageIn) { 239 if (numbering) { 240 messageIn = "" + messageNumber + " " + messageIn; 241 messageNumber++; 242 } 243 dialog.displayMessage(messageIn); 244 } 245 246 }// Sysout class 247 248 /** 249 This is part of the standard test machinery. It provides a place for the 250 test instructions to be displayed, and a place for interactive messages 251 to the user to be displayed. 252 To have the test instructions displayed, see Sysout. 253 To have a message to the user be displayed, see Sysout. 254 Do not call anything in this dialog directly. 255 */ 256 class TestDialog extends Dialog implements ActionListener { 257 258 TextArea instructionsText; 259 TextArea messageText; 260 int maxStringLength = 80; 261 Panel buttonP = new Panel(); 262 Button passB = new Button("pass"); 263 Button failB = new Button("fail"); 264 265 //DO NOT call this directly, go through Sysout 266 public TestDialog(Frame frame, String name) { 267 super(frame, name); 268 int scrollBoth = TextArea.SCROLLBARS_BOTH; 269 instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); 270 add("North", instructionsText); 271 272 messageText = new TextArea("", 5, maxStringLength, scrollBoth); 273 add("Center", messageText); 274 275 passB = new Button("pass"); 276 passB.setActionCommand("pass"); 277 passB.addActionListener(this); 278 buttonP.add("East", passB); 279 280 failB = new Button("fail"); 281 failB.setActionCommand("fail"); 282 failB.addActionListener(this); 283 buttonP.add("West", failB); 284 285 add("South", buttonP); 286 pack(); 287 288 setVisible(true); 289 }// TestDialog() 290 291 //DO NOT call this directly, go through Sysout 292 public void printInstructions(String[] instructions) { 293 //Clear out any current instructions 294 instructionsText.setText(""); 295 296 //Go down array of instruction strings 297 298 String printStr, remainingStr; 299 for (int i = 0; i < instructions.length; i++) { 300 //chop up each into pieces maxSringLength long 301 remainingStr = instructions[i]; 302 while (remainingStr.length() > 0) { 303 //if longer than max then chop off first max chars to print 304 if (remainingStr.length() >= maxStringLength) { 305 //Try to chop on a word boundary 306 int posOfSpace = remainingStr. 307 lastIndexOf(' ', maxStringLength - 1); 308 309 if (posOfSpace <= 0) posOfSpace = maxStringLength - 1; 310 311 printStr = remainingStr.substring(0, posOfSpace + 1); 312 remainingStr = remainingStr.substring(posOfSpace + 1); 313 } 314 //else just print 315 else { 316 printStr = remainingStr; 317 remainingStr = ""; 318 } 319 320 instructionsText.append(printStr + "\n"); 321 322 }// while 323 324 }// for 325 326 }//printInstructions() 327 328 //DO NOT call this directly, go through Sysout 329 public void displayMessage(String messageIn) { 330 messageText.append(messageIn + "\n"); 331 System.out.println(messageIn); 332 } 333 334 //catch presses of the passed and failed buttons. 335 //simply call the standard pass() or fail() static methods of 336 //ManualMainTest 337 public void actionPerformed(ActionEvent e) { 338 if (e.getActionCommand() == "pass") { 339 XJavaUrlDataFlavorTest.pass(); 340 } else { 341 XJavaUrlDataFlavorTest.fail(); 342 } 343 } 344 345 }// TestDialog class