| 1 9 package com.vladium.emma.rt; 10 11 import java.io.File ; 12 import java.io.FileInputStream ; 13 import java.io.FileNotFoundException ; 14 import java.io.IOException ; 15 import java.io.InputStream ; 16 import java.util.Map ; 17 import java.util.jar.JarInputStream ; 18 import java.util.jar.Manifest ; 19 import java.util.zip.ZipEntry ; 20 import java.util.zip.ZipInputStream ; 21 22 import com.vladium.jcd.cls.ClassDef; 23 import com.vladium.jcd.parser.ClassDefParser; 24 import com.vladium.logging.Logger; 25 import com.vladium.util.ByteArrayOStream; 26 import com.vladium.util.Files; 27 import com.vladium.util.IPathEnumerator; 28 import com.vladium.util.asserts.$assert; 29 import com.vladium.emma.IAppErrorCodes; 30 import com.vladium.emma.EMMARuntimeException; 31 import com.vladium.emma.data.IMetaData; 32 import com.vladium.emma.filter.IInclExclFilter; 33 import com.vladium.emma.instr.InstrVisitor; 34 35 39 public 40 final class ClassPathProcessorST implements IPathEnumerator.IPathHandler, IAppErrorCodes 41 { 42 44 public void run () 45 { 46 long start = System.currentTimeMillis (); 47 48 final IPathEnumerator enumerator = IPathEnumerator.Factory.create (m_path, m_canonical, this); 50 51 m_readbuf = new byte [BUF_SIZE]; m_readpos = 0; 54 m_baos = new ByteArrayOStream (BUF_SIZE); 56 if (m_log.atINFO ()) 57 { 58 m_log.info ("processing classpath ..."); 59 } 60 61 try 63 { 64 enumerator.enumerate (); 65 } 66 catch (IOException ioe) 67 { 68 throw new EMMARuntimeException (INSTR_IO_FAILURE, ioe); 69 } 70 71 if (m_log.atINFO ()) 72 { 73 final long end = System.currentTimeMillis (); 74 75 m_log.info ("[" + m_classCount + " class(es) processed in " + (end - start) + " ms]"); 76 } 77 } 78 79 81 public void handleArchiveStart (final File parentDir, final File archive, final Manifest manifest) 82 { 83 m_archiveFile = Files.newFile (parentDir, archive.getPath ()); 84 } 85 86 public void handleArchiveEntry (final JarInputStream in, final ZipEntry entry) 87 { 88 if (m_log.atTRACE2 ()) m_log.trace2 ("handleArchiveEntry", "[" + entry.getName () + "]"); 89 90 final String name = entry.getName (); 91 final String lcName = name.toLowerCase (); 92 93 if (lcName.endsWith (".class")) 94 { 95 final String className = name.substring (0, name.length () - 6).replace ('/', '.'); 96 97 if ((m_coverageFilter == null) || m_coverageFilter.included (className)) 98 { 99 String srcURL = null; 100 InputStream clsin = null; 101 try 102 { 103 readZipEntry (in, entry); 104 105 srcURL = "jar:".concat (m_archiveFile.toURL ().toExternalForm ()).concat ("!/").concat (name); 106 } 107 catch (FileNotFoundException fnfe) 108 { 109 if ($assert.ENABLED) 111 { 112 fnfe.printStackTrace (System.out); 113 } 114 } 115 catch (IOException ioe) 116 { 117 throw new EMMARuntimeException (ioe); 119 } 120 finally 121 { 122 if (clsin != null) 123 try 124 { 125 clsin.close (); 126 clsin = null; 127 } 128 catch (Exception e) 129 { 130 throw new EMMARuntimeException (e); 132 } 133 } 134 135 137 try 138 { 139 ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos); 140 if (! clsDef.isInterface ()) ++ m_classCount; 141 142 m_visitor.process (clsDef, false, false, true, m_instrResult); clsDef = null; 144 145 boolean cacheClassDef = true; 146 147 if (m_instrResult.m_descriptor != null) 148 { 149 152 if (! m_mdata.add (m_instrResult.m_descriptor, false)) 153 cacheClassDef = false; 154 } 155 156 if (cacheClassDef && (m_cache != null)) 157 { 158 final byte [] bytes = new byte [m_readpos]; 159 System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos); 160 161 m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL)); 162 } 163 } 164 catch (IOException ioe) 165 { 166 throw new EMMARuntimeException (ioe); 168 } 169 } 170 } 171 } 172 173 public void handleArchiveEnd (final File parentDir, final File archive) 174 { 175 m_archiveFile = null; 176 } 177 178 179 public void handleDirStart (final File pathDir, final File dir) 180 { 181 } 183 184 public void handleFile (final File pathDir, final File file) 185 { 186 if (m_log.atTRACE2 ()) m_log.trace2 ("handleFile", "[" + pathDir + "] [" + file + "]"); 187 188 final String name = file.getPath (); 189 final String lcName = name.toLowerCase (); 190 191 if (lcName.endsWith (".class")) 192 { 193 final String className = name.substring (0, name.length () - 6).replace (File.separatorChar, '.'); 194 195 if ((m_coverageFilter == null) || m_coverageFilter.included (className)) 196 { 197 String srcURL = null; 198 InputStream clsin = null; 199 try 200 { 201 final File inFile = Files.newFile (pathDir, file.getPath ()); 202 readFile (inFile); 203 204 srcURL = inFile.toURL ().toExternalForm (); 205 } 206 catch (FileNotFoundException fnfe) 207 { 208 if ($assert.ENABLED) 210 { 211 fnfe.printStackTrace (System.out); 212 } 213 } 214 catch (IOException ioe) 215 { 216 throw new EMMARuntimeException (ioe); 218 } 219 finally 220 { 221 if (clsin != null) 222 try 223 { 224 clsin.close (); 225 clsin = null; 226 } 227 catch (Exception e) 228 { 229 throw new EMMARuntimeException (e); 231 } 232 } 233 234 236 try 237 { 238 ClassDef clsDef = ClassDefParser.parseClass (m_readbuf, m_readpos); 239 if (! clsDef.isInterface ()) ++ m_classCount; 240 241 m_visitor.process (clsDef, false, false, true, m_instrResult); clsDef = null; 243 244 245 boolean cacheClassDef = true; 246 247 if (m_instrResult.m_descriptor != null) 248 { 249 252 if (! m_mdata.add (m_instrResult.m_descriptor, false)) 253 cacheClassDef = false; 254 } 255 256 if (cacheClassDef && (m_cache != null)) 257 { 258 final byte [] bytes = new byte [m_readpos]; 259 System.arraycopy (m_readbuf, 0, bytes, 0, m_readpos); 260 261 m_cache.put (className, new ClassPathCacheEntry (bytes, srcURL)); 262 } 263 } 264 catch (IOException ioe) 265 { 266 throw new EMMARuntimeException (ioe); 268 } 269 } 270 } 271 } 272 273 public void handleDirEnd (final File pathDir, final File dir) 274 { 275 } 277 278 280 282 283 287 ClassPathProcessorST (final File [] path, final boolean canonical, 288 final IMetaData mdata, final IInclExclFilter filter, 289 final Map cache) 290 { 291 if (path == null) throw new IllegalArgumentException ("null input: path"); 292 if (mdata == null) throw new IllegalArgumentException ("null input: mdata"); 293 294 m_path = path; 295 m_canonical = canonical; 296 m_mdata = mdata; 297 m_coverageFilter = filter; 298 m_cache = cache; m_visitor = new InstrVisitor (mdata.getOptions ()); 300 m_instrResult = new InstrVisitor.InstrResult (); 301 302 m_log = Logger.getLogger (); 303 } 304 305 307 308 311 private void readFile (final File file) 312 throws IOException  313 { 314 final int length = (int) file.length (); 315 316 ensureReadCapacity (length); 317 318 InputStream in = null; 319 try 320 { 321 in = new FileInputStream (file); 322 323 int totalread = 0; 324 for (int read; 325 (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0; 326 totalread += read); 327 m_readpos = totalread; 328 } 329 finally 330 { 331 if (in != null) try { in.close (); } catch (Exception ignore) {} 332 } 333 } 334 335 338 private void readZipEntry (final ZipInputStream in, final ZipEntry entry) 339 throws IOException  340 { 341 final int length = (int) entry.getSize (); 343 if (length >= 0) 344 { 345 ensureReadCapacity (length); 346 347 int totalread = 0; 348 for (int read; 349 (totalread < length) && (read = in.read (m_readbuf, totalread, length - totalread)) >= 0; 350 totalread += read); 351 m_readpos = totalread; 352 } 353 else 354 { 355 ensureReadCapacity (BUF_SIZE); 356 357 m_baos.reset (); 358 for (int read; (read = in.read (m_readbuf)) >= 0; m_baos.write (m_readbuf, 0, read)); 359 360 m_readbuf = m_baos.copyByteArray (); 361 m_readpos = m_readbuf.length; 362 } 363 } 364 365 private void ensureReadCapacity (final int capacity) 366 { 367 if (m_readbuf.length < capacity) 368 { 369 final int readbuflen = m_readbuf.length; 370 m_readbuf = null; 371 m_readbuf = new byte [Math.max (readbuflen << 1, capacity)]; 372 } 373 } 374 375 376 private final File [] m_path; private final boolean m_canonical; 378 private final IMetaData m_mdata; private final IInclExclFilter m_coverageFilter; private final InstrVisitor m_visitor; 381 private final InstrVisitor.InstrResult m_instrResult; 382 private final Map m_cache; 384 private final Logger m_log; 386 private int m_classCount; 387 388 private byte [] m_readbuf; 389 private int m_readpos; 390 private ByteArrayOStream m_baos; 392 private File m_archiveFile; 393 394 private static final int BUF_SIZE = 32 * 1024; 395 396 } | Popular Tags |