FileDocCategorySizeDatePackage
RT.javaAPI DocAndroid 1.5 API9307Wed May 06 22:41:16 BST 2009com.vladium.emma.rt

RT

public abstract class RT extends Object implements com.vladium.emma.IAppConstants
author
Vlad Roubtsov, (C) 2003

Fields Summary
private static com.vladium.emma.data.ICoverageData
s_cdata
private static Runnable
s_exitHook
private static com.vladium.util.IProperties
s_appProperties
private static final com.vladium.util.exit.ExitHookManager
EXIT_HOOK_MANAGER
private static final boolean
DEBUG
Constructors Summary
private RT()

Methods Summary
public static synchronized voiddumpCoverageData(java.io.File outFile, boolean merge, boolean stopDataCollection)
Public API for forcing coverage data dump.

param
outFile
param
merge
param
stopDataCollection

        if (DEBUG) System.out.println ("RT::dumpCoverageData() DUMPING " + RT.class.getClassLoader ());
        outFile = outFile != null ? outFile : getCoverageOutFile ();
        
        ICoverageData cdata = s_cdata; // no need to use accessor
        if (stopDataCollection) s_cdata = null; // TODO: log this NOTE: this does not really stop data collection, merely prevents new class registration
        
        RTCoverageDataPersister.dumpCoverageData (cdata, ! stopDataCollection, outFile, merge);
    
public static synchronized voiddumpCoverageData(java.io.File outFile, boolean stopDataCollection)

        outFile = outFile != null ? outFile : getCoverageOutFile ();
        
        ICoverageData cdata = s_cdata; // no need to use accessor
        if (stopDataCollection) s_cdata = null; // TODO: log this NOTE: this does not really stop data collection, merely prevents new class registration
        
        RTCoverageDataPersister.dumpCoverageData (cdata, ! stopDataCollection, outFile, getCoverageOutMerge ());
    
public static synchronized com.vladium.util.IPropertiesgetAppProperties()

        return s_appProperties;
    
public static synchronized com.vladium.emma.data.ICoverageDatagetCoverageData()

        return s_cdata;
    
private static java.io.FilegetCoverageOutFile()

        final IProperties appProperties = getAppProperties (); // sync accessor
        if (appProperties != null)
        {
            final String property = appProperties.getProperty (EMMAProperties.PROPERTY_COVERAGE_DATA_OUT_FILE,
                                                               EMMAProperties.DEFAULT_COVERAGE_DATA_OUT_FILE);
            return new File (property);
        }
        
        return new File (EMMAProperties.DEFAULT_COVERAGE_DATA_OUT_FILE); 
    
private static booleangetCoverageOutMerge()

        final IProperties appProperties = getAppProperties (); // sync accessor
        if (appProperties != null)
        {
            // [Boolean.toString (boolean) is J2SDK 1.4+]
            
            final String property = appProperties.getProperty (EMMAProperties.PROPERTY_COVERAGE_DATA_OUT_MERGE,
                                                               EMMAProperties.DEFAULT_COVERAGE_DATA_OUT_MERGE.toString ());
            return Property.toBoolean (property);
        }
        
        return EMMAProperties.DEFAULT_COVERAGE_DATA_OUT_MERGE.booleanValue ();
    
public static voidr(boolean[][] coverage, java.lang.String classVMName, long stamp)

        // note that we use class names, not the actual Class objects, as the keys here. This
        // is not the best possible solution because it is not capable of supporting
        // multiply (re)loaded classes within the same app, but the rest of the toolkit
        // isn't designed to support this anyway. Furthermore, this does not interfere
        // with class unloading.

        final ICoverageData cdata = getCoverageData (); // need to use accessor for JMM reasons

        // ['cdata' can be null if a previous call to dumpCoverageData() disabled data collection]
        
        if (cdata != null)
        {
            synchronized (cdata.lock ())
            {
                // TODO: could something useful be communicated back to the class
                // by returning something here [e.g., unique class ID (solves the
                // issues of class name collisions and class reloading) or RT.class
                // (to prevent RT reloading)]
                
                cdata.addClass (coverage, classVMName, stamp);
            }
        }
    
public static synchronized com.vladium.emma.data.ICoverageDatareset(boolean createCoverageData, boolean createExitHook)

        // reload the app properties [needs to be done to accomodate classloader rearrangements]:
        
        // avoid the call context tricks at runtime in case security causes problems,
        // use an explicit caller parameter for getAppProperties():
        
        ClassLoader loader = RT.class.getClassLoader ();
        if (loader == null) loader = ClassLoader.getSystemClassLoader (); 
        
        IProperties appProperties = null;
        try
        {
            appProperties = EMMAProperties.getAppProperties (loader);
        }
        catch (Throwable t)
        {
            // TODO: handle better
            t.printStackTrace (System.out);
        }
        s_appProperties = appProperties;


        if (EXIT_HOOK_MANAGER != null)
        {
            // disable/remove the current hook, if any:
            
            if (s_exitHook != null)
            {
                 // note: no attempt is made to execute the existing hook, so its coverage
                 // data may be simply discarded
                
                EXIT_HOOK_MANAGER.removeExitHook (s_exitHook);
                s_exitHook = null;
            }
        }
        
        ICoverageData cdata = s_cdata; // no sync accessor needed
        if (createCoverageData)
        {
            cdata = DataFactory.newCoverageData ();
            s_cdata = cdata;
        }
        else
        {
            s_cdata = null;
        }
        
        if (EXIT_HOOK_MANAGER != null)
        {
            if (createExitHook && (cdata != null))
            {
                final Runnable exitHook = new RTExitHook (RT.class, cdata, getCoverageOutFile (), getCoverageOutMerge ());

                // FR SF978671: fault all classes that we might need to do coverage
                // data dumping (this forces classdefs to be loaded into classloader
                // class cache and allows output file writing to succeed even if
                // the RT classloader is some component loader (e.g, in a J2EE container)
                // that gets invalidated by the time the exit hook thread is run:
                
                RTExitHook.createClassLoaderClosure ();
                
                if (EXIT_HOOK_MANAGER.addExitHook (exitHook))
                {
                    s_exitHook = exitHook;
                }
                // else TODO: log/warn
            }
        }
        
        return cdata;