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: /**
050: *
051: * Runs actions with or without waiting.
052: *
053: * <BR><BR>Timeouts used: <BR>
054: * ActionProducer.MaxActionTime - time action should be finished in. <BR>
055: *
056: * @see Action
057: * @see Timeouts
058: *
059: * @author Alexandre Iline (alexandre.iline@sun.com)
060: */
061:
062: public class ActionProducer extends Thread implements Action, Waitable,
063: Timeoutable {
064:
065: private final static long ACTION_TIMEOUT = 10000;
066:
067: private Action action;
068: private boolean needWait = true;
069: private Object parameter;
070: private boolean finished;
071: private Object result = null;
072: private Timeouts timeouts;
073: private Waiter waiter;
074: private TestOut output;
075: private Throwable exception;
076:
077: /**
078: * Creates a producer for an action.
079: * @param a Action implementation.
080: */
081: public ActionProducer(Action a) {
082: super ();
083: waiter = new Waiter(this );
084: action = a;
085: setTimeouts(JemmyProperties.getProperties().getTimeouts());
086: setOutput(JemmyProperties.getProperties().getOutput());
087: finished = false;
088: exception = null;
089: }
090:
091: /**
092: * Creates a producer for an action.
093: * @param a Action implementation.
094: * @param nw Defines if <code>produceAction</code>
095: * method should wait for the end of action.
096: */
097: public ActionProducer(Action a, boolean nw) {
098: super ();
099: waiter = new Waiter(this );
100: action = a;
101: needWait = nw;
102: setTimeouts(JemmyProperties.getProperties().getTimeouts());
103: setOutput(JemmyProperties.getProperties().getOutput());
104: finished = false;
105: exception = null;
106: }
107:
108: /**
109: * Creates a producer.
110: * <code>produceAction</code> must be overridden.
111: */
112: protected ActionProducer() {
113: super ();
114: waiter = new Waiter(this );
115: setTimeouts(JemmyProperties.getProperties().getTimeouts());
116: setOutput(JemmyProperties.getProperties().getOutput());
117: finished = false;
118: exception = null;
119: }
120:
121: /**
122: * Creates a producer.
123: * <code>produceAction</code> must be overridden.
124: * @param nw Defines if <code>produceAction</code>
125: * method should wait for the end of action.
126: */
127: protected ActionProducer(boolean nw) {
128: super ();
129: waiter = new Waiter(this );
130: needWait = nw;
131: setTimeouts(JemmyProperties.getProperties().getTimeouts());
132: setOutput(JemmyProperties.getProperties().getOutput());
133: finished = false;
134: exception = null;
135: }
136:
137: static {
138: Timeouts.initDefault("ActionProducer.MaxActionTime",
139: ACTION_TIMEOUT);
140: }
141:
142: /**
143: * Set all the time outs used by sleeps or waits used by the launched action.
144: * @param ts An object containing timeout information.
145: * @see org.netbeans.jemmy.Timeouts
146: * @see org.netbeans.jemmy.Timeoutable
147: * @see #getTimeouts
148: */
149: public void setTimeouts(Timeouts ts) {
150: timeouts = ts;
151: }
152:
153: /**
154: * Get all the time outs used by sleeps or waits used by the launched action.
155: * @return an object containing information about timeouts.
156: * @see org.netbeans.jemmy.Timeouts
157: * @see org.netbeans.jemmy.Timeoutable
158: * @see #setTimeouts
159: */
160: public Timeouts getTimeouts() {
161: return (timeouts);
162: }
163:
164: /**
165: * Identity of the streams or writers used for print output.
166: * @param out An object containing print output assignments for
167: * output and error streams.
168: * @see org.netbeans.jemmy.TestOut
169: * @see org.netbeans.jemmy.Outputable
170: */
171: public void setOutput(TestOut out) {
172: output = out;
173: waiter.setOutput(output);
174: }
175:
176: /**
177: * Returns the exception value.
178: * @return a Throwable object representing the exception value
179: */
180: public Throwable getException() {
181: return (exception);
182: }
183:
184: /**
185: * Defines action priority in terms of thread priority.
186: * Increase (decrease) parameter value to Thread.MIN_PRIORITY(MAX_PRIORITY)
187: * in case if it is less(more) then it.
188: *
189: * @param newPriority New thread priority.
190: */
191: public void setActionPriority(int newPriority) {
192: int priority;
193: if (newPriority < Thread.MIN_PRIORITY) {
194: priority = MIN_PRIORITY;
195: } else if (newPriority > Thread.MAX_PRIORITY) {
196: priority = MAX_PRIORITY;
197: } else {
198: priority = newPriority;
199: }
200: try {
201: setPriority(priority);
202: } catch (IllegalArgumentException e) {
203: } catch (SecurityException e) {
204: }
205: }
206:
207: /**
208: * Get the result of a launched action.
209: * @return a launched action's result.
210: * without waiting in case if <code>getFinished()</code>
211: * @see #getFinished()
212: */
213: public Object getResult() {
214: return (result);
215: }
216:
217: /**
218: * Check if a launched action has finished.
219: * @return <code>true</code> if the launched action has completed,
220: * either normally or with an exception; <code>false</code> otherwise.
221: */
222: public boolean getFinished() {
223: synchronized (this ) {
224: return (finished);
225: }
226: }
227:
228: /**
229: * Does nothing; the method should be overridden by inheritors.
230: * @param obj An object used to modify execution. This might be a
231: * <code>java.lang.String[]</code> that lists a test's command line
232: * arguments.
233: * @return An object - result of the action.
234: * @see org.netbeans.jemmy.Action
235: */
236: public Object launch(Object obj) {
237: return (null);
238: }
239:
240: /**
241: * @return this <code>ActionProducer</code>'s description.
242: * @see Action
243: */
244: public String getDescription() {
245: if (action != null) {
246: return (action.getDescription());
247: } else {
248: return ("Unknown action");
249: }
250: }
251:
252: /**
253: * Starts execution.
254: * Uses ActionProducer.MaxActionTime timeout.
255: *
256: * @param obj Parameter to be passed into action's <code>launch(Object)</code> method.
257: * This parameter might be a <code>java.lang.String[]</code> that lists a test's
258: * command line arguments.
259: * @return <code>launch(Object)</code> result.
260: * @throws TimeoutExpiredException
261: * @exception InterruptedException
262: */
263: public Object produceAction(Object obj) throws InterruptedException {
264: parameter = obj;
265: synchronized (this ) {
266: finished = false;
267: }
268: start();
269: if (needWait) {
270: Timeouts times = timeouts.cloneThis();
271: times.setTimeout("Waiter.WaitingTime", timeouts
272: .getTimeout("ActionProducer.MaxActionTime"));
273: waiter.setTimeouts(times);
274: try {
275: waiter.waitAction(null);
276: } catch (TimeoutExpiredException e) {
277: output
278: .printError("Timeout for \""
279: + getDescription()
280: + "\" action has been expired. Thread has been interrupted.");
281: interrupt();
282: throw (e);
283: }
284: }
285: return (result);
286: }
287:
288: /**
289: * Launch an action in a separate thread of execution.
290: * When the action finishes, record that fact. If the action finishes
291: * normally, store it's result. Use <code>getFinished()</code>
292: * and <code>getResult</code> to answer questions about test
293: * completion and return value, respectively.
294: * @see #getFinished()
295: * @see #getResult()
296: * @see java.lang.Runnable
297: */
298: public final void run() {
299: result = null;
300: try {
301: result = launchAction(parameter);
302: } catch (Throwable e) {
303: exception = e;
304: }
305: synchronized (this ) {
306: finished = true;
307: }
308: }
309:
310: /**
311: * Inquire for a reference to the object returned by a launched action.
312: * @param obj Not used.
313: * @return the result returned when a launched action finishes
314: * normally.
315: * @see org.netbeans.jemmy.Waitable
316: */
317: public final Object actionProduced(Object obj) {
318: synchronized (this ) {
319: if (finished) {
320: if (result == null) {
321: return (new Integer(0));
322: } else {
323: return (result);
324: }
325: } else {
326: return (null);
327: }
328: }
329: }
330:
331: /**
332: * Launch some action.
333: * Pass the action parameters and get it's return value, too.
334: * @param obj Parameter used to configure the execution of whatever
335: * this <code>ActionProducer</code> puts into execution.
336: * This parameter might be a <code>java.lang.String[]</code> that lists a
337: * test's command line arguments.
338: * @return the return value of the action. This might be a
339: * <code>java.lang.Integer</code> wrapped around a status code.
340: */
341: private Object launchAction(Object obj) {
342: if (action != null) {
343: return (action.launch(obj));
344: } else {
345: return (launch(obj));
346: }
347: }
348: }
|