package net.sourceforge.cobertura.coveragedata;
import net.sourceforge.cobertura.CoverageIgnore;
import java.util.*;
@CoverageIgnore
public class ClassData extends CoverageDataContainer
implements
Comparable<ClassData> {
private static final long serialVersionUID = 5;
private Map<Integer, LineData> branches = new HashMap<Integer, LineData>();
private boolean containsInstrumentationInfo = false;
private Set<String> methodNamesAndDescriptors = new HashSet<String>();
private String name = null;
private String sourceFileName = null;
public ClassData() {
}
public ClassData(String name) {
if (name == null)
throw new IllegalArgumentException("Class name must be specified.");
this.name = name;
}
public LineData addLine(int lineNumber, String methodName,
String methodDescriptor) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData == null) {
lineData = new LineData(lineNumber);
children.put(new Integer(lineNumber), lineData);
}
lineData.setMethodNameAndDescriptor(methodName, methodDescriptor);
if (methodName != null && methodDescriptor != null)
methodNamesAndDescriptors.add(methodName + methodDescriptor);
return lineData;
} finally {
lock.unlock();
}
}
public int compareTo(ClassData o) {
if (!o.getClass().equals(ClassData.class))
return Integer.MAX_VALUE;
return this.name.compareTo(((ClassData) o).name);
}
public boolean containsInstrumentationInfo() {
lock.lock();
try {
return this.containsInstrumentationInfo;
} finally {
lock.unlock();
}
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if ((obj == null) || !(obj.getClass().equals(this.getClass())))
return false;
ClassData classData = (ClassData) obj;
getBothLocks(classData);
try {
return super.equals(obj)
&& this.branches.equals(classData.branches)
&& this.methodNamesAndDescriptors
.equals(classData.methodNamesAndDescriptors)
&& this.name.equals(classData.name)
&& this.sourceFileName.equals(classData.sourceFileName);
} finally {
lock.unlock();
classData.lock.unlock();
}
}
public String getBaseName() {
int lastDot = this.name.lastIndexOf('.');
if (lastDot == -1) {
return this.name;
}
return this.name.substring(lastDot + 1);
}
public double getBranchCoverageRate(String methodNameAndDescriptor) {
int total = 0;
int covered = 0;
lock.lock();
try {
for (Iterator<LineData> iter = branches.values().iterator(); iter
.hasNext();) {
LineData next = (LineData) iter.next();
if (methodNameAndDescriptor.equals(next.getMethodName()
+ next.getMethodDescriptor())) {
total += next.getNumberOfValidBranches();
covered += next.getNumberOfCoveredBranches();
}
}
if (total == 0)
return 1.0;
return (double) covered / total;
} finally {
lock.unlock();
}
}
public Collection<Integer> getBranches() {
lock.lock();
try {
return Collections.unmodifiableCollection(branches.keySet());
} finally {
lock.unlock();
}
}
public LineData getLineCoverage(int lineNumber) {
Integer lineObject = new Integer(lineNumber);
lock.lock();
try {
if (!children.containsKey(lineObject)) {
return null;
}
return (LineData) children.get(lineObject);
} finally {
lock.unlock();
}
}
public double getLineCoverageRate(String methodNameAndDescriptor) {
int total = 0;
int hits = 0;
lock.lock();
try {
Iterator<CoverageData> iter = children.values().iterator();
while (iter.hasNext()) {
LineData next = (LineData) iter.next();
if (methodNameAndDescriptor.equals(next.getMethodName()
+ next.getMethodDescriptor())) {
total++;
if (next.getHits() > 0) {
hits++;
}
}
}
if (total == 0)
return 1d;
return (double) hits / total;
} finally {
lock.unlock();
}
}
public LineData getLineData(int lineNumber) {
lock.lock();
try {
return (LineData) children.get(Integer.valueOf(lineNumber));
} finally {
lock.unlock();
}
}
public SortedSet<CoverageData> getLines() {
lock.lock();
try {
return new TreeSet<CoverageData>(this.children.values());
} finally {
lock.unlock();
}
}
public Collection<CoverageData> getLines(String methodNameAndDescriptor) {
Collection<CoverageData> lines = new HashSet<CoverageData>();
lock.lock();
try {
Iterator<CoverageData> iter = children.values().iterator();
while (iter.hasNext()) {
LineData next = (LineData) iter.next();
if (methodNameAndDescriptor.equals(next.getMethodName()
+ next.getMethodDescriptor())) {
lines.add(next);
}
}
return lines;
} finally {
lock.unlock();
}
}
public Set<String> getMethodNamesAndDescriptors() {
lock.lock();
try {
return methodNamesAndDescriptors;
} finally {
lock.unlock();
}
}
public String getName() {
return name;
}
public int getNumberOfValidBranches() {
int number = 0;
lock.lock();
try {
for (Iterator<LineData> i = branches.values().iterator(); i
.hasNext(); number += ((LineData) i.next())
.getNumberOfValidBranches());
return number;
} finally {
lock.unlock();
}
}
public int getNumberOfCoveredBranches() {
int number = 0;
lock.lock();
try {
for (Iterator<LineData> i = branches.values().iterator(); i
.hasNext(); number += ((LineData) i.next())
.getNumberOfCoveredBranches());
return number;
} finally {
lock.unlock();
}
}
public String getPackageName() {
int lastDot = this.name.lastIndexOf('.');
if (lastDot == -1) {
return "";
}
return this.name.substring(0, lastDot);
}
public String getSourceFileName() {
String baseName;
lock.lock();
try {
if (sourceFileName != null)
baseName = sourceFileName;
else {
baseName = getBaseName();
int firstDollarSign = baseName.indexOf('$');
if (firstDollarSign == -1 || firstDollarSign == 0)
baseName += ".java";
else
baseName = baseName.substring(0, firstDollarSign) + ".java";
}
String packageName = getPackageName();
if (packageName.equals(""))
return baseName;
return packageName.replace('.', '/') + '/' + baseName;
} finally {
lock.unlock();
}
}
public int hashCode() {
return this.name.hashCode();
}
public boolean hasBranch(int lineNumber) {
lock.lock();
try {
return branches.containsKey(Integer.valueOf(lineNumber));
} finally {
lock.unlock();
}
}
public boolean isValidSourceLineNumber(int lineNumber) {
lock.lock();
try {
return children.containsKey(Integer.valueOf(lineNumber));
} finally {
lock.unlock();
}
}
public void addLineJump(int lineNumber, int branchNumber) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData != null) {
lineData.addJump(branchNumber);
this.branches.put(Integer.valueOf(lineNumber), lineData);
}
} finally {
lock.unlock();
}
}
public void addLineSwitch(int lineNumber, int switchNumber, int min,
int max, int maxBranches) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData != null) {
lineData.addSwitch(switchNumber, min, max, maxBranches);
this.branches.put(Integer.valueOf(lineNumber), lineData);
}
} finally {
lock.unlock();
}
}
public void merge(CoverageData coverageData) {
ClassData classData = (ClassData) coverageData;
if (!this.getName().equals(classData.getName()))
return;
getBothLocks(classData);
try {
super.merge(coverageData);
for (Iterator<Integer> iter = classData.branches.keySet()
.iterator(); iter.hasNext();) {
Integer key = iter.next();
if (!this.branches.containsKey(key)) {
this.branches.put(key, classData.branches.get(key));
}
}
this.containsInstrumentationInfo |= classData.containsInstrumentationInfo;
this.methodNamesAndDescriptors.addAll(classData
.getMethodNamesAndDescriptors());
if (classData.sourceFileName != null)
this.sourceFileName = classData.sourceFileName;
} finally {
lock.unlock();
classData.lock.unlock();
}
}
public void removeLine(int lineNumber) {
Integer lineObject = Integer.valueOf(lineNumber);
lock.lock();
try {
children.remove(lineObject);
branches.remove(lineObject);
} finally {
lock.unlock();
}
}
public void setContainsInstrumentationInfo() {
lock.lock();
try {
this.containsInstrumentationInfo = true;
} finally {
lock.unlock();
}
}
public void setSourceFileName(String sourceFileName) {
lock.lock();
try {
this.sourceFileName = sourceFileName;
} finally {
lock.unlock();
}
}
public void touch(int lineNumber, int hits) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData == null)
lineData = addLine(lineNumber, null, null);
lineData.touch(hits);
} finally {
lock.unlock();
}
}
public void touchJump(int lineNumber, int branchNumber, boolean branch,
int hits) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData == null)
lineData = addLine(lineNumber, null, null);
lineData.touchJump(branchNumber, branch, hits);
} finally {
lock.unlock();
}
}
public void touchSwitch(int lineNumber, int switchNumber, int branch,
int hits) {
lock.lock();
try {
LineData lineData = getLineData(lineNumber);
if (lineData == null)
lineData = addLine(lineNumber, null, null);
lineData.touchSwitch(switchNumber, branch, hits);
} finally {
lock.unlock();
}
}
}