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: RTExitHook.java,v 1.1.1.1.2.2 2004/07/10 03:34:53 vlad_r Exp $ 8 */ 9package com.vladium.emma.rt; 10 11import java.io.File; 12import java.io.IOException; 13import java.io.InputStream; 14import java.util.Properties; 15import java.util.StringTokenizer; 16 17import com.vladium.emma.data.ICoverageData; 18 19// ---------------------------------------------------------------------------- 20/** 21 * @author Vlad Roubtsov, (C) 2003 22 */ 23final class RTExitHook implements Runnable 24{ 25 // public: ................................................................ 26 27 28 public synchronized void run () 29 { 30 if (m_cdata != null) 31 { 32 RTCoverageDataPersister.dumpCoverageData (m_cdata, true, m_outFile, m_merge); 33 34 m_RT = null; 35 m_cdata = null; 36 } 37 } 38 39 public static void createClassLoaderClosure () 40 { 41 Properties closureMap = null; 42 43 InputStream in = null; 44 try 45 { 46 // note that this does not use ClassLoaderResolver by design 47 // (closure loading must not load any app classes that are outside 48 /// the closure list) 49 50 in = RTExitHook.class.getResourceAsStream (CLOSURE_RESOURCE); 51 if (in != null) 52 { 53 closureMap = new Properties (); 54 closureMap.load (in); 55 } 56 else 57 { 58 throw new Error ("packaging failure: closure resource not found"); 59 } 60 } 61 catch (Exception e) 62 { 63 e.printStackTrace (System.out); 64 65 throw new Error ("packaging failure: " + e.toString ()); 66 } 67 finally 68 { 69 if (in != null) try { in.close (); } catch (IOException ignore) { ignore.printStackTrace (); } 70 } 71 in = null; 72 73 final String closureList = closureMap.getProperty ("closure"); 74 if (closureList == null) 75 { 76 throw new Error ("packaging failure: no closure mapping"); 77 } 78 79 // note that this uses the current classloader (only), consistently 80 // with the getResourceAsStream() above: 81 82 final ClassLoader loader = RTExitHook.class.getClassLoader (); 83 84 final StringTokenizer tokenizer = new StringTokenizer (closureList, ","); 85 while (tokenizer.hasMoreTokens ()) 86 { 87 final String className = tokenizer.nextToken (); 88 89 try 90 { 91 Class.forName (className, true, loader); 92 } 93 catch (Exception e) 94 { 95 throw new Error ("packaging failure: class [" + className + "] not found {" + e.toString () + "}"); 96 } 97 } 98 } 99 100 // protected: ............................................................. 101 102 // package: ............................................................... 103 104 105 RTExitHook (final Class RT, final ICoverageData cdata, final File outFile, final boolean merge) 106 { 107 m_RT = RT; 108 m_cdata = cdata; 109 110 m_outFile = outFile; 111 m_merge = merge; 112 } 113 114 // private: ............................................................... 115 116 117 private final File m_outFile; 118 private final boolean m_merge; 119 120 private Class m_RT; // keep our RT class pinned in memory 121 private ICoverageData m_cdata; 122 123 private static final String CLOSURE_RESOURCE = "RTExitHook.closure"; // relative to this package 124 125} // end of class 126// ----------------------------------------------------------------------------