1 /* 2 * Copyright (c) 2007, 2017 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 package org.jemmy.env; 24 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.IOException; 28 import java.util.ArrayList; 29 import java.util.HashMap; 30 import java.util.List; 31 import java.util.Properties; 32 import java.util.Set; 33 import org.jemmy.JemmyException; 34 import org.jemmy.action.ActionExecutor; 35 import org.jemmy.action.DefaultExecutor; 36 import org.jemmy.control.Wrap; 37 import org.jemmy.image.ImageCapturer; 38 import org.jemmy.image.ImageLoader; 39 import org.jemmy.input.CharBindingMap; 40 import org.jemmy.interfaces.ControlInterfaceFactory; 41 import org.jemmy.timing.Waiter; 42 43 /** 44 * 45 * @author shura, mrkam, erikgreijus 46 */ 47 public class Environment { 48 49 /** 50 * 51 */ 52 public static final String JEMMY_PROPERTIES_FILE_PROPERTY = "jemmy.properties"; 53 public static final String TIMEOUTS_FILE_PROPERTY = "timeouts"; 54 /** 55 * Information output for Environment class 56 */ 57 public static final String OUTPUT = Environment.class.getName() + ".OUTPUT"; 58 private final static Environment env = new Environment(null); 59 60 /** 61 * 62 * @return 63 */ 64 public static Environment getEnvironment() { 65 return env; 66 } 67 68 static { 69 env.setOutput(new TestOut(System.in, System.out, System.err)); 70 env.setExecutor(new DefaultExecutor()); 71 } 72 private HashMap<PropertyKey, Object> environment = new HashMap<PropertyKey, Object>(); 73 private Environment parent; 74 75 /** 76 * 77 * @param parent 78 */ 79 public Environment(Environment parent) { 80 this.parent = parent; 81 environment = new HashMap<PropertyKey, Object>(); 82 if (parent == null) { 83 loadProperties(System.getProperty(JEMMY_PROPERTIES_FILE_PROPERTY)); 84 } 85 } 86 87 /** 88 * 89 */ 90 public Environment() { 91 this(getEnvironment()); 92 } 93 94 /** 95 * 96 * @return 97 */ 98 public Environment getParentEnvironment() { 99 return parent; 100 } 101 102 /** 103 * 104 * @param parent 105 */ 106 public void setParentEnvironment(Environment parent) { 107 this.parent = parent; 108 } 109 110 public void loadProperties(String propFileName) { 111 if (propFileName == null || propFileName.length() == 0) { 112 propFileName = System.getProperty("user.home") + File.separator + ".jemmy.properties"; 113 } 114 File propFile = new File(propFileName); 115 System.out.println("Loading jemmy properties from " + propFile); 116 if (propFile.exists()) { 117 Properties props = new Properties(); 118 try { 119 props.load(new FileInputStream(propFile)); 120 } catch (IOException ex) { 121 throw new JemmyException("Unable to load properties", ex, propFileName); 122 } 123 for (String k : props.stringPropertyNames()) { 124 if (k.equals(TIMEOUTS_FILE_PROPERTY)) { 125 loadTimeouts(propFile.getParentFile(), props.getProperty(k)); 126 } else { 127 setProperty(k, props.getProperty(k)); 128 } 129 } 130 } else { 131 System.out.println("Property file " + propFile + " does not exists. Ignoring."); 132 } 133 } 134 135 private void loadTimeouts(File propDir, String file) { 136 File timeoutsFile = new File(file); 137 if (!timeoutsFile.isAbsolute()) { 138 timeoutsFile = new File(propDir.getAbsolutePath() + File.separator + file); 139 } 140 System.out.println("Loading timeouts from " + timeoutsFile.getAbsolutePath()); 141 try { 142 Properties timeouts = new Properties(); 143 timeouts.load(new FileInputStream(timeoutsFile)); 144 for (String k : timeouts.stringPropertyNames()) { 145 setTimeout(k, Long.parseLong(timeouts.getProperty(k))); 146 } 147 } catch (IOException ex) { 148 throw new JemmyException("Unable to load timeouts", ex, timeoutsFile.getAbsolutePath()); 149 } 150 } 151 152 /** 153 * 154 * @param cls 155 * @return 156 */ 157 public List<?> get(Class cls) { 158 Set<PropertyKey> all = environment.keySet(); 159 ArrayList<Object> result = new ArrayList<Object>(); 160 for (PropertyKey key : all) { 161 if (key.getCls().equals(cls)) { 162 result.add(environment.get(key)); 163 } 164 } 165 return result; 166 } 167 168 /** 169 * 170 * @param defaultExecutor 171 * @return 172 */ 173 public ActionExecutor setExecutor(ActionExecutor defaultExecutor) { 174 return (ActionExecutor) setProperty(ActionExecutor.class, defaultExecutor); 175 } 176 177 /** 178 * 179 * @return 180 */ 181 public ActionExecutor getExecutor() { 182 ActionExecutor res = (ActionExecutor) getProperty(ActionExecutor.class); 183 if (res == null) { 184 String executorClassName = (String) getProperty(ActionExecutor.ACTION_EXECUTOR_PROPERTY); 185 try { 186 res = ActionExecutor.class.cast(Class.forName(executorClassName).newInstance()); 187 setExecutor(res); 188 } catch (InstantiationException ex) { 189 throw new JemmyException("Unable to instantiate executor ", ex, executorClassName); 190 } catch (IllegalAccessException ex) { 191 throw new JemmyException("Unable to instantiate executor ", ex, executorClassName); 192 } catch (ClassNotFoundException ex) { 193 throw new JemmyException("No executorclass ", ex, executorClassName); 194 } 195 } 196 return res; 197 } 198 199 public <T> T setProperty(Class<T> cls, Object ref, T obj) { 200 return setProperty(new PropertyKey<T>(cls, ref), obj); 201 } 202 203 private <T> T setPropertyIfNotSet(Class<T> cls, Object ref, T obj) { 204 return setPropertyIfNotSet(new PropertyKey<T>(cls, ref), obj); 205 } 206 207 private <T> T getProperty(Class<T> cls, Object ref) { 208 return getProperty(cls, ref, null); 209 } 210 211 @SuppressWarnings("unchecked") 212 public <T> T getProperty(Class cls, Object ref, T defaultValue) { 213 for (PropertyKey pk : environment.keySet()) { 214 if (pk.equals(new PropertyKey(cls, ref))) { 215 return (T) environment.get(pk); 216 } 217 } 218 if (getParentEnvironment() != null) { 219 return getParentEnvironment().getProperty(cls, ref, defaultValue); 220 } else { 221 return defaultValue; 222 } 223 } 224 225 /** 226 * 227 * @param <T> 228 * @param cls 229 * @param obj if null then property is removed 230 * @return 231 */ 232 public <T> T setProperty(Class<T> cls, T obj) { 233 return setProperty(cls, null, obj); 234 } 235 236 /** 237 * 238 * @param <T> 239 * @param cls 240 * @param obj if null then property is removed 241 * @return 242 */ 243 public <T> T setPropertyIfNotSet(Class<T> cls, T obj) { 244 return setPropertyIfNotSet(cls, null, obj); 245 } 246 247 /** 248 * 249 * @param <T> 250 * @param cls 251 * @return 252 */ 253 public <T> T getProperty(Class<T> cls) { 254 return getProperty(cls, null); 255 } 256 257 /** 258 * 259 * @param name 260 * @param obj if null then property is removed 261 * @return 262 */ 263 public Object setProperty(String name, Object obj) { 264 return setProperty(Object.class, name, obj); 265 } 266 267 /** 268 * 269 * @param name 270 * @param obj 271 * @return 272 */ 273 public Object setPropertyIfNotSet(String name, Object obj) { 274 return setPropertyIfNotSet(Object.class, name, obj); 275 } 276 277 /** 278 * 279 * @param name 280 * @return 281 */ 282 public Object getProperty(String name) { 283 return getProperty(Object.class, name); 284 } 285 286 /** 287 * 288 * @param name 289 * @param defaultValue 290 * @return 291 */ 292 public Object getProperty(String name, Object defaultValue) { 293 return getProperty(Environment.class, name, defaultValue); 294 } 295 296 private <T> T setProperty(PropertyKey<T> key, Object value) { 297 if (value == null) { 298 return key.cls.cast(environment.remove(key)); 299 } else { 300 return key.cls.cast(environment.put(key, value)); 301 } 302 } 303 304 private <T> T setPropertyIfNotSet(PropertyKey<T> key, T value) { 305 if (getParentEnvironment() != null) { 306 T res = key.cls.cast(getParentEnvironment().getProperty(key)); 307 if (res != null) { 308 return res; 309 } 310 } 311 T res = key.cls.cast(environment.get(key)); 312 if (res == null) { 313 return key.cls.cast(environment.put(key, value)); 314 } else { 315 return res; 316 } 317 } 318 319 private Object getProperty(PropertyKey key) { 320 return environment.get(key); 321 } 322 323 /** 324 * 325 * @param out 326 * @return 327 */ 328 public TestOut setOutput(TestOut out) { 329 return (TestOut) setProperty(TestOut.class, out); 330 } 331 332 /** 333 * 334 * @return 335 */ 336 public TestOut getOutput() { 337 return (TestOut) getProperty(TestOut.class); 338 } 339 340 /** 341 * Set some specific output. All classes which provide output should use 342 * some specific outputs. Please consult javadoc for a class in question. 343 * Use <code>null</code> to unset the property. 344 * 345 * @param outputName 346 * @param out 347 * @return 348 */ 349 public TestOut setOutput(String outputName, TestOut out) { 350 return (TestOut) setProperty(TestOut.class, outputName, out); 351 } 352 353 /** 354 * Initializes some specific output only if it is not yet set. 355 * 356 * @param outputName 357 * @param out 358 * @return 359 */ 360 public TestOut initOutput(String outputName, TestOut out) { 361 TestOut res = (TestOut) getProperty(TestOut.class, outputName); 362 if (res == null) { 363 return setOutput(outputName, out); 364 } else { 365 return res; 366 } 367 } 368 369 /** 370 * Get's a specific output. If nothing assigned, returns 371 * <code>getOutput()</code> 372 * 373 * @param outputName 374 * @return 375 */ 376 public TestOut getOutput(String outputName) { 377 TestOut res = (TestOut) getProperty(TestOut.class, outputName); 378 return (res != null) ? res : getOutput(); 379 } 380 381 /** 382 * 383 * @param timeout 384 * @return 385 */ 386 public Waiter getWaiter(Timeout timeout) { 387 return getWaiter(timeout.getName()); 388 } 389 390 /** 391 * 392 * @param timeoutName 393 * @return 394 */ 395 public Waiter getWaiter(String timeoutName) { 396 return new Waiter(getTimeout(timeoutName)); 397 } 398 399 /** 400 * 401 * @param timeout 402 * @return 403 */ 404 public Timeout getTimeout(Timeout timeout) { 405 return getTimeout(timeout.getName()); 406 } 407 408 /** 409 * 410 * @param name 411 * @return 412 */ 413 public Timeout getTimeout(String name) { 414 return (Timeout) getProperty(Timeout.class, name); 415 } 416 417 /** 418 * Sets timeout. 419 * 420 * @param timeout Timeout to set. 421 * @return replaced timeout if it was already set. 422 */ 423 public Timeout setTimeout(Timeout timeout) { 424 return (Timeout) setProperty(Timeout.class, timeout.getName(), timeout); 425 } 426 427 /** 428 * Initializes timeout only if it is not set. 429 * 430 * @param timeout Timeout to set. 431 * @return replaced timeout if it was already set. 432 */ 433 public Timeout initTimeout(Timeout timeout) { 434 if (getProperty(Timeout.class, timeout.getName()) == null) { 435 return setTimeout(timeout); 436 } 437 return getTimeout(timeout); 438 } 439 440 /** 441 * Sets new value for the timeout specified by Timeout object instance. 442 * 443 * @param timeout Timeout object instance which identifies the name of the 444 * timeout to set. 445 * @param value new value for the timout. 446 * @return replaced timeout if it was already set. 447 */ 448 public Timeout setTimeout(Timeout timeout, long value) { 449 return setTimeout(timeout.getName(), value); 450 } 451 452 /** 453 * Sets new value for the timeout. 454 * 455 * @param name Name of the timeout. 456 * @param value Value of the timeout. 457 * @return replaced timeout if it was already set. 458 */ 459 public Timeout setTimeout(String name, long value) { 460 return setTimeout(new Timeout(name, value)); 461 } 462 463 /** 464 * 465 * @return 466 */ 467 public CharBindingMap getBindingMap() { 468 return (CharBindingMap) getProperty(CharBindingMap.class); 469 } 470 471 /** 472 * 473 * @param map 474 * @return 475 */ 476 public CharBindingMap setBindingMap(CharBindingMap map) { 477 return (CharBindingMap) setProperty(CharBindingMap.class, map); 478 } 479 480 /** 481 * 482 * @return 483 */ 484 public ImageLoader getImageLoader() { 485 ImageLoader res = (ImageLoader) getProperty(ImageLoader.class); 486 if (res == null) { 487 String loaderClass = (String) getProperty(Wrap.IMAGE_LOADER_PROPERTY); 488 if (loaderClass == null) { 489 throw new IllegalStateException("No image loader provided!"); 490 } 491 try { 492 res = ImageLoader.class.cast(Class.forName(String.class.cast(loaderClass)).newInstance()); 493 setImageLoader(res); 494 } catch (InstantiationException ex) { 495 throw new JemmyException("Unable to instantiate image loader ", ex, loaderClass); 496 } catch (IllegalAccessException ex) { 497 throw new JemmyException("Unable to instantiate image loader ", ex, loaderClass); 498 } catch (ClassNotFoundException ex) { 499 throw new JemmyException("No image loader class ", ex, loaderClass); 500 } 501 } 502 return res; 503 } 504 505 /** 506 * 507 * @return 508 */ 509 public ImageCapturer getImageCapturer() { 510 ImageCapturer res = (ImageCapturer) getProperty(ImageCapturer.class); 511 if (res == null) { 512 String capturerClass = (String) getProperty(Wrap.IMAGE_CAPTURER_PROPERTY); 513 if (capturerClass == null) { 514 throw new IllegalStateException("No image capturer provided!"); 515 } 516 try { 517 res = ImageCapturer.class.cast(Class.forName(String.class.cast(capturerClass)).newInstance()); 518 setImageCapturer(res); 519 } catch (InstantiationException ex) { 520 throw new JemmyException("Unable to instantiate image capturer ", ex, capturerClass); 521 } catch (IllegalAccessException ex) { 522 throw new JemmyException("Unable to instantiate image capturer ", ex, capturerClass); 523 } catch (ClassNotFoundException ex) { 524 throw new JemmyException("No image capturer class ", ex, capturerClass); 525 } 526 } 527 return res; 528 } 529 530 /** 531 * 532 * @param imageLoader 533 * @return 534 */ 535 public ImageLoader setImageLoader(ImageLoader imageLoader) { 536 return (ImageLoader) setProperty(ImageLoader.class, imageLoader); 537 } 538 539 /** 540 * 541 * @param imageCapturer 542 * @return 543 */ 544 public ImageCapturer setImageCapturer(ImageCapturer imageCapturer) { 545 getOutput(OUTPUT).println("ImageCapturer set to " + imageCapturer); 546 return (ImageCapturer) setProperty(ImageCapturer.class, imageCapturer); 547 } 548 549 /** 550 * 551 * @return 552 */ 553 public ControlInterfaceFactory getInputFactory() { 554 ControlInterfaceFactory res = (ControlInterfaceFactory) getProperty(ControlInterfaceFactory.class); 555 if (res == null) { 556 String factoryClass = (String) getProperty(Wrap.INPUT_FACTORY_PROPERTY); 557 if (factoryClass != null) { 558 try { 559 res = ControlInterfaceFactory.class.cast(Class.forName(String.class.cast(factoryClass)).newInstance()); 560 setInputFactory(res); 561 } catch (InstantiationException ex) { 562 throw new JemmyException("Unable to instantiate input factory", ex, factoryClass); 563 } catch (IllegalAccessException ex) { 564 throw new JemmyException("Unable to instantiate input factory", ex, factoryClass); 565 } catch (ClassNotFoundException ex) { 566 throw new JemmyException("Unable to load input factory", ex, factoryClass); 567 } 568 } 569 } 570 return res; 571 } 572 573 /** 574 * 575 * @param factory 576 * @return 577 */ 578 public ControlInterfaceFactory setInputFactory(ControlInterfaceFactory factory) { 579 getOutput(OUTPUT).println("Input factory set to " + factory); 580 return (ControlInterfaceFactory) setProperty(ControlInterfaceFactory.class, factory); 581 } 582 583 private static class PropertyKey<TYPE> { 584 585 private Class<TYPE> cls; 586 private Object ref; 587 588 public PropertyKey(Class<TYPE> cls, Object ref) { 589 this.cls = cls; 590 this.ref = ref; 591 } 592 593 private PropertyKey(Class<TYPE> cls) { 594 this(cls, null); 595 } 596 597 public Class<TYPE> getCls() { 598 return cls; 599 } 600 601 public Object getRef() { 602 return ref; 603 } 604 605 @Override 606 public boolean equals(Object obj) { 607 if (obj == null) { 608 return false; 609 } 610 if (getClass() != obj.getClass()) { 611 return false; 612 } 613 final PropertyKey other = (PropertyKey) obj; 614 if (this.cls != other.cls && (this.cls == null || !this.cls.equals(other.cls))) { 615 return false; 616 } 617 if (this.ref != other.ref && (this.ref == null || !this.ref.equals(other.ref))) { 618 return false; 619 } 620 return true; 621 } 622 623 @Override 624 public int hashCode() { 625 int hash = 7; 626 hash = 41 * hash + (this.cls != null ? this.cls.hashCode() : 0); 627 hash = 41 * hash + (this.ref != null ? this.ref.hashCode() : 0); 628 return hash; 629 } 630 } 631 }