1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. 2 * 3 * This program and the accompanying materials are made available under 4 * the terms of the Common Public License v1.0 which accompanies this distribution, 5 * and is available at http://www.eclipse.org/legal/cpl-v10.html 6 * 7 * $Id: ExitHookManager.java,v 1.1.1.1 2004/05/09 16:57:58 vlad_r Exp $ 8 */ 9 package com.vladium.util.exit; 10 11 import java.util.HashMap; 12 import java.util.Map; 13 14 import com.vladium.util.IJREVersion; 15 import com.vladium.util.Property; 16 import com.vladium.emma.IAppConstants; 17 18 // ---------------------------------------------------------------------------- 19 /** 20 * @author Vlad Roubtsov, (C) 2003 21 */ 22 public 23 abstract class ExitHookManager implements IJREVersion 24 { 25 // public: ................................................................ 26 27 // TOTO: handle thread groups as well? 28 addExitHook(Runnable runnable)29 public abstract boolean addExitHook (Runnable runnable); removeExitHook(Runnable runnable)30 public abstract boolean removeExitHook (Runnable runnable); 31 getSingleton()32 public static synchronized ExitHookManager getSingleton () 33 { 34 if (s_singleton == null) 35 { 36 if (JRE_1_3_PLUS) 37 { 38 s_singleton = new JRE13ExitHookManager (); 39 } 40 else 41 { 42 throw new UnsupportedOperationException ("no shutdown hook manager available [JVM: " + Property.getSystemFingerprint () + "]"); 43 } 44 } 45 46 return s_singleton; 47 } 48 49 // protected: ............................................................. 50 51 ExitHookManager()52 protected ExitHookManager () {} 53 54 // package: ............................................................... 55 56 // private: ............................................................... 57 58 59 private static final class JRE13ExitHookManager extends ExitHookManager 60 { addExitHook(final Runnable runnable)61 public synchronized boolean addExitHook (final Runnable runnable) 62 { 63 if ((runnable != null) && ! m_exitThreadMap.containsKey (runnable)) 64 { 65 final Thread exitThread = new Thread (runnable, IAppConstants.APP_NAME + " shutdown handler thread"); 66 67 try 68 { 69 Runtime.getRuntime ().addShutdownHook (exitThread); 70 m_exitThreadMap.put (runnable, exitThread); // TODO: use identity here 71 72 return true; 73 } 74 catch (Exception e) 75 { 76 System.out.println ("exception caught while adding a shutdown hook:"); 77 e.printStackTrace (System.out); 78 } 79 } 80 81 return false; 82 } 83 removeExitHook(final Runnable runnable)84 public synchronized boolean removeExitHook (final Runnable runnable) 85 { 86 if (runnable != null) 87 { 88 final Thread exitThread = (Thread) m_exitThreadMap.get (runnable); // TODO: use identity here 89 90 if (exitThread != null) 91 { 92 try 93 { 94 Runtime.getRuntime ().removeShutdownHook (exitThread); 95 m_exitThreadMap.remove (runnable); 96 97 return true; 98 } 99 catch (Exception e) 100 { 101 System.out.println ("exception caught while removing a shutdown hook:"); 102 e.printStackTrace (System.out); 103 } 104 } 105 } 106 107 return false; 108 } 109 JRE13ExitHookManager()110 JRE13ExitHookManager () 111 { 112 m_exitThreadMap = new HashMap (); 113 } 114 115 116 private final Map /* Runnable->Thread */ m_exitThreadMap; 117 118 } // end of nested class 119 120 private static ExitHookManager s_singleton; 121 122 } // end of class 123 // ---------------------------------------------------------------------------- 124