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: ClassPathProcessorST.java,v 1.1.1.1.2.1 2004/07/16 23:32:03 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.FileInputStream; 13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.FileNotFoundException; 14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.IOException; 15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.InputStream; 16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Map; 17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.jar.JarInputStream; 18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.jar.Manifest; 19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.zip.ZipEntry; 20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.zip.ZipInputStream; 21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.jcd.cls.ClassDef; 23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.jcd.parser.ClassDefParser; 24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.logging.Logger; 25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.ByteArrayOStream; 26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Files; 27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IPathEnumerator; 28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.asserts.$assert; 29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.IAppErrorCodes; 30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.EMMARuntimeException; 31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.IMetaData; 32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.filter.IInclExclFilter; 33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.instr.InstrVisitor; 34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ---------------------------------------------------------------------------- 36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/** 37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2003 38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpublic 40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectfinal class ClassPathProcessorST implements IPathEnumerator.IPathHandler, IAppErrorCodes 41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{ 42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // public: ................................................................ 43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void run () 45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project long start = System.currentTimeMillis (); 47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // construct instr path enumerator [throws on illegal input only]: 49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final IPathEnumerator enumerator = IPathEnumerator.Factory.create (m_path, m_canonical, this); 50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // allocate I/O buffers: 52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readbuf = new byte [BUF_SIZE]; // don't reuse this across run() calls to reset it to the original size 53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readpos = 0; 54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_baos = new ByteArrayOStream (BUF_SIZE); // don't reuse this across run() calls to reset it to the original size 55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_log.atINFO ()) 57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_log.info ("processing classpath ..."); 59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // actual work is driven by the path enumerator: 62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project enumerator.enumerate (); 65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (IOException ioe) 67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (INSTR_IO_FAILURE, ioe); 69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_log.atINFO ()) 72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final long end = System.currentTimeMillis (); 74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_log.info ("[" + m_classCount + " class(es) processed in " + (end - start) + " ms]"); 76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // IPathEnumerator.IPathHandler: 80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleArchiveStart (final File parentDir, final File archive, final Manifest manifest) 82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_archiveFile = Files.newFile (parentDir, archive.getPath ()); 84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleArchiveEntry (final JarInputStream in, final ZipEntry entry) 87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_log.atTRACE2 ()) m_log.trace2 ("handleArchiveEntry", "[" + entry.getName () + "]"); 89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String name = entry.getName (); 91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String lcName = name.toLowerCase (); 92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (lcName.endsWith (".class")) 94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String className = name.substring (0, name.length () - 6).replace ('/', '.'); 96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ((m_coverageFilter == null) || m_coverageFilter.included (className)) 98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project String srcURL = null; 100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project InputStream clsin = null; 101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project readZipEntry (in, entry); 104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcURL = "jar:".concat (m_archiveFile.toURL ().toExternalForm ()).concat ("!/").concat (name); 106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (FileNotFoundException fnfe) 108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // ignore: this should never happen 110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ($assert.ENABLED) 111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project fnfe.printStackTrace (System.out); 113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (IOException ioe) 116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (ioe); 119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project finally 121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (clsin != null) 123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsin.close (); 126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsin = null; 127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (Exception e) 129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (e); 132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // [original class def read into m_readbuf] 136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos); 140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (! clsDef.isInterface ()) ++ m_classCount; 141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_visitor.process (clsDef, false, false, true, m_instrResult); // get metadata only 143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsDef = null; 144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project boolean cacheClassDef = true; 146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_instrResult.m_descriptor != null) 148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // do not overwrite existing descriptors to support "first 150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // in the classpath wins" semantics: 151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (! m_mdata.add (m_instrResult.m_descriptor, false)) 153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project cacheClassDef = false; 154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (cacheClassDef && (m_cache != null)) 157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final byte [] bytes = new byte [m_readpos]; 159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos); 160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL)); 162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (IOException ioe) 165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (ioe); 168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleArchiveEnd (final File parentDir, final File archive) 174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_archiveFile = null; 176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleDirStart (final File pathDir, final File dir) 180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // do nothing 182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleFile (final File pathDir, final File file) 185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_log.atTRACE2 ()) m_log.trace2 ("handleFile", "[" + pathDir + "] [" + file + "]"); 187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String name = file.getPath (); 189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String lcName = name.toLowerCase (); 190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (lcName.endsWith (".class")) 192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String className = name.substring (0, name.length () - 6).replace (File.separatorChar, '.'); 194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ((m_coverageFilter == null) || m_coverageFilter.included (className)) 196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project String srcURL = null; 198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project InputStream clsin = null; 199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final File inFile = Files.newFile (pathDir, file.getPath ()); 202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project readFile (inFile); 203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcURL = inFile.toURL ().toExternalForm (); 205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (FileNotFoundException fnfe) 207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // ignore: this should never happen 209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ($assert.ENABLED) 210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project fnfe.printStackTrace (System.out); 212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (IOException ioe) 215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (ioe); 218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project finally 220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (clsin != null) 222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsin.close (); 225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsin = null; 226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (Exception e) 228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (e); 231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // [original class def read into m_readbuf] 235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos); 239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (! clsDef.isInterface ()) ++ m_classCount; 240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_visitor.process (clsDef, false, false, true, m_instrResult); // get metadata only 242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project clsDef = null; 243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project boolean cacheClassDef = true; 246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_instrResult.m_descriptor != null) 248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // do not overwrite existing descriptors to support "first 250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // in the classpath wins" semantics: 251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (! m_mdata.add (m_instrResult.m_descriptor, false)) 253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project cacheClassDef = false; 254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (cacheClassDef && (m_cache != null)) 257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final byte [] bytes = new byte [m_readpos]; 259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos); 260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL)); 262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project catch (IOException ioe) 265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: error code 267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (ioe); 268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public void handleDirEnd (final File pathDir, final File dir) 274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // do nothing 276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // protected: ............................................................. 279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // package: ............................................................... 281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project /* 284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * null 'cache' indicates to only populate the metadata and not bother with 285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * caching instrumented class defs 286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ClassPathProcessorST (final File [] path, final boolean canonical, 288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final IMetaData mdata, final IInclExclFilter filter, 289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final Map cache) 290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (path == null) throw new IllegalArgumentException ("null input: path"); 292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (mdata == null) throw new IllegalArgumentException ("null input: mdata"); 293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_path = path; 295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_canonical = canonical; 296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_mdata = mdata; 297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_coverageFilter = filter; 298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_cache = cache; // can be null 299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_visitor = new InstrVisitor (mdata.getOptions ()); 300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_instrResult = new InstrVisitor.InstrResult (); 301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_log = Logger.getLogger (); 303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // private: ............................................................... 306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project /* 309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * Reads into m_readbuf (m_readpos is updated correspondingly) 310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private void readFile (final File file) 312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throws IOException 313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final int length = (int) file.length (); 315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ensureReadCapacity (length); 317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project InputStream in = null; 319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project try 320f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 321f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project in = new FileInputStream (file); 322f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 323f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project int totalread = 0; 324f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project for (int read; 325f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0; 326f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project totalread += read); 327f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readpos = totalread; 328f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 329f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project finally 330f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 331f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (in != null) try { in.close (); } catch (Exception ignore) {} 332f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 333f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 334f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 335f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project /* 336f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * Reads into m_readbuf (m_readpos is updated correspondingly) 337f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 338f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private void readZipEntry (final ZipInputStream in, final ZipEntry entry) 339f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throws IOException 340f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 341f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final int length = (int) entry.getSize (); // can be -1 if unknown 342f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 343f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (length >= 0) 344f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 345f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ensureReadCapacity (length); 346f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 347f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project int totalread = 0; 348f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project for (int read; 349f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0; 350f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project totalread += read); 351f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readpos = totalread; 352f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 353f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project else 354f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 355f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ensureReadCapacity (BUF_SIZE); 356f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 357f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_baos.reset (); 358f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project for (int read; (read = in.read (m_readbuf)) >= 0; m_baos.write (m_readbuf, 0, read)); 359f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 360f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readbuf = m_baos.copyByteArray (); 361f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readpos = m_readbuf.length; 362f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 363f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 364f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 365f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private void ensureReadCapacity (final int capacity) 366f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 367f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (m_readbuf.length < capacity) 368f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 369f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final int readbuflen = m_readbuf.length; 370f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readbuf = null; 371f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_readbuf = new byte [Math.max (readbuflen << 1, capacity)]; 372f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 373f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 374f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 375f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 376f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final File [] m_path; // never null 377f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final boolean m_canonical; 378f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final IMetaData m_mdata; // never null 379f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final IInclExclFilter m_coverageFilter; // can be null 380f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final InstrVisitor m_visitor; 381f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final InstrVisitor.InstrResult m_instrResult; 382f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final Map /* classJavaName:String -> ClassPathCacheEntry */ m_cache; // can be null 383f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 384f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final Logger m_log; // this class is instantiated and used on a single thread 385f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 386f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private int m_classCount; 387f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 388f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private byte [] m_readbuf; 389f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private int m_readpos; 390f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private ByteArrayOStream m_baos; // TODO: code to guard this from becoming too large 391f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 392f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private File m_archiveFile; 393f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 394f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private static final int BUF_SIZE = 32 * 1024; 395f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 396f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class 397f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------