/*****************************************************************************
* Copyright (c) 2014,2015 ASML Netherlands B.V. and others.
*
* 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
*
* Contributors:
* ASML Netherlands B.V. - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.tools.coverage.ui;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.m2m.qvt.oml.tools.coverage.Activator;
import org.eclipse.m2m.qvt.oml.tools.coverage.ui.CoveragePlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.ViewPart;
public class CoverageView extends ViewPart {
public static final String VIEW_ID = "org.eclipse.m2m.qvt.oml.tools.coverage.ui.coverageView";
protected static final int COLUMN_ELEMENT = 0;
private TreeViewer viewer;
private CoverageModel coverageModel;
private Composite myParent;
public CoverageView() {
}
@Override
public void createPartControl(Composite parent) {
myParent = parent;
loadViewer();
}
private void loadViewer() {
viewer = new TreeViewer(myParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.getTree().setHeaderVisible(true);
viewer.getTree().setLinesVisible(true);
TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);
column0.getColumn().setText("Module");
column0.getColumn().setWidth(200);
column0.setLabelProvider(new PathLabelProvider());
TreeViewerColumn column00 = new TreeViewerColumn(viewer, SWT.LEFT);
column00.getColumn().setText("Total function coverage");
column00.getColumn().setWidth(150);
column00.setLabelProvider(new TotalLabelProvider());
TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.LEFT);
column1.getColumn().setText("Mapping Coverage");
column1.getColumn().setWidth(130);
column1.setLabelProvider(new MappingLabelProvider());
TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.LEFT);
column2.getColumn().setText("Helper Coverage");
column2.getColumn().setWidth(130);
column2.setLabelProvider(new HelperLabelProvider());
TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.LEFT);
column3.getColumn().setText("Constructor Coverage");
column3.getColumn().setWidth(130);
column3.setLabelProvider(new ConstructorLabelProvider());
TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.LEFT);
column4.getColumn().setText("Estimated Expression Coverage");
column4.getColumn().setWidth(200);
column4.setLabelProvider(new ExpressionLabelProvider());
viewer.setContentProvider(new ViewContentProvider());
viewer.addDoubleClickListener(new TransformationClickListener());
}
public void clear() {
removeMarkers();
//update(new CoverageModel(new CoverageData()));
}
private void removeMarkers() {
if (coverageModel == null) {
return;
}
for (ProjectCoverageModel pcm : coverageModel.getProjectModels()) {
for (TransformationCoverageModel tcm : pcm.getTransformationModels()) {
IFile file = tcm.getFile();
CoverageAnnotator annotator = new CoverageAnnotator();
annotator.removeAnnotations(file);
}
}
}
public void setLoading(boolean loading) {
if (loading) {
viewer.getTree().setLinesVisible(false);
} else {
viewer.getTree().setLinesVisible(true);
}
}
public void update(CoverageModel model) {
if (viewer == null) {
loadViewer();
}
removeMarkers();
coverageModel = model;
viewer.setInput(coverageModel);
viewer.expandAll();
}
class TransformationClickListener implements IDoubleClickListener {
@Override
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection thisSelection = (IStructuredSelection) event.getSelection();
Object selectedElement = thisSelection.getFirstElement();
if (selectedElement instanceof TransformationCoverageModel) {
final TransformationCoverageModel transformationModel = (TransformationCoverageModel) selectedElement;
// Annotate expressions
final IFile file = transformationModel.getFile();
final CoverageAnnotator annotator = new CoverageAnnotator();
annotator.annotateTouched(file, transformationModel.getTouchedRanges());
annotator.annotateUntouched(file, transformationModel.getUntouchedRanges());
// Open
try {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IDE.openEditor(page, file, true);
} catch (PartInitException e) {
Activator.error("Failed to activate coveraged file", e);
}
}
}
}
class ViewContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
return coverageModel.getProjectModels();
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof ProjectCoverageModel) {
return ((ProjectCoverageModel) parentElement).getTransformationModels();
}
return null;
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
if (element instanceof ProjectCoverageModel) {
return true;
}
return false;
}
}
class PathLabelProvider extends ColumnLabelProvider {
@Override
public String getText(Object element) {
if (element instanceof ProjectCoverageModel) {
return ((ProjectCoverageModel) element).getProject().getName();
} else if (element instanceof TransformationCoverageModel) {
return ((TransformationCoverageModel) element).getModule().getName();
}
return "";
}
}
abstract class ColoredLabelProvider extends ColumnLabelProvider {
public abstract int getUntouchedNodesCount(ProjectCoverageModel model);
public abstract int getTouchedNodesCount(ProjectCoverageModel model);
public abstract int getUntouchedNodesCount(TransformationCoverageModel model);
public abstract int getTouchedNodesCount(TransformationCoverageModel model);
@Override
public String getText(Object element) {
if (element instanceof ProjectCoverageModel) {
return formatCoverage(getUntouchedNodesCount((ProjectCoverageModel) element),
getTouchedNodesCount((ProjectCoverageModel) element));
} else if (element instanceof TransformationCoverageModel) {
return formatCoverage(getUntouchedNodesCount((TransformationCoverageModel) element),
getTouchedNodesCount((TransformationCoverageModel) element));
}
return "";
}
@Override
public Color getBackground(Object element) {
int touched = 0;
int untouched = 0;
if (element instanceof TransformationCoverageModel) {
touched = getTouchedNodesCount((TransformationCoverageModel) element);
untouched = getUntouchedNodesCount((TransformationCoverageModel) element);
} else if (element instanceof ProjectCoverageModel) {
touched = getTouchedNodesCount((ProjectCoverageModel) element);
untouched = getUntouchedNodesCount((ProjectCoverageModel) element);
}
double percent = computePercent(touched + untouched, touched);
if (percent * 100 >= CoveragePlugin.getDefault().getPreferenceStore()
.getInt(CoveragePlugin.HIGH_THRESHOLD_PREFERENCE)) {
// green
return new Color(Display.getCurrent(), 154, 205, 50);
} else if (percent * 100 < CoveragePlugin.getDefault().getPreferenceStore()
.getInt(CoveragePlugin.LOW_THRESHOLD_PREFERENCE)) {
// red
return new Color(Display.getCurrent(), 250, 128, 114);
}
return super.getBackground(element);
}
@Override
public Font getFont(Object element) {
if (element instanceof ProjectCoverageModel) {
Font afont = new Font(Display.getCurrent(), "Arial", 8, SWT.BOLD);
return afont;
}
return super.getFont(element);
}
}
class TotalLabelProvider extends ColoredLabelProvider {
@Override
public int getTouchedNodesCount(TransformationCoverageModel model) {
return model.getTouchedMappingNodes().size() + model.getTouchedHelperNodes().size()
+ model.getTouchedConstructorNodes().size();
}
@Override
public int getUntouchedNodesCount(TransformationCoverageModel model) {
return model.getUntouchedMappingNodes().size() + model.getUntouchedHelperNodes().size()
+ model.getUntouchedConstructorNodes().size();
}
@Override
public int getTouchedNodesCount(ProjectCoverageModel model) {
return model.getTouchedMappingNodes().size() + model.getTouchedHelperNodes().size()
+ model.getTouchedConstructorNodes().size();
}
@Override
public int getUntouchedNodesCount(ProjectCoverageModel model) {
return model.getUntouchedMappingNodes().size() + model.getUntouchedHelperNodes().size()
+ model.getUntouchedConstructorNodes().size();
}
}
class MappingLabelProvider extends ColoredLabelProvider {
@Override
public int getTouchedNodesCount(TransformationCoverageModel model) {
return model.getTouchedMappingNodes().size();
}
@Override
public int getUntouchedNodesCount(TransformationCoverageModel model) {
return model.getUntouchedMappingNodes().size();
}
@Override
public int getTouchedNodesCount(ProjectCoverageModel model) {
return model.getTouchedMappingNodes().size();
}
@Override
public int getUntouchedNodesCount(ProjectCoverageModel model) {
return model.getUntouchedMappingNodes().size();
}
}
class HelperLabelProvider extends ColoredLabelProvider {
@Override
public int getTouchedNodesCount(TransformationCoverageModel model) {
return model.getTouchedHelperNodes().size();
}
@Override
public int getUntouchedNodesCount(TransformationCoverageModel model) {
return model.getUntouchedHelperNodes().size();
}
@Override
public int getTouchedNodesCount(ProjectCoverageModel model) {
return model.getTouchedHelperNodes().size();
}
@Override
public int getUntouchedNodesCount(ProjectCoverageModel model) {
return model.getUntouchedHelperNodes().size();
}
}
class ConstructorLabelProvider extends ColoredLabelProvider {
@Override
public int getTouchedNodesCount(TransformationCoverageModel model) {
return model.getTouchedConstructorNodes().size();
}
@Override
public int getUntouchedNodesCount(TransformationCoverageModel model) {
return model.getUntouchedConstructorNodes().size();
}
@Override
public int getTouchedNodesCount(ProjectCoverageModel model) {
return model.getTouchedConstructorNodes().size();
}
@Override
public int getUntouchedNodesCount(ProjectCoverageModel model) {
return model.getUntouchedConstructorNodes().size();
}
}
class ExpressionLabelProvider extends ColoredLabelProvider {
@Override
public int getTouchedNodesCount(TransformationCoverageModel model) {
return model.getTouchedExpressionNodes().size();
}
@Override
public int getUntouchedNodesCount(TransformationCoverageModel model) {
return model.getUntouchedExpressionNodes().size();
}
@Override
public int getTouchedNodesCount(ProjectCoverageModel model) {
return model.getTouchedExpressionNodes().size();
}
@Override
public int getUntouchedNodesCount(ProjectCoverageModel model) {
return model.getUntouchedExpressionNodes().size();
}
}
private String formatCoverage(int untouched, int touched) {
int total = untouched + touched;
double percent = computePercent(total, touched);
return (int) (percent * 100) + "% (" + touched + " of " + total + ")";
}
private double computePercent(int total, int touched) {
double percent;
if (total == 0) {
percent = 1;
} else {
percent = (double) touched / total;
}
return percent;
}
@Override
public void setFocus() {
}
@Override
public void dispose() {
clear();
myParent = null;
}
}