001: /*
002: * @(#)MinDirChannelLogger.java
003: *
004: * Copyright (C) 2003-2004 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a
009: * copy of this software and associated documentation files (the "Software"),
010: * to deal in the Software without restriction, including without limitation
011: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
012: * and/or sell copies of the Software, and to permit persons to whom the
013: * Software is furnished to do so, subject to the following conditions:
014: *
015: * The above copyright notice and this permission notice shall be included in
016: * all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
019: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
020: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
021: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
022: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
023: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
024: * DEALINGS IN THE SOFTWARE.
025: */
026:
027: package net.sourceforge.groboutils.codecoverage.v2.logger;
028:
029: import java.io.File;
030: import java.io.FileWriter;
031: import java.io.IOException;
032: import java.util.HashSet;
033: import java.util.Set;
034:
035: /**
036: * Same as the DirectoryChannelLogger, but includes a JDK 1.2 optimization
037: * to minimize the size of the log files.
038: *
039: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
040: * @author Graf Leonardo <a href="mailto:leolegenie@hotmail.com">leolegenie@hotmail.com</a>
041: * @version $Date: 2004/07/07 09:39:10 $
042: * @since December 3, 2003
043: */
044: public class MinDirChannelLogger extends DirectoryChannelLogger {
045: private final Set covered = new HashSet(10000, 0.75f);
046:
047: public MinDirChannelLogger(File baseDir) {
048: super (baseDir);
049: }
050:
051: /**
052: * Records a coverage of a marked bytecode instruction. This method should
053: * never throw an exception.
054: *
055: * @param classSignature a signature of the class file being covered.
056: * this signature includes the fully-qualified name of the class,
057: * along with a checksum to uniquely identify it.
058: * @param methodIndex index for a method within the class. The meta-data
059: * store will know how to translate the index to a method signature.
060: * @param markIndex the index of the bytecode instruction mark for this
061: * particular channel.
062: */
063: public void cover(String classSignature, short methodIndex,
064: short markIndex) {
065: if (this .baseDir != null) {
066: char[] out = createCoverString(methodIndex, markIndex);
067:
068: // optimize
069: // String key = classSignature + '.' + out;
070: int csl = classSignature.length();
071: char cs[] = new char[csl + 3];
072: classSignature.getChars(0, csl, cs, 0);
073: cs[csl] = '-';
074: cs[csl + 1] = (char) methodIndex;
075: cs[csl + 2] = (char) markIndex;
076: String key = new String(cs);
077:
078: synchronized (this ) {
079: // access to covered needs to be inside the synchronized block
080: if (!covered.contains(key)) {
081: covered.add(key);
082:
083: File f = getClassFile(this .baseDir, classSignature);
084: FileWriter fw = null;
085: try {
086: fw = new FileWriter(f.toString(), true);
087: try {
088: fw.write(out);
089: fw.flush();
090: } finally {
091: fw.close();
092: }
093: } catch (IOException ioe) {
094: // don't throw this exception outside this block.
095: ioe.printStackTrace();
096:
097: // prevent these errors from occuring again
098: this.baseDir = null;
099: }
100: }
101: }
102: }
103: }
104: }
|