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

ClassPathProcessorST

public final class ClassPathProcessorST extends Object implements com.vladium.emma.IAppErrorCodes, IPathEnumerator.IPathHandler
author
Vlad Roubtsov, (C) 2003

Fields Summary
private final File[]
m_path
private final boolean
m_canonical
private final com.vladium.emma.data.IMetaData
m_mdata
private final com.vladium.emma.filter.IInclExclFilter
m_coverageFilter
private final com.vladium.emma.instr.InstrVisitor
m_visitor
private final InstrVisitor.InstrResult
m_instrResult
private final Map
m_cache
private final com.vladium.logging.Logger
m_log
private int
m_classCount
private byte[]
m_readbuf
private int
m_readpos
private com.vladium.util.ByteArrayOStream
m_baos
private File
m_archiveFile
private static final int
BUF_SIZE
Constructors Summary
ClassPathProcessorST(File[] path, boolean canonical, com.vladium.emma.data.IMetaData mdata, com.vladium.emma.filter.IInclExclFilter filter, Map cache)

        if (path == null) throw new IllegalArgumentException ("null input: path");
        if (mdata == null) throw new IllegalArgumentException ("null input: mdata");
        
        m_path = path;
        m_canonical = canonical;
        m_mdata = mdata;
        m_coverageFilter = filter;
        m_cache = cache; // can be null
        m_visitor = new InstrVisitor (mdata.getOptions ());
        m_instrResult = new InstrVisitor.InstrResult ();
        
        m_log = Logger.getLogger ();
    
Methods Summary
private voidensureReadCapacity(int capacity)

        if (m_readbuf.length < capacity)
        {
            final int readbuflen = m_readbuf.length;
            m_readbuf = null;
            m_readbuf = new byte [Math.max (readbuflen << 1, capacity)];
        }
    
public voidhandleArchiveEnd(java.io.File parentDir, java.io.File archive)

        m_archiveFile = null;
    
public voidhandleArchiveEntry(java.util.jar.JarInputStream in, java.util.zip.ZipEntry entry)

        if (m_log.atTRACE2 ()) m_log.trace2 ("handleArchiveEntry", "[" + entry.getName () + "]");
        
        final String name = entry.getName ();
        final String lcName = name.toLowerCase ();
        
        if (lcName.endsWith (".class"))
        {
            final String className = name.substring (0, name.length () - 6).replace ('/", '.");
            
            if ((m_coverageFilter == null) || m_coverageFilter.included (className))
            {
                String srcURL = null;
                InputStream clsin = null;
                try
                {
                    readZipEntry (in, entry);
                    
                    srcURL = "jar:".concat (m_archiveFile.toURL ().toExternalForm ()).concat ("!/").concat (name);
                }
                catch (FileNotFoundException fnfe)
                {
                    // ignore: this should never happen
                    if ($assert.ENABLED)
                    {
                        fnfe.printStackTrace (System.out);
                    }
                }
                catch (IOException ioe)
                {
                    // TODO: error code
                    throw new EMMARuntimeException (ioe);
                }
                finally
                {
                    if (clsin != null)
                        try
                        {
                            clsin.close ();
                            clsin = null;
                        }
                        catch (Exception e)
                        {
                            // TODO: error code
                            throw new EMMARuntimeException (e);
                        }
                }
                
                // [original class def read into m_readbuf]
                
                try
                {
                    ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos);
                    if (! clsDef.isInterface ()) ++ m_classCount;
                    
                    m_visitor.process (clsDef, false, false, true, m_instrResult); // get metadata only
                    clsDef = null;
                    
                    boolean cacheClassDef = true;
                  
                    if (m_instrResult.m_descriptor != null)
                    {
                        // do not overwrite existing descriptors to support "first
                        // in the classpath wins" semantics:
                        
                        if (! m_mdata.add (m_instrResult.m_descriptor, false))
                           cacheClassDef = false; 
                    }
                    
                    if (cacheClassDef && (m_cache != null))
                    {
                        final byte [] bytes = new byte [m_readpos];
                        System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos);
                        
                        m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL));
                    }
                }
                catch (IOException ioe)
                {
                    // TODO: error code
                    throw new EMMARuntimeException (ioe);
                }
            }
        }
    
public voidhandleArchiveStart(java.io.File parentDir, java.io.File archive, java.util.jar.Manifest manifest)

        m_archiveFile = Files.newFile (parentDir, archive.getPath ());
    
public voidhandleDirEnd(java.io.File pathDir, java.io.File dir)

        // do nothing
    
public voidhandleDirStart(java.io.File pathDir, java.io.File dir)

        // do nothing
    
public voidhandleFile(java.io.File pathDir, java.io.File file)

        if (m_log.atTRACE2 ()) m_log.trace2 ("handleFile", "[" + pathDir + "] [" + file + "]");
        
        final String name = file.getPath ();
        final String lcName = name.toLowerCase ();
        
        if (lcName.endsWith (".class"))
        {
            final String className = name.substring (0, name.length () - 6).replace (File.separatorChar, '.");
            
            if ((m_coverageFilter == null) || m_coverageFilter.included (className))
            {
                String srcURL = null;
                InputStream clsin = null;
                try
                {
                    final File inFile = Files.newFile (pathDir, file.getPath ());
                    readFile (inFile);
                    
                    srcURL = inFile.toURL ().toExternalForm ();
                }
                catch (FileNotFoundException fnfe)
                {
                    // ignore: this should never happen
                    if ($assert.ENABLED)
                    {
                        fnfe.printStackTrace (System.out);
                    }
                }
                catch (IOException ioe)
                {
                    // TODO: error code
                    throw new EMMARuntimeException (ioe);
                }
                finally
                {
                    if (clsin != null)
                        try
                        {
                            clsin.close ();
                            clsin = null;
                        }
                        catch (Exception e)
                        {
                            // TODO: error code
                            throw new EMMARuntimeException (e);
                        }
                }
                
                // [original class def read into m_readbuf]
                
                try
                {
                    ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos);
                    if (! clsDef.isInterface ()) ++ m_classCount;
                    
                    m_visitor.process (clsDef, false, false, true, m_instrResult); // get metadata only
                    clsDef = null;
                    
                    
                    boolean cacheClassDef = true;
                  
                    if (m_instrResult.m_descriptor != null)
                    {
                        // do not overwrite existing descriptors to support "first
                        // in the classpath wins" semantics:
                        
                        if (! m_mdata.add (m_instrResult.m_descriptor, false))
                           cacheClassDef = false; 
                    }
                    
                    if (cacheClassDef && (m_cache != null))
                    {
                        final byte [] bytes = new byte [m_readpos];
                        System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos);
                        
                        m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL));
                    }
                }
                catch (IOException ioe)
                {
                    // TODO: error code
                    throw new EMMARuntimeException (ioe);
                }
            }
        }
    
private voidreadFile(java.io.File file)

        final int length = (int) file.length ();
        
        ensureReadCapacity (length);
        
        InputStream in = null;
        try
        {
            in = new FileInputStream (file);
            
            int totalread = 0;
            for (int read;
                 (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0;
                 totalread += read);
            m_readpos = totalread;
        } 
        finally
        {
            if (in != null) try { in.close (); } catch (Exception ignore) {} 
        }
    
private voidreadZipEntry(java.util.zip.ZipInputStream in, java.util.zip.ZipEntry entry)

        final int length = (int) entry.getSize (); // can be -1 if unknown
        
        if (length >= 0)
        {
            ensureReadCapacity (length);
            
            int totalread = 0;
            for (int read;
                 (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0;
                 totalread += read);
            m_readpos = totalread;
        }
        else
        {
            ensureReadCapacity (BUF_SIZE);
            
            m_baos.reset ();
            for (int read; (read = in.read (m_readbuf)) >= 0; m_baos.write (m_readbuf, 0, read));
            
            m_readbuf = m_baos.copyByteArray ();
            m_readpos = m_readbuf.length;
        }
    
public voidrun()

        long start = System.currentTimeMillis ();
        
        // construct instr path enumerator [throws on illegal input only]:
        final IPathEnumerator enumerator = IPathEnumerator.Factory.create (m_path, m_canonical, this);
        
        // allocate I/O buffers:
        m_readbuf = new byte [BUF_SIZE]; // don't reuse this across run() calls to reset it to the original size
        m_readpos = 0;
        m_baos = new ByteArrayOStream (BUF_SIZE); // don't reuse this across run() calls to reset it to the original size
        
        if (m_log.atINFO ())
        {
            m_log.info ("processing classpath ...");
        }
        
        // actual work is driven by the path enumerator:
        try
        {
            enumerator.enumerate ();
        }
        catch (IOException ioe)
        {
            throw new EMMARuntimeException (INSTR_IO_FAILURE, ioe);
        }
        
        if (m_log.atINFO ())
        {
            final long end = System.currentTimeMillis ();
            
            m_log.info ("[" + m_classCount + " class(es) processed in " + (end - start) + " ms]");
        }