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