aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2011-12-12 17:56:02 +0100
committerFabrice Bellingard <bellingard@gmail.com>2011-12-12 17:58:19 +0100
commit2a1309d55d918fe59634e3858ccbb852ddf28408 (patch)
tree93b27a8b6931543ca83066d9391e38991db20fe0
parent087df4135ce0089a2c96711f6bf2cdcdf921f361 (diff)
downloadsonarqube-2a1309d55d918fe59634e3858ccbb852ddf28408.tar.gz
sonarqube-2a1309d55d918fe59634e3858ccbb852ddf28408.zip
SONAR-3063 Implement the hotspots page as a dashboard
-rw-r--r--plugins/sonar-core-gwt/pom.xml1
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java41
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java66
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java124
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java134
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java127
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java128
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java150
-rw-r--r--plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml9
-rw-r--r--plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspotsDev.gwt.xml6
-rw-r--r--plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css102
-rw-r--r--plugins/sonar-core-gwt/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html36
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java2
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java40
-rw-r--r--plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java2
-rw-r--r--sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java70
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() + "%'>&nbsp;</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> &nbsp;&nbsp;[<a href="#"
- onclick="javascript:$('error').hide();return false;">hide</a>]
-</div>
-<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> &nbsp;&nbsp;[<a href="#"
- onclick="javascript:$('warning').hide();return false;">hide</a>]
-</div>
-<div class="notice" id="info" style="display:none"><span id="infomsg"></span> &nbsp;&nbsp;[<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;
+ }
+
+ }
+
}