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: Waiter.java,v 1.9 2007/10/05 11:36:07 jskrivanek Exp $ $Revision: 1.9 $ $Date: 2007/10/05 11:36:07 $
044: *
045: */
046:
047: package org.netbeans.jemmy;
048:
049: import java.awt.Component;
050:
051: /**
052: *
053: * Waits for something defined by Waitable interface to be happened.
054: *
055: * <BR><BR>Timeouts used: <BR>
056: * Waiter.TimeDelta - time delta to check actionProduced result.<BR>
057: * Waiter.WaitingTime - maximal waiting time<BR>
058: * Waiter.AfterWaitingTime - time to sleep after waiting has been finished.<BR>
059: *
060: * @see Timeouts
061: * @see Waitable
062: *
063: * @author Alexandre Iline (alexandre.iline@sun.com)
064: */
065:
066: public class Waiter implements Waitable, Timeoutable, Outputable {
067:
068: private final static long TIME_DELTA = 10;
069: private final static long WAIT_TIME = 60000;
070: private final static long AFTER_WAIT_TIME = 0;
071:
072: private Waitable waitable;
073: private long startTime = 0;
074: private long endTime = -1;
075: private Object result;
076: private Timeouts timeouts;
077: private TestOut out;
078:
079: /**
080: * Constructor.
081: * @param w Waitable object defining waiting criteria.
082: */
083: public Waiter(Waitable w) {
084: super ();
085: setTimeouts(JemmyProperties.getProperties().getTimeouts());
086: setOutput(JemmyProperties.getProperties().getOutput());
087: waitable = w;
088: }
089:
090: /**
091: * Can be used from subclass.
092: */
093: protected Waiter() {
094: super ();
095: setTimeouts(JemmyProperties.getProperties().getTimeouts());
096: setOutput(JemmyProperties.getProperties().getOutput());
097: }
098:
099: static {
100: Timeouts.initDefault("Waiter.TimeDelta", TIME_DELTA);
101: Timeouts.initDefault("Waiter.WaitingTime", WAIT_TIME);
102: Timeouts
103: .initDefault("Waiter.AfterWaitingTime", AFTER_WAIT_TIME);
104: }
105:
106: /**
107: * Defines current timeouts.
108: *
109: * @param timeouts A collection of timeout assignments.
110: * @see org.netbeans.jemmy.Timeoutable
111: * @see org.netbeans.jemmy.Timeouts
112: * @see #getTimeouts
113: */
114: public void setTimeouts(Timeouts timeouts) {
115: this .timeouts = timeouts;
116: }
117:
118: /**
119: * Return current timeouts.
120: * @return the collection of current timeout assignments.
121: * @see org.netbeans.jemmy.Timeoutable
122: * @see org.netbeans.jemmy.Timeouts
123: * @see #setTimeouts
124: */
125: public Timeouts getTimeouts() {
126: return (timeouts);
127: }
128:
129: /**
130: * Defines print output streams or writers.
131: * @param out Identify the streams or writers used for print output.
132: * @see org.netbeans.jemmy.Outputable
133: * @see org.netbeans.jemmy.TestOut
134: * @see #getOutput
135: */
136: public void setOutput(TestOut out) {
137: this .out = out;
138: }
139:
140: /**
141: * Returns print output streams or writers.
142: * @return an object that contains references to objects for
143: * printing to output and err streams.
144: * @see org.netbeans.jemmy.Outputable
145: * @see org.netbeans.jemmy.TestOut
146: * @see #setOutput
147: */
148: public TestOut getOutput() {
149: return (out);
150: }
151:
152: /**
153: * Waits for not null result of actionProduced method of Waitable implementation passed into constructor.
154: * @param waitableObject Object to be passed into actionProduced method.
155: * @return non null result of action.
156: * @throws TimeoutExpiredException
157: * @exception InterruptedException
158: */
159: public Object waitAction(Object waitableObject)
160: throws InterruptedException {
161: startTime = System.currentTimeMillis();
162: out.printTrace(getWaitingStartedMessage());
163: out.printGolden(getGoldenWaitingStartedMessage());
164: long timeDelta = timeouts.getTimeout("Waiter.TimeDelta");
165: while ((result = checkActionProduced(waitableObject)) == null) {
166: Thread.currentThread().sleep(timeDelta);
167: if (timeoutExpired()) {
168: out
169: .printError(getTimeoutExpiredMessage(timeFromStart()));
170: out.printGolden(getGoldenTimeoutExpiredMessage());
171: throw (new TimeoutExpiredException(
172: getActualDescription()));
173: }
174: }
175: endTime = System.currentTimeMillis();
176: out.printTrace(getActionProducedMessage(endTime - startTime,
177: result));
178: out.printGolden(getGoldenActionProducedMessage());
179: Thread.currentThread().sleep(
180: timeouts.getTimeout("Waiter.AfterWaitingTime"));
181: return (result);
182: }
183:
184: /**
185: * @see Waitable
186: * @param obj
187: */
188: public Object actionProduced(Object obj) {
189: return (Boolean.TRUE);
190: }
191:
192: /**
193: * @see Waitable
194: */
195: public String getDescription() {
196: return ("Unknown waiting");
197: }
198:
199: /**
200: * Returns message to be printed before waiting start.
201: * @return a message.
202: */
203: protected String getWaitingStartedMessage() {
204: return ("Start to wait action \"" + getActualDescription() + "\"");
205: }
206:
207: /**
208: * Returns message to be printed when waiting timeout has been expired.
209: * @param timeSpent time from waiting start (milliseconds)
210: * @return a message.
211: */
212: protected String getTimeoutExpiredMessage(long timeSpent) {
213: return ("\"" + getActualDescription()
214: + "\" action has not been produced in "
215: + (new Long(timeSpent)).toString() + " milliseconds");
216: }
217:
218: /**
219: * Returns message to be printed when waiting has been successfully finished.
220: * @param timeSpent time from waiting start (milliseconds)
221: * @param result result of Waitable.actionproduced method.
222: * @return a message.
223: */
224: protected String getActionProducedMessage(long timeSpent,
225: final Object result) {
226: String resultToString;
227: if (result instanceof Component) {
228: // run toString in dispatch thread
229: resultToString = (String) new QueueTool()
230: .invokeSmoothly(new QueueTool.QueueAction(
231: "result.toString()") {
232: public Object launch() {
233: return result.toString();
234: }
235: });
236: } else {
237: resultToString = result.toString();
238: }
239: return ("\"" + getActualDescription()
240: + "\" action has been produced in "
241: + (new Long(timeSpent)).toString()
242: + " milliseconds with result " + "\n : " + resultToString);
243: }
244:
245: /**
246: * Returns message to be printed int golden output before waiting start.
247: * @return a message.
248: */
249: protected String getGoldenWaitingStartedMessage() {
250: return ("Start to wait action \"" + getActualDescription() + "\"");
251: }
252:
253: /**
254: * Returns message to be printed int golden output when waiting timeout has been expired.
255: * @return a message.
256: */
257: protected String getGoldenTimeoutExpiredMessage() {
258: return ("\"" + getActualDescription() + "\" action has not been produced");
259: }
260:
261: /**
262: * Returns message to be printed int golden output when waiting has been successfully finished.
263: * @return a message.
264: */
265: protected String getGoldenActionProducedMessage() {
266: return ("\"" + getActualDescription() + "\" action has been produced");
267: }
268:
269: /**
270: * Returns time from waiting start.
271: * @return Time spent for waiting already.
272: */
273: protected long timeFromStart() {
274: return (System.currentTimeMillis() - startTime);
275: }
276:
277: private Object checkActionProduced(Object obj) {
278: if (waitable != null) {
279: return (waitable.actionProduced(obj));
280: } else {
281: return (actionProduced(obj));
282: }
283: }
284:
285: private String getActualDescription() {
286: if (waitable != null) {
287: return (waitable.getDescription());
288: } else {
289: return (getDescription());
290: }
291: }
292:
293: private boolean timeoutExpired() {
294: return (timeFromStart() > timeouts
295: .getTimeout("Waiter.WaitingTime"));
296: }
297:
298: }
|