1 /*
2  * Copyright (c) 1997, 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. 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.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.PrintStream;
32 import java.io.PrintWriter;
33 import java.util.Enumeration;
34 import java.util.Hashtable;
35 import java.util.Properties;
36 
37 /**
38  *
39  * Class to store and process a set of timeout values.
40  *
41  * @see #setDefault(String, long)
42  * @see #getDefault(String)
43  * @see #setTimeout(String, long)
44  * @see #getTimeout(String)
45  *
46  * @author Alexandre Iline (alexandre.iline@oracle.com)
47  */
48 public class Timeouts {
49 
50     private static final long DELTA_TIME = 100;
51     private static final Timeouts defaults;
52     private static double timeoutsScale = -1;
53 
54     private final Hashtable<String, Long> timeouts;
55 
56     /**
57      * Creates empty Timeouts object.
58      */
Timeouts()59     public Timeouts() {
60         super();
61         timeouts = new Hashtable<>();
62         setTimeout("Timeouts.DeltaTimeout", DELTA_TIME);
63         try {
64             load();
65         } catch (IOException ignored) {
66         }
67     }
68 
69     /**
70      * Stores default timeout value.
71      *
72      * @param name Timeout name.
73      * @param newValue Timeout value.
74      * @see #getDefault(String)
75      * @see #initDefault(String, long)
76      * @see #containsDefault(String)
77      */
setDefault(String name, long newValue)78     public static void setDefault(String name, long newValue) {
79         defaults.setTimeout(name, newValue);
80     }
81 
82     /**
83      * Sets default timeout value if it was not set before.
84      *
85      * @param name Timeout name.
86      * @param newValue Timeout value.
87      * @see #setDefault(String, long)
88      * @see #getDefault(String)
89      * @see #containsDefault(String)
90      */
initDefault(String name, long newValue)91     public static void initDefault(String name, long newValue) {
92         defaults.initTimeout(name, newValue);
93     }
94 
95     /**
96      * Gets default timeout value.
97      *
98      * @param name Timeout name.
99      * @return Timeout value or -1 if timeout is not defined.
100      * @see #setDefault(String, long)
101      * @see #initDefault(String, long)
102      * @see #containsDefault(String)
103      */
getDefault(String name)104     public static long getDefault(String name) {
105         return defaults.getTimeout(name);
106     }
107 
108     /**
109      * Check that default timeout value was defined.
110      *
111      * @param name Timeout name.
112      * @return True if timeout has been defined, false otherwise.
113      * @see #setDefault(String, long)
114      * @see #getDefault(String)
115      * @see #initDefault(String, long)
116      */
containsDefault(String name)117     public static boolean containsDefault(String name) {
118         return defaults.contains(name);
119     }
120 
121     static {
122         defaults = new Timeouts();
123     }
124 
125     /**
126      * Loads default timeouts values.
127      *
128      * @param stream Stream to load timeouts from.
129      * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
130      * @see org.netbeans.jemmy.Timeouts#loadDefaults()
131      * @exception IOException
132      */
loadDefaults(InputStream stream)133     public void loadDefaults(InputStream stream)
134             throws IOException {
135         defaults.load(stream);
136     }
137 
138     /**
139      * Loads default timeouts values from file.
140      *
141      * @param fileName File to load timeouts from.
142      * @see org.netbeans.jemmy.Timeouts#loadDefaults(InputStream)
143      * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
144      * @exception IOException
145      * @exception FileNotFoundException
146      */
loadDefaults(String fileName)147     public void loadDefaults(String fileName)
148             throws FileNotFoundException, IOException {
149         defaults.load(fileName);
150     }
151 
152     /**
153      * Loads default timeouts values. Uses jemmy.timeouts system property to get
154      * timeouts file.
155      *
156      * @see org.netbeans.jemmy.Timeouts#loadDefaults(InputStream)
157      * @see org.netbeans.jemmy.Timeouts#loadDefaults(String)
158      * @exception IOException
159      * @exception FileNotFoundException
160      */
loadDefaults()161     public void loadDefaults()
162             throws FileNotFoundException, IOException {
163         defaults.load();
164     }
165 
166     /**
167      * Creates Timeout new object by name and getTimeout(name) value.
168      *
169      * @param name Timeout name.
170      * @return a Timeout instance.
171      */
create(String name)172     public Timeout create(String name) {
173         return new Timeout(name, getTimeout(name));
174     }
175 
176     /**
177      * Create timeout for "Timeouts.DeltaTimeout" name.
178      *
179      * @return a Timeout instance.
180      */
createDelta()181     public Timeout createDelta() {
182         return create("Timeouts.DeltaTimeout");
183     }
184 
185     /**
186      * Checks if timeout has already been defined in this timeout instance.
187      *
188      * @param name Timeout name.
189      * @return True if timeout has been defined, false otherwise.
190      * @see #containsDefault(String)
191      */
contains(String name)192     public boolean contains(String name) {
193         return timeouts.containsKey(name);
194     }
195 
196     /**
197      * Sets new timeout value.
198      *
199      * @param name Timeout name.
200      * @param newValue Timeout value.
201      * @return old timeout value
202      * @see #getTimeout
203      */
setTimeout(String name, long newValue)204     public long setTimeout(String name, long newValue) {
205         long oldValue = -1;
206         if (contains(name)) {
207             oldValue = getTimeout(name);
208         }
209         timeouts.put(name, newValue);
210         return oldValue;
211     }
212 
213     /**
214      * Gets timeout value. It timeout was not defined in this instance, returns
215      * default timeout value.
216      *
217      * @param name Timeout name.
218      * @return Timeout value.
219      * @see #getDefault(String)
220      * @see #setTimeout
221      */
getTimeout(String name)222     public long getTimeout(String name) {
223         long timeout;
224         if (contains(name) && timeouts.get(name) != null) {
225             timeout = timeouts.get(name);
226             timeout = (long) ((double) timeout * getTimeoutsScale());
227         } else if (this != defaults) {
228             timeout = getDefault(name);
229         } else {
230             timeout = -1;
231         }
232         return timeout;
233     }
234 
235     /**
236      * Gets "Timeouts.DeltaTimeout" timeout value.
237      *
238      * @return Timeout value.
239      * @see #getDefault(String)
240      */
getDeltaTimeout()241     public long getDeltaTimeout() {
242         return getTimeout("Timeouts.DeltaTimeout");
243     }
244 
245     /**
246      * Sets timeout value if it was not set before.
247      *
248      * @param name Timeout name.
249      * @param newValue Timeout value.
250      * @return old timeout value
251      */
initTimeout(String name, long newValue)252     public long initTimeout(String name, long newValue) {
253         long result = getTimeout(name);
254         if (!contains(name)) {
255             setTimeout(name, newValue);
256         }
257         return result;
258     }
259 
260     /**
261      * Creates a copy of the current timeouts set.
262      *
263      * @return A copy.
264      */
cloneThis()265     public Timeouts cloneThis() {
266         Timeouts t = new Timeouts();
267         Enumeration<String> e = timeouts.keys();
268         String name = "";
269         while (e.hasMoreElements()) {
270             name = e.nextElement();
271             t.setTimeout(name,
272                     getTimeout(name));
273         }
274         return t;
275     }
276 
277     /**
278      * Sleeps for the "name" timeout value. Can throw InterruptedException if
279      * current thread was interrupted.
280      *
281      * @param name Timeout name.
282      * @exception InterruptedException
283      */
eSleep(String name)284     public void eSleep(String name) throws InterruptedException {
285         if (contains(name)
286                 || defaults.contains(name)) {
287             Thread.sleep(getTimeout(name));
288         }
289     }
290 
291     /**
292      * Sleeps for the "name" timeout value. Does not throw InterruptedException
293      * anyway.
294      *
295      * @param name Timeout name.
296      */
sleep(String name)297     public void sleep(String name) {
298         create(name).sleep();
299     }
300 
301     /**
302      * Prints all defined timeouts.
303      *
304      * @param pw PrintWriter to print into.
305      */
print(PrintWriter pw)306     public void print(PrintWriter pw) {
307         Enumeration<String> e = timeouts.keys();
308         String name = "";
309         while (e.hasMoreElements()) {
310             name = e.nextElement();
311             pw.println(name + " = " + Long.toString(getTimeout(name)));
312         }
313         pw.println("Default values:");
314         e = defaults.timeouts.keys();
315         name = "";
316         while (e.hasMoreElements()) {
317             name = e.nextElement();
318             if (!contains(name)) {
319                 pw.println(name + " = " + Long.toString(getDefault(name)));
320             }
321         }
322     }
323 
324     /**
325      * Prins all defined timeouts.
326      *
327      * @param ps PrintStream to print into.
328      */
print(PrintStream ps)329     public void print(PrintStream ps) {
330         print(new PrintWriter(ps));
331     }
332 
333     /**
334      * Loads timeouts values.
335      *
336      * @param stream Stream to load timeouts from.
337      * @see org.netbeans.jemmy.Timeouts#load(String)
338      * @see org.netbeans.jemmy.Timeouts#load()
339      * @exception IOException
340      */
load(InputStream stream)341     public void load(InputStream stream)
342             throws IOException {
343         Properties props = new Properties();
344         props.load(stream);
345         Enumeration<?> propNames = props.propertyNames();
346         long propValue;
347         String propName = null;
348         while (propNames.hasMoreElements()) {
349             propName = (String) propNames.nextElement();
350             propValue = Long.parseLong(props.getProperty(propName));
351             setTimeout(propName, propValue);
352         }
353     }
354 
355     /**
356      * Loads timeouts values from file.
357      *
358      * @param fileName File to load timeouts from.
359      * @see org.netbeans.jemmy.Timeouts#load(InputStream)
360      * @see org.netbeans.jemmy.Timeouts#load(String)
361      * @exception IOException
362      * @exception FileNotFoundException
363      */
load(String fileName)364     public void load(String fileName)
365             throws FileNotFoundException, IOException {
366         try (FileInputStream fileInputStream = new FileInputStream(fileName)) {
367             load(fileInputStream);
368         }
369     }
370 
371     /**
372      * Loads timeouts values. Uses jemmy.timeouts system property to get
373      * timeouts file.
374      *
375      * @see org.netbeans.jemmy.Timeouts#load(InputStream)
376      * @see org.netbeans.jemmy.Timeouts#load(String)
377      * @exception IOException
378      * @exception FileNotFoundException
379      */
load()380     public void load()
381             throws FileNotFoundException, IOException {
382         if (System.getProperty("jemmy.timeouts") != null
383                 && !System.getProperty("jemmy.timeouts").equals("")) {
384             load(System.getProperty("jemmy.timeouts"));
385         }
386     }
387 
388     /**
389      * Loads debug timeouts values.
390      *
391      * @exception IOException
392      */
loadDebugTimeouts()393     public void loadDebugTimeouts() throws IOException {
394         load(getClass().getClassLoader().getResourceAsStream("org/netbeans/jemmy/debug.timeouts"));
395     }
396 
397     /**
398      * Get timeouts scale. Uses jemmy.timeouts.scale system property to get the
399      * value.
400      *
401      * @return timeouts scale or 1 if the property is not set.
402      */
getTimeoutsScale()403     public static double getTimeoutsScale() {
404         if (timeoutsScale == -1) {
405             String s = System.getProperty("jemmy.timeouts.scale", "1");
406             try {
407                 timeoutsScale = Double.parseDouble(s);
408             } catch (NumberFormatException e) {
409                 timeoutsScale = 1;
410             }
411         }
412         if (timeoutsScale < 0) {
413             timeoutsScale = 1;
414         }
415         return timeoutsScale;
416     }
417 
418     /**
419      * This method is designed to be used by unit test for testing purpose.
420      */
resetTimeoutScale()421     static void resetTimeoutScale() {
422         timeoutsScale = -1;
423     }
424 }
425