1 /* 2 * Copyright (c) 1997, 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.netbeans.jemmy; 26 27 import java.io.BufferedReader; 28 import java.io.FileInputStream; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.InputStreamReader; 32 import java.lang.reflect.InvocationTargetException; 33 import java.util.Enumeration; 34 import java.util.Hashtable; 35 import java.util.Properties; 36 import java.util.Stack; 37 import java.util.StringTokenizer; 38 39 import org.netbeans.jemmy.drivers.APIDriverInstaller; 40 import org.netbeans.jemmy.drivers.DefaultDriverInstaller; 41 import org.netbeans.jemmy.drivers.DriverInstaller; 42 import org.netbeans.jemmy.drivers.InputDriverInstaller; 43 import org.netbeans.jemmy.explorer.GUIBrowser; 44 45 /** 46 * 47 * Keeps default Jemmy properties. 48 * 49 * @author Alexandre Iline (alexandre.iline@oracle.com) 50 * 51 */ 52 public class JemmyProperties { 53 54 /** 55 * The event queue model mask. 56 * 57 * @see #getCurrentDispatchingModel() 58 * @see #setCurrentDispatchingModel(int) 59 */ 60 public static final int QUEUE_MODEL_MASK = 1; 61 62 /** 63 * The robot using model mask. 64 * 65 * @see #getCurrentDispatchingModel() 66 * @see #setCurrentDispatchingModel(int) 67 */ 68 public static final int ROBOT_MODEL_MASK = 2; 69 70 /** 71 * Event shorcutting model mask. Should not be used together with robot 72 * mask. 73 * 74 * @see #getCurrentDispatchingModel() 75 * @see #setCurrentDispatchingModel(int) 76 */ 77 public static final int SHORTCUT_MODEL_MASK = 4; 78 79 /** 80 * The robot using model mask. 81 * 82 * @see #getCurrentDispatchingModel() 83 * @see #setCurrentDispatchingModel(int) 84 */ 85 public static final int SMOOTH_ROBOT_MODEL_MASK = 8; 86 87 private static final int DEFAULT_DRAG_AND_DROP_STEP_LENGTH = 100; 88 private static final Stack<JemmyProperties> propStack = new Stack<>(); 89 90 Hashtable<String, Object> properties; 91 92 /** 93 * 94 */ 95 protected JemmyProperties() { 96 super(); 97 properties = new Hashtable<>(); 98 setProperty("timeouts", new Timeouts()); 99 setProperty("output", new TestOut()); 100 setProperty("resources", new BundleManager()); 101 setProperty("binding.map", new DefaultCharBindingMap()); 102 setProperty("dispatching.model", getDefaultDispatchingModel()); 103 setProperty("drag_and_drop.step_length", DEFAULT_DRAG_AND_DROP_STEP_LENGTH); 104 } 105 106 /** 107 * Returns major version (like 1.0). 108 * 109 * @return a String representing the major version value. 110 */ 111 public static String getMajorVersion() { 112 return (extractValue(getProperties().getClass(). 113 getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"), 114 "Jemmy-MajorVersion")); 115 } 116 117 /** 118 * Returns minor version (like 1). 119 * 120 * @return a String representing the minor version value. 121 */ 122 public static String getMinorVersion() { 123 return (extractValue(getProperties().getClass(). 124 getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"), 125 "Jemmy-MinorVersion")); 126 } 127 128 /** 129 * Returns build (like 20011231 (yyyymmdd)). 130 * 131 * @return a String representing the build value. 132 */ 133 public static String getBuild() { 134 return (extractValue(getProperties().getClass(). 135 getClassLoader().getResourceAsStream("org/netbeans/jemmy/version_info"), 136 "Jemmy-Build")); 137 } 138 139 /** 140 * Returns full version string (like 1.0.1-20011231). 141 * 142 * @return a String representing the full version value. 143 */ 144 public static String getFullVersion() { 145 return (getMajorVersion() + "." 146 + getMinorVersion() + "-" 147 + getBuild()); 148 } 149 150 /** 151 * Returns version string (like 1.0.1). 152 * 153 * @return a String representing the short version value. 154 */ 155 public static String getVersion() { 156 return (getMajorVersion() + "." 157 + getMinorVersion()); 158 } 159 160 /** 161 * Creates a copy of the current JemmyProperties object and pushes it into 162 * the properties stack. 163 * 164 * @return New current properties. 165 */ 166 public static JemmyProperties push() { 167 return push(getProperties().cloneThis()); 168 } 169 170 /** 171 * Pops last pushed properties from the properties stack. If stack has just 172 * one element, does nothing. 173 * 174 * @return Poped properties. 175 */ 176 public static JemmyProperties pop() { 177 JemmyProperties result = propStack.pop(); 178 if (propStack.isEmpty()) { 179 propStack.push(result); 180 } 181 return result; 182 } 183 184 /** 185 * Just like getProperties().getProperty(propertyName). 186 * 187 * @param propertyName a property key 188 * @return a property value 189 * @see #setCurrentProperty 190 * @see #setCurrentTimeout 191 */ 192 public static Object getCurrentProperty(String propertyName) { 193 return getProperties().getProperty(propertyName); 194 } 195 196 /** 197 * Just like getProperties().setProperty(propertyName, propertyValue). 198 * 199 * @param propertyName a property key 200 * @param propertyValue a property value 201 * @return previous property value 202 * @see #getCurrentProperty 203 * @see #getCurrentTimeout 204 */ 205 public static Object setCurrentProperty(String propertyName, Object propertyValue) { 206 return getProperties().setProperty(propertyName, propertyValue); 207 } 208 209 /** 210 * Removes a property from current properties list. 211 * 212 * @param propertyName a property key. 213 * @return previous property value 214 */ 215 public static Object removeCurrentProperty(String propertyName) { 216 return getProperties().removeProperty(propertyName); 217 } 218 219 /** 220 * Returns the current key values. 221 * 222 * @return an array of Strings representing the current key values 223 */ 224 public static String[] getCurrentKeys() { 225 return getProperties().getKeys(); 226 } 227 228 /** 229 * Just like getProperties().getTimeouts(). 230 * 231 * @return a Timeouts object representing the current timeouts. 232 * @see #setCurrentTimeouts 233 */ 234 public static Timeouts getCurrentTimeouts() { 235 return getProperties().getTimeouts(); 236 } 237 238 /** 239 * Just like getProperties().setTimeouts(to). 240 * 241 * @param to New timeouts 242 * @return old timeouts. 243 * @see #getCurrentTimeouts 244 */ 245 public static Timeouts setCurrentTimeouts(Timeouts to) { 246 return getProperties().setTimeouts(to); 247 } 248 249 /** 250 * Just like getProperties().getTimeouts().setTimeout(name, newValue). 251 * 252 * @param name a timeout name 253 * @param newValue a timeout value 254 * @return previous timeout value 255 * @see #getCurrentTimeout 256 */ 257 public static long setCurrentTimeout(String name, long newValue) { 258 return getProperties().getTimeouts().setTimeout(name, newValue); 259 } 260 261 /** 262 * Just like getProperties().getTimeouts().getTimeout(name). 263 * 264 * @param name a timeout name 265 * @return a timeout value 266 * @see #setCurrentTimeout 267 */ 268 public static long getCurrentTimeout(String name) { 269 return getProperties().getTimeouts().getTimeout(name); 270 } 271 272 /** 273 * Just like getProperties().getTimeouts().initTimeout(name, newValue). 274 * 275 * @param name a timeout name 276 * @param newValue a timeout value 277 * @return a timeout value 278 * @see #setCurrentTimeout 279 */ 280 public static long initCurrentTimeout(String name, long newValue) { 281 return getProperties().getTimeouts().initTimeout(name, newValue); 282 } 283 284 /** 285 * Just like getProperties().getOutput(). 286 * 287 * @return a TestOut object representing the current output. 288 * @see #setCurrentOutput 289 */ 290 public static TestOut getCurrentOutput() { 291 return getProperties().getOutput(); 292 } 293 294 /** 295 * Just like getProperties().setOutput(out). 296 * 297 * @param out new output 298 * @return a TestOut object representing the current output. 299 * @see #getCurrentOutput 300 */ 301 public static TestOut setCurrentOutput(TestOut out) { 302 return getProperties().setOutput(out); 303 } 304 305 /** 306 * Just like getProperties().getBundleManager(). 307 * 308 * @return a BundleManager object representing the current bundle manager. 309 * @see #setCurrentBundleManager 310 */ 311 public static BundleManager getCurrentBundleManager() { 312 return getProperties().getBundleManager(); 313 } 314 315 /** 316 * Just like getProperties().setBundleManager(resources). 317 * 318 * @param resources new BundleManager 319 * @return a BundleManager object representing the current bundle manager. 320 * @see #getCurrentBundleManager 321 */ 322 public static BundleManager setCurrentBundleManager(BundleManager resources) { 323 return getProperties().setBundleManager(resources); 324 } 325 326 /** 327 * Just like getProperties().getBundleManager().getResource(key). 328 * 329 * @param key a resource key. 330 * @return a resource value 331 */ 332 public static String getCurrentResource(String key) { 333 return getProperties().getBundleManager().getResource(key); 334 } 335 336 /** 337 * Just like getProperties().getBundleManager().getResource(bundleID, key). 338 * 339 * @param key a resource key. 340 * @param bundleID a bundle ID 341 * @return a resource value 342 */ 343 public static String getCurrentResource(String bundleID, String key) { 344 return getProperties().getBundleManager().getResource(bundleID, key); 345 } 346 347 /** 348 * Just like getProperties().getCharBindingMap(). 349 * 350 * @return a CharBindingMap object representing the current char binding 351 * map. 352 * @see #setCurrentCharBindingMap 353 */ 354 public static CharBindingMap getCurrentCharBindingMap() { 355 return getProperties().getCharBindingMap(); 356 } 357 358 /** 359 * Just like getProperties().setCharBindingMap(map). 360 * 361 * @param map new CharBindingMap. 362 * @return old CharBindingMap object. 363 * @see #getCurrentCharBindingMap 364 */ 365 public static CharBindingMap setCurrentCharBindingMap(CharBindingMap map) { 366 return getProperties().setCharBindingMap(map); 367 } 368 369 /** 370 * Returns the current dispatching model. 371 * 372 * @return Event dispatching model. 373 * @see #getDispatchingModel() 374 * @see #setCurrentDispatchingModel(int) 375 * @see #QUEUE_MODEL_MASK 376 * @see #ROBOT_MODEL_MASK 377 */ 378 public static int getCurrentDispatchingModel() { 379 return getProperties().getDispatchingModel(); 380 } 381 382 /** 383 * Defines event dispatching model. If (model & ROBOT_MODEL_MASK) != 0 384 * java.awt.Robot class is used to reproduce user actions, otherwise actions 385 * are reproduced by event posting. If (model & QUEUE_MODEL_MASK) != 0 386 * actions are reproduced through event queue. 387 * 388 * @param model New dispatching model value. 389 * @return Previous dispatching model value. 390 * @see #setDispatchingModel(int) 391 * @see #getCurrentDispatchingModel() 392 * @see #QUEUE_MODEL_MASK 393 * @see #ROBOT_MODEL_MASK 394 * @see #initDispatchingModel(boolean, boolean) 395 * @see #initDispatchingModel() 396 */ 397 public static int setCurrentDispatchingModel(int model) { 398 return getProperties().setDispatchingModel(model); 399 } 400 401 /** 402 * Returns default event dispatching model. 403 * 404 * @return QUEUE_MODEL_MASK 405 * @see #setCurrentDispatchingModel(int) 406 * @see #QUEUE_MODEL_MASK 407 * @see #ROBOT_MODEL_MASK 408 */ 409 public static int getDefaultDispatchingModel() { 410 return SHORTCUT_MODEL_MASK | QUEUE_MODEL_MASK; 411 } 412 413 /** 414 * Returns the current drag and drop step length value. 415 * 416 * @return Pixel count to move mouse during one drag'n'drop step. 417 * @see #getDragAndDropStepLength() 418 * @see #setCurrentDragAndDropStepLength(int) 419 */ 420 public static int getCurrentDragAndDropStepLength() { 421 return getProperties().getDragAndDropStepLength(); 422 } 423 424 /** 425 * Specifies the current drag and drop step length value. 426 * 427 * @param model Pixel count to move mouse during one drag'n'drop step. 428 * @return Previous value. 429 * @see #setDragAndDropStepLength(int) 430 * @see #getCurrentDragAndDropStepLength() 431 */ 432 public static int setCurrentDragAndDropStepLength(int model) { 433 return getProperties().setDragAndDropStepLength(model); 434 } 435 436 /** 437 * Peeks upper JemmyProperties instance from stack. 438 * 439 * @return a JemmyProperties object representing the properties value. 440 */ 441 public static JemmyProperties getProperties() { 442 if (propStack.empty()) { 443 propStack.add(new JemmyProperties()); 444 } 445 return propStack.peek(); 446 } 447 448 /** 449 * Prints full version into standard output. 450 * 451 * @param argv Application args. 452 */ 453 public static void main(String[] argv) { 454 if (argv.length == 0) { 455 System.out.println("Jemmy version : " + getVersion()); 456 } else if (argv.length == 1 457 && argv[0].equals("-f")) { 458 System.out.println("Jemmy full version : " + getFullVersion()); 459 } else if (argv.length > 0 460 && argv[0].equals("-e")) { 461 String[] newArgv = new String[argv.length - 1]; 462 System.arraycopy(argv, 1, newArgv, 0, argv.length - 1); 463 GUIBrowser.main(newArgv); 464 } else { 465 System.out.println("Parameters: "); 466 System.out.println("<no parameters> - report Jemmy version."); 467 System.out.println("\"-f\" - report full jemmy version."); 468 } 469 } 470 471 /** 472 * Pushes properties stack. 473 * 474 * @param props a JemmyProperties instance to put into the stack head. 475 * @return a JemmyProperties object. 476 */ 477 protected static JemmyProperties push(JemmyProperties props) { 478 return propStack.push(props); 479 } 480 481 static { 482 setCurrentDispatchingModel(getDefaultDispatchingModel()); 483 } 484 485 /** 486 * Method to initialize timeouts and resources. 487 * 488 * @param prop_file File to get filenames from. <BR> 489 * Can contain definition of variables TIMEOUTS_FILE - full path to timeouts 490 * file, <BR> 491 * RESOURCE_FILE - full path to resource file. 492 * @see org.netbeans.jemmy.JemmyProperties#initProperties() 493 */ 494 public void initProperties(String prop_file) { 495 try { 496 getOutput().printLine("Loading properties from " + prop_file + " file"); 497 Properties props = new Properties(); 498 try (FileInputStream fileStream = new FileInputStream(prop_file)) { 499 props.load(fileStream); 500 } 501 if (props.getProperty("TIMEOUTS_FILE") != null 502 && !props.getProperty("TIMEOUTS_FILE").equals("")) { 503 getOutput().printLine("Loading timeouts from " + props.getProperty("TIMEOUTS_FILE") 504 + " file"); 505 getTimeouts().loadDefaults(props.getProperty("TIMEOUTS_FILE")); 506 } 507 if (props.getProperty("RESOURCE_FILE") != null 508 && !props.getProperty("RESOURCE_FILE").equals("")) { 509 getOutput().printLine("Loading resources from " + props.getProperty("RESOURCE_FILE") 510 + " file"); 511 getBundleManager().loadBundleFromFile(props.getProperty("RESOURCE_FILE"), ""); 512 } 513 } catch (IOException e) { 514 getOutput().printStackTrace(e); 515 } 516 } 517 518 /** 519 * Method to initialize timeouts and resources. <BR> 520 * Uses jemmy.properties system property to find file. 521 * 522 * @see org.netbeans.jemmy.JemmyProperties#initProperties(String) 523 */ 524 public void initProperties() { 525 if (System.getProperty("jemmy.properties") != null 526 && !System.getProperty("jemmy.properties").equals("")) { 527 initProperties(System.getProperty("jemmy.properties")); 528 } else { 529 try { 530 getTimeouts().load(); 531 getBundleManager().load(); 532 } catch (IOException e) { 533 getOutput().printStackTrace(e); 534 } 535 } 536 } 537 538 /** 539 * Initializes dispatching model. 540 * 541 * @param queue Notifies that event queue dispatching should be used. 542 * @param robot Notifies that robot dispatching should be used. 543 * @param shortcut Notifies that event shorcutting should be used. 544 */ 545 public void initDispatchingModel(boolean queue, boolean robot, boolean shortcut) { 546 initDispatchingModel(queue, robot, shortcut, false); 547 } 548 549 /** 550 * Initializes dispatching model. 551 * 552 * @param queue Notifies that event queue dispatching should be used. 553 * @param robot Notifies that robot dispatching should be used. 554 * @param shortcut Notifies that event shorcutting should be used. 555 */ 556 public void initDispatchingModel(boolean queue, boolean robot, boolean shortcut, boolean smooth) { 557 int model = getDefaultDispatchingModel(); 558 getOutput().print("Reproduce user actions "); 559 if (queue) { 560 model = QUEUE_MODEL_MASK; 561 getOutput().printLine("through event queue."); 562 } else { 563 model = model - (model & QUEUE_MODEL_MASK); 564 getOutput().printLine("directly."); 565 } 566 getOutput().print("Use "); 567 if (robot) { 568 model = model | ROBOT_MODEL_MASK; 569 getOutput().print("java.awt.Robot class"); 570 } else { 571 model = model - (model & ROBOT_MODEL_MASK); 572 getOutput().print("event dispatching"); 573 } 574 if (smooth) { 575 model = model | SMOOTH_ROBOT_MODEL_MASK; 576 } else { 577 model = model - (model & SMOOTH_ROBOT_MODEL_MASK); 578 } 579 getOutput().printLine(" to reproduce user actions"); 580 if (shortcut) { 581 model = model | SHORTCUT_MODEL_MASK; 582 getOutput().print("Shortcut"); 583 } else { 584 model = model - (model & SHORTCUT_MODEL_MASK); 585 getOutput().print("Dispatch"); 586 } 587 getOutput().printLine(" test events"); 588 setDispatchingModel(model); 589 } 590 591 /** 592 * Initializes dispatching model. 593 * 594 * @param queue Notifies that event queue dispatching should be used. 595 * @param robot Notifies that robot dispatching should be used. 596 */ 597 public void initDispatchingModel(boolean queue, boolean robot) { 598 this.initDispatchingModel(queue, robot, false); 599 } 600 601 /** 602 * Initializes dispatching model. Uses "jemmy.queue_dispatching" and 603 * "jemmy.robot_dispatching" system properties to determine what model 604 * should be used. Possible values for the both properties: <BR> 605 * "off" - switch mode off. <BR> 606 * "on" - switch mode on. <BR> 607 * "" - use default value. 608 * 609 * @see #getDefaultDispatchingModel() 610 */ 611 public void initDispatchingModel() { 612 boolean qmask = ((getDefaultDispatchingModel() & QUEUE_MODEL_MASK) != 0); 613 boolean rmask = ((getDefaultDispatchingModel() & ROBOT_MODEL_MASK) != 0); 614 boolean srmask = ((getDefaultDispatchingModel() & SMOOTH_ROBOT_MODEL_MASK) != 0); 615 boolean smask = ((getDefaultDispatchingModel() & SHORTCUT_MODEL_MASK) != 0); 616 if (System.getProperty("jemmy.queue_dispatching") != null 617 && !System.getProperty("jemmy.queue_dispatching").equals("")) { 618 qmask = System.getProperty("jemmy.queue_dispatching").equals("on"); 619 } 620 if (System.getProperty("jemmy.robot_dispatching") != null 621 && !System.getProperty("jemmy.robot_dispatching").equals("")) { 622 rmask = System.getProperty("jemmy.robot_dispatching").equals("on"); 623 } 624 if (System.getProperty("jemmy.smooth_robot_dispatching") != null 625 && !System.getProperty("jemmy.smooth_robot_dispatching").equals("")) { 626 srmask = System.getProperty("jemmy.smooth_robot_dispatching").equals("on"); 627 } 628 if (System.getProperty("jemmy.shortcut_events") != null 629 && !System.getProperty("jemmy.shortcut_events").equals("")) { 630 smask = System.getProperty("jemmy.shortcut_events").equals("on"); 631 } 632 initDispatchingModel(qmask, rmask, smask, srmask); 633 } 634 635 /** 636 * Inits properties and dispatching model from system environment variables. 637 * 638 * @see #initProperties() 639 * @see #initDispatchingModel() 640 */ 641 public void init() { 642 initProperties(); 643 initDispatchingModel(); 644 } 645 646 /** 647 * Returns timeouts. 648 * 649 * @return the Timeouts value. 650 * @see #setTimeouts 651 */ 652 public Timeouts getTimeouts() { 653 return (Timeouts) getProperty("timeouts"); 654 } 655 656 /** 657 * Changes timeouts. 658 * 659 * @param to new timeouts. 660 * @return old timeouts. 661 * @see #getTimeouts 662 */ 663 public Timeouts setTimeouts(Timeouts to) { 664 return (Timeouts) setProperty("timeouts", to); 665 } 666 667 /** 668 * Changes a timeouts value. 669 * 670 * @param name Timeout name 671 * @param newValue New timeout value 672 * @return previous timeout value 673 * @see #getTimeout 674 */ 675 public long setTimeout(String name, long newValue) { 676 return getTimeouts().setTimeout(name, newValue); 677 } 678 679 /** 680 * Returns a timeouts value. 681 * 682 * @param name Timeout name 683 * @return a timeout value 684 * @see #setTimeout 685 */ 686 public long getTimeout(String name) { 687 return getTimeouts().getTimeout(name); 688 } 689 690 /** 691 * Inits a timeouts value. 692 * 693 * @param name Timeout name 694 * @param newValue New timeout value 695 * @return a timeout value 696 */ 697 public long initTimeout(String name, long newValue) { 698 return getTimeouts().initTimeout(name, newValue); 699 } 700 701 /** 702 * Returns output. 703 * 704 * @return a TestOut object representing the output value 705 * @see #setOutput 706 */ 707 public TestOut getOutput() { 708 return (TestOut) getProperty("output"); 709 } 710 711 /** 712 * Changes output. 713 * 714 * @param out new output. 715 * @return old output. 716 * @see #getOutput 717 */ 718 public TestOut setOutput(TestOut out) { 719 return (TestOut) setProperty("output", out); 720 } 721 722 /** 723 * Returns bundle manager. 724 * 725 * @return a BundleManager object representing the bundle manager value. 726 * @see #setBundleManager 727 */ 728 public BundleManager getBundleManager() { 729 return (BundleManager) getProperty("resources"); 730 } 731 732 /** 733 * Changes bundle manager. 734 * 735 * @param resources new bundle manager. 736 * @return old bundle manager 737 * @see #getBundleManager 738 */ 739 public BundleManager setBundleManager(BundleManager resources) { 740 return (BundleManager) setProperty("resources", resources); 741 } 742 743 /** 744 * Returns resource value. 745 * 746 * @param key Resource key. 747 * @return resource value 748 */ 749 public String getResource(String key) { 750 return getBundleManager().getResource(key); 751 } 752 753 /** 754 * Returns resource value from the specified bundle. 755 * 756 * @param bundleID Id of a bundle to get resource from. 757 * @param key Resource key. 758 * @return resource value 759 */ 760 public String getResource(String bundleID, String key) { 761 return getBundleManager().getResource(bundleID, key); 762 } 763 764 /** 765 * Returns char binding map. 766 * 767 * @return the char binding map. 768 * @see #setCharBindingMap 769 */ 770 public CharBindingMap getCharBindingMap() { 771 return (CharBindingMap) getProperty("binding.map"); 772 } 773 774 /** 775 * Changes char binding map. 776 * 777 * @param map new char binding map. 778 * @return old char binding map. 779 * @see #getCharBindingMap 780 */ 781 public CharBindingMap setCharBindingMap(CharBindingMap map) { 782 return (CharBindingMap) setProperty("binding.map", map); 783 } 784 785 /** 786 * Returns the dispatching model. 787 * 788 * @return Event dispatching model. 789 * @see #getCurrentDispatchingModel() 790 * @see #setDispatchingModel(int) 791 * @see #QUEUE_MODEL_MASK 792 * @see #ROBOT_MODEL_MASK 793 */ 794 public int getDispatchingModel() { 795 return (Integer) getProperty("dispatching.model"); 796 } 797 798 private static DriverInstaller getDriverInstaller(int model) { 799 String name = System.getProperty("jemmy.drivers.installer"); 800 DriverInstaller installer = null; 801 try { 802 if (name != null && !(name.length() == 0)) { 803 installer = (DriverInstaller) new ClassReference(name).newInstance(null, null); 804 } 805 } catch (ClassNotFoundException 806 | IllegalAccessException 807 | NoSuchMethodException 808 | InstantiationException 809 | InvocationTargetException e) { 810 getCurrentOutput().printLine("Cannot init driver installer:"); 811 getCurrentOutput().printStackTrace(e); 812 } 813 if (installer == null) { 814 if (System.getProperty("os.name").startsWith("Mac OS X")) { 815 installer = new APIDriverInstaller((model & SHORTCUT_MODEL_MASK) != 0); 816 } else { 817 installer = new DefaultDriverInstaller((model & SHORTCUT_MODEL_MASK) != 0); 818 } 819 } 820 getCurrentOutput().printLine("Using " + installer.getClass().getName() + " driver installer"); 821 return installer; 822 } 823 824 /** 825 * Specifies the dispatching model value. 826 * 827 * @param model New dispatching model value. 828 * @return Previous dispatching model value. 829 * @see #setCurrentDispatchingModel(int) 830 * @see #getDispatchingModel() 831 * @see #QUEUE_MODEL_MASK 832 * @see #ROBOT_MODEL_MASK 833 */ 834 public int setDispatchingModel(int model) { 835 new InputDriverInstaller((model & ROBOT_MODEL_MASK) == 0, (model & SMOOTH_ROBOT_MODEL_MASK) != 0).install(); 836 getDriverInstaller(model).install(); 837 return (Integer) setProperty("dispatching.model", model); 838 } 839 840 /** 841 * Returns the drag and drop step length value. 842 * 843 * @return Pixel count to move mouse during one drag'n'drop step. 844 * @see #getCurrentDragAndDropStepLength() 845 * @see #setDragAndDropStepLength(int) 846 */ 847 public int getDragAndDropStepLength() { 848 return (Integer) getProperty("drag_and_drop.step_length"); 849 } 850 851 /** 852 * Specifies the drag and drop step length value. 853 * 854 * @param length Pixel count to move mouse during one drag'n'drop step. 855 * @return Previous value. 856 * @see #setCurrentDragAndDropStepLength(int) 857 * @see #getDragAndDropStepLength() 858 */ 859 public int setDragAndDropStepLength(int length) { 860 return (Integer) setProperty("drag_and_drop.step_length", length); 861 } 862 863 /** 864 * Checks if "name" propery currently has a value. 865 * 866 * @param name Property name. Should by unique. 867 * @return true if property was defined. 868 * @see #setProperty(String, Object) 869 * @see #getProperty(String) 870 */ 871 public boolean contains(String name) { 872 return properties.containsKey(name); 873 } 874 875 /** 876 * Saves object as a static link to be used by other objects. 877 * 878 * @param name Property name. Should by unique. 879 * @param newValue Property value. 880 * @return Previous value of "name" property. 881 * @see #setCurrentProperty(String, Object) 882 * @see #getProperty(String) 883 * @see #contains(String) 884 */ 885 public Object setProperty(String name, Object newValue) { 886 Object oldValue = null; 887 if (contains(name)) { 888 oldValue = properties.get(name); 889 properties.remove(name); 890 } 891 properties.put(name, newValue); 892 return oldValue; 893 } 894 895 /** 896 * Returns the property value. 897 * 898 * @param name Property name. Should by unique. 899 * @return Property value stored by setProperty(String, Object) method. 900 * @see #getCurrentProperty(String) 901 * @see #setProperty(String, Object) 902 * @see #contains(String) 903 */ 904 public Object getProperty(String name) { 905 if (contains(name)) { 906 return properties.get(name); 907 } else { 908 return null; 909 } 910 } 911 912 /** 913 * Removes the property. 914 * 915 * @param name A name of the property to be removed. 916 * @return previous property value 917 */ 918 public Object removeProperty(String name) { 919 if (contains(name)) { 920 return properties.remove(name); 921 } else { 922 return null; 923 } 924 } 925 926 /** 927 * Returns the key values. 928 * 929 * @return an array of Strings representing the key values. 930 */ 931 public String[] getKeys() { 932 Enumeration<String> keys = properties.keys(); 933 String[] result = new String[properties.size()]; 934 int i = 0; 935 while (keys.hasMoreElements()) { 936 result[i] = keys.nextElement(); 937 i++; 938 } 939 return result; 940 } 941 942 /** 943 * Copy all properties from this instance into another. 944 * 945 * @param properties a JemmyProperties instance to copy properties into. 946 */ 947 public void copyTo(JemmyProperties properties) { 948 String[] keys = getKeys(); 949 for (String key : keys) { 950 properties.setProperty(key, getProperty(key)); 951 } 952 //some should be cloned 953 properties.setTimeouts(getTimeouts().cloneThis()); 954 properties.setBundleManager(getBundleManager().cloneThis()); 955 } 956 957 /** 958 * Creates an exact copy on this instance. 959 * 960 * @return new JemmyProperties object. 961 */ 962 protected JemmyProperties cloneThis() { 963 JemmyProperties result = new JemmyProperties(); 964 copyTo(result); 965 return result; 966 } 967 968 private static String extractValue(InputStream stream, String varName) { 969 try { 970 BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 971 StringTokenizer token; 972 String nextLine; 973 while ((nextLine = reader.readLine()) != null) { 974 token = new StringTokenizer(nextLine, ":"); 975 String nextToken = token.nextToken(); 976 if (nextToken.trim().equals(varName)) { 977 return token.nextToken().trim(); 978 } 979 } 980 return ""; 981 } catch (IOException e) { 982 getCurrentOutput().printStackTrace(e); 983 return ""; 984 } 985 } 986 987 }