package net.sourceforge.cobertura.coveragedata;
import net.sourceforge.cobertura.CoverageIgnore;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@CoverageIgnore
public abstract class CoverageDataContainer
implements
CoverageData,
Serializable {
private static final long serialVersionUID = 2;
protected transient Lock lock;
Map<Object, CoverageData> children = new HashMap<Object, CoverageData>();
public CoverageDataContainer() {
initLock();
}
private void initLock() {
lock = new ReentrantLock();
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if ((obj == null) || !(obj.getClass().equals(this.getClass())))
return false;
synchronizeState();
CoverageDataContainer coverageDataContainer = (CoverageDataContainer) obj;
coverageDataContainer.synchronizeState();
lock.lock();
try {
return this.children.equals(coverageDataContainer.children);
} finally {
lock.unlock();
}
}
public double getBranchCoverageRate() {
synchronizeState();
int number = 0;
int numberCovered = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfValidBranches();
numberCovered += coverageContainer.getNumberOfCoveredBranches();
}
} finally {
lock.unlock();
}
if (number == 0) {
return 1d;
}
return (double) numberCovered / number;
}
public CoverageData getChild(String name) {
lock.lock();
try {
return (CoverageData) this.children.get(name);
} finally {
lock.unlock();
}
}
public double getLineCoverageRate() {
synchronizeState();
int number = 0;
int numberCovered = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfValidLines();
numberCovered += coverageContainer.getNumberOfCoveredLines();
}
} finally {
lock.unlock();
}
if (number == 0) {
return 1d;
}
return (double) numberCovered / number;
}
public int getNumberOfChildren() {
synchronizeState();
lock.lock();
try {
return this.children.size();
} finally {
lock.unlock();
}
}
public int getNumberOfCoveredBranches() {
synchronizeState();
int number = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfCoveredBranches();
}
} finally {
lock.unlock();
}
return number;
}
public int getNumberOfCoveredLines() {
synchronizeState();
int number = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfCoveredLines();
}
} finally {
lock.unlock();
}
return number;
}
public int getNumberOfValidBranches() {
synchronizeState();
int number = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfValidBranches();
}
} finally {
lock.unlock();
}
return number;
}
public int getNumberOfValidLines() {
synchronizeState();
int number = 0;
lock.lock();
try {
Iterator<CoverageData> iter = this.children.values().iterator();
while (iter.hasNext()) {
CoverageData coverageContainer = (CoverageData) iter.next();
number += coverageContainer.getNumberOfValidLines();
}
} finally {
lock.unlock();
}
return number;
}
public int hashCode() {
synchronizeState();
lock.lock();
try {
return this.children.size();
} finally {
lock.unlock();
}
}
public void merge(CoverageData coverageData) {
synchronizeState();
CoverageDataContainer container = (CoverageDataContainer) coverageData;
container.synchronizeState();
getBothLocks(container);
try {
Iterator<Object> iter = container.children.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
CoverageData newChild = (CoverageData) container.children
.get(key);
CoverageData existingChild = (CoverageData) this.children
.get(key);
if (existingChild != null) {
existingChild.merge(newChild);
} else {
this.children.put(key, newChild);
}
}
} finally {
lock.unlock();
container.lock.unlock();
}
}
protected void getBothLocks(CoverageDataContainer other) {
boolean myLock = false;
boolean otherLock = false;
while ((!myLock) || (!otherLock)) {
try {
myLock = lock.tryLock();
otherLock = other.lock.tryLock();
} finally {
if ((!myLock) || (!otherLock)) {
if (myLock) {
lock.unlock();
}
if (otherLock) {
other.lock.unlock();
}
Thread.yield();
}
}
}
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
initLock();
}
public void synchronizeState() {
}
}