package gb.svnfilter.junit;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.statushandlers.StatusManager;
/**
* Resource manager for JCallDB files
*/
public class JCallDBLoader {
private static final Map<IProject,Map<String, Set<String>>> loadedJCallDB =
new ConcurrentHashMap<IProject, Map<String,Set<String>>>();
/**
* @param proj
* @return The latest JCallDB, loaded from the filesystem if necessary.
*/
@SuppressWarnings("unchecked")
public static synchronized Map<String, Set<String>> loadJCallDB(IProject proj)
{
Map<String, Set<String>> coverageMap = loadedJCallDB.get(proj);
if (coverageMap == null)
{
IFile jcallDB = proj.getFile("test.jcalldb");
String jcallDBPath = jcallDB.getLocation().toOSString();
try
{
ObjectInputStream objIn =
new ObjectInputStream(new FileInputStream(new File(jcallDBPath)));
coverageMap = (Map<String, Set<String>>)objIn.readObject();
loadedJCallDB.put(proj, coverageMap);
listenForChanges(proj);
} catch (Exception e)
{
IStatus status = new Status(IStatus.ERROR,
Activator.PLUGIN_ID,
"Failed to load coverage DB: ", e);
StatusManager.getManager().handle(status);
}
}
return coverageMap;
}
private static synchronized void invalidateJCallDB(final IProject proj)
{
loadedJCallDB.remove(proj);
}
private static void listenForChanges(final IProject proj)
{
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IResourceChangeListener changeListen = new IResourceChangeListener() {
@Override
public void resourceChanged(IResourceChangeEvent xiEvent) {
IResourceDeltaVisitor changeVisitor = new IResourceDeltaVisitor() {
boolean keepLooking = true;
@Override
public boolean visit(IResourceDelta xiDelta) {
if ((xiDelta.getResource() != null) &&
(xiDelta.getResource().getName().equals("test.jcalldb")))
{
invalidateJCallDB(proj);
keepLooking = false;
}
return keepLooking;
}
};
try {
xiEvent.getDelta().accept(changeVisitor);
} catch (CoreException e) {
// Throw away exception
}
}
};
workspace.addResourceChangeListener(changeListen,
IResourceChangeEvent.POST_CHANGE);
}
}