/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: JavaCoverageLoader.java 199 2006-12-18 14:49:40Z mtnminds $
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.ISessionListener;
import com.mountainminds.eclemma.core.ISessionManager;
import com.mountainminds.eclemma.core.analysis.ICoverageFilter;
import com.mountainminds.eclemma.core.analysis.IJavaCoverageListener;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
import com.mountainminds.eclemma.internal.core.analysis.SessionAnalyzer;
/**
* Internal utility class that loads the coverage data asynchronously, holds the
* current {@link IJavaModelCoverage} object and sends out events in case of
* changed coverage information.
*
* @author Marc R. Hoffmann
* @version $Revision: 199 $
*/
public class JavaCoverageLoader {
private final ISessionManager sessionManager;
private ICoverageSession activeSession;
private IJavaModelCoverage coverage;
private final List listeners = new ArrayList();
/**
* List containing all active {@link ICoverageFilter} instances. The list is
* never null but is normally empty.
*/
private final List coverageFilters = new ArrayList();
private ISessionListener sessionListener = new ISessionListener() {
public void sessionActivated(ICoverageSession session) {
activeSession = session;
// TODO Looks like this has no effect
Platform.getJobManager().cancel(LOADJOB);
if (session == null) {
coverage = null;
fireCoverageChanged();
} else {
coverage = IJavaModelCoverage.LOADING;
fireCoverageChanged();
new LoadSessionJob(activeSession).schedule();
}
}
public void sessionAdded(ICoverageSession addedSession) {
}
public void sessionRemoved(ICoverageSession removedSession) {
}
};
private static final Object LOADJOB = new Object();
private class LoadSessionJob extends Job {
private final ICoverageSession session;
public LoadSessionJob(ICoverageSession session) {
super(NLS.bind(CoreMessages.AnalyzingCoverageSession_task, session.getDescription()));
this.session = session;
}
protected IStatus run(IProgressMonitor monitor) {
// Before we process the session we must reset all filters
synchronized (coverageFilters) {
Iterator coverageFiltersIter = coverageFilters.iterator();
while (coverageFiltersIter.hasNext())
{
((ICoverageFilter)coverageFiltersIter.next()).resetFilter();
}
}
IJavaModelCoverage c;
try {
c = new SessionAnalyzer().processSession(session, monitor);
} catch (CoreException e) {
return e.getStatus();
}
coverage = monitor.isCanceled() ? null : c;
fireCoverageChanged();
return Status.OK_STATUS;
}
public boolean belongsTo(Object family) {
return family == LOADJOB;
}
};
public JavaCoverageLoader(ISessionManager sessionManager) {
this.sessionManager = sessionManager;
sessionManager.addSessionListener(sessionListener);
}
public void addJavaCoverageListener(IJavaCoverageListener l) {
if (l == null)
throw new NullPointerException();
if (!listeners.contains(l)) {
listeners.add(l);
}
}
public void removeJavaCoverageListener(IJavaCoverageListener l) {
listeners.remove(l);
}
/**
* @param filter Filter to add to list of active filters.
*/
public void addCoverageFilter(ICoverageFilter filter) {
if (filter == null)
throw new NullPointerException();
synchronized (coverageFilters) {
if (!coverageFilters.contains(filter)) {
coverageFilters.add(filter);
}
}
}
/**
* @param filter Filter to remove from list of active filters.
*/
public void removeCoverageFilter(ICoverageFilter filter) {
if (filter == null)
throw new NullPointerException();
synchronized (coverageFilters) {
coverageFilters.remove(filter);
}
}
/**
* @return If some filters are active
*/
public boolean coverageFiltersActive() {
return (coverageFilters.size() > 0);
}
/**
* @param element Element to test.
* @param defaultRet The value to return if no filters are present.
* @return True if the element should be excluded from the coverage view.
*/
public boolean isElementFiltered(IJavaElement element, boolean defaultRet) {
boolean isElementFiltered = defaultRet;
synchronized (coverageFilters) {
// Consult all the load helpers
if ((coverageFilters.size() > 0) &&
(element != null))
{
isElementFiltered = false;
Iterator iter = coverageFilters.iterator();
while (iter.hasNext())
{
ICoverageFilter loadHelper = (ICoverageFilter)iter.next();
try
{
isElementFiltered |= loadHelper.isElementFiltered(element);
}
catch (Throwable th)
{
IStatus status = new Status(IStatus.ERROR, EclEmmaCorePlugin.ID,
IStatus.ERROR,
"Uncaught exception when invoking Coverage Filer: " + //$NON-NLS-1$
loadHelper.getName(), th);
EclEmmaCorePlugin.getInstance().getLog().log(status);
}
}
}
}
return isElementFiltered;
}
public int[] getFilteredLines(int[] lines, IJavaElement element, boolean defaultRet) {
int[] filteredLines = lines;
synchronized (coverageFilters) {
// Consult all the load helpers
if ((coverageFilters.size() > 0) &&
(element != null))
{
Iterator iter = coverageFilters.iterator();
while (iter.hasNext())
{
ICoverageFilter loadHelper = (ICoverageFilter)iter.next();
try
{
filteredLines = loadHelper.getFilteredLines(filteredLines, element);
}
catch (Throwable th)
{
IStatus status = new Status(IStatus.ERROR, EclEmmaCorePlugin.ID,
IStatus.ERROR,
"Uncaught exception when invoking Coverage Filer: " + //$NON-NLS-1$
loadHelper.getName(), th);
EclEmmaCorePlugin.getInstance().getLog().log(status);
}
}
}
}
return filteredLines;
}
protected void fireCoverageChanged() {
// avoid concurrent modification issues
Iterator i = new ArrayList(listeners).iterator();
while (i.hasNext()) {
((IJavaCoverageListener) i.next()).coverageChanged();
}
}
public IJavaModelCoverage getJavaModelCoverage() {
return coverage;
}
public void dispose() {
sessionManager.removeSessionListener(sessionListener);
}
}