| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Boeing. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Boeing - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.osee.ote.core; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashSet; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import org.eclipse.osee.framework.logging.OseeLog; |
| import org.eclipse.osee.ote.core.environment.TestEnvironment; |
| import org.eclipse.osee.ote.core.internal.Activator; |
| |
| /** |
| * @author Ken J. Aguilar |
| */ |
| public abstract class OseeTestThread { |
| |
| private static final Logger logger = Logger.getLogger("osee.test.core.OseeTestThread"); |
| private final Thread thread; |
| private final WeakReference<TestEnvironment> env; |
| private static final HashSet<OseeTestThread> threadList = new HashSet<>(32); |
| private volatile Throwable causeOfDeath = null; |
| private volatile Date timeOfDeath = null; |
| |
| /** |
| * Creates the thread with the given name and as a non daemon thread |
| */ |
| public OseeTestThread(String name, TestEnvironment env) { |
| this(name, false, null, env); |
| } |
| |
| public OseeTestThread(String name, ThreadGroup group, TestEnvironment env) { |
| this(name, false, group, env); |
| } |
| |
| public Thread.State getState() { |
| return thread.getState(); |
| } |
| |
| /** |
| * Creates the thread with the given name and daemon flag |
| * |
| * @param name the name of this thread |
| * @param isDaemon marks the thread as a daemon thread |
| */ |
| public OseeTestThread(String name, boolean isDaemon, ThreadGroup group, TestEnvironment env) { |
| GCHelper.getGCHelper().addRefWatch(this); |
| this.env = new WeakReference<>(env); |
| thread = new Thread(group, name) { |
| |
| @Override |
| public void run() { |
| try { |
| OseeTestThread.this.run(); |
| synchronized (threadList) { |
| threadList.remove(OseeTestThread.this); |
| } |
| } catch (TestException e) { |
| OseeLog.log(Activator.class, e.getLevel(), |
| "TestException in " + e.getThreadName() + ": " + e.getMessage(), e); |
| cleanupAfterException(e); |
| } catch (Throwable t) { |
| OseeLog.log(Activator.class, Level.SEVERE, "Unhandled exception in " + thread.getName(), t); |
| cleanupAfterException(t); |
| } |
| } |
| }; |
| thread.setDaemon(isDaemon); |
| threadList.add(this); |
| } |
| |
| /** |
| * Starts the thread |
| */ |
| public void start() { |
| thread.start(); |
| } |
| |
| public void setName(String name) { |
| thread.setName(name); |
| } |
| |
| public String getName() { |
| return thread.getName(); |
| } |
| |
| public boolean isAlive() { |
| return thread.isAlive(); |
| } |
| |
| public void interrupt() { |
| thread.interrupt(); |
| } |
| |
| private static final class Trace extends RuntimeException { |
| private static final long serialVersionUID = 8520935964300439490L; |
| |
| Trace() { |
| super("call trace"); |
| } |
| } |
| |
| /** |
| * This method will be called upon thread execution |
| */ |
| protected abstract void run() throws Exception; |
| |
| public void join() throws InterruptedException { |
| thread.join(); |
| } |
| |
| public void join(int milliseconds) throws InterruptedException { |
| thread.join(milliseconds); |
| } |
| |
| public TestEnvironment getEnvironment() { |
| return OseeTestThread.this.env.get(); |
| } |
| |
| public static Collection<OseeTestThread> getThreads() { |
| return threadList; |
| } |
| |
| private synchronized void cleanupAfterException(Throwable t) { |
| causeOfDeath = t; |
| timeOfDeath = Calendar.getInstance().getTime(); |
| this.env.get().handleException(t, Level.OFF); |
| } |
| |
| public Throwable getCauseOfDeath() { |
| return causeOfDeath; |
| } |
| |
| public Date getTimeOfDeath() { |
| return timeOfDeath; |
| } |
| |
| public static void clearThreadReferences() { |
| synchronized (threadList) { |
| threadList.clear(); |
| } |
| } |
| |
| public boolean isInterrupted() { |
| return thread.isInterrupted(); |
| } |
| |
| public void setDaemon(boolean isDaemon) { |
| thread.setDaemon(isDaemon); |
| } |
| |
| public Thread getThread() { |
| return thread; |
| } |
| } |