./codecover/src/org/codecover/eclipse/views/CorrelationView.java
/******************************************************************************
* Copyright (c) 2007 Stefan Franke, Robert Hanussek, Benjamin Keil, *
* Steffen Kieß, Johannes Langauf, *
* Christoph Marian Müller, Igor Podolskiy, *
* Tilmann Scheller, Michael Starzmann, Markus Wittlinger *
* All rights reserved. This program and the accompanying materials *
* are made available under the terms of the Eclipse Public License v1.0 *
* which accompanies this distribution, and is available at *
* http://www.eclipse.org/legal/epl-v10.html *
******************************************************************************/
package org.codecover.eclipse.views;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;
import org.codecover.eclipse.CodeCoverPlugin;
import org.codecover.eclipse.Messages;
import org.codecover.eclipse.preferences.PreferencePageRoot;
import org.codecover.eclipse.preferences.RGBWithBoundaries;
import org.codecover.eclipse.tscmanager.ActiveTSContainerInfo;
import org.codecover.eclipse.tscmanager.TSContainerInfo;
import org.codecover.eclipse.tscmanager.TSContainerManagerListener;
import org.codecover.eclipse.views.controls.LegendControl;
import org.codecover.eclipse.views.controls.MatrixControl;
import org.codecover.eclipse.views.controls.LegendControl.ILegendContentProvider;
import org.codecover.eclipse.views.controls.MatrixControl.CorrelationInfo;
import org.codecover.eclipse.views.controls.MatrixControl.IMatrixContentProvider;
import org.codecover.eclipse.views.controls.MatrixControl.TestCaseInfo;
import org.codecover.metrics.Metric;
import org.codecover.metrics.MetricProvider;
import org.codecover.metrics.correlation.CorrelationMetric;
import org.codecover.metrics.correlation.CorrelationResult;
import org.codecover.model.TestCase;
import org.codecover.model.TestSession;
import org.codecover.model.TestSessionContainer;
import org.codecover.model.utils.ChangeType;
import org.codecover.model.utils.Logger;
import org.codecover.model.utils.criteria.Criterion;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
/**
* This class represents an eclipse view. It is used to calculate and display
* the results of the available {@link CorrelationMetric}s.
*
* @author Markus Wittlinger
* @version 1.0 ($Id: CorrelationView.java 1 2007-12-12 17:37:26Z t-scheller $)
*/
public class CorrelationView extends ViewPart {
private static final Logger logger = CodeCoverPlugin.getDefault()
.getLogger();
private static final String TAG_WEIGHTS_LENGTH = "WeightsLength"; //$NON-NLS-1$
private static final String TAG_FILTER_TREE_ACTION = "filterTreeAction"; //$NON-NLS-1$
private static final String TAG_SHOW_LEGEND_ACTION = "showLegendAction"; //$NON-NLS-1$
private static final String TAG_AUTO_CALCULATE_ACTION = "autoCalculateAction"; //$NON-NLS-1$
private static final String TAG_SELECTED = "Selected"; //$NON-NLS-1$
private static final String TAG_SASH_WEIGHTS = "sashWeights"; //$NON-NLS-1$
private static final String TAG_SASH_WEIGHT_PREFIX = "sashWeight"; //$NON-NLS-1$
private static final String TAG_ALL_CORRELATIONS_ACTION = "allCorrelationsAction"; //$NON-NLS-1$
private final Set correlationMetrics;
private final List correlationActions;
private IAction allCorrelationsAction;
private IAction autoCalculateAction;
private IAction filterTreeAction;
private MatrixControl matrixControl;
private TreeViewer treeViewer;
private IAction showLegendAction;
private final Map resultMap;
private final GraphElement rootChainElement;
private final List activeTestCases;
private final List lastUsedTestCases;
private ScrolledComposite scrolledComposite;
private final Set activeMetrics;
private IMemento memento;
private SashForm sashForm;
private boolean calculationPending = false;
private final Object lock = new Object();
private final CorrelationMetricComparator correlationMetricComparator = new CorrelationMetricComparator();
private final TestCaseComparator testCaseComparator = new TestCaseComparator();
private static final String TREE_LABEL_FORMAT = Messages
.getString("CorrelationView.TREE_LABEL_FORMAT"); //$NON-NLS-1$
private static final String TOOLTIP_SHOW_LEGEND_ACTION = Messages
.getString("CorrelationView.TOOLTIP_SHOW_LEGEND_ACTION"); //$NON-NLS-1$
private static final String DESCRIPTION_CHOOSE_CORRELATION_ACTION = Messages
.getString("CorrelationView.DESCRIPTION_CHOOSE_CORRELATION_ACTION"); //$NON-NLS-1$
private static final String TOOLTIP_CHOOSE_CORRELATION_ACTION = Messages
.getString("CorrelationView.TOOLTIP_CHOOSE_CORRELATION_ACTION"); //$NON-NLS-1$
private static final String LABEL_CHOOSE_CORRELATION_ACTION = Messages
.getString("CorrelationView.LABEL_CHOOSE_CORRELATION_ACTION"); //$NON-NLS-1$
private static final String TOOLTIP_AUTO_CALCULATE_ACTION = Messages
.getString("CorrelationView.TOOLTIP_AUTO_CALCULATE_ACTION"); //$NON-NLS-1$
private static final String DESCRIPTION_AUTO_CALCULATE_ACTION = Messages
.getString("CorrelationView.DESCRIPTION_AUTO_CALCULATE_ACTION"); //$NON-NLS-1$
private static final String LABEL_AUTO_CALCULATE_ACTION = Messages
.getString("CorrelationView.LABEL_AUTO_CALCULATE_ACTION"); //$NON-NLS-1$
private static final String DESCRIPTION_SHOW_LEGEND_ACTION = Messages
.getString("CorrelationView.DESCRIPTION_SHOW_LEGEND_ACTION"); //$NON-NLS-1$
private static final String LABEL_SHOW_LEGEND_ACTION = Messages
.getString("CorrelationView.LABEL_SHOW_LEGEND_ACTION"); //$NON-NLS-1$
private static final String TOOLTIP_FILTER_TREE_ACTION = Messages
.getString("CorrelationView.TOOLTIP_FILTER_TREE_ACTION"); //$NON-NLS-1$
private static final String DESCRIPTION_FILTER_TREE_ACTION = Messages
.getString("CorrelationView.DESCRIPTION_FILTER_TREE_ACTION"); //$NON-NLS-1$
private static final String LABEL_FILTER_TREE_ACTION = Messages
.getString("CorrelationView.LABEL_FILTER_TREE_ACTION"); //$NON-NLS-1$
private static final String DESCRIPTION_ALL_CORRELATION_METRICS = Messages
.getString("CorrelationView.DESCRIPTION_ALL_CORRELATION_METRICS"); //$NON-NLS-1$
private static final String LABEL_ALL_CORRELATION_METRICS = Messages
.getString("CorrelationView.LABEL_ALL_CORRELATION_METRICS"); //$NON-NLS-1$
private static final String LABEL_CSV_EXPORT_FILE_DIALOG = Messages
.getString("CorrelationView.LABEL_CSV_EXPORT_FILE_DIALOG"); //$NON-NLS-1$
private static final String LABEL_CSV_EXPORT_ACTION = Messages
.getString("CorrelationView.LABEL_CSV_EXPORT_ACTION"); //$NON-NLS-1$
private static final String CSV_EXPORT_TOOLTIP_DESCRIPTION = Messages
.getString("CorrelationView.CSV_EXPORT_TOOLTIP_DESCRIPTION"); //$NON-NLS-1$
/**
* Constructor.
*/
public CorrelationView() {
this.resultMap = new HashMap();
this.activeTestCases = new Vector();
this.lastUsedTestCases = new Vector();
this.activeMetrics = new TreeSet(
this.correlationMetricComparator);
this.correlationMetrics = new TreeSet(
this.correlationMetricComparator);
this.correlationActions = new Vector();
this.rootChainElement = new GraphElement();
CodeCoverPlugin.getDefault().getTSContainerManager().addListener(
new TSManagerListener());
}
/**
* Gets all the {@link CorrelationMetric}s
*
* @return the {@link Set} of {@link CorrelationMetric}s
*/
private final static Set getCorrelationMetrics() {
Set correlationMetrics = new HashSet();
for (Metric metric : MetricProvider.getAvailabeMetrics(CodeCoverPlugin
.getDefault().getEclipsePluginManager().getPluginManager(),
CodeCoverPlugin.getDefault().getLogger())) {
if (metric instanceof CorrelationMetric) {
correlationMetrics.add((CorrelationMetric) metric);
}
}
return correlationMetrics;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
this.correlationMetrics.addAll(getCorrelationMetrics());
this.filterTreeAction = createActionFilterTree();
this.showLegendAction = createActionShowLegend();
this.autoCalculateAction = createActionAutoCalculate();
this.correlationActions.addAll(createCorrelationActions());
this.allCorrelationsAction = createAllCorrelationsAction();
initializeToolBar();
this.sashForm = new SashForm(parent, SWT.HORIZONTAL);
// Initialize the tree viewer pane.
Composite leftComposite = new Composite(this.sashForm, SWT.NONE);
leftComposite.setLayout(new GridLayout(1, false));
createTreeViewerPane(leftComposite);
// Initialize the matrix pane.
Composite rightComposite = new Composite(this.sashForm, SWT.NONE);
rightComposite.setLayout(new GridLayout(2, false));
createCorrelationMatrixPane(rightComposite);
// Set the weights of the sash from.
this.sashForm.setWeights(getWeightsFromMemento());
calculateCorrelation();
this.lastUsedTestCases.clear();
this.activeTestCases.clear();
ActiveTSContainerInfo activeTSContainer = CodeCoverPlugin.getDefault()
.getTSContainerManager().getActiveTSContainer();
if (activeTSContainer != null) {
this.lastUsedTestCases.addAll(sortTestCases(activeTSContainer
.getActiveTestCases()));
this.activeTestCases.addAll(sortTestCases(activeTSContainer
.getActiveTestCases()));
}
calculateSumbsumptionChain();
refreshTreeViewer();
refreshMatrix();
CodeCoverPlugin.getDefault().getPreferenceStore()
.addPropertyChangeListener(new PreferenceChangeListener());
this.treeViewer.setInput(this.rootChainElement);
}
private final int[] getWeightsFromMemento() {
int[] weights = new int[] {1, 4};
if (this.memento != null) {
IMemento sashWeightsMemento = this.memento
.getChild(TAG_SASH_WEIGHTS);
if (sashWeightsMemento != null) {
int length = sashWeightsMemento.getInteger(TAG_WEIGHTS_LENGTH);
weights = new int[length];
for (int i = 0; i < length; i++) {
weights[i] = sashWeightsMemento
.getInteger(TAG_SASH_WEIGHT_PREFIX + i);
}
}
}
return weights;
}
/*
* Creates the tree viewer pane on the given composite. @param mainComposite
* the given composite.
*/
private final void createTreeViewerPane(Composite mainComposite) {
this.treeViewer = new TreeViewer(mainComposite, SWT.H_SCROLL
| SWT.V_SCROLL);
this.treeViewer.setContentProvider(new TreeContentProvider());
this.treeViewer.setLabelProvider(new TreeLabelProvider());
this.treeViewer.setComparator(new TreeComparator());
this.treeViewer.getTree().setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true));
}
/**
* Creates the matrix pane in the given composite
*
* @param mainComposite
* the given composite.
*/
private final void createCorrelationMatrixPane(Composite mainComposite) {
this.scrolledComposite = new ScrolledComposite(mainComposite,
SWT.H_SCROLL | SWT.V_SCROLL);
this.matrixControl = new MatrixControl(this.scrolledComposite,
SWT.BORDER);
this.matrixControl
.setMatrixContentProvider(new MatrixContentProvider());
this.matrixControl
.setLegendContentProvider(new LegendContentProvider());
this.matrixControl.setShowLegend(this.showLegendAction.isChecked());
this.scrolledComposite.setContent(this.matrixControl);
this.scrolledComposite.setExpandVertical(true);
this.scrolledComposite.setExpandHorizontal(true);
this.scrolledComposite.setAlwaysShowScrollBars(true);
this.scrolledComposite.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
CorrelationView.this.scrolledComposite
.setMinSize(CorrelationView.this.matrixControl
.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
this.scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
true, true));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
@Override
public void setFocus() {
this.matrixControl.forceFocus();
}
private final Color getColorForCorrelation(double correlation) {
Display display = getViewSite().getShell().getDisplay();
for (RGBWithBoundaries boundaries : PreferencePageRoot
.getCorrelationMatrixColors()) {
double lower = (double) boundaries.getLowerBoundary() / 100;
double upper = (double) boundaries.getUpperBoundary() / 100;
if (lower == upper) {
if (correlation == lower) {
return new Color(display, boundaries.getRGB());
}
} else {
if (correlation >= lower && correlation < upper) {
return new Color(display, boundaries.getRGB());
}
}
}
return display.getSystemColor(SWT.COLOR_BLACK);
}
private final List getCorrelationInfos() {
List list = new Vector();
if (this.activeMetrics.isEmpty()) {
return list;
}
for (int i = 0; i < this.lastUsedTestCases.size(); i++) {
TestCase firstTestCase = this.lastUsedTestCases.get(i);
for (int a = 0; a < this.lastUsedTestCases.size(); a++) {
TestCase secondTestCase = this.lastUsedTestCases.get(a);
Set testCases = new HashSet();
testCases.add(firstTestCase);
testCases.add(secondTestCase);
int amountFirstTestCase = 0;
int amountSecondTestCase = 0;
int amountShared = 0;
// XXX: (see comment in getCummulatedCorrelation) -- Johannes
double correlation = getCummulatedCorrelation(firstTestCase,
secondTestCase);
for (CorrelationMetric correlationMetric : this.activeMetrics) {
CorrelationResult result = this.resultMap
.get(correlationMetric);
if (result == null) {
continue;
}
amountFirstTestCase += result
.getCoverableItemCount(firstTestCase);
amountSecondTestCase += result
.getCoverableItemCount(secondTestCase);
amountShared += result
.getSharedCoverableItemCount(testCases);
}
CorrelationInfo correlationInfo = this.matrixControl.new CorrelationInfo(
correlation, amountShared, amountFirstTestCase,
amountSecondTestCase);
list.add(correlationInfo);
}
}
return list;
}
private final List getTestCaseInfos() {
List list = new Vector();
if (this.activeMetrics.isEmpty()) {
return list;
}
for (TestCase testCase : this.lastUsedTestCases) {
TestCaseInfo testCaseInfo = this.matrixControl.new TestCaseInfo(
testCase.getName(), truncateString(testCase.getName(), 9),
testCase.getTestSession().getName());
list.add(testCaseInfo);
}
return list;
}
private final String truncateString(String text, int length) {
String trailString = "…"; //$NON-NLS-1$
if (text.length() <= length) {
return text;
}
String truncatedString = text.substring(0, length
- trailString.length());
truncatedString += trailString;
return truncatedString;
}
private final void initializeToolBar() {
IToolBarManager toolBarManager = getViewSite().getActionBars()
.getToolBarManager();
toolBarManager.add(createActionCSVExport());
toolBarManager.add(this.filterTreeAction);
toolBarManager.add(createActionChooseMetric());
toolBarManager.add(this.autoCalculateAction);
toolBarManager.add(this.showLegendAction);
}
private final IAction createActionFilterTree() {
IAction filterTreeAction = new Action(LABEL_FILTER_TREE_ACTION,
IAction.AS_CHECK_BOX) {
@Override
public void run() {
onFilterTree();
}
};
filterTreeAction.setChecked(getBooleanFromMemento(
TAG_FILTER_TREE_ACTION, false));
filterTreeAction.setDescription(DESCRIPTION_FILTER_TREE_ACTION);
filterTreeAction.setToolTipText(TOOLTIP_FILTER_TREE_ACTION);
filterTreeAction.setImageDescriptor(CodeCoverPlugin.getDefault()
.getImageRegistry().getDescriptor(
CodeCoverPlugin.Image.HIDE_TREE_ITEMS.getPath()));
return filterTreeAction;
}
private final IAction createActionShowLegend() {
IAction showLegendAction = new Action(LABEL_SHOW_LEGEND_ACTION,
IAction.AS_CHECK_BOX) {
@Override
public void run() {
onShowLegend();
}
};
showLegendAction.setChecked(getBooleanFromMemento(
TAG_SHOW_LEGEND_ACTION, true));
showLegendAction.setDescription(DESCRIPTION_SHOW_LEGEND_ACTION);
showLegendAction.setToolTipText(TOOLTIP_SHOW_LEGEND_ACTION);
showLegendAction.setImageDescriptor(CodeCoverPlugin.getDefault()
.getImageRegistry().getDescriptor(
CodeCoverPlugin.Image.SHOW_LEGEND.getPath()));
return showLegendAction;
}
private final IAction createActionAutoCalculate() {
IAction autoCalculateAction = new Action(LABEL_AUTO_CALCULATE_ACTION,
IAction.AS_CHECK_BOX) {
@Override
public void run() {
if (CorrelationView.this.autoCalculateAction.isChecked()) {
onCalculateCorrelation();
}
}
};
autoCalculateAction.setChecked(getBooleanFromMemento(
TAG_AUTO_CALCULATE_ACTION, true));
autoCalculateAction.setDescription(DESCRIPTION_AUTO_CALCULATE_ACTION);
autoCalculateAction.setToolTipText(TOOLTIP_AUTO_CALCULATE_ACTION);
autoCalculateAction.setImageDescriptor(CodeCoverPlugin.getDefault()
.getImageRegistry().getDescriptor(
CodeCoverPlugin.Image.AUTO_CALCULATE.getPath()));
return autoCalculateAction;
}
private final IAction createActionChooseMetric() {
IAction chooseMetricAction = new Action(
LABEL_CHOOSE_CORRELATION_ACTION, IAction.AS_DROP_DOWN_MENU) {
@Override
public void run() {
onCalculateCorrelation();
}
};
chooseMetricAction
.setDescription(DESCRIPTION_CHOOSE_CORRELATION_ACTION);
chooseMetricAction.setToolTipText(TOOLTIP_CHOOSE_CORRELATION_ACTION);
chooseMetricAction.setImageDescriptor(CodeCoverPlugin.getDefault()
.getImageRegistry().getDescriptor(
CodeCoverPlugin.Image.CALCULATE_CORRELATION.getPath()));
chooseMetricAction.setMenuCreator(new MetricMenuCreator());
return chooseMetricAction;
}
private final IAction createActionCSVExport() {
IAction exportCSVAction = new Action(LABEL_CSV_EXPORT_ACTION,
IAction.AS_PUSH_BUTTON) {
@Override
public void run() {
onExportCSV();
}
};
exportCSVAction.setDescription(CSV_EXPORT_TOOLTIP_DESCRIPTION);
exportCSVAction.setToolTipText(CSV_EXPORT_TOOLTIP_DESCRIPTION);
exportCSVAction.setImageDescriptor(CodeCoverPlugin.getDefault()
.getImageRegistry().getDescriptor(
CodeCoverPlugin.Image.CSV_EXPORT.getPath()));
return exportCSVAction;
}
private final void refreshLastUsedTestCases(Collection testCases) {
this.lastUsedTestCases.clear();
this.lastUsedTestCases.addAll(sortTestCases(testCases));
}
private final void onActiveTestCasesChanged(Set testCases) {
refreshActiveTestCaseList(testCases);
if (this.autoCalculateAction.isChecked()) {
refreshLastUsedTestCases(this.activeTestCases);
refreshTreeViewer();
refreshMatrix();
}
}
private final void onTSCChanged(Set testCases) {
synchronized (lock) {
this.calculationPending = false;
}
refreshActiveTestCaseList(testCases);
if (this.autoCalculateAction.isChecked()) {
onCalculateCorrelation();
}
}
private final void onExportCSV() {
FileDialog fileDialog = new FileDialog(getSite().getShell(), SWT.SAVE);
fileDialog.setText(LABEL_CSV_EXPORT_FILE_DIALOG);
fileDialog.setFilterExtensions(new String[] {"*.csv", "*.*"}); //$NON-NLS-1$//$NON-NLS-2$
String location = fileDialog.open();
if (location != null) {
File exportFile = new File(location);
String outputString = this.matrixControl.createCSVExportString();
exportFile.delete();
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(exportFile, true);
FileChannel outChannel = fileOutputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(outputString.length());
byte[] bytes = outputString.getBytes();
buffer.put(bytes);
buffer.flip();
outChannel.write(buffer);
fileOutputStream.close();
} catch (FileNotFoundException e) {
CorrelationView.logger.error("A FileNotFoundException " + //$NON-NLS-1$
"occurred during csv export", e); //$NON-NLS-1$
} catch (IOException e) {
CorrelationView.logger.error(
"A IOException occurred during csv export", e); //$NON-NLS-1$
}
}
}
private final void onShowLegend() {
this.matrixControl.setShowLegend(!this.matrixControl.isShowLegend());
refreshMatrix();
}
private final void onChooseMetric(CorrelationMetric correlationMetric) {
this.activeMetrics.clear();
this.activeMetrics.add(correlationMetric);
refreshTreeViewer();
refreshMatrix();
}
private final void onChooseAllMetrics() {
this.activeMetrics.addAll(this.correlationMetrics);
refreshTreeViewer();
refreshMatrix();
}
private final void onFilterTree() {
boolean visible = !this.filterTreeAction.isChecked();
for (GraphElement graphElement : this.rootChainElement.children) {
if (graphElement.children.isEmpty()) {
graphElement.visible = visible;
} else {
graphElement.visible = true;
}
}
refreshTreeViewer();
}
private final void onCalculateCorrelation() {
calculateCorrelation();
calculateSumbsumptionChain();
refreshTreeViewer();
refreshMatrix();
}
private final List getAllTestCasesFromActiveContainer() {
List testCases = new LinkedList();
ActiveTSContainerInfo activeTSContainer = CodeCoverPlugin.getDefault()
.getTSContainerManager().getActiveTSContainer();
if (activeTSContainer == null) {
return testCases;
}
TestSessionContainer testSessionContainer = activeTSContainer
.getTestSessionContainer();
for (TestSession testSession : testSessionContainer.getTestSessions()) {
testCases.addAll(testSession.getTestCases());
}
return testCases;
}
private final void calculateCorrelation() {
ActiveTSContainerInfo activeTSContainer = CodeCoverPlugin.getDefault()
.getTSContainerManager().getActiveTSContainer();
if (activeTSContainer == null) {
return;
}
TestSessionContainer testSessionContainer = activeTSContainer
.getTestSessionContainer();
List testCases = new Vector();
for (TestSession testSession : testSessionContainer.getTestSessions()) {
testCases.addAll(testSession.getTestCases());
}
// If there are no test cases, then nothing can be calculated.
if (testCases.isEmpty()) {
return;
}
Set allTestCases = new HashSet(testCases);
Set lastUsed = new HashSet(this.activeTestCases);
/*
* We remove all those test cases, that were still in the collection of
* last used test cases, but not in the total list of test cases of the
* current test session container. This will fix the synchronization
* between the TSContainerManager and this view, in case of a change in
* the test session container, e.g. a deletion.
*/
lastUsed.retainAll(allTestCases);
refreshLastUsedTestCases(lastUsed);
this.resultMap.clear();
Set availableCriteria = testSessionContainer.getCriteria();
for (CorrelationMetric correlationMetric : this.correlationMetrics) {
// Only calculate those metrics, whose required criteria are
// present.
if (availableCriteria.containsAll(correlationMetric
.getRequiredCriteria())) {
CorrelationResult result = correlationMetric
.calculateCorrelation(testCases);
this.resultMap.put(correlationMetric, result);
}
}
}
private final boolean isTestCaseActive(TestCase testCase) {
return this.lastUsedTestCases.contains(testCase);
}
private final void calculateSumbsumptionChain() {
List elements = new Vector();
this.rootChainElement.reset();
if (this.activeMetrics.size() == 0) {
return;
}
List testCases = new LinkedList(
getAllTestCasesFromActiveContainer());
/* If there are no test cases, then nothing can be calculated. */
if (testCases.isEmpty()) {
return;
}
for (TestCase testCase : testCases) {
GraphElement element = new GraphElement();
element.testCases.add(testCase);
elements.add(element);
}
for (GraphElement topElement : elements) {
boolean noChange = false;
while (!noChange) {
noChange = true;
for (TestCase testCase : testCases) {
double correlation = getCummulatedCorrelation(
new Vector(topElement.testCases)
.firstElement(), testCase);
if (correlation != 1.0) {
continue;
} else {
noChange &= !recurseGraphElement(topElement, testCase);
}
}
}
}
/* Add all elements, which have no parent to the root element. */
for (GraphElement graphElement : elements) {
GraphElement subElement = graphElement;
while (subElement.parent != null) {
subElement = subElement.parent;
}
subElement.parent = this.rootChainElement;
this.rootChainElement.children.add(subElement);
// Hide the top level elements, if the action is set.
if (subElement.children.isEmpty()) {
subElement.visible = !this.filterTreeAction.isChecked();
}
}
}
private final boolean recurseGraphElement(GraphElement element,
TestCase testCase) {
boolean anyInsertion = false;
Iterator iterator = new HashSet(
element.children).iterator();
while (iterator.hasNext()) {
anyInsertion |= recurseGraphElement(iterator.next(), testCase);
}
if (!anyInsertion) {
double topCorrelation = getCummulatedCorrelation(
new Vector(element.testCases).firstElement(),
testCase);
double bottomCorrelation = getCummulatedCorrelation(testCase,
new Vector(element.testCases).firstElement());
if (topCorrelation == 1.0 && bottomCorrelation == 1.0) {
anyInsertion = element.testCases.add(testCase);
} else if (topCorrelation == 1.0) {
GraphElement newElement = new GraphElement();
newElement.testCases.add(testCase);
newElement.parent = element;
boolean alreadyPresentInTree = false;
for (GraphElement child : element.children) {
double childCorrelation = getCummulatedCorrelation(
new Vector(child.testCases)
.firstElement(), testCase);
if (childCorrelation == 1.0) {
alreadyPresentInTree = true;
break;
}
}
if (!alreadyPresentInTree) {
anyInsertion = element.children.add(newElement);
}
} else if (bottomCorrelation == 1.0 && element.parent != null) {
GraphElement newElement = new GraphElement();
newElement.testCases.add(testCase);
GraphElement parent = element.parent;
double parentTopCorrelation = getCummulatedCorrelation(
new Vector(parent.testCases).firstElement(),
testCase);
double parentBottonCorrelation = getCummulatedCorrelation(
testCase, new Vector(parent.testCases)
.firstElement());
if (parentTopCorrelation == 1.0
&& parentBottonCorrelation == 1.0) {
anyInsertion = false;
} else if (parentTopCorrelation == 1.0) {
parent.children.remove(element);
parent.children.add(newElement);
newElement.parent = parent;
newElement.children.add(element);
element.parent = newElement;
anyInsertion = true;
}
}
}
return anyInsertion;
}
// XXX: averaging is bad here, because Metrics without coverable items make
// the result diverge from what you expect, but they shouldn't change the
// result at all. Rethink this whole thing and make it's own Metric? --
// Johannes
private final double getCummulatedCorrelation(TestCase case1, TestCase case2) {
double correlation = 0.0;
int summands = 0;
for (CorrelationMetric correlationMetric : this.activeMetrics) {
CorrelationResult result = this.resultMap.get(correlationMetric);
if (result == null) {
continue;
}
if (result.getCoverableItemCount(case2) > 0) {
/*
* this metric is relevant, because it detected coverable items
* in the second test case
*/
correlation += result.getCorrelation(case1, case2);
++summands;
}
}
// We have added the correlations for each relevant metric together, so
// now we have to divide it by the amount of summands.
if (summands > 0) {
correlation /= summands;
} else {
/* no metric is contributing coverable items */
correlation = 1.0;
}
return correlation;
}
private final List createCorrelationActions() {
IWorkbench workbench = PlatformUI.getWorkbench();
ISharedImages platformImages = workbench.getSharedImages();
final List correlationActions = new Vector();
for (final CorrelationMetric correlationMetric : this.correlationMetrics) {
String name = correlationMetric.getName();
IAction action = new Action(name, IAction.AS_RADIO_BUTTON) {
@Override
public void run() {
onChooseMetric(correlationMetric);
}
};
action.setDescription(correlationMetric.getDescription());
action.setImageDescriptor(platformImages
.getImageDescriptor(ISharedImages.IMG_DEF_VIEW));
action.setChecked(getBooleanFromMemento(escapeWhiteSpaces(name),
false));
if (action.isChecked()) {
// Add the metric to the activeMetrics set, if the action is
// checked.
this.activeMetrics.add(correlationMetric);
}
correlationActions.add(action);
}
return correlationActions;
}
private final IAction createAllCorrelationsAction() {
IWorkbench workbench = PlatformUI.getWorkbench();
ISharedImages platformImages = workbench.getSharedImages();
IAction action = new Action(LABEL_ALL_CORRELATION_METRICS,
IAction.AS_RADIO_BUTTON) {
@Override
public void run() {
onChooseAllMetrics();
}
};
action.setDescription(DESCRIPTION_ALL_CORRELATION_METRICS);
action.setImageDescriptor(platformImages
.getImageDescriptor(ISharedImages.IMG_DEF_VIEW));
// We check the all correlations action, if no other actions were
// selected.
action.setChecked(getBooleanFromMemento(TAG_ALL_CORRELATIONS_ACTION,
areNoDistinctCorrelationActionChecked()));
if (action.isChecked()) {
this.activeMetrics.addAll(this.correlationMetrics);
}
return action;
}
private final boolean areNoDistinctCorrelationActionChecked() {
for (IAction correlationAction : this.correlationActions) {
if (correlationAction.isChecked()) {
return false;
}
}
return true;
}
private final boolean getBooleanFromMemento(String tagName,
boolean defaultValue) {
boolean checked = defaultValue;
if (this.memento != null) {
IMemento mem = this.memento.getChild(tagName);
if (mem != null) {
checked = Boolean.parseBoolean(mem.getString(TAG_SELECTED));
}
}
return checked;
}
private final void refreshMatrix() {
this.matrixControl.refreshMatrix();
this.scrolledComposite.setMinSize(this.matrixControl.computeSize(
SWT.DEFAULT, SWT.DEFAULT));
}
private final void refreshTreeViewer() {
this.treeViewer.refresh();
}
private final void refreshActiveTestCaseList(Set testCases) {
this.activeTestCases.clear();
this.activeTestCases.addAll(sortTestCases(testCases));
}
private final List sortTestCases(Collection testCases) {
List list = new Vector();
list.addAll(testCases);
Collections.sort(list, this.testCaseComparator);
return list;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite,
* org.eclipse.ui.IMemento)
*/
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
this.memento = memento;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
*/
@Override
public void saveState(IMemento memento) {
super.saveState(memento);
for (IAction action : this.correlationActions) {
IMemento mem = memento.createChild(escapeWhiteSpaces(action
.getText()));
mem.putString(TAG_SELECTED, Boolean.toString(action.isChecked()));
}
IMemento allCorrelationsMemento = memento
.createChild(TAG_ALL_CORRELATIONS_ACTION);
allCorrelationsMemento.putString(TAG_SELECTED, Boolean
.toString(this.allCorrelationsAction.isChecked()));
IMemento autoCalculateMemento = memento
.createChild(TAG_AUTO_CALCULATE_ACTION);
autoCalculateMemento.putString(TAG_SELECTED, Boolean
.toString(this.autoCalculateAction.isChecked()));
IMemento showLegendMemento = memento
.createChild(TAG_SHOW_LEGEND_ACTION);
showLegendMemento.putString(TAG_SELECTED, Boolean
.toString(this.showLegendAction.isChecked()));
IMemento hideTopLevelMemento = memento
.createChild(TAG_FILTER_TREE_ACTION);
hideTopLevelMemento.putString(TAG_SELECTED, Boolean
.toString(this.filterTreeAction.isChecked()));
IMemento sashWeightsMemento = memento.createChild(TAG_SASH_WEIGHTS);
int[] weights = this.sashForm.getWeights();
sashWeightsMemento.putInteger(TAG_WEIGHTS_LENGTH, weights.length);
for (int i = 0; i < weights.length; i++) {
int weight = weights[i];
sashWeightsMemento.putInteger(TAG_SASH_WEIGHT_PREFIX + i, weight);
}
}
private final String escapeWhiteSpaces(String text) {
return text.replace(' ', '_');
}
private Runnable getTSCChangedRunnable(final ActiveTSContainerInfo tscInfo) {
return new Runnable() {
public void run() {
if (CorrelationView.this.matrixControl.isDisposed()) {
return;
}
if (tscInfo != null) {
onTSCChanged(tscInfo.getActiveTestCases());
} else {
onTSCChanged(new HashSet());
}
}
};
}
private Runnable getActiveTestCasesChangedRunnable(
final ActiveTSContainerInfo tscInfo) {
return new Runnable() {
public void run() {
if (CorrelationView.this.matrixControl.isDisposed()) {
return;
}
if (tscInfo != null) {
onActiveTestCasesChanged(tscInfo.getActiveTestCases());
} else {
onActiveTestCasesChanged(new HashSet());
}
}
};
}
private final class TestCaseComparator implements Comparator {
/**
* Compares two {@link TestCase}s
*
* @param testCase1
* the first {@link TestCase}
* @param testCase2
* the second {@link TestCase}
* @return the comparison result of the names of the {@link TestCase}'s
* {@link TestSession}s, or, if those names are equal, the
* comparison result of the names of the {@link TestCase}s
*/
public int compare(TestCase testCase1, TestCase testCase2) {
int result;
result = testCase1.getTestSession().getName().compareTo(
testCase2.getTestSession().getName());
if (result == 0) {
result = testCase1.getName().compareTo(testCase2.getName());
}
return result;
}
}
private final class GraphElement {
GraphElement parent;
boolean visible = true;
final Set testCases = new TreeSet(
CorrelationView.this.testCaseComparator);
final Set children = new HashSet();
/**
* Resets the data of the element.
*/
void reset() {
this.parent = null;
this.visible = true;
this.testCases.clear();
this.children.clear();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof GraphElement)) {
return false;
}
GraphElement that = (GraphElement) obj;
if (!this.testCases.equals(that.testCases)) {
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int hash = 0;
for (TestCase testCase : this.testCases) {
hash += testCase.getName().hashCode();
hash += testCase.getTestSession().getName().hashCode();
}
return hash;
}
}
private final class MetricMenuCreator implements IMenuCreator {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.IMenuCreator#dispose()
*/
public void dispose() {
// Nothing to do here.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control)
*/
public Menu getMenu(Control parent) {
Menu dropDownMenu = new Menu(parent);
for (IAction action : CorrelationView.this.correlationActions) {
ActionContributionItem contributionItem = new ActionContributionItem(
action);
contributionItem.fill(dropDownMenu, -1);
}
// new MenuItem(dropDownMenu, SWT.SEPARATOR);
ActionContributionItem allMetricsItem = new ActionContributionItem(
CorrelationView.this.allCorrelationsAction);
allMetricsItem.fill(dropDownMenu, -1);
return dropDownMenu;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu)
*/
public Menu getMenu(Menu parent) {
return null;
}
}
private final class MatrixContentProvider implements IMatrixContentProvider {
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.MatrixControl.IMatrixContentProvider#getColorForCorrelation(double)
*/
public Color getColorForCorrelation(double correlation) {
return CorrelationView.this.getColorForCorrelation(correlation);
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.MatrixControl.IMatrixContentProvider#getCorrelationInfos()
*/
public List getCorrelationInfos() {
return CorrelationView.this.getCorrelationInfos();
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.MatrixControl.IMatrixContentProvider#getTestCaseInfos()
*/
public List getTestCaseInfos() {
return CorrelationView.this.getTestCaseInfos();
}
}
private final class LegendContentProvider implements ILegendContentProvider {
private LegendControl legendControl;
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.LegendControl.ILegendContentProvider#setClient(org.codecover.eclipse.views.controls.LegendControl)
*/
public void setClient(LegendControl legendControl) {
this.legendControl = legendControl;
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.LegendControl.ILegendContentProvider#getColors()
*/
public List getColors() {
List list = new Vector();
if (this.legendControl == null) {
return list;
}
Display display = this.legendControl.getDisplay();
for (RGBWithBoundaries boundaries : PreferencePageRoot
.getCorrelationMatrixColors()) {
list.add(new Color(display, boundaries.getRGB()));
}
return list;
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.views.controls.LegendControl.ILegendContentProvider#getLabels()
*/
public List getLabels() {
List list = new Vector();
if (this.legendControl == null) {
return list;
}
for (RGBWithBoundaries boundaries : PreferencePageRoot
.getCorrelationMatrixColors()) {
int lower = boundaries.getLowerBoundary();
int upper = boundaries.getUpperBoundary();
StringBuilder sb = new StringBuilder();
if (lower == upper) {
sb.append(String.format("%1$d%%", lower)); //$NON-NLS-1$
} else {
sb.append(String.format("%1$d%% - %2$d%%", lower, upper)); //$NON-NLS-1$
}
list.add(sb.toString());
}
return list;
}
}
private final class TreeContentProvider implements ITreeContentProvider {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof GraphElement) {
List list = new Vector();
GraphElement element = (GraphElement) parentElement;
for (GraphElement testCaseChainElement : element.children) {
list.addAll(rec(testCaseChainElement));
}
return removeDuplicateEntries(list).toArray();
}
return null;
}
private final List rec(GraphElement graphElement) {
List list = new LinkedList();
boolean anySelection = false;
for (TestCase testCase : graphElement.testCases) {
anySelection |= isTestCaseActive(testCase);
}
if (anySelection && graphElement.visible) {
list.add(graphElement);
} else {
for (GraphElement element : graphElement.children) {
list.addAll(rec(element));
}
}
return list;
}
private final List removeDuplicateEntries(
List inputList) {
List newList = new LinkedList();
for (GraphElement graphElement : inputList) {
boolean alreadyPresent = false;
for (GraphElement element : newList) {
if (element.testCases.equals(graphElement.testCases)) {
alreadyPresent = true;
break;
}
}
if (!alreadyPresent) {
newList.add(graphElement);
}
}
return newList;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent(Object element) {
if (element instanceof GraphElement) {
return ((GraphElement) element).parent;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren(Object element) {
if (element instanceof GraphElement) {
if (((GraphElement) element).children.isEmpty()) {
return false;
} else {
List list = new LinkedList();
for (GraphElement graphElement : ((GraphElement) element).children) {
return list.addAll(rec(graphElement));
}
return !list.isEmpty();
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
// Do nothing here
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// The input will never be changed.
}
}
private final class TreeLabelProvider implements ILabelProvider {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
*/
public Image getImage(Object element) {
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
*/
public String getText(Object element) {
if (element instanceof GraphElement) {
StringBuilder sb = new StringBuilder();
boolean firstElement = true;
for (TestCase testCase : ((GraphElement) element).testCases) {
/* If a test case isn't active, no name is displayed. */
if (!isTestCaseActive(testCase)) {
continue;
}
String name = testCase.getName();
String sessionName = testCase.getTestSession().getName();
if (firstElement) {
firstElement = false;
} else {
sb.append(", "); //$NON-NLS-1$
}
sb.append(String.format(TREE_LABEL_FORMAT, name,
sessionName));
}
return sb.toString();
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
public void addListener(ILabelProviderListener listener) {
// No Listener required.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
public void dispose() {
// Nothing needs to be done here.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
* java.lang.String)
*/
public boolean isLabelProperty(Object element, String property) {
// We don't need this feature.
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
public void removeListener(ILabelProviderListener listener) {
// No listeners are used in this provider
}
}
private final class TreeComparator extends ViewerComparator {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
IBaseLabelProvider baseLabelProvider = ((ContentViewer) viewer)
.getLabelProvider();
if (baseLabelProvider instanceof ILabelProvider) {
ILabelProvider labelProvider = (ILabelProvider) baseLabelProvider;
return labelProvider.getText(e1).compareTo(
labelProvider.getText(e2));
}
return super.compare(viewer, e1, e2);
}
}
private final class TSManagerListener implements TSContainerManagerListener {
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testCaseChanged(ActiveTSContainerInfo,
* ChangeType, TestCase)
*/
public void testCaseChanged(final ActiveTSContainerInfo tscInfo,
ChangeType changeType, TestCase testCase) {
Display d = getSite().getShell().getDisplay();
switch (changeType) {
case CHANGE:
synchronized (lock) {
if (CorrelationView.this.calculationPending) {
return;
}
d.asyncExec(getActiveTestCasesChangedRunnable(tscInfo));
}
break;
case ADD:
break;
case REMOVE:
break;
default:
return;
}
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testCasesActivated(ActiveTSContainerInfo)
*/
public void testCasesActivated(final ActiveTSContainerInfo tscInfo) {
Display disp = getSite().getShell().getDisplay();
synchronized (lock) {
if (CorrelationView.this.calculationPending) {
return;
}
disp.asyncExec(getActiveTestCasesChangedRunnable(tscInfo));
}
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testSessionChanged(ActiveTSContainerInfo,
* ChangeType, TestSession)
*/
public void testSessionChanged(final ActiveTSContainerInfo tscInfo,
ChangeType changeType, TestSession testSession) {
Display disp = getSite().getShell().getDisplay();
synchronized (lock) {
if (CorrelationView.this.calculationPending) {
return;
}
CorrelationView.this.calculationPending = true;
disp.asyncExec(getTSCChangedRunnable(tscInfo));
}
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testSessionContainerActivated(ActiveTSContainerInfo)
*/
public void testSessionContainerActivated(
final ActiveTSContainerInfo tscInfo) {
Display disp = getSite().getShell().getDisplay();
synchronized (lock) {
if (CorrelationView.this.calculationPending) {
return;
}
CorrelationView.this.calculationPending = true;
disp.asyncExec(getTSCChangedRunnable(tscInfo));
}
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testSessionContainerAdded(org.codecover.eclipse.tscmanager.TSContainerInfo,
* int)
*/
public void testSessionContainerAdded(TSContainerInfo tscInfo, int index) {
// We don't react on this.
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testSessionContainerChanged(ChangeType,
* ActiveTSContainerInfo)
*/
public void testSessionContainerChanged(ChangeType changeType,
final ActiveTSContainerInfo tscInfo) {
Display disp = getSite().getShell().getDisplay();
synchronized (lock) {
if (CorrelationView.this.calculationPending) {
return;
}
CorrelationView.this.calculationPending = true;
disp.asyncExec(getTSCChangedRunnable(tscInfo));
}
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#testSessionContainerRemoved(org.codecover.eclipse.tscmanager.TSContainerInfo)
*/
public void testSessionContainerRemoved(TSContainerInfo tscInfo) {
// We don't react on this.
}
/*
* (non-Javadoc)
*
* @see org.codecover.eclipse.tscmanager.TSContainerManagerListener#synchronizedStateChanged(TSContainerInfo, boolean)
*/
public void synchronizedStateChanged(TSContainerInfo tscInfo,
boolean isSynchronized) {
// We don't react on this.
}
}
private final class PreferenceChangeListener implements
IPropertyChangeListener {
/*
* * (non-Javadoc)
*
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
CorrelationView.this.refreshMatrix();
}
}
private final class CorrelationMetricComparator implements
Comparator {
/**
* Compares two {@link CorrelationMetric}s according to their names.
*
* @param o1
* the first {@link CorrelationMetric}
* @param o2
* the second {@link CorrelationMetric}
* @return the result of the comparison of their names.
*/
public int compare(CorrelationMetric o1, CorrelationMetric o2) {
int result = 0;
result = o1.getName().compareTo(o2.getName());
return result;
}
}
}