1 package org.codehaus.plexus.util; 2 3 /* 4 * Copyright The Codehaus Foundation. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 import java.util.Collection; 20 import java.util.Vector; 21 import java.util.logging.Logger; 22 23 /** 24 * Manages a number of test threads, which notify this manager when they have completed. Allows TestCases to easily 25 * start and manage multiple test threads. 26 * <p> 27 * Created on 9/06/2003 28 * </p> 29 * 30 * @author <a href="mailto:bert@tuaworks.co.nz">Bert van Brakel</a> 31 * @version $Id: $Id 32 * @since 3.4.0 33 */ 34 public class TestThreadManager { 35 // ~ Instance fields ---------------------------------------------------------------------------- 36 37 /** Test threads which have completed running */ 38 private Collection<AbstractTestThread> runThreads = new Vector<AbstractTestThread>(); 39 40 /** Test threads still needing to be run, or are currently running */ 41 private Collection<AbstractTestThread> toRunThreads = new Vector<AbstractTestThread>(); 42 43 private Logger logger = null; 44 45 /** Any test threads which failed */ 46 private Vector<AbstractTestThread> failedThreads = new Vector<AbstractTestThread>(); 47 48 /** 49 * The object to notify when all the test threads have completed. Clients use this to lock on (wait) while waiting 50 * for the tests to complete 51 */ 52 private Object notify = null; 53 54 // ~ Constructors ------------------------------------------------------------------------------- 55 56 /** 57 * <p>Constructor for TestThreadManager.</p> 58 * 59 * @param notify a {@link java.lang.Object} object. 60 */ 61 public TestThreadManager(Object notify) { 62 super(); 63 this.notify = notify; 64 } 65 66 // ~ Methods ------------------------------------------------------------------------------------ 67 68 /** 69 * <p>Getter for the field <code>runThreads</code>.</p> 70 * 71 * @return a {@link java.util.Collection} object. 72 */ 73 public Collection<AbstractTestThread> getRunThreads() { 74 return runThreads; 75 } 76 77 /** 78 * <p>runTestThreads.</p> 79 */ 80 public void runTestThreads() { 81 failedThreads.clear(); 82 // use an array as the tests may run very quickly 83 // and modify the toRunThreads vector and hence 84 // cause a Concurrent ModificationException on an 85 // iterator 86 for (AbstractTestThread toRunThread : toRunThreads) { 87 toRunThread.start(); 88 } 89 } 90 91 /** 92 * <p>getFailedTests.</p> 93 * 94 * @return a {@link java.util.Collection} object. 95 */ 96 public Collection<AbstractTestThread> getFailedTests() { 97 return failedThreads; 98 } 99 100 /** 101 * Return the object which threads can wait on to be notified when all the test threads have completed running 102 * 103 * @return a {@link java.lang.Object} object. 104 */ 105 public Object getNotifyObject() { 106 return notify; 107 } 108 109 /** 110 * <p>hasFailedThreads.</p> 111 * 112 * @return a boolean. 113 */ 114 public boolean hasFailedThreads() { 115 return !failedThreads.isEmpty(); 116 } 117 118 /** 119 * Determine if any threads are still running! 120 * 121 * @return DOCUMENT ME! 122 */ 123 public boolean isStillRunningThreads() { 124 return !toRunThreads.isEmpty(); 125 } 126 127 /** 128 * <p>Getter for the field <code>toRunThreads</code>.</p> 129 * 130 * @return a {@link java.util.Collection} object. 131 */ 132 public Collection<AbstractTestThread> getToRunThreads() { 133 return toRunThreads; 134 } 135 136 /** 137 * DOCUMENT ME! 138 */ 139 public void clear() { 140 toRunThreads.clear(); 141 runThreads.clear(); 142 failedThreads.clear(); 143 } 144 145 /* 146 * (non-Javadoc) 147 * @see java.util.Collection#remove(java.lang.Object) 148 */ 149 /** 150 * <p>completed.</p> 151 * 152 * @param thread a {@link org.codehaus.plexus.util.AbstractTestThread} object. 153 */ 154 public synchronized void completed(AbstractTestThread thread) { 155 toRunThreads.remove(thread); 156 runThreads.add(thread); 157 if (thread.hasFailed()) { 158 failedThreads.add(thread); 159 } 160 // wakeup thread which is waiting for the threads to complete 161 // execution 162 if (toRunThreads.isEmpty()) { 163 synchronized (notify) { 164 notify.notify(); 165 } 166 } 167 } 168 169 /** 170 * Override this to add your own stuff. Called after <code>registerThread(Object)</code> 171 * 172 * @param thread DOCUMENT ME! 173 */ 174 public void doRegisterThread(AbstractTestThread thread) {} 175 176 /** 177 * <p>registerThread.</p> 178 * 179 * @param thread a {@link org.codehaus.plexus.util.AbstractTestThread} object. 180 */ 181 public final void registerThread(AbstractTestThread thread) { 182 thread.setThreadRegistry(this); 183 if (toRunThreads.contains(thread) == false) { 184 toRunThreads.add(thread); 185 doRegisterThread(thread); 186 } 187 } 188 189 /** 190 * Put all the runThreads back in the que to be run again and clear the failedTest collection 191 */ 192 public void reset() { 193 toRunThreads.clear(); 194 for (Object runThread : runThreads) { 195 AbstractTestThread test = (AbstractTestThread) runThread; 196 test.reset(); 197 registerThread(test); 198 } 199 200 runThreads.clear(); 201 failedThreads.clear(); 202 } 203 }