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