package abbot.util; import java.security.Permission; import java.util.*; import abbot.NoExitSecurityManager; /** Provides a method for terminating threads over which you otherwise have no * control. Usually works.<p> * NOTE: Still needs some work; if main script editor exits from the event * dispatch thread, an exception is thrown and the exit aborted. Perhaps * ignore event dispatch threads? */ public abstract class ThreadTerminatingSecurityManager extends NoExitSecurityManager { public class ThreadTerminatedException extends SecurityException { private static final long serialVersionUID = 1L; } private Map terminatedGroups = new WeakHashMap(); private boolean isTerminated(Thread t) { Iterator iter = terminatedGroups.keySet().iterator(); while (iter.hasNext()) { ThreadGroup group = (ThreadGroup)iter.next(); ThreadGroup thisGroup = t.getThreadGroup(); if (thisGroup != null && group.parentOf(thisGroup)) { return true; } } return false; } /** Ensure ThreadTermination exceptions are thrown for any thread in the * given group when any such thread causes the security manager to be * invoked. */ public void terminateThreads(ThreadGroup group) { if (group == null) throw new NullPointerException("Thread group must not be null"); terminatedGroups.put(group, Boolean.TRUE); // maybe do an interrupt/notify; but be careful b/c you might block // trying to sycnhronize on the thread if (group.activeCount() == 0) { try { group.destroy(); } catch(IllegalThreadStateException e) { } } } /** Throw ThreadTerminated for any thread marked for termination. */ public void checkPermission(Permission perm, Object context) { if (isTerminated(Thread.currentThread())) throw new ThreadTerminatedException(); super.checkPermission(perm, context); } /** Throw ThreadTerminated for any thread marked for termination. */ public void checkPermission(Permission perm) { if (isTerminated(Thread.currentThread())) throw new ThreadTerminatedException(); super.checkPermission(perm); } }