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