aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2011-08-25 16:29:16 +0200
committerFabrice Bellingard <bellingard@gmail.com>2011-08-25 16:29:16 +0200
commitb667702b4608edd0dc8f461a165a33cabb7e08a7 (patch)
tree6f3980543068ea8a170a4c8d2c53e9ddadb1990e /plugins
parent8a4f61072115d5c57098ae43d13dc4bba1292250 (diff)
downloadsonarqube-b667702b4608edd0dc8f461a165a33cabb7e08a7.tar.gz
sonarqube-b667702b4608edd0dc8f461a165a33cabb7e08a7.zip
SONAR-2701 New "Time Machine" widget
Allows to display measures of required metrics by past version
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java1
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimeMachineWidget.java58
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/time_machine.html.erb114
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb8
-rw-r--r--plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties3
5 files changed, 180 insertions, 4 deletions
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 4a30f0daac8..fd6b705e6bc 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
@@ -215,6 +215,7 @@ public class CorePlugin extends SonarPlugin {
extensions.add(EventsWidget.class);
extensions.add(CustomMeasuresWidget.class);
extensions.add(TimelineWidget.class);
+ extensions.add(TimeMachineWidget.class);
// chart
extensions.add(XradarChart.class);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimeMachineWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimeMachineWidget.java
new file mode 100644
index 00000000000..5d8af7e9a35
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimeMachineWidget.java
@@ -0,0 +1,58 @@
+/*
+ * 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.widgets;
+
+import org.sonar.api.web.AbstractRubyTemplate;
+import org.sonar.api.web.RubyRailsWidget;
+import org.sonar.api.web.WidgetProperties;
+import org.sonar.api.web.WidgetProperty;
+import org.sonar.api.web.WidgetPropertyType;
+
+@WidgetProperties(
+ {
+ @WidgetProperty(key = "numberOfVersions", type = WidgetPropertyType.INTEGER, defaultValue = "4"),
+ @WidgetProperty(key = "displaySparkLine", type = WidgetPropertyType.BOOLEAN),
+ @WidgetProperty(key = "metric1", type = WidgetPropertyType.METRIC, defaultValue = "ncloc"),
+ @WidgetProperty(key = "metric2", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric3", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric4", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric5", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric6", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric7", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric8", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric9", type = WidgetPropertyType.METRIC),
+ @WidgetProperty(key = "metric10", type = WidgetPropertyType.METRIC)
+ }
+)
+public class TimeMachineWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+ public String getId() {
+ return "time_machine";
+ }
+
+ public String getTitle() {
+ return "Time Machine";
+ }
+
+ @Override
+ protected String getTemplatePath() {
+ return "/org/sonar/plugins/core/widgets/time_machine.html.erb";
+ //return "/Users/fbellingard/Documents/Sonar/repos/sonar/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/time_machine.html.erb";
+ }
+} \ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/time_machine.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/time_machine.html.erb
new file mode 100644
index 00000000000..e1d0aee470f
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/time_machine.html.erb
@@ -0,0 +1,114 @@
+<%
+ # Retrieve widget settings
+ metric_ids = []
+ (1..10).each do |index|
+ metric=widget_properties["metric#{index}"]
+ if metric
+ metric_ids << metric.id
+ end
+ end
+ if metric_ids.empty?
+ # No metric has been selected, it's the first time the widget is displayed: 'ncloc' is the default metric
+ ncloc = Metric.find(:first, :conditions => "name = 'ncloc'")
+ metric_ids << ncloc.id
+ end
+ numberOfVersions = widget_properties["numberOfVersions"].to_i == 0 ? 4 : widget_properties["numberOfVersions"].to_i
+ displaySparkLine = widget_properties["displaySparkLine"]
+
+ # Retrieve the measures for each metric on each snapshot
+ options = {}
+ from_date = dashboard_configuration.from_datetime
+ if from_date
+ options[:from] = from_date
+ end
+ snapshots=Snapshot.for_timemachine_widget(@resource, numberOfVersions, options)
+ sids = snapshots.collect{|s| s.id}.uniq
+ measures=ProjectMeasure.find(:all, :conditions => {:snapshot_id => sids, :metric_id => metric_ids})
+
+ # And prepare the rows to display
+ snapshot_by_id={}
+ snapshots.each do |s|
+ snapshot_by_id[s.id]=s
+ end
+ rows_by_metric_id={}
+ rows=[]
+ measures.each do |measure|
+ next unless measure.metric
+
+ if measure.metric.timemachine? && (measure.value || measure.text_value)
+ row=rows_by_metric_id[measure.metric_id]
+ unless row
+ row=Sonar::TimemachineRow.new(measure.metric)
+ rows<<row
+ rows_by_metric_id[measure.metric_id]=row
+ end
+
+ #optimization : avoid eager loading of snapshots
+ measure.snapshot=snapshot_by_id[measure.snapshot_id]
+ row.add_measure(measure)
+ end
+ end
+
+ rows.sort!
+%>
+
+<div class="widget-matrix">
+
+<table class="widget-matrix">
+
+ <thead>
+ <tr>
+ <th valign="top" nowrap="nowrap" style="background-color: #FFFFFF; border: 0px;">
+ </th>
+ <% snapshots.each do |snapshot| %>
+ <th nowrap="nowrap" align="right" valign="top">
+ <%= l snapshot.created_at.to_date %>
+ <br/>
+ <% snapshot.user_events.each do |event| %>
+ <b><%= event.name %></b>
+ <br/>
+ <% end %>
+ </th>
+ <% end %>
+ <th> </th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <%
+ previous_domain=''
+ rows.select{|row| row.metric.val_type != Metric::VALUE_TYPE_DISTRIB}.each do |row|
+ if previous_domain != row.domain
+ %>
+ <tr>
+ <td class="title" colspan="<%= snapshots.size + 2 -%>"><%= row.domain %></td>
+ </tr>
+ <%
+ end
+ previous_domain = row.domain
+ %>
+ <tr class="<%= cycle("even", "odd", :name => row.domain) -%>">
+ <td width="1%" nowrap="nowrap" valign="top">
+ <%= row.metric.short_name %>
+ </td>
+ <%
+ snapshots.each do |snapshot|
+ measure=row.measure(snapshot)
+ %>
+ <td align="right" width="1%" nowrap="nowrap"><%= format_measure(measure, :skip_span_id => true) %></td>
+ <% end %>
+ <td>
+ <%
+ sparkline_url=row.sparkline_url
+ if displaySparkLine && sparkline_url
+ %>
+ <%= image_tag(sparkline_url) %>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+
+</table>
+
+</div> \ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb
index ad44fbac17a..806d77f7a7c 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb
@@ -1,5 +1,6 @@
<%= javascript_include_tag 'protovis-sonar' %>
<%
+ # Retrieve widget settings
metric_data_map = {}
metric_name_map = {}
(1..3).each do |index|
@@ -11,10 +12,11 @@
end
if metric_data_map.empty?
# No metric has been selected, it's the first time the widget is displayed: 'ncloc' is the default metric
- ncloc = Metric.find(:all, :conditions => "name = 'ncloc'").first
+ ncloc = Metric.find(:first, :conditions => "name = 'ncloc'")
metric_data_map[ncloc.id] = []
metric_name_map[ncloc.id] = message('metric.ncloc.name')
end
+ chartHeight = widget_properties["chartHeight"].to_i == 0 ? "null" : widget_properties["chartHeight"]
# Retrieve metric trend information
options = {}
@@ -98,9 +100,7 @@
js_translations = "{"
js_translations += "\"date\":\"" + message("date") + "\""
js_translations += "}"
-
- # Check if the widget height was specified
- chartHeight = widget_properties["chartHeight"].to_i == 0 ? "null" : widget_properties["chartHeight"]
+
%>
<% if widget_properties["chartTitle"] %>
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 c0754fd8e2f..97560a509c0 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
@@ -514,6 +514,9 @@ widget.timeline.name=Timeline
widget.timeline.description=Displays up to 3 metrics on a history chart.
widget.timeline.timeline_not_displayed=The timeline won't be displayed as currently only 1 snapshot is available.
+widget.time_machine.name=Time Machine
+widget.time_machine.description=Displays up to 10 metrics in a table, showing their value for a specified number of past snapshots.
+
widget.ckjm.name=Chidamber & Kemerer
widget.ckjm.description=Reports on LCOM4 and RFC average and distribution.
widget.ckjm.lcom4=LCOM4