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