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.action; 24 25 26 import java.util.LinkedList; 27 import org.jemmy.JemmyException; 28 import org.jemmy.TimeoutExpiredException; 29 30 31 /** 32 * 33 * @author shura, KAM 34 */ 35 class ActionQueue { 36 37 private Thread queueThread; 38 private final LinkedList<ActionRecord> queue; 39 private boolean stop = false; 40 41 public ActionQueue() { 42 queue = new LinkedList<ActionRecord>(); 43 queueThread = new Thread(new Runnable() { 44 45 public void run() { 46 int size; 47 while (!stop) { 48 synchronized (queue) { 49 size = queue.size(); 50 if (size == 0) { 51 try { 52 queue.wait(); 53 } catch (InterruptedException ex) { 54 } 55 } 56 } 57 if (size > 0) { 58 ActionRecord r; 59 synchronized (queue) { 60 r = queue.poll(); 61 } 62 try { 63 r.execute(); 64 } catch (Exception e) { 65 System.err.println("Action '" + r + "' failed with the following exception: "); 66 e.printStackTrace(System.err); 67 System.err.flush(); 68 } 69 r.setCompleted(true); 70 } 71 } 72 } 73 }, "ActionQueue.queueThread"); 74 queueThread.start(); 75 } 76 77 public int actionsInQueue() { 78 synchronized(queue) { 79 return queue.size(); 80 } 81 } 82 83 public void stop() { 84 stop = true; 85 } 86 87 /** 88 * Returns internal ActionQueue event dispatching thread 89 * @return queue dispatching thread of ActionQueue object 90 */ 91 public Thread getQueueThread() { 92 return queueThread; 93 } 94 95 /** 96 * Schedules execution of an action throught the internal ActionQueue queue 97 * and exits immediately 98 * @param action action to execute 99 * @param parameters parameters to pass to action.run() method 100 */ 101 public void invoke(Action action, Object... parameters) { 102 synchronized (queue) { 103 queue.add(new ActionRecord(action, parameters)); 104 queue.notifyAll(); 105 } 106 } 107 108 /** 109 * Schedules execution of an action through the internal ActionQueue queue 110 * and waits until it is completed 111 * @param action action to execute 112 * @param parameters parameters to pass to action.run() method 113 */ 114 public void invokeAndWait(Action action, Object... parameters) { 115 ActionRecord r = new ActionRecord(action, parameters); 116 synchronized (queue) { 117 queue.add(r); 118 queue.notifyAll(); 119 } 120 r.waitCompleted(); 121 122 if (r.failed()) { 123 throw new JemmyException("Action '" + r + "' invoked through ActionQueue failed", r.getThrowable()); 124 } 125 } 126 127 private class ActionRecord { 128 129 Action action; 130 Object[] parameters; 131 boolean completed; 132 boolean started; 133 134 public ActionRecord(Action action, Object[] parameters) { 135 this.action = action; 136 this.parameters = parameters; 137 } 138 139 public boolean failed() { 140 return action.failed(); 141 } 142 143 public Throwable getThrowable() { 144 return action.getThrowable(); 145 } 146 147 public Object[] getParameters() { 148 return parameters; 149 } 150 151 public boolean isCompleted() { 152 return completed; 153 } 154 155 public synchronized void setCompleted(boolean completed) { 156 this.completed = completed; 157 notifyAll(); 158 } 159 160 public void execute() { 161 synchronized (this) { 162 started = true; 163 notifyAll(); 164 } 165 action.execute(parameters); 166 } 167 168 public synchronized void waitCompleted() { 169 try { 170 while (!started) { 171 wait(); 172 } 173 if (!completed) { 174 wait(action.getAllowedTime()); 175 if (!completed) { 176 action.interrupt(); 177 throw new TimeoutExpiredException("Action did not finish in " + action.getAllowedTime() + " ms: " + action); 178 } 179 } 180 } catch (InterruptedException ex) { 181 } 182 } 183 184 @Override 185 public String toString() { 186 return action.toString(); 187 } 188 } 189 }