aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/HotspotsDashboard.java91
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/SonarMainDashboard.java49
-rw-r--r--plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties8
-rw-r--r--sonar-core/src/main/java/org/sonar/persistence/model/Dashboard.java4
-rw-r--r--sonar-core/src/main/java/org/sonar/persistence/model/Widget.java4
-rw-r--r--sonar-core/src/test/java/org/sonar/persistence/dao/DashboardDaoTest.java5
-rw-r--r--sonar-core/src/test/resources/org/sonar/persistence/dao/DashboardDaoTest/shouldInsert-result.xml8
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboard.java75
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java53
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java65
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidgets.java43
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetProperty.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Dashboard.java164
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardLayouts.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardLayouts.java)26
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardTemplate.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/web/Template.java)19
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Widget.java94
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/DashboardTest.java65
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/WidgetTest.java48
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedDashboards.java65
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboards_controller.rb1
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb10
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/236_add_key_to_dashboards.rb6
-rw-r--r--sonar-server/src/test/java/org/sonar/server/startup/RegisterProvidedDashboardsTest.java128
24 files changed, 535 insertions, 503 deletions
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 03f71f62496..f6625d8854c 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
@@ -19,72 +19,49 @@
*/
package org.sonar.plugins.core.dashboards;
-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;
-import org.sonar.api.web.WidgetPropertyType;
+import org.sonar.api.web.dashboard.Dashboard;
+import org.sonar.api.web.dashboard.DashboardLayouts;
+import org.sonar.api.web.dashboard.DashboardTemplate;
+import org.sonar.api.web.dashboard.Widget;
-@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")
+/**
+ * Hotspot dashboard for Sonar
+ */
+public class HotspotsDashboard extends DashboardTemplate {
- }),
- @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")
+ @Override
+ public org.sonar.api.web.dashboard.Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.createDashboard("sonar-hotspots", "Hotspots", DashboardLayouts.TWO_COLUMNS);
- }),
- @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")
+ Widget widget = dashboard.addWidget("hotspot_most_violated_rules", 1, 1);
- }),
- @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")
+ widget = dashboard.addWidget("hotspot_metric", 1, 2);
+ widget.addProperty("metric", "test_execution_time");
+ widget.addProperty("title", "Longest unit tests");
- }),
- @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")
+ widget = dashboard.addWidget("hotspot_metric", 1, 3);
+ widget.addProperty("metric", "complexity");
+ widget.addProperty("title", "Highest 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")
+ widget = dashboard.addWidget("hotspot_metric", 1, 4);
+ widget.addProperty("metric", "duplicated_lines");
+ widget.addProperty("title", "Highest duplications");
- })
-})
-/**
- * Hotspot dashboard for Sonar
- */
-public class HotspotsDashboard extends AbstractDashboard implements Dashboard {
+ widget = dashboard.addWidget("hotspot_most_violated_resources", 2, 1);
- @Override
- public String getId() {
- return "sonar-hotspots-dashboard";
- }
+ widget = dashboard.addWidget("hotspot_metric", 2, 2);
+ widget.addProperty("metric", "uncovered_lines");
+ widget.addProperty("title", "Highest untested lines");
- @Override
- public String getName() {
- return "Hotspots";
- }
-
- @Override
- public String getLayout() {
- return DashboardLayouts.TWO_COLUMNS;
+ widget = dashboard.addWidget("hotspot_metric", 2, 3);
+ widget.addProperty("metric", "function_complexity");
+ widget.addProperty("title", "Highest average method complexity");
+
+ widget = dashboard.addWidget("hotspot_metric", 2, 4);
+ widget.addProperty("metric", "public_undocumented_api");
+ widget.addProperty("title", "Most undocumented APIs");
+
+ return dashboard;
}
} \ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/SonarMainDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/SonarMainDashboard.java
index 820419a462d..8b81c8b747e 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/SonarMainDashboard.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/SonarMainDashboard.java
@@ -19,43 +19,30 @@
*/
package org.sonar.plugins.core.dashboards;
-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.dashboard.Dashboard;
+import org.sonar.api.web.dashboard.DashboardLayouts;
+import org.sonar.api.web.dashboard.DashboardTemplate;
-@DashboardWidgets ({
- @DashboardWidget(id="size", columnIndex=1, rowIndex=1),
- @DashboardWidget(id="comments_duplications", columnIndex=1, rowIndex=2),
- @DashboardWidget(id="complexity", columnIndex=1, rowIndex=3),
- @DashboardWidget(id="code_coverage", columnIndex=1, rowIndex=4),
- @DashboardWidget(id="events", columnIndex=1, rowIndex=5),
- @DashboardWidget(id="description", columnIndex=1, rowIndex=6),
- @DashboardWidget(id="rules", columnIndex=2, rowIndex=1),
- @DashboardWidget(id="alerts", columnIndex=2, rowIndex=2),
- @DashboardWidget(id="file_design", columnIndex=2, rowIndex=3),
- @DashboardWidget(id="package_design", columnIndex=2, rowIndex=4),
- @DashboardWidget(id="ckjm", columnIndex=2, rowIndex=5)
-})
/**
* Default dashboard for Sonar
*/
-public class SonarMainDashboard extends AbstractDashboard implements Dashboard {
+public class SonarMainDashboard extends DashboardTemplate {
@Override
- public String getId() {
- return "sonar-main-dashboard";
- }
-
- @Override
- public String getName() {
- return "Dashboard";
- }
-
- @Override
- public String getLayout() {
- return DashboardLayouts.TWO_COLUMNS;
+ public org.sonar.api.web.dashboard.Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.createDashboard("sonar-main", "Dashboard", DashboardLayouts.TWO_COLUMNS);
+ dashboard.addWidget("size", 1, 1);
+ dashboard.addWidget("comments_duplications", 1, 2);
+ dashboard.addWidget("complexity", 1, 3);
+ dashboard.addWidget("code_coverage", 1, 4);
+ dashboard.addWidget("events", 1, 5);
+ dashboard.addWidget("description", 1, 6);
+ dashboard.addWidget("rules", 2, 1);
+ dashboard.addWidget("alerts", 2, 2);
+ dashboard.addWidget("file_design", 2, 3);
+ dashboard.addWidget("package_design", 2, 4);
+ dashboard.addWidget("ckjm", 2, 5);
+ return dashboard;
}
} \ 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 60f4c525a91..78585d8bd10 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
@@ -449,11 +449,11 @@ property.category.server_id=Server ID
#
#------------------------------------------------------------------------------
-dashboard.sonar-main-dashboard.name=Dashboard
-dashboard.sonar-main-dashboard.description=Default dashboard
+dashboard.sonar-main.name=Dashboard
+dashboard.sonar-main.description=Default dashboard
-dashboard.sonar-hotspots-dashboard.name=Hotspots
-dashboard.sonar-hotspots-dashboard.description=Most useful hotspots widgets
+dashboard.sonar-hotspots.name=Hotspots
+dashboard.sonar-hotspots.description=Most useful hotspots widgets
#------------------------------------------------------------------------------
diff --git a/sonar-core/src/main/java/org/sonar/persistence/model/Dashboard.java b/sonar-core/src/main/java/org/sonar/persistence/model/Dashboard.java
index a2281e83cce..91429cd1005 100644
--- a/sonar-core/src/main/java/org/sonar/persistence/model/Dashboard.java
+++ b/sonar-core/src/main/java/org/sonar/persistence/model/Dashboard.java
@@ -19,9 +19,9 @@
*/
package org.sonar.persistence.model;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
import com.google.common.collect.Lists;
@@ -36,7 +36,7 @@ public class Dashboard {
private boolean shared;
private Date createdAt;
private Date updatedAt;
- private ArrayList<Widget> widgets = Lists.newArrayList();
+ private List<Widget> widgets = Lists.newArrayList();
/**
* @return the id
diff --git a/sonar-core/src/main/java/org/sonar/persistence/model/Widget.java b/sonar-core/src/main/java/org/sonar/persistence/model/Widget.java
index 163db94bb5a..a90a4834819 100644
--- a/sonar-core/src/main/java/org/sonar/persistence/model/Widget.java
+++ b/sonar-core/src/main/java/org/sonar/persistence/model/Widget.java
@@ -19,9 +19,9 @@
*/
package org.sonar.persistence.model;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
import com.google.common.collect.Lists;
@@ -37,7 +37,7 @@ public class Widget {
private boolean configured;
private Date createdAt;
private Date updatedAt;
- private ArrayList<WidgetProperty> widgetProperties = Lists.newArrayList();
+ private List<WidgetProperty> widgetProperties = Lists.newArrayList();
/**
* @return the id
diff --git a/sonar-core/src/test/java/org/sonar/persistence/dao/DashboardDaoTest.java b/sonar-core/src/test/java/org/sonar/persistence/dao/DashboardDaoTest.java
index c8fea9648ff..1824cd169bd 100644
--- a/sonar-core/src/test/java/org/sonar/persistence/dao/DashboardDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/persistence/dao/DashboardDaoTest.java
@@ -39,7 +39,7 @@ public class DashboardDaoTest extends DaoTestCase {
@Test
public void shouldInsert() throws Exception {
setupData("shouldInsert");
- Date aDate = new Date(123456789);
+ Date aDate = new Date();
Dashboard dashboard = new Dashboard();
dashboard.setKey("d-key");
@@ -70,13 +70,12 @@ public class DashboardDaoTest extends DaoTestCase {
dao.insert(dashboard);
- checkTables("shouldInsert", "dashboards", "widgets", "widget_properties");
+ checkTables("shouldInsert", new String[] { "created_at", "updated_at" }, "dashboards", "widgets", "widget_properties");
}
@Test
public void shouldInsertWithNullableColumns() throws Exception {
setupData("shouldInsert");
- Date aDate = new Date(123456789);
Dashboard dashboard = new Dashboard();
dashboard.setKey("d-key");
diff --git a/sonar-core/src/test/resources/org/sonar/persistence/dao/DashboardDaoTest/shouldInsert-result.xml b/sonar-core/src/test/resources/org/sonar/persistence/dao/DashboardDaoTest/shouldInsert-result.xml
index f5b4eca9ec8..5f4e92ddd80 100644
--- a/sonar-core/src/test/resources/org/sonar/persistence/dao/DashboardDaoTest/shouldInsert-result.xml
+++ b/sonar-core/src/test/resources/org/sonar/persistence/dao/DashboardDaoTest/shouldInsert-result.xml
@@ -7,9 +7,7 @@
name="My Dashboard"
description="This is a dashboard"
column_layout="100%"
- shared="true"
- created_at="1970-01-02 11:17:36.789"
- updated_at="1970-01-02 11:17:36.789"/>
+ shared="true"/>
<widgets
id="1"
@@ -19,9 +17,7 @@
description="Widget for code coverage"
column_index="13"
row_index="14"
- configured="true"
- created_at="1970-01-02 11:17:36.789"
- updated_at="1970-01-02 11:17:36.789"/>
+ configured="true"/>
<widget_properties
id="1"
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboard.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboard.java
deleted file mode 100644
index d127c7c533c..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboard.java
+++ /dev/null
@@ -1,75 +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.api.web;
-
-/**
- * Class that every plugin predefined dashboard should extend (as long as implement the {@link Dashboard} interface).
- *
- * @since 2.13
- */
-public abstract class AbstractDashboard {
-
- private static final String TEMPLATE_TYPE = "DASHBOARD";
-
- /**
- * Returns the identifier of this template.
- *
- * @see Template#getId()
- * @return
- */
- public abstract String getId();
-
- /**
- * Returns the name of the dashboard.
- *
- * @return the name
- */
- public abstract String getName();
-
- /**
- * Returns the description of the dashboard.
- *
- * @return the description
- */
- public String getDescription() {
- return "";
- }
-
- /**
- * Returns the layout for the dashboard.
- *
- * @see DashboardLayouts for the possible values.
- * @return the layout
- */
- public String getLayout() {
- return DashboardLayouts.TWO_COLUMNS;
- }
-
- /**
- * Returns the kind of template.
- *
- * @see Template#getType()
- * @return the type
- */
- public final String getType() {
- return TEMPLATE_TYPE;
- }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
deleted file mode 100644
index 4472dc08b08..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
+++ /dev/null
@@ -1,53 +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.api.web;
-
-/**
- * A dashboard is a set of predefined and potentially parameterized widgets.
- *
- * As a "Template" extension, a dashboard will get created in the DB only once, when its plugin executes for the first time.
- *
- * @since 2.13
- */
-public interface Dashboard extends Template {
-
- /**
- * Returns the name of the dashboard.
- *
- * @return the name
- */
- String getName();
-
- /**
- * Returns the description of the dashboard.
- *
- * @return the description
- */
- String getDescription();
-
- /**
- * Returns the layout for the dashboard.
- *
- * @see DashboardLayouts for the possible values.
- * @return the layout
- */
- String getLayout();
-
-}
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
deleted file mode 100644
index 7c7085c2f9f..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidget.java
+++ /dev/null
@@ -1,65 +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.api.web;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation used to specify a widget associated to a dashboard template. It must be nested inside a {@link DashboardWidgets} annotation.
- * It can contain {@link WidgetProperties} annotation to modify the widget default parameters.
- *
- * @since 2.13
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.ANNOTATION_TYPE)
-public @interface DashboardWidget {
-
- /**
- * ID of the widget.
- *
- * @return the id
- */
- String id();
-
- /**
- * The index of the column for this widget.
- *
- * @return the column index
- */
- int columnIndex();
-
- /**
- * The index of the row for this widget.
- *
- * @return the row index
- */
- int rowIndex();
-
- /**
- * The widget specific properties.
- *
- * @return the widget properties
- */
- WidgetProperty[] properties() default {};
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidgets.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidgets.java
deleted file mode 100644
index c9680521e2c..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardWidgets.java
+++ /dev/null
@@ -1,43 +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.api.web;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation used to specify the list of widgets associated to a dashboard template.
- *
- * @see AbstractDashboard
- * @since 2.13
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface DashboardWidgets {
-
- /**
- * List of {@link DashboardWidget} definitions.
- *
- * @return
- */
- DashboardWidget[] value() default {};
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetProperty.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetProperty.java
index 484d3b374fc..b1b4b6a8b05 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetProperty.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetProperty.java
@@ -19,10 +19,13 @@
*/
package org.sonar.api.web;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
public @interface WidgetProperty {
String key();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Dashboard.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Dashboard.java
new file mode 100644
index 00000000000..4843418eb04
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Dashboard.java
@@ -0,0 +1,164 @@
+/*
+ * 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.api.web.dashboard;
+
+import java.util.Collection;
+
+import com.google.common.collect.Lists;
+
+/**
+ *
+ * Definition of a dashboard.
+ *
+ * Its name and description can be retrieved using the i18n mechanism, using the keys "dashboard.&lt;id&gt;.name" and
+ * "dashboard.&lt;id&gt;.description".
+ *
+ * @since 2.13
+ */
+public final class Dashboard {
+
+ private String id;
+ private String name;
+ private String description;
+ private String layout;
+ private Collection<Widget> widgets;
+
+ private Dashboard() {
+ widgets = Lists.newArrayList();
+ }
+
+ /**
+ * Creates a new {@link Dashboard}. See {@link DashboardLayouts} for the layout parameter.
+ *
+ * @param id
+ * the id
+ * @param name
+ * the name
+ * @param layout
+ * the layout
+ */
+ public static Dashboard createDashboard(String id, String name, String layout) {
+ Dashboard dashboard = new Dashboard();
+ dashboard.setId(id);
+ dashboard.setName(name);
+ dashboard.setDescription("");
+ dashboard.setLayout(layout);
+ return dashboard;
+ }
+
+ /**
+ * Add a widget with the given parameters, and return the newly created {@link Widget} object if one wants to add parameters to it.
+ *
+ * @param id
+ * the id of the widget
+ * @param columnId
+ * the column for the widget
+ * @param rowId
+ * the row for the widget
+ * @return the new widget
+ */
+ public Widget addWidget(String id, int columnId, int rowId) {
+ Widget widget = new Widget(id, columnId, rowId);
+ widgets.add(widget);
+ return widget;
+ }
+
+ /**
+ * Returns the list of widgets.
+ *
+ * @return the widgets of this dashboard
+ */
+ public Collection<Widget> getWidgets() {
+ return widgets;
+ }
+
+ /**
+ * Returns the identifier of the dashboard.
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ private void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the name of the dashboard.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ * the name to set
+ */
+ private void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the description of the dashboard.
+ *
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets the description of the dashboard.
+ *
+ * Note: you should use the i18n mechanism for the description.
+ *
+ * @param description
+ * the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Returns the layout of the dashboard.
+ *
+ * @return the layout
+ */
+ public String getLayout() {
+ return layout;
+ }
+
+ /**
+ * @param layout
+ * the layout to set
+ */
+ private void setLayout(String layout) {
+ this.layout = layout;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardLayouts.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardLayouts.java
index 5aa79ce4055..186a16f5b4c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/DashboardLayouts.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardLayouts.java
@@ -17,19 +17,41 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
-package org.sonar.api.web;
+package org.sonar.api.web.dashboard;
/**
* Possible layouts for a dashboard.
*
* @since 2.13
*/
-public class DashboardLayouts {
+public final class DashboardLayouts {
+ private DashboardLayouts() {
+ }
+
+ /**
+ * Only 1 column that take all the page
+ */
public static final String ONE_COLUMN = "100%";
+
+ /**
+ * 2 columns of the same width
+ */
public static final String TWO_COLUMNS = "50%-50%";
+
+ /**
+ * 2 columns with the first one smaller than the second
+ */
public static final String TWO_COLUMNS_30_70 = "30%-70%";
+
+ /**
+ * 2 columns with the first one bigger than the second
+ */
public static final String TWO_COLUMNS_70_30 = "70%-30%";
+
+ /**
+ * 3 columns of the same width
+ */
public static final String TREE_COLUMNS = "33%-33%-33%";
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Template.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardTemplate.java
index c8eec915ed1..17412997c68 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/Template.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/DashboardTemplate.java
@@ -17,28 +17,23 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
-package org.sonar.api.web;
+package org.sonar.api.web.dashboard;
import org.sonar.api.ServerExtension;
/**
- * A template defines a server extension that will be run only once to initialize and store some data in the database.
+ *
+ * This extension point must be implemented to define a new dashboard.
*
* @since 2.13
*/
-public interface Template extends ServerExtension {
+public abstract class DashboardTemplate implements ServerExtension {
/**
- * Returns the identifier of this template.
+ * Returns the {@link Dashboard} object that represents the dashboard to use.
*
- * @return the id
+ * @return the dashboard
*/
- String getId();
+ public abstract Dashboard createDashboard();
- /**
- * Returns the kind of template.
- *
- * @return the type
- */
- String getType();
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Widget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Widget.java
new file mode 100644
index 00000000000..8929f4f60f9
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/dashboard/Widget.java
@@ -0,0 +1,94 @@
+/*
+ * 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.api.web.dashboard;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+/**
+ *
+ * Definition of a widget inside a dashboard.
+ *
+ * @since 2.13
+ */
+public final class Widget {
+
+ private String id;
+ private int columnIndex;
+ private int rowIndex;
+ private Map<String, String> properties;
+
+ Widget(String id, int columnIndex, int rowIndex) {
+ this.id = id;
+ this.columnIndex = columnIndex;
+ this.rowIndex = rowIndex;
+ this.properties = Maps.newHashMap();
+ }
+
+ /**
+ * Adds a property to this widget.
+ *
+ * @param key
+ * the id of the property
+ * @param value
+ * the value of the property
+ */
+ public void addProperty(String key, String value) {
+ properties.put(key, value);
+ }
+
+ /**
+ * Returns the properties of this widget.
+ *
+ * @return the properties
+ */
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Returns the identifier of this widget.
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the column index of this widget.
+ *
+ * @return the columnIndex
+ */
+ public int getColumnIndex() {
+ return columnIndex;
+ }
+
+ /**
+ * Returns the row index of this widget.
+ *
+ * @return the rowIndex
+ */
+ public int getRowIndex() {
+ return rowIndex;
+ }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/DashboardTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/DashboardTest.java
new file mode 100644
index 00000000000..bcac4887a06
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/DashboardTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.api.web.dashboard;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.junit.Test;
+
+public class DashboardTest {
+
+ @Test
+ public void shouldCreateDashboardAndWidget() throws Exception {
+ Dashboard dashboard = Dashboard.createDashboard("fake-dashboard", "Fake", "30%-70%");
+ assertThat(dashboard.getId(), is("fake-dashboard"));
+ assertThat(dashboard.getName(), is("Fake"));
+ assertThat(dashboard.getLayout(), is("30%-70%"));
+ assertThat(dashboard.getDescription(), is(""));
+
+ Widget widget = dashboard.addWidget("fake-widget", 12, 13);
+ assertThat(widget.getId(), is("fake-widget"));
+ assertThat(widget.getColumnIndex(), is(12));
+ assertThat(widget.getRowIndex(), is(13));
+
+ widget.addProperty("fake-property", "fake_metric");
+ Set<Entry<String, String>> properties = widget.getProperties().entrySet();
+ assertThat(properties.size(), is(1));
+ Entry<String, String> property = properties.iterator().next();
+ assertThat(property.getKey(), is("fake-property"));
+ assertThat(property.getValue(), is("fake_metric"));
+ }
+
+ @Test
+ public void shouldAddWidget() throws Exception {
+ Dashboard dashboard = Dashboard.createDashboard("fake-dashboard", "Fake", "30%-70%");
+ dashboard.addWidget("fake-widget", 12, 13);
+
+ Widget widget = dashboard.getWidgets().iterator().next();
+
+ assertThat(widget.getId(), is("fake-widget"));
+ assertThat(widget.getColumnIndex(), is(12));
+ assertThat(widget.getRowIndex(), is(13));
+ }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/WidgetTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/WidgetTest.java
new file mode 100644
index 00000000000..199d83cd9ef
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/web/dashboard/WidgetTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.api.web.dashboard;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.junit.Test;
+
+public class WidgetTest {
+
+ @Test
+ public void shouldCreateWidgetWithProperties() throws Exception {
+ Dashboard dashboard = Dashboard.createDashboard("fake-dashboard", "Fake", "30%-70%");
+ Widget widget = dashboard.addWidget("fake-widget", 12, 13);
+ assertThat(widget.getId(), is("fake-widget"));
+ assertThat(widget.getColumnIndex(), is(12));
+ assertThat(widget.getRowIndex(), is(13));
+
+ widget.addProperty("fake-property", "fake_metric");
+ Set<Entry<String, String>> properties = widget.getProperties().entrySet();
+ assertThat(properties.size(), is(1));
+ Entry<String, String> property = properties.iterator().next();
+ assertThat(property.getKey(), is("fake-property"));
+ assertThat(property.getValue(), is("fake_metric"));
+ }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedDashboards.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedDashboards.java
index 470bb0c5271..87af9748a50 100644
--- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedDashboards.java
+++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedDashboards.java
@@ -23,31 +23,31 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
+import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.utils.TimeProfiler;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardWidget;
-import org.sonar.api.web.DashboardWidgets;
-import org.sonar.api.web.WidgetProperty;
+import org.sonar.api.web.dashboard.Dashboard;
+import org.sonar.api.web.dashboard.DashboardTemplate;
+import org.sonar.api.web.dashboard.Widget;
import org.sonar.core.i18n.I18nManager;
import org.sonar.persistence.dao.ActiveDashboardDao;
import org.sonar.persistence.dao.DashboardDao;
import org.sonar.persistence.dao.LoadedTemplateDao;
import org.sonar.persistence.model.ActiveDashboard;
import org.sonar.persistence.model.LoadedTemplate;
-import org.sonar.persistence.model.Widget;
import com.google.common.collect.Lists;
public final class RegisterProvidedDashboards {
private static final Logger LOGGER = LoggerFactory.getLogger(RegisterProvidedDashboards.class);
- private static final String MAIN_DASHBOARD_ID = "sonar-main-dashboard";
+ private static final String MAIN_DASHBOARD_ID = "sonar-main";
- private ArrayList<Dashboard> dashboards;
+ private List<DashboardTemplate> dashboardTemplates;
private DashboardDao dashboardDao;
private ActiveDashboardDao activeDashboardDao;
private LoadedTemplateDao loadedTemplateDao;
@@ -55,12 +55,12 @@ public final class RegisterProvidedDashboards {
public RegisterProvidedDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao,
I18nManager i18nManager) {
- this(new Dashboard[] {}, dashboardDao, activeDashboardDao, loadedTemplateDao, i18nManager);
+ this(new DashboardTemplate[] {}, dashboardDao, activeDashboardDao, loadedTemplateDao, i18nManager);
}
- public RegisterProvidedDashboards(Dashboard[] dashboardArray, DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao,
- LoadedTemplateDao loadedTemplateDao, I18nManager i18nManager) {
- this.dashboards = Lists.newArrayList(dashboardArray);
+ public RegisterProvidedDashboards(DashboardTemplate[] dashboardTemplatesArray, DashboardDao dashboardDao,
+ ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao, I18nManager i18nManager) {
+ this.dashboardTemplates = Lists.newArrayList(dashboardTemplatesArray);
this.dashboardDao = dashboardDao;
this.activeDashboardDao = activeDashboardDao;
this.loadedTemplateDao = loadedTemplateDao;
@@ -73,7 +73,8 @@ public final class RegisterProvidedDashboards {
// load the dashboards that need to be loaded
ArrayList<org.sonar.persistence.model.Dashboard> loadedDashboards = Lists.newArrayList();
org.sonar.persistence.model.Dashboard mainDashboard = null;
- for (Dashboard dashboard : dashboards) {
+ for (DashboardTemplate dashboardTemplate : dashboardTemplates) {
+ Dashboard dashboard = dashboardTemplate.createDashboard();
if (shouldBeLoaded(dashboard)) {
org.sonar.persistence.model.Dashboard dashboardDataModel = loadDashboard(dashboard);
if (MAIN_DASHBOARD_ID.equals(dashboard.getId())) {
@@ -89,7 +90,7 @@ public final class RegisterProvidedDashboards {
profiler.stop();
}
- protected void activateDashboards(ArrayList<org.sonar.persistence.model.Dashboard> loadedDashboards,
+ protected void activateDashboards(List<org.sonar.persistence.model.Dashboard> loadedDashboards,
org.sonar.persistence.model.Dashboard mainDashboard) {
int nextOrderIndex = 0;
if (mainDashboard != null) {
@@ -132,28 +133,22 @@ public final class RegisterProvidedDashboards {
dashboardDataModel.setCreatedAt(now);
dashboardDataModel.setUpdatedAt(now);
- DashboardWidgets dashboardWidgets = dashboard.getClass().getAnnotation(DashboardWidgets.class);
- if (dashboardWidgets != null) {
- for (DashboardWidget dashboardWidget : dashboardWidgets.value()) {
- Widget widget = new Widget();
- widget.setKey(dashboardWidget.id());
- widget.setName(i18nManager.message(Locale.ENGLISH, "widget." + dashboardWidget.id() + ".name", ""));
- widget.setColumnIndex(dashboardWidget.columnIndex());
- widget.setRowIndex(dashboardWidget.rowIndex());
- widget.setConfigured(true);
- widget.setCreatedAt(now);
- widget.setUpdatedAt(now);
- dashboardDataModel.addWidget(widget);
-
- WidgetProperty[] dashboardWidgetProperties = dashboardWidget.properties();
- for (int i = 0; i < dashboardWidgetProperties.length; i++) {
- WidgetProperty dashboardWidgetProperty = dashboardWidgetProperties[i];
- org.sonar.persistence.model.WidgetProperty widgetProperty = new org.sonar.persistence.model.WidgetProperty();
- widgetProperty.setKey(dashboardWidgetProperty.key());
- widgetProperty.setValue(dashboardWidgetProperty.defaultValue());
- widgetProperty.setValueType(dashboardWidgetProperty.type().toString());
- widget.addWidgetProperty(widgetProperty);
- }
+ for (Widget widget : dashboard.getWidgets()) {
+ org.sonar.persistence.model.Widget widgetDataModel = new org.sonar.persistence.model.Widget();
+ widgetDataModel.setKey(widget.getId());
+ widgetDataModel.setName(i18nManager.message(Locale.ENGLISH, "widget." + widget.getId() + ".name", ""));
+ widgetDataModel.setColumnIndex(widget.getColumnIndex());
+ widgetDataModel.setRowIndex(widget.getRowIndex());
+ widgetDataModel.setConfigured(true);
+ widgetDataModel.setCreatedAt(now);
+ widgetDataModel.setUpdatedAt(now);
+ dashboardDataModel.addWidget(widgetDataModel);
+
+ for (Entry<String, String> property : widget.getProperties().entrySet()) {
+ org.sonar.persistence.model.WidgetProperty widgetPropertyDataModel = new org.sonar.persistence.model.WidgetProperty();
+ widgetPropertyDataModel.setKey(property.getKey());
+ widgetPropertyDataModel.setValue(property.getValue());
+ widgetDataModel.addWidgetProperty(widgetPropertyDataModel);
}
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboards_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboards_controller.rb
index d0868c84a84..22bfe87eb5a 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboards_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboards_controller.rb
@@ -168,7 +168,6 @@ class DashboardsController < ApplicationController
def load_dashboard_from_params(dashboard)
dashboard.name=params[:name]
- dashboard.kee=dashboard.name.strip.downcase.sub(/\s+/, '_')
dashboard.description=params[:description]
dashboard.shared=(params[:shared].present? && is_admin?)
dashboard.user_id=current_user.id
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb
index 1a136f86081..bb5c54c1a84 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb
@@ -30,17 +30,15 @@ class Dashboard < ActiveRecord::Base
validates_length_of :description, :maximum => 1000, :allow_blank => true, :allow_nil => true
validates_length_of :column_layout, :maximum => 20, :allow_blank => false, :allow_nil => false
validates_uniqueness_of :name, :scope => :user_id
+
+ before_create { |dashboard| dashboard.kee=dashboard.name.strip.downcase.sub(/\s+/, '_') }
def name
- default_name = read_attribute(:name)
- default_name = Api::Utils.message('dashboard.' + read_attribute(:kee) + '.name', :default => default_name) if read_attribute(:kee)
- default_name
+ Api::Utils.message("dashboard.#{kee}.name", :default => read_attribute(:name))
end
def description
- default_description = read_attribute(:description)
- default_description = Api::Utils.message('dashboard.' + read_attribute(:kee) + '.description', :default => default_description) if read_attribute(:kee)
- default_description
+ Api::Utils.message("dashboard.#{kee}.description", :default => read_attribute(:description))
end
def shared?
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb
index 57cd8bc438a..bd313df7d43 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb
@@ -29,12 +29,10 @@ class CreateLoadedTemplates < ActiveRecord::Migration
t.column 'template_type', :string, :null => true, :limit => 15
end
- alter_to_big_primary_key('loaded_templates')
-
# if this is a migration, then the default dashboard already exists in the DB so it should not be loaded again
main_dashboard = Dashboard.find(:first, :conditions => {:name => 'Dashboard'})
if main_dashboard
- LoadedTemplate.new({:kee => 'sonar-main-dashboard', :template_type => 'DASHBOARD'}).save
+ LoadedTemplate.create({:kee => 'sonar-main', :template_type => 'DASHBOARD'})
end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/236_add_key_to_dashboards.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/236_add_key_to_dashboards.rb
index f000fc068f1..d1031a6eeeb 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/236_add_key_to_dashboards.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/236_add_key_to_dashboards.rb
@@ -24,7 +24,7 @@
class AddKeyToDashboards < ActiveRecord::Migration
def self.up
- add_column 'dashboards', 'kee', :string, :limit => 256
+ add_column 'dashboards', 'kee', :string, :limit => 200
Dashboard.reset_column_information
Dashboard.find(:all).each do |d|
@@ -34,11 +34,11 @@ class AddKeyToDashboards < ActiveRecord::Migration
main_dashboard = Dashboard.find(:first, :conditions => {:name => 'Dashboard'})
if main_dashboard
- main_dashboard.kee = 'sonar-main-dashboard'
+ main_dashboard.kee = 'sonar-main'
main_dashboard.save
end
- change_column 'dashboards', 'kee', :string, :limit => 256, :null => false
+ change_column 'dashboards', 'kee', :string, :limit => 200, :null => false
Dashboard.reset_column_information
end
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 4525ad3e9ee..6973393972b 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
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -35,13 +36,8 @@ import java.util.Locale;
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;
-import org.sonar.api.web.WidgetPropertyType;
+import org.sonar.api.web.dashboard.Dashboard;
+import org.sonar.api.web.dashboard.DashboardTemplate;
import org.sonar.core.i18n.I18nManager;
import org.sonar.persistence.dao.ActiveDashboardDao;
import org.sonar.persistence.dao.DashboardDao;
@@ -58,8 +54,8 @@ public class RegisterProvidedDashboardsTest {
private DashboardDao dashboardDao;
private ActiveDashboardDao activeDashboardDao;
private LoadedTemplateDao loadedTemplateDao;
- private Dashboard dashboard;
private I18nManager i18nManager;
+ private DashboardTemplate fakeDashboardTemplate;
@Before
public void init() {
@@ -69,40 +65,45 @@ public class RegisterProvidedDashboardsTest {
i18nManager = mock(I18nManager.class);
when(i18nManager.message(Locale.ENGLISH, "widget.fake-widget.name", "")).thenReturn("Fake Widget");
when(i18nManager.message(Locale.ENGLISH, "dashboard.fake-dashboard.name", "Fake")).thenReturn("Fake Dashboard");
- dashboard = new FakeDashboard();
- registerProvidedDashboards = new RegisterProvidedDashboards(new Dashboard[] { dashboard }, dashboardDao, activeDashboardDao,
- loadedTemplateDao, i18nManager);
+ fakeDashboardTemplate = new FakeDashboard();
+
+ registerProvidedDashboards = new RegisterProvidedDashboards(new DashboardTemplate[] { fakeDashboardTemplate }, dashboardDao,
+ activeDashboardDao, loadedTemplateDao, i18nManager);
+ }
+
+ @Test
+ public void testStart() throws Exception {
+ registerProvidedDashboards.start();
+ verify(dashboardDao).insert(any(org.sonar.persistence.model.Dashboard.class));
+ verify(loadedTemplateDao).insert(any(LoadedTemplate.class));
+ verify(activeDashboardDao).insert(any(ActiveDashboard.class));
}
@Test
public void testShouldNotBeLoaded() throws Exception {
when(loadedTemplateDao.selectByKeyAndType("fake-dashboard", LoadedTemplate.DASHBOARD_TYPE)).thenReturn(new LoadedTemplate());
- assertThat(registerProvidedDashboards.shouldBeLoaded(dashboard), is(false));
+ assertThat(registerProvidedDashboards.shouldBeLoaded(fakeDashboardTemplate.createDashboard()), is(false));
}
@Test
public void testShouldBeLoaded() throws Exception {
- assertThat(registerProvidedDashboards.shouldBeLoaded(dashboard), is(true));
+ assertThat(registerProvidedDashboards.shouldBeLoaded(fakeDashboardTemplate.createDashboard()), is(true));
}
@Test
public void shouldLoadDasboard() throws Exception {
- org.sonar.persistence.model.Dashboard dataModelDashboard = registerProvidedDashboards.loadDashboard(dashboard);
+ org.sonar.persistence.model.Dashboard dataModelDashboard = registerProvidedDashboards.loadDashboard(fakeDashboardTemplate
+ .createDashboard());
assertNotNull(dataModelDashboard);
verify(dashboardDao).insert(dataModelDashboard);
verify(loadedTemplateDao).insert(eq(new LoadedTemplate("fake-dashboard", LoadedTemplate.DASHBOARD_TYPE)));
}
@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);
+ org.sonar.persistence.model.Dashboard dataModelDashboard = registerProvidedDashboards
+ .createDataModelFromExtension(fakeDashboardTemplate.createDashboard());
assertThat(dataModelDashboard.getUserId(), is(nullValue()));
assertThat(dataModelDashboard.getKey(), is("fake-dashboard"));
assertThat(dataModelDashboard.getName(), is("Fake Dashboard"));
@@ -125,7 +126,6 @@ public class RegisterProvidedDashboardsTest {
org.sonar.persistence.model.WidgetProperty widgetProperty = widget.getWidgetProperties().iterator().next();
assertThat(widgetProperty.getKey(), is("fake-property"));
assertThat(widgetProperty.getValue(), is("fake_metric"));
- assertThat(widgetProperty.getValueType(), is("METRIC"));
}
@Test
@@ -186,87 +186,15 @@ public class RegisterProvidedDashboardsTest {
verify(activeDashboardDao).insert(eq(ad2));
}
- @DashboardWidgets({ @DashboardWidget(id = "fake-widget", columnIndex = 12, rowIndex = 13, properties = { @WidgetProperty(
- key = "fake-property", type = WidgetPropertyType.METRIC, defaultValue = "fake_metric") }) })
- public class FakeDashboard extends AbstractDashboard implements Dashboard {
+ public class FakeDashboard extends DashboardTemplate {
@Override
- public String getId() {
- return "fake-dashboard";
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.createDashboard("fake-dashboard", "Fake", "30%-70%");
+ org.sonar.api.web.dashboard.Widget widget = dashboard.addWidget("fake-widget", 12, 13);
+ widget.addProperty("fake-property", "fake_metric");
+ return dashboard;
}
-
- @Override
- public String getName() {
- return "Fake";
- }
-
- @Override
- public String getLayout() {
- return "30%-70%";
- }
-
}
-
- @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;
- }
-
- }
-
}