diff options
author | Fabrice Bellingard <bellingard@gmail.com> | 2011-12-12 17:56:02 +0100 |
---|---|---|
committer | Fabrice Bellingard <bellingard@gmail.com> | 2011-12-12 17:58:19 +0100 |
commit | 2a1309d55d918fe59634e3858ccbb852ddf28408 (patch) | |
tree | 93b27a8b6931543ca83066d9391e38991db20fe0 | |
parent | 087df4135ce0089a2c96711f6bf2cdcdf921f361 (diff) | |
download | sonarqube-2a1309d55d918fe59634e3858ccbb852ddf28408.tar.gz sonarqube-2a1309d55d918fe59634e3858ccbb852ddf28408.zip |
SONAR-3063 Implement the hotspots page as a dashboard
17 files changed, 109 insertions, 931 deletions
diff --git a/plugins/sonar-core-gwt/pom.xml b/plugins/sonar-core-gwt/pom.xml index ee180e8c590..4248a3723f1 100644 --- a/plugins/sonar-core-gwt/pom.xml +++ b/plugins/sonar-core-gwt/pom.xml @@ -60,7 +60,6 @@ <configuration> <modules> <module>org.sonar.plugins.core.testdetailsviewer.TestsViewer${gwt.permutationSuffix}</module> - <module>org.sonar.plugins.core.hotspots.GwtHotspots${gwt.permutationSuffix}</module> </modules> <skip>${skipGwt}</skip> <webappDirectory>${project.build.directory}/classes</webappDirectory> diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java deleted file mode 100644 index 33a02af82cd..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots; - -import org.sonar.api.resources.Resource; -import org.sonar.api.web.GwtPage; -import org.sonar.api.web.NavigationSection; -import org.sonar.api.web.ResourceScope; -import org.sonar.api.web.UserRole; - -@NavigationSection(NavigationSection.RESOURCE) -@ResourceScope({Resource.SCOPE_SET, Resource.SCOPE_SPACE}) -@UserRole(UserRole.USER) -public class Hotspots extends GwtPage { - - public String getTitle() { - return "Hotspots"; - } - - public String getGwtId() { - return "org.sonar.plugins.core.hotspots.GwtHotspots"; - } - -} diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java deleted file mode 100644 index f0adee74dbc..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client; - -import com.google.gwt.gen2.table.override.client.Grid; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.user.client.ui.Widget; -import org.sonar.gwt.Metrics; -import org.sonar.gwt.ui.Page; -import org.sonar.plugins.core.hotspots.client.widget.MetricHotspot; -import org.sonar.plugins.core.hotspots.client.widget.MostBadlyDesignedFiles; -import org.sonar.plugins.core.hotspots.client.widget.MostViolatedResources; -import org.sonar.plugins.core.hotspots.client.widget.MostViolatedRules; -import org.sonar.wsclient.services.Resource; - -public class GwtHotspots extends Page { - @Override - protected Widget doOnResourceLoad(Resource resource) { - Grid grid = new Grid(1, 2); - grid.setStylePrimaryName("gwt-Hotspots"); - loadHotspots(grid, resource); - return grid; - } - - - private void loadHotspots(Grid grid, Resource resource) { - VerticalPanel column1 = new VerticalPanel(); - column1.setStyleName("hotspotcol"); - VerticalPanel column2 = new VerticalPanel(); - column2.setStyleName("hotspotcol"); - - Dictionary l10n = Dictionary.getDictionary("l10n"); - column1.add(new MostViolatedRules(resource)); - column1.add(new MetricHotspot(resource, Metrics.TEST_EXECUTION_TIME, l10n.get("hotspot.titleLongestTests"))); - column1.add(new MetricHotspot(resource, Metrics.COMPLEXITY, l10n.get("hotspot.titleMostComplexResources"))); - column1.add(new MetricHotspot(resource, Metrics.DUPLICATED_LINES, l10n.get("hotspot.titleMostDuplicatedResources"))); - column1.add(new MostBadlyDesignedFiles(resource)); - - column2.add(new MostViolatedResources(resource)); - column2.add(new MetricHotspot(resource, Metrics.UNCOVERED_LINES, l10n.get("hotspot.titleLessTested"))); - column2.add(new MetricHotspot(resource, Metrics.FUNCTION_COMPLEXITY, l10n.get("hotspot.titleMostComplexMethods"))); - column2.add(new MetricHotspot(resource, Metrics.PUBLIC_UNDOCUMENTED_API, l10n.get("hotspot.titleMostUndocumentedAPI"))); - - grid.setWidget(0, 0, column1); - grid.setWidget(0, 1, column2); - } - -} diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java deleted file mode 100644 index aa0426dcbcb..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client.widget; - -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.*; -import org.sonar.gwt.Links; -import org.sonar.gwt.ui.Loading; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; - -public abstract class AbstractHotspot extends Composite { - - private Panel hotspot; - private Panel data; - private Resource resource; - - public static final int LIMIT = 5; - - protected AbstractHotspot(String id, Resource resource) { - this.resource = resource; - hotspot = new VerticalPanel(); - hotspot.getElement().setId(id); - hotspot.setStyleName("gwt-HotspotPanel"); - initWidget(hotspot); - } - - public Resource getResource() { - return resource; - } - - @Override - public void onLoad() { - hotspot.add(createHeader()); - data = new SimplePanel(); - hotspot.add(data); - loadData(); - } - - protected void loadData() { - data.clear(); - data.add(new Loading()); - doLoadData(); - } - - abstract Widget createHeader(); - - abstract void doLoadData(); - - protected void render(Widget widget) { - data.clear(); - data.add(widget); - } - - protected void renderEmptyResults() { - Grid grid = new Grid(1, 1); - grid.setWidget(0, 0, new HTML(Dictionary.getDictionary("l10n").get("hotspot.noMeasures"))); - grid.getCellFormatter().setStyleName(0, 0, getRowCssClass(0) + " emptyResultsCell"); - grid.setStyleName("gwt-Hotspot"); - render(grid); - } - - protected void renderNameCell(Grid hotspotGrid, final Resource resource, final String metricKey, int row, int column) { - Anchor link = new Anchor(resource.getName()); - link.getElement().setAttribute("title", resource.getName(true)); - link.getElement().setAttribute("rel", resource.getName(true)); - link.addClickHandler(new ClickHandler() { - public void onClick(final ClickEvent event) { - if (resource.getCopy() != null) { - Window.Location.assign(Links.baseUrl() + "/plugins/resource/" + resource.getCopy() + "?page=org.sonar.plugins.core.hotspots.GwtHotspots"); - } else { - Links.openMeasurePopup(resource.getKey(), metricKey); - } - } - }); - hotspotGrid.setWidget(row, column, link); - hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " resourceCell"); - } - - protected void renderValueCell(Grid hotspotGrid, Measure measure, int row, int column) { - hotspotGrid.setHTML(row, column, measure.getFormattedValue()); - hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " resultCell"); - } - - protected void renderGraphCell(Grid hotspotGrid, Measure measure, Measure firstMeasure, int row, int column) { - Double value = Double.valueOf(measure.getValue()); - Double upperValue = Double.valueOf(firstMeasure.getValue()); - Double percentPonderated = getPercentPonderatedValue(value, 0d, upperValue); - String graph = "<span style='width:100%'><ul class='hbar' style='float: right;'><li style='background-color: rgb(119, 119, 119); width: " + percentPonderated.intValue() + "%'> </li></ul></span>"; - hotspotGrid.setHTML(row, column, graph); - hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " graphCell"); - } - - protected String getRowCssClass(int row) { - return row % 2 == 0 ? "even" : "odd"; - } - - protected double getPercentPonderatedValue(Double value, Double lower, Double upper) { - if (value < lower) return 0; - if (value > upper) return 100; - double percentIncrement = (upper - lower) / 100d; - return (value - lower) / percentIncrement; - } -} diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java deleted file mode 100644 index bb3ac53b6de..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client.widget; - -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.*; -import org.sonar.gwt.Links; -import org.sonar.wsclient.gwt.AbstractListCallback; -import org.sonar.wsclient.gwt.Sonar; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; -import org.sonar.wsclient.services.ResourceQuery; - -import java.util.ArrayList; -import java.util.List; - -public class MetricHotspot extends AbstractHotspot { - - private String metric; - private String title; - - public MetricHotspot(Resource resource, String metric, String title) { - super(metric + "-hotspot", resource); - this.metric = metric; - this.title = title; - } - - @Override - Widget createHeader() { - Dictionary l10n = Dictionary.getDictionary("l10n"); - final Label label = new Label(title); - label.setStyleName("header"); - - final Anchor moreLink = new Anchor(l10n.get("hotspot.moreDetails")); - moreLink.getElement().setId("more-" + metric); - moreLink.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getKey() + "?metric=" + metric); - } - }); - - final HorizontalPanel horizontal = new HorizontalPanel(); - horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); - horizontal.setWidth("98%"); - horizontal.add(label); - horizontal.add(moreLink); - horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); - - return horizontal; - } - - @Override - void doLoadData() { - final ResourceQuery query = getResourceQuery(); - Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { - - @Override - protected void doOnResponse(List<Resource> resources) { - List<HotspotMeasure> measures = new ArrayList<HotspotMeasure>(); - for (Resource resource : resources) { - for (Measure measure : resource.getMeasures()) { - measures.add(new HotspotMeasure(resource, measure)); - } - } - - if (measures.isEmpty()) { - renderEmptyResults(); - - } else { - final Grid grid = new Grid(measures.size(), 3); - grid.setStyleName("gwt-Hotspot"); - int row = 0; - HotspotMeasure firstMeasure = measures.get(0); - for (HotspotMeasure measure : measures) { - renderNameCell(grid, measure.getResource(), metric, row, 0); - renderValueCell(grid, measure.getMeasure(), row, 1); - renderGraphCell(grid, measure.getMeasure(), firstMeasure.getMeasure(), row, 2); - row++; - } - - render(grid); - } - } - }); - } - - protected ResourceQuery getResourceQuery() { - return ResourceQuery.createForResource(getResource(), metric) - .setScopes(Resource.SCOPE_ENTITY) - .setDepth(ResourceQuery.DEPTH_UNLIMITED) - .setLimit(LIMIT); - } - - public static class HotspotMeasure { - private Resource resource; - private Measure measure; - - public HotspotMeasure(Resource resource, Measure measure) { - super(); - this.resource = resource; - this.measure = measure; - } - - public Resource getResource() { - return resource; - } - - public Measure getMeasure() { - return measure; - } - - } -} diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java deleted file mode 100644 index 954effd1362..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client.widget; - -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.*; -import org.sonar.gwt.Links; -import org.sonar.wsclient.gwt.AbstractListCallback; -import org.sonar.wsclient.gwt.Sonar; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; -import org.sonar.wsclient.services.ResourceQuery; - -import java.util.List; - -public class MostBadlyDesignedFiles extends AbstractHotspot { - - private ListBox metricSelectBox; - - public MostBadlyDesignedFiles(Resource resource) { - super("design-hotspot", resource); - } - - @Override - Widget createHeader() { - Dictionary l10n = Dictionary.getDictionary("l10n"); - metricSelectBox = new ListBox(false); - metricSelectBox.addItem(l10n.get("hotspot.lcom4"), "lcom4"); - metricSelectBox.addItem(l10n.get("hotspot.rfc"), "rfc"); - metricSelectBox.setStyleName("small"); - metricSelectBox.addChangeHandler(new ChangeHandler() { - public void onChange(ChangeEvent event) { - loadData(); - } - }); - - final Label label = new Label(l10n.get("hotspot.designTitle")); - label.setStyleName("header"); - - final Anchor moreLink = new Anchor(l10n.get("hotspot.moreDetails")); - moreLink.getElement().setId("more-design"); - moreLink.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - final String metric = getSelectedMetric(); - Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getId() + "?metric=" + metric); - } - }); - - final HorizontalPanel horizontal = new HorizontalPanel(); - horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); - horizontal.setWidth("98%"); - horizontal.add(label); - horizontal.add(metricSelectBox); - horizontal.add(moreLink); - horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(metricSelectBox, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); - - return horizontal; - } - - @Override - void doLoadData() { - final ResourceQuery query = getResourceQuery(); - Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { - - @Override - protected void doOnResponse(List<Resource> resources) { - final Grid grid = new Grid(resources.size(), 3); - grid.setStyleName("gwt-Hotspot"); - int row = 0; - Measure firstMeasure = null; - for (Resource resource : resources) { - if (resource.getMeasures().size() == 1) { - if (firstMeasure == null) { - firstMeasure = resource.getMeasures().get(0); - } - renderNameCell(grid, resource, firstMeasure.getMetricKey(), row, 0); - renderValueCell(grid, resource.getMeasures().get(0), row, 1); - renderGraphCell(grid, resource.getMeasures().get(0), firstMeasure, row, 2); - row++; - } - } - - if (firstMeasure == null) { - renderEmptyResults(); - } else { - render(grid); - } - } - }); - } - - public ResourceQuery getResourceQuery() { - return ResourceQuery.createForResource(getResource(), getSelectedMetric()) - .setDepth(-1) - .setQualifiers(Resource.QUALIFIER_CLASS) - .setLimit(LIMIT); - } - - private String getSelectedMetric() { - return metricSelectBox.getValue(metricSelectBox.getSelectedIndex()); - } -} - diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java deleted file mode 100644 index feff7db5e35..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client.widget; - -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.*; -import org.sonar.gwt.Links; -import org.sonar.gwt.Metrics; -import org.sonar.gwt.ui.Icons; -import org.sonar.wsclient.gwt.AbstractListCallback; -import org.sonar.wsclient.gwt.Sonar; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; -import org.sonar.wsclient.services.ResourceQuery; - -import java.util.List; -import java.util.Map; - -public class MostViolatedResources extends AbstractHotspot { - - public MostViolatedResources(Resource resource) { - super("violated-files-hotspot", resource); - } - - @Override - Widget createHeader() { - Dictionary l10n = Dictionary.getDictionary("l10n"); - final Label label = new Label(l10n.get("hotspot.titleMostViolatedResources")); - label.setStyleName("header"); - - final Anchor moreLink = new Anchor(l10n.get("hotspot.moreDetails")); - moreLink.getElement().setId("more-violated-resources"); - moreLink.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getId() + "?metric=" + Metrics.WEIGHTED_VIOLATIONS); - } - }); - - final HorizontalPanel horizontal = new HorizontalPanel(); - horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); - horizontal.setWidth("98%"); - horizontal.add(label); - horizontal.add(moreLink); - horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); - - return horizontal; - } - - @Override - void doLoadData() { - final ResourceQuery query = getResourceQuery(); - Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { - - @Override - protected void doOnResponse(List<Resource> resources) { - Grid grid = new Grid(resources.size(), 11); - grid.setStyleName("gwt-Hotspot"); - int row = 0; - for (Resource resource : resources) { - if (resource.getMeasures().size() > 0) { - renderNameCell(grid, resource, Metrics.WEIGHTED_VIOLATIONS, row, 0); - renderPriorities(grid, resource, row); - row++; - } - } - if (row == 0) { - renderEmptyResults(); - } else { - render(grid); - } - } - }); - } - - - private void renderPriorities(Grid grid, Resource resource, int row) { - Measure debt = resource.getMeasures().get(0); - if (debt != null && debt.getData() != null) { - Map<String, String> map = debt.getDataAsMap(";"); - renderSeverity(grid, row, map, 1, "BLOCKER"); - renderSeverity(grid, row, map, 3, "CRITICAL"); - renderSeverity(grid, row, map, 5, "MAJOR"); - renderSeverity(grid, row, map, 7, "MINOR"); - renderSeverity(grid, row, map, 9, "INFO"); - } - } - - private void renderSeverity(Grid grid, int row, Map<String, String> map, int column, String severity) { - grid.setWidget(row, column, Icons.forPriority(severity).createImage()); - grid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " small right"); - - if (map.containsKey(severity)) { - grid.setWidget(row, column + 1, new HTML(map.get(severity))); - } else { - grid.setWidget(row, column + 1, new HTML("0")); - } - grid.getCellFormatter().setStyleName(row, column + 1, getRowCssClass(row) + " small left"); - } - - private ResourceQuery getResourceQuery() { - return ResourceQuery.createForResource(getResource(), Metrics.WEIGHTED_VIOLATIONS) - .setScopes(Resource.SCOPE_ENTITY) - .setQualifiers(Resource.QUALIFIER_CLASS, Resource.QUALIFIER_FILE, Resource.QUALIFIER_PROJECT) - .setDepth(ResourceQuery.DEPTH_UNLIMITED) - .setLimit(LIMIT); - } -} diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java deleted file mode 100644 index 4c707e6f327..00000000000 --- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.hotspots.client.widget; - -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.i18n.client.Dictionary; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.*; -import org.sonar.gwt.Links; -import org.sonar.gwt.Metrics; -import org.sonar.gwt.ui.Icons; -import org.sonar.wsclient.gwt.AbstractCallback; -import org.sonar.wsclient.gwt.Sonar; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; -import org.sonar.wsclient.services.ResourceQuery; - -public class MostViolatedRules extends AbstractHotspot { - - private ListBox severity; - - public MostViolatedRules(Resource resource) { - super("rules-hotspot", resource); - } - - @Override - Widget createHeader() { - Dictionary l10n = Dictionary.getDictionary("l10n"); - severity = new ListBox(false); - severity.addItem(l10n.get("hotspot.anySeverity"), ""); - severity.addItem("Blocker", "BLOCKER"); - severity.addItem("Critical", "CRITICAL"); - severity.addItem("Major", "MAJOR"); - severity.addItem("Minor", "MINOR"); - severity.addItem("Info", "INFO"); - severity.setStyleName("small"); - severity.addChangeHandler(new ChangeHandler() { - public void onChange(ChangeEvent event) { - loadData(); - } - }); - - final Label label = new Label(l10n.get("hotspot.titleMostViolatedRules")); - label.setStyleName("header"); - - final Anchor moreLink = new Anchor(l10n.get("hotspot.moreDetails")); - moreLink.getElement().setId("more-rules"); - moreLink.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - Window.Location.assign(Links.baseUrl() + "/drilldown/violations/" + getResource().getId()); - } - }); - - final HorizontalPanel horizontal = new HorizontalPanel(); - horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); - horizontal.setWidth("98%"); - horizontal.add(label); - horizontal.add(severity); - horizontal.add(moreLink); - horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(severity, HorizontalPanel.ALIGN_LEFT); - horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); - - return horizontal; - } - - @Override - void doLoadData() { - final ResourceQuery query = getResourceQuery(); - Sonar.getInstance().find(query, new AbstractCallback<Resource>() { - - @Override - protected void doOnResponse(Resource resource) { - if (resource==null || resource.getMeasures().isEmpty()) { - renderEmptyResults(); - } else { - renderGrid(resource); - } - } - }); - } - - private void renderGrid(Resource resource) { - final Grid grid = new Grid(resource.getMeasures().size(), 4); - grid.setStyleName("gwt-Hotspot"); - int row = 0; - Measure firstMeasure = resource.getMeasures().get(0); - for (Measure measure : resource.getMeasures()) { - renderRule(grid, measure, row); - renderValueCell(grid, measure, row, 2); - renderGraphCell(grid, measure, firstMeasure, row, 3); - row++; - } - render(grid); - } - - protected void renderRule(final Grid grid, final Measure measure, final int row) { - Anchor drillDown = new Anchor(measure.getRuleName()); - drillDown.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - Window.Location.assign(Links.baseUrl() + "/drilldown/violations/" + getResource().getId() + "?rule=" + measure.getRuleKey()); - } - }); - - grid.setWidget(row, 0, new HTML("<a id=\"rule" + row + "\" href=\"" + Links.urlForRule(measure.getRuleKey(), false) + "\" onclick=\"window.open(this.href,'rule','height=800,width=900,scrollbars=1,resizable=1');return false;\" title=\"" + measure.getRuleKey() + "\">" + Icons.forPriority(measure.getRulePriority()).getHTML() + "</a>")); - grid.setWidget(row, 1, drillDown); - grid.getCellFormatter().setStyleName(row, 0, getRowCssClass(row) + ""); - grid.getCellFormatter().setStyleName(row, 1, getRowCssClass(row) + " resourceCell"); - } - - public ResourceQuery getResourceQuery() { - ResourceQuery query = ResourceQuery.createForResource(getResource(), Metrics.VIOLATIONS) - .setDepth(0) - .setExcludeRules(false) - .setLimit(LIMIT); - String severity = getSelectedPriority(); - if (severity!=null) { - query.setRuleSeverities(severity); - } - return query; - } - - private String getSelectedPriority() { - String priority = severity.getValue(severity.getSelectedIndex()); - if ("".equals(priority) || priority == null) { - return null; - } - return priority; - } -} diff --git a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml b/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml deleted file mode 100644 index ffb2d169793..00000000000 --- a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml +++ /dev/null @@ -1,9 +0,0 @@ -<module> - <inherits name="com.google.gwt.user.User"/> - <inherits name="com.google.gwt.json.JSON"/> - <inherits name="com.google.gwt.http.HTTP"/> - <inherits name="org.sonar.Sonar"/> - <inherits name="com.google.gwt.i18n.I18N"/> - <stylesheet src="hotspots.css"/> - <entry-point class="org.sonar.plugins.core.hotspots.client.GwtHotspots"/> -</module>
\ No newline at end of file diff --git a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspotsDev.gwt.xml b/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspotsDev.gwt.xml deleted file mode 100644 index 47a4c556c08..00000000000 --- a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspotsDev.gwt.xml +++ /dev/null @@ -1,6 +0,0 @@ -<module rename-to="org.sonar.plugins.core.hotspots.GwtHotspots"> - <inherits name="org.sonar.plugins.core.hotspots.GwtHotspots"/> - <inherits name="org.sonar.SonarDev"/> - - <entry-point class="org.sonar.plugins.core.hotspots.client.GwtHotspots"/> -</module> diff --git a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css b/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css deleted file mode 100644 index c0c7310675a..00000000000 --- a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css +++ /dev/null @@ -1,102 +0,0 @@ -.gwt-Hotspots { - width: 780px; -} - -.gwt-Hotspots td { - width: 380px; - vertical-align: top; -} - -.gwt-HotspotPanel { - width: 100%; -} - -.gwt-HotspotPanel .header { - color: #333; - font-size: 93%; - font-weight: bold; - padding: 3px 0 3px 5px; - white-space: nowrap; -} -.hotspotcol { - vertical-align: top; -} - -.gwt-Hotspot { - border: 1px solid #ccc; - border-top-width: 1px; - border-bottom-width: 1px; - margin-left: 5px; - margin-right: 5px; - margin-bottom: 10px; - width: 390px; -} - -.gwt-Hotspot td { - padding: 3px 4px; - line-height: 18px; -} - -.gwt-Hotspot td.small { - padding: 3px 1px; -} - -.gwt-Hotspot .header { - color: #333; - font-size: 93%; - font-weight: bold; - padding: 4px 0 3px 9px; -} - -.gwt-Hotspot .resourceCell { - width: 99%; -} - -.gwt-Hotspot .ccResourceCell { - width: 60%; -} - -.gwt-Hotspot .resultCell { - width: 1%; - white-space: nowrap; - text-align: right; - border-right: none; -} - -.gwt-Hotspot .ccResultCell { - border-right: 1px solid #C0C0C0; - width: 1%; - white-space: nowrap; - text-align: right; -} - -.gwt-Hotspot .graphCell { - width: 1%; - white-space: nowrap; - text-align: right; - border-left: none; -} - -.gwt-Hotspot .header.ccHeaderResource { - width: 60%; -} - -.gwt-Hotspot .header.headerResource { - width: 70%; -} - -.gwt-Hotspot .header.headerEmptyResults { - width: 100%; -} - -.gwt-Hotspot .header.headerResult { - width: 20%; -} - -.gwt-Hotspot .header.ccHeaderResult { - width: 30%; -} - -.gwt-Hotspot .header.headerGraph { - width: 10%; -}
\ No newline at end of file diff --git a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html b/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html deleted file mode 100644 index d66011fb116..00000000000 --- a/plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html +++ /dev/null @@ -1,36 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> - -<html> -<head> - <meta http-equiv="content-type" content="text/html; charset=UTF-8"> - <title>Hotspots</title> - <link href="http://localhost:9000/stylesheets/sonar.css" media="all" rel="Stylesheet" type="text/css"/> - <script src="http://localhost:9000/javascripts/sonar.js" type="text/javascript"></script> -</head> - -<body> -<script type="text/javascript"> - var config = { - "sonar_url": "http://localhost:9000", - "resource_key" : "org.apache.struts:struts-parent" - }; -</script> - -<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" - onclick="javascript:$('error').hide();return false;">hide</a>] -</div> -<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" - onclick="javascript:$('warning').hide();return false;">hide</a>] -</div> -<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" - onclick="javascript:$('info').hide();return false;">hide</a>] -</div> - -<div id="gwtpage"> -</div> - -<script type="text/javascript" language="javascript" - src="org.sonar.plugins.core.hotspots.GwtHotspots.nocache.js"></script> -</body> -</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index ab2544c3580..26e4d609471 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -35,7 +35,6 @@ import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; import org.sonar.plugins.core.dashboards.HotspotsDashboard; import org.sonar.plugins.core.dashboards.SonarMainDashboard; -import org.sonar.plugins.core.hotspots.Hotspots; import org.sonar.plugins.core.metrics.UserManagedMetrics; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; import org.sonar.plugins.core.sensors.*; @@ -227,7 +226,6 @@ public class CorePlugin extends SonarPlugin { // pages extensions.add(TestsViewerDefinition.class); - extensions.add(Hotspots.class); extensions.add(Lcom4Viewer.class); // widgets diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java index 04369cb8ab2..03f71f62496 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java @@ -28,9 +28,43 @@ import org.sonar.api.web.WidgetProperty; import org.sonar.api.web.WidgetPropertyType; @DashboardWidgets ({ - @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=1, + @DashboardWidget(id="hotspot_most_violated_rules", columnIndex=1, rowIndex=1), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=2, properties={ - @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "complexity") + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "test_execution_time"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Longest unit tests") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=3, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "complexity"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest complexity") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=4, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "duplicated_lines"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest duplications") + + }), + @DashboardWidget(id="hotspot_most_violated_resources", columnIndex=2, rowIndex=1), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=2, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "uncovered_lines"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest untested lines") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=3, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "function_complexity"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest average method complexity") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=4, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "public_undocumented_api"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Most undocumented APIs") + }) }) /** @@ -50,7 +84,7 @@ public class HotspotsDashboard extends AbstractDashboard implements Dashboard { @Override public String getLayout() { - return DashboardLayouts.TREE_COLUMNS; + return DashboardLayouts.TWO_COLUMNS; } }
\ No newline at end of file diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties index 6fecff23723..60f4c525a91 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -452,7 +452,7 @@ property.category.server_id=Server ID dashboard.sonar-main-dashboard.name=Dashboard dashboard.sonar-main-dashboard.description=Default dashboard -dashboard.sonar-hotspots-dashboard.name=Hotspots [NEW!!] +dashboard.sonar-hotspots-dashboard.name=Hotspots dashboard.sonar-hotspots-dashboard.description=Most useful hotspots widgets diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java index b27f12923a4..7c7085c2f9f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java @@ -31,7 +31,7 @@ import java.lang.annotation.Target; * @since 2.13 */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) +@Target(ElementType.ANNOTATION_TYPE) public @interface DashboardWidget { /** diff --git a/sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java index ccaf5a85928..4525ad3e9ee 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java @@ -37,6 +37,7 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.web.AbstractDashboard; import org.sonar.api.web.Dashboard; +import org.sonar.api.web.DashboardLayouts; import org.sonar.api.web.DashboardWidget; import org.sonar.api.web.DashboardWidgets; import org.sonar.api.web.WidgetProperty; @@ -94,6 +95,12 @@ public class RegisterProvidedDashboardsTest { } @Test + public void test() { + org.sonar.persistence.model.Dashboard dataModelDashboard = registerProvidedDashboards.createDataModelFromExtension(new HotspotsDashboard()); + System.out.println(dataModelDashboard); + } + + @Test public void shouldCreateDataModelFromExtension() { org.sonar.persistence.model.Dashboard dataModelDashboard = registerProvidedDashboards.createDataModelFromExtension(dashboard); assertThat(dataModelDashboard.getUserId(), is(nullValue())); @@ -199,4 +206,67 @@ public class RegisterProvidedDashboardsTest { } } + + @DashboardWidgets ({ + @DashboardWidget(id="hotspot_most_violated_rules", columnIndex=1, rowIndex=1), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=2, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "test_execution_time"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Longest unit tests") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=3, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "complexity"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest complexity") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=1, rowIndex=4, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "duplicated_lines"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest duplications") + + }), + @DashboardWidget(id="hotspot_most_violated_resources", columnIndex=2, rowIndex=1), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=2, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "uncovered_lines"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest untested lines") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=3, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "function_complexity"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Highest average method complexity") + + }), + @DashboardWidget(id="hotspot_metric", columnIndex=2, rowIndex=4, + properties={ + @WidgetProperty(key = "metric", type = WidgetPropertyType.METRIC, defaultValue = "public_undocumented_api"), + @WidgetProperty(key = "title", type = WidgetPropertyType.STRING, defaultValue = "Most undocumented APIs") + + }) + }) + /** + * Hotspot dashboard for Sonar + */ + public class HotspotsDashboard extends AbstractDashboard implements Dashboard { + + @Override + public String getId() { + return "sonar-hotspots-dashboard"; + } + + @Override + public String getName() { + return "Hotspots"; + } + + @Override + public String getLayout() { + return DashboardLayouts.TWO_COLUMNS; + } + + } + } |