001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s): Alexandre Iline.
025: *
026: * The Original Software is the Jemmy library.
027: * The Initial Developer of the Original Software is Alexandre Iline.
028: * All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: *
041: *
042: *
043: * $Id$ $Revision$ $Date$
044: *
045: */
046:
047: package org.netbeans.jemmy;
048:
049: import java.io.BufferedReader;
050: import java.io.InputStream;
051: import java.io.InputStreamReader;
052: import java.io.IOException;
053: import java.io.FileInputStream;
054:
055: import java.lang.reflect.InvocationTargetException;
056:
057: import java.util.Enumeration;
058: import java.util.Hashtable;
059: import java.util.Properties;
060: import java.util.Stack;
061: import java.util.StringTokenizer;
062:
063: import org.netbeans.jemmy.drivers.APIDriverInstaller;
064: import org.netbeans.jemmy.drivers.DefaultDriverInstaller;
065: import org.netbeans.jemmy.drivers.DriverInstaller;
066: import org.netbeans.jemmy.drivers.InputDriverInstaller;
067:
068: /**
069: *
070: * Keeps default Jemmy properties.
071: *
072: * @author Alexandre Iline (alexandre.iline@sun.com)
073: *
074: */
075:
076: public class JemmyProperties {
077:
078: /**
079: * The event queue model mask.
080: * @see #getCurrentDispatchingModel()
081: * @see #setCurrentDispatchingModel(int)
082: */
083: public static int QUEUE_MODEL_MASK = 1;
084:
085: /**
086: * The robot using model mask.
087: * @see #getCurrentDispatchingModel()
088: * @see #setCurrentDispatchingModel(int)
089: */
090: public static int ROBOT_MODEL_MASK = 2;
091:
092: /**
093: * Event shorcutting model mask. Should not be used
094: * together with robot mask.
095: * @see #getCurrentDispatchingModel()
096: * @see #setCurrentDispatchingModel(int)
097: */
098: public static int SHORTCUT_MODEL_MASK = 4;
099:
100: /**
101: * The robot using model mask.
102: * @see #getCurrentDispatchingModel()
103: * @see #setCurrentDispatchingModel(int)
104: */
105: public static int SMOOTH_ROBOT_MODEL_MASK = 8;
106:
107: private static final int DEFAULT_DRAG_AND_DROP_STEP_LENGTH = 100;
108: private static Stack propStack = null;
109:
110: Hashtable properties;
111:
112: /***/
113: protected JemmyProperties() {
114: super ();
115: properties = new Hashtable();
116: setProperty("timeouts", new Timeouts());
117: setProperty("output", new TestOut());
118: setProperty("resources", new BundleManager());
119: setProperty("binding.map", new DefaultCharBindingMap());
120: setProperty("dispatching.model", new Integer(
121: getDefaultDispatchingModel()));
122: setProperty("drag_and_drop.step_length", new Integer(
123: DEFAULT_DRAG_AND_DROP_STEP_LENGTH));
124: }
125:
126: /**
127: * Returns major version (like 1.0).
128: * @return a String representing the major version value.
129: */
130: public static String getMajorVersion() {
131: return (extractValue(getProperties().getClass()
132: .getClassLoader().getResourceAsStream(
133: "org/netbeans/jemmy/version_info"),
134: "Jemmy-MajorVersion"));
135: }
136:
137: /**
138: * Returns minor version (like 1).
139: * @return a String representing the minor version value.
140: */
141: public static String getMinorVersion() {
142: return (extractValue(getProperties().getClass()
143: .getClassLoader().getResourceAsStream(
144: "org/netbeans/jemmy/version_info"),
145: "Jemmy-MinorVersion"));
146: }
147:
148: /**
149: * Returns build (like 20011231 (yyyymmdd)).
150: * @return a String representing the build value.
151: */
152: public static String getBuild() {
153: return (extractValue(getProperties().getClass()
154: .getClassLoader().getResourceAsStream(
155: "org/netbeans/jemmy/version_info"),
156: "Jemmy-Build"));
157: }
158:
159: /**
160: * Returns full version string (like 1.0.1-20011231).
161: * @return a String representing the full version value.
162: */
163: public static String getFullVersion() {
164: return (getMajorVersion() + "." + getMinorVersion() + "-" + getBuild());
165: }
166:
167: /**
168: * Returns version string (like 1.0.1).
169: * @return a String representing the short version value.
170: */
171: public static String getVersion() {
172: return (getMajorVersion() + "." + getMinorVersion());
173: }
174:
175: /**
176: * Creates a copy of the current JemmyProperties object
177: * and pushes it into the properties stack.
178: * @return New current properties.
179: */
180: public static JemmyProperties push() {
181: return (push(getProperties().cloneThis()));
182: }
183:
184: /**
185: * Pops last pushed properties from the properties stack.
186: * If stack has just one element, does nothing.
187: * @return Poped properties.
188: */
189: public static JemmyProperties pop() {
190: JemmyProperties result = (JemmyProperties) propStack.pop();
191: if (propStack.isEmpty()) {
192: propStack.push(result);
193: }
194: return (result);
195: }
196:
197: /**
198: * Just like getProperties().getProperty(propertyName).
199: * @param propertyName a property key
200: * @return a property value
201: * @see #setCurrentProperty
202: * @see #setCurrentTimeout
203: */
204: public static Object getCurrentProperty(String propertyName) {
205: return (getProperties().getProperty(propertyName));
206: }
207:
208: /**
209: * Just like getProperties().setProperty(propertyName, propertyValue).
210: * @param propertyName a property key
211: * @param propertyValue a property value
212: * @return previous property value
213: * @see #getCurrentProperty
214: * @see #getCurrentTimeout
215: */
216: public static Object setCurrentProperty(String propertyName,
217: Object propertyValue) {
218: return (getProperties()
219: .setProperty(propertyName, propertyValue));
220: }
221:
222: /**
223: * Removes a property from current properties list.
224: * @param propertyName a property key.
225: * @return previous property value
226: */
227: public static Object removeCurrentProperty(String propertyName) {
228: return (getProperties().removeProperty(propertyName));
229: }
230:
231: /**
232: * Returns the current key values.
233: * @return an array of Strings representing the current key values
234: */
235: public static String[] getCurrentKeys() {
236: return (getProperties().getKeys());
237: }
238:
239: /**
240: * Just like getProperties().getTimeouts().
241: * @return a Timeouts object representing the current timeouts.
242: * @see #setCurrentTimeouts
243: */
244: public static Timeouts getCurrentTimeouts() {
245: return (getProperties().getTimeouts());
246: }
247:
248: /**
249: * Just like getProperties().setTimeouts(to).
250: * @param to New timeouts
251: * @return old timeouts.
252: * @see #getCurrentTimeouts
253: */
254: public static Timeouts setCurrentTimeouts(Timeouts to) {
255: return (getProperties().setTimeouts(to));
256: }
257:
258: /**
259: * Just like getProperties().getTimeouts().setTimeout(name, newValue).
260: * @param name a timeout name
261: * @param newValue a timeout value
262: * @return previous timeout value
263: * @see #getCurrentTimeout
264: */
265: public static long setCurrentTimeout(String name, long newValue) {
266: return (getProperties().getTimeouts()
267: .setTimeout(name, newValue));
268: }
269:
270: /**
271: * Just like getProperties().getTimeouts().getTimeout(name).
272: * @param name a timeout name
273: * @return a timeout value
274: * @see #setCurrentTimeout
275: */
276: public static long getCurrentTimeout(String name) {
277: return (getProperties().getTimeouts().getTimeout(name));
278: }
279:
280: /**
281: * Just like getProperties().getTimeouts().initTimeout(name, newValue).
282: * @param name a timeout name
283: * @param newValue a timeout value
284: * @return a timeout value
285: * @see #setCurrentTimeout
286: */
287: public static long initCurrentTimeout(String name, long newValue) {
288: return (getProperties().getTimeouts().initTimeout(name,
289: newValue));
290: }
291:
292: /**
293: * Just like getProperties().getOutput().
294: * @return a TestOut object representing the current output.
295: * @see #setCurrentOutput
296: */
297: public static TestOut getCurrentOutput() {
298: return (getProperties().getOutput());
299: }
300:
301: /**
302: * Just like getProperties().setOutput(out).
303: * @param out new output
304: * @return a TestOut object representing the current output.
305: * @see #getCurrentOutput
306: */
307: public static TestOut setCurrentOutput(TestOut out) {
308: return (getProperties().setOutput(out));
309: }
310:
311: /**
312: * Just like getProperties().getBundleManager().
313: * @return a BundleManager object representing the current bundle manager.
314: * @see #setCurrentBundleManager
315: */
316: public static BundleManager getCurrentBundleManager() {
317: return (getProperties().getBundleManager());
318: }
319:
320: /**
321: * Just like getProperties().setBundleManager(resources).
322: * @param resources new BundleManager
323: * @return a BundleManager object representing the current bundle manager.
324: * @see #getCurrentBundleManager
325: */
326: public static BundleManager setCurrentBundleManager(
327: BundleManager resources) {
328: return (getProperties().setBundleManager(resources));
329: }
330:
331: /**
332: * Just like getProperties().getBundleManager().getResource(key).
333: * @param key a resource key.
334: * @return a resource value
335: */
336: public static String getCurrentResource(String key) {
337: return (getProperties().getBundleManager().getResource(key));
338: }
339:
340: /**
341: * Just like getProperties().getBundleManager().getResource(bundleID, key).
342: * @param key a resource key.
343: * @param bundleID a bundle ID
344: * @return a resource value
345: */
346: public static String getCurrentResource(String bundleID, String key) {
347: return (getProperties().getBundleManager().getResource(
348: bundleID, key));
349: }
350:
351: /**
352: * Just like getProperties().getCharBindingMap().
353: * @return a CharBindingMap object representing the current char binding map.
354: * @see #setCurrentCharBindingMap
355: */
356: public static CharBindingMap getCurrentCharBindingMap() {
357: return (getProperties().getCharBindingMap());
358: }
359:
360: /**
361: * Just like getProperties().setCharBindingMap(map).
362: * @param map new CharBindingMap.
363: * @return old CharBindingMap object.
364: * @see #getCurrentCharBindingMap
365: */
366: public static CharBindingMap setCurrentCharBindingMap(
367: CharBindingMap map) {
368: return (getProperties().setCharBindingMap(map));
369: }
370:
371: /**
372: * Returns the current dispatching model.
373: * @return Event dispatching model.
374: * @see #getDispatchingModel()
375: * @see #setCurrentDispatchingModel(int)
376: * @see #QUEUE_MODEL_MASK
377: * @see #ROBOT_MODEL_MASK
378: */
379: public static int getCurrentDispatchingModel() {
380: return (getProperties().getDispatchingModel());
381: }
382:
383: /**
384: * Defines event dispatching model.
385: * If (model & ROBOT_MODEL_MASK) != 0 java.awt.Robot class
386: * is used to reproduce user actions, otherwise actions
387: * are reproduced by event posting.
388: * If (model & QUEUE_MODEL_MASK) != 0 actions are reproduced through
389: * event queue.
390: * @param model New dispatching model value.
391: * @return Previous dispatching model value.
392: * @see #setDispatchingModel(int)
393: * @see #getCurrentDispatchingModel()
394: * @see #QUEUE_MODEL_MASK
395: * @see #ROBOT_MODEL_MASK
396: * @see #initDispatchingModel(boolean, boolean)
397: * @see #initDispatchingModel()
398: */
399: public static int setCurrentDispatchingModel(int model) {
400: return (getProperties().setDispatchingModel(model));
401: }
402:
403: /**
404: * Returns default event dispatching model.
405: * @return QUEUE_MODEL_MASK
406: * @see #setCurrentDispatchingModel(int)
407: * @see #QUEUE_MODEL_MASK
408: * @see #ROBOT_MODEL_MASK
409: */
410: public static int getDefaultDispatchingModel() {
411: return (SHORTCUT_MODEL_MASK | QUEUE_MODEL_MASK);
412: }
413:
414: /**
415: * Returns the current drag and drop step length value.
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: * @param model Pixel count to move mouse during one drag'n'drop step.
427: * @return Previous value.
428: * @see #setDragAndDropStepLength(int)
429: * @see #getCurrentDragAndDropStepLength()
430: */
431: public static int setCurrentDragAndDropStepLength(int model) {
432: return (getProperties().setDragAndDropStepLength(model));
433: }
434:
435: /**
436: * Peeks upper JemmyProperties instance from stack.
437: * @return a JemmyProperties object representing the properties value.
438: */
439: public static JemmyProperties getProperties() {
440: if (propStack == null) {
441: propStack = new Stack();
442: }
443: if (propStack.empty()) {
444: propStack.add(new JemmyProperties());
445: }
446: return ((JemmyProperties) propStack.peek());
447: }
448:
449: /**
450: * Prints full version into satndart output.
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 && argv[0].equals("-f")) {
457: System.out.println("Jemmy full version : "
458: + getFullVersion());
459: } else {
460: System.out.println("Parameters: ");
461: System.out
462: .println("<no parameters> - report Jemmy version.");
463: System.out.println("\"-f\" - report full jemmy version.");
464: }
465: System.exit(0);
466: }
467:
468: /**
469: * Pushes properties stack.
470: * @param props a JemmyProperties instance to put into the stack head.
471: * @return a JemmyProperties object.
472: */
473: protected static JemmyProperties push(JemmyProperties props) {
474: return ((JemmyProperties) propStack.push(props));
475: }
476:
477: static {
478: setCurrentDispatchingModel(getDefaultDispatchingModel());
479: }
480:
481: /**
482: * Method to initialize timeouts and resources.
483: * @param prop_file File to get filenames from. <BR>
484: * Can contain definition of variables TIMEOUTS_FILE - full path to timeouts file, <BR>
485: * RESOURCE_FILE - full path to resource file.
486: * @see org.netbeans.jemmy.JemmyProperties#initProperties()
487: */
488: public void initProperties(String prop_file) {
489: try {
490: getOutput().printLine(
491: "Loading properties from " + prop_file + " file");
492: Properties props = new Properties();
493: props.load(new FileInputStream(prop_file));
494: if (props.getProperty("TIMEOUTS_FILE") != null
495: && !props.getProperty("TIMEOUTS_FILE").equals("")) {
496: getOutput().printLine(
497: "Loading timeouts from "
498: + props.getProperty("TIMEOUTS_FILE")
499: + " file");
500: getTimeouts().loadDefaults(
501: props.getProperty("TIMEOUTS_FILE"));
502: }
503: if (props.getProperty("RESOURCE_FILE") != null
504: && !props.getProperty("RESOURCE_FILE").equals("")) {
505: getOutput().printLine(
506: "Loading resources from "
507: + props.getProperty("RESOURCE_FILE")
508: + " file");
509: getBundleManager().loadBundleFromFile(
510: props.getProperty("RESOURCE_FILE"), "");
511: }
512: } catch (IOException e) {
513: getOutput().printStackTrace(e);
514: }
515: }
516:
517: /**
518: * Method to initialize timeouts and resources. <BR>
519: * Uses jemmy.properties system property to find file.
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: * @param queue Notifies that event queue dispatching should be used.
539: * @param robot Notifies that robot dispatching should be used.
540: * @param shortcut Notifies that event shorcutting should be used.
541: */
542: public void initDispatchingModel(boolean queue, boolean robot,
543: boolean shortcut) {
544: initDispatchingModel(queue, robot, shortcut, false);
545: }
546:
547: /**
548: * Initializes dispatching model.
549: * @param queue Notifies that event queue dispatching should be used.
550: * @param robot Notifies that robot dispatching should be used.
551: * @param shortcut Notifies that event shorcutting should be used.
552: */
553: public void initDispatchingModel(boolean queue, boolean robot,
554: 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: * @param queue Notifies that event queue dispatching should be used.
592: * @param robot Notifies that robot dispatching should be used.
593: */
594: public void initDispatchingModel(boolean queue, boolean robot) {
595: this .initDispatchingModel(queue, robot, false);
596: }
597:
598: /**
599: * Initializes dispatching model.
600: * Uses "jemmy.queue_dispatching" and "jemmy.robot_dispatching" system properties
601: * to determine what model should be used.
602: * Possible values for the both properties: <BR>
603: * "off" - switch mode off. <BR>
604: * "on" - switch mode on. <BR>
605: * "" - use default value.
606: * @see #getDefaultDispatchingModel()
607: */
608: public void initDispatchingModel() {
609: boolean qmask = ((getDefaultDispatchingModel() & QUEUE_MODEL_MASK) != 0);
610: boolean rmask = ((getDefaultDispatchingModel() & ROBOT_MODEL_MASK) != 0);
611: boolean srmask = ((getDefaultDispatchingModel() & SMOOTH_ROBOT_MODEL_MASK) != 0);
612: boolean smask = ((getDefaultDispatchingModel() & SHORTCUT_MODEL_MASK) != 0);
613: if (System.getProperty("jemmy.queue_dispatching") != null
614: && !System.getProperty("jemmy.queue_dispatching")
615: .equals("")) {
616: qmask = System.getProperty("jemmy.queue_dispatching")
617: .equals("on");
618: }
619: if (System.getProperty("jemmy.robot_dispatching") != null
620: && !System.getProperty("jemmy.robot_dispatching")
621: .equals("")) {
622: rmask = System.getProperty("jemmy.robot_dispatching")
623: .equals("on");
624: }
625: if (System.getProperty("jemmy.smooth_robot_dispatching") != null
626: && !System
627: .getProperty("jemmy.smooth_robot_dispatching")
628: .equals("")) {
629: srmask = System.getProperty(
630: "jemmy.smooth_robot_dispatching").equals("on");
631: }
632: if (System.getProperty("jemmy.shortcut_events") != null
633: && !System.getProperty("jemmy.shortcut_events").equals(
634: "")) {
635: smask = System.getProperty("jemmy.shortcut_events").equals(
636: "on");
637: }
638: initDispatchingModel(qmask, rmask, smask, srmask);
639: }
640:
641: /**
642: * Inits properties and dispatching model from system environment variables.
643: * @see #initProperties()
644: * @see #initDispatchingModel()
645: */
646: public void init() {
647: initProperties();
648: initDispatchingModel();
649: }
650:
651: /**
652: * Returns timeouts.
653: * @return the Timeouts value.
654: * @see #setTimeouts
655: */
656: public Timeouts getTimeouts() {
657: return ((Timeouts) getProperty("timeouts"));
658: }
659:
660: /**
661: * Changes timeouts.
662: * @param to new timeouts.
663: * @return old timeouts.
664: * @see #getTimeouts
665: */
666: public Timeouts setTimeouts(Timeouts to) {
667: return ((Timeouts) setProperty("timeouts", to));
668: }
669:
670: /**
671: * Changes a timeouts value.
672: * @param name Timeout name
673: * @param newValue New timeout value
674: * @return previous timeout value
675: * @see #getTimeout
676: */
677: public long setTimeout(String name, long newValue) {
678: return (getTimeouts().setTimeout(name, newValue));
679: }
680:
681: /**
682: * Returns a timeouts value.
683: * @param name Timeout name
684: * @return a timeout value
685: * @see #setTimeout
686: */
687: public long getTimeout(String name) {
688: return (getTimeouts().getTimeout(name));
689: }
690:
691: /**
692: * Inits a timeouts value.
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: * @return a TestOut object representing the output value
704: * @see #setOutput
705: */
706: public TestOut getOutput() {
707: return ((TestOut) getProperty("output"));
708: }
709:
710: /**
711: * Changes output.
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: * @return a BundleManager object representing the bundle manager value.
723: * @see #setBundleManager
724: */
725: public BundleManager getBundleManager() {
726: return ((BundleManager) getProperty("resources"));
727: }
728:
729: /**
730: * Changes bundle manager.
731: * @param resources new bundle manager.
732: * @return old bundle manager
733: * @see #getBundleManager
734: */
735: public BundleManager setBundleManager(BundleManager resources) {
736: return ((BundleManager) setProperty("resources", resources));
737: }
738:
739: /**
740: * Returns resource value.
741: * @param key Resource key.
742: * @return resource value
743: */
744: public String getResource(String key) {
745: return (getBundleManager().getResource(key));
746: }
747:
748: /**
749: * Returns resource value from the specified bundle.
750: * @param bundleID Id of a bundle to get resource from.
751: * @param key Resource key.
752: * @return resource value
753: */
754: public String getResource(String bundleID, String key) {
755: return (getBundleManager().getResource(bundleID, key));
756: }
757:
758: /**
759: * Returns char binding map.
760: * @return the char binding map.
761: * @see #setCharBindingMap
762: */
763: public CharBindingMap getCharBindingMap() {
764: return ((CharBindingMap) getProperty("binding.map"));
765: }
766:
767: /**
768: * Changes char binding map.
769: * @param map new char binding map.
770: * @return old char binding map.
771: * @see #getCharBindingMap
772: */
773: public CharBindingMap setCharBindingMap(CharBindingMap map) {
774: return ((CharBindingMap) setProperty("binding.map", map));
775: }
776:
777: /**
778: * Returns the dispatching model.
779: * @return Event dispatching model.
780: * @see #getCurrentDispatchingModel()
781: * @see #setDispatchingModel(int)
782: * @see #QUEUE_MODEL_MASK
783: * @see #ROBOT_MODEL_MASK
784: */
785: public int getDispatchingModel() {
786: return (((Integer) getProperty("dispatching.model")).intValue());
787: }
788:
789: private static DriverInstaller getDriverInstaller(int model) {
790: String name = System.getProperty("jemmy.drivers.installer");
791: DriverInstaller installer = null;
792: try {
793: if (name != null && !(name.length() == 0)) {
794: installer = (DriverInstaller) new ClassReference(name)
795: .newInstance(null, null);
796: }
797: } catch (ClassNotFoundException e) {
798: getCurrentOutput().printLine(
799: "Cannot init driver installer:");
800: getCurrentOutput().printStackTrace(e);
801: } catch (IllegalAccessException e) {
802: getCurrentOutput().printLine(
803: "Cannot init driver installer:");
804: getCurrentOutput().printStackTrace(e);
805: } catch (NoSuchMethodException e) {
806: getCurrentOutput().printLine(
807: "Cannot init driver installer:");
808: getCurrentOutput().printStackTrace(e);
809: } catch (InstantiationException e) {
810: getCurrentOutput().printLine(
811: "Cannot init driver installer:");
812: getCurrentOutput().printStackTrace(e);
813: } catch (InvocationTargetException e) {
814: getCurrentOutput().printLine(
815: "Cannot init driver installer:");
816: getCurrentOutput().printStackTrace(e);
817: }
818: if (installer == null) {
819: if (System.getProperty("os.name").startsWith("Mac OS X")) {
820: installer = new APIDriverInstaller(
821: (model & SHORTCUT_MODEL_MASK) != 0);
822: } else {
823: installer = new DefaultDriverInstaller(
824: (model & SHORTCUT_MODEL_MASK) != 0);
825: }
826: }
827: ;
828: getCurrentOutput().printLine(
829: "Using " + installer.getClass().getName()
830: + " driver installer");
831: return (installer);
832: }
833:
834: /**
835: * Specifies the dispatching model value.
836: * @param model New dispatching model value.
837: * @return Previous dispatching model value.
838: * @see #setCurrentDispatchingModel(int)
839: * @see #getDispatchingModel()
840: * @see #QUEUE_MODEL_MASK
841: * @see #ROBOT_MODEL_MASK
842: */
843: public int setDispatchingModel(int model) {
844: new InputDriverInstaller((model & ROBOT_MODEL_MASK) == 0,
845: (model & SMOOTH_ROBOT_MODEL_MASK) != 0).install();
846: getDriverInstaller(model).install();
847: return (((Integer) setProperty("dispatching.model",
848: new Integer(model))).intValue());
849: }
850:
851: /**
852: * Returns the drag and drop step length value.
853: * @return Pixel count to move mouse during one drag'n'drop step.
854: * @see #getCurrentDragAndDropStepLength()
855: * @see #setDragAndDropStepLength(int)
856: */
857: public int getDragAndDropStepLength() {
858: return (((Integer) getProperty("drag_and_drop.step_length"))
859: .intValue());
860: }
861:
862: /**
863: * Specifies the drag and drop step length value.
864: * @param length Pixel count to move mouse during one drag'n'drop step.
865: * @return Previous value.
866: * @see #setCurrentDragAndDropStepLength(int)
867: * @see #getDragAndDropStepLength()
868: */
869: public int setDragAndDropStepLength(int length) {
870: return (((Integer) setProperty("drag_and_drop.step_length",
871: new Integer(length))).intValue());
872: }
873:
874: /**
875: * Checks if "name" propery currently has a value.
876: * @param name Property name. Should by unique.
877: * @return true if property was defined.
878: * @see #setProperty(String, Object)
879: * @see #getProperty(String)
880: */
881: public boolean contains(String name) {
882: return (properties.containsKey(name));
883: }
884:
885: /**
886: * Saves object as a static link to be used by other objects.
887: * @param name Property name. Should by unique.
888: * @param newValue Property value.
889: * @return Previous value of "name" property.
890: * @see #setCurrentProperty(String, Object)
891: * @see #getProperty(String)
892: * @see #contains(String)
893: */
894: public Object setProperty(String name, Object newValue) {
895: Object oldValue = null;
896: if (contains(name)) {
897: oldValue = properties.get(name);
898: properties.remove(name);
899: }
900: properties.put(name, newValue);
901: return (oldValue);
902: }
903:
904: /**
905: * Returns the property value.
906: * @param name Property name. Should by unique.
907: * @return Property value stored by setProperty(String, Object) method.
908: * @see #getCurrentProperty(String)
909: * @see #setProperty(String, Object)
910: * @see #contains(String)
911: */
912: public Object getProperty(String name) {
913: if (contains(name)) {
914: return (properties.get(name));
915: } else {
916: return (null);
917: }
918: }
919:
920: /**
921: * Removes the property.
922: * @param name A name of the property to be removed.
923: * @return previous property value
924: */
925: public Object removeProperty(String name) {
926: if (contains(name)) {
927: return (properties.remove(name));
928: } else {
929: return (null);
930: }
931: }
932:
933: /**
934: * Returns the key values.
935: @return an array of Strings representing the key values.
936: */
937: public String[] getKeys() {
938: Enumeration keys = properties.keys();
939: String[] result = new String[properties.size()];
940: int i = 0;
941: while (keys.hasMoreElements()) {
942: result[i] = (String) keys.nextElement();
943: i++;
944: }
945: return (result);
946: }
947:
948: /**
949: * Copy all properties from this instance into another.
950: * @param properties a JemmyProperties instance to copy properties into.
951: */
952: public void copyTo(JemmyProperties properties) {
953: String[] keys = getKeys();
954: for (int i = 0; i < keys.length; i++) {
955: properties.setProperty(keys[i], getProperty(keys[i]));
956: }
957: //some should be cloned
958: properties.setTimeouts(getTimeouts().cloneThis());
959: properties.setBundleManager(getBundleManager().cloneThis());
960: }
961:
962: /**
963: * Creates an exact copy on this instance.
964: * @return new JemmyProperties object.
965: */
966: protected JemmyProperties cloneThis() {
967: JemmyProperties result = new JemmyProperties();
968: copyTo(result);
969: return (result);
970: }
971:
972: private static String extractValue(InputStream stream,
973: String varName) {
974: try {
975: BufferedReader reader = new BufferedReader(
976: new InputStreamReader(stream));
977: StringTokenizer token;
978: String nextLine;
979: while ((nextLine = reader.readLine()) != null) {
980: token = new StringTokenizer(nextLine, ":");
981: String nextToken = token.nextToken();
982: if (nextToken != null
983: && nextToken.trim().equals(varName)) {
984: return (token.nextToken().trim());
985: }
986: }
987: return ("");
988: } catch (IOException e) {
989: getCurrentOutput().printStackTrace(e);
990: return ("");
991: }
992: }
993:
994: }
|