import org.sonar.plugins.core.charts.DistributionBarChart;
import org.sonar.plugins.core.charts.XradarChart;
import org.sonar.plugins.core.colorizers.JavaColorizerFormat;
-import org.sonar.plugins.core.dashboards.DefaultDashboard;
-import org.sonar.plugins.core.dashboards.HotspotsDashboard;
-import org.sonar.plugins.core.dashboards.MyFavouritesDashboard;
-import org.sonar.plugins.core.dashboards.ProjectsDashboard;
-import org.sonar.plugins.core.dashboards.ReviewsDashboard;
-import org.sonar.plugins.core.dashboards.TimeMachineDashboard;
-import org.sonar.plugins.core.dashboards.TreemapDashboard;
+import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard;
+import org.sonar.plugins.core.dashboards.ProjectReviewsDashboard;
+import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard;
import org.sonar.plugins.core.filters.MyFavouritesFilter;
import org.sonar.plugins.core.filters.ProjectFilter;
-import org.sonar.plugins.core.filters.TreeMapFilter;
import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
import org.sonar.plugins.core.sensors.CheckAlertThresholds;
import org.sonar.plugins.core.widgets.CustomMeasuresWidget;
import org.sonar.plugins.core.widgets.DescriptionWidget;
import org.sonar.plugins.core.widgets.EventsWidget;
-import org.sonar.plugins.core.widgets.FilterWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterListWidget;
import org.sonar.plugins.core.widgets.HotspotMetricWidget;
import org.sonar.plugins.core.widgets.HotspotMostViolatedResourcesWidget;
import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget;
import org.sonar.plugins.core.widgets.ItCoverageWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterTreemapWidget;
import org.sonar.plugins.core.widgets.RulesWidget;
import org.sonar.plugins.core.widgets.SizeWidget;
import org.sonar.plugins.core.widgets.TimeMachineWidget;
import org.sonar.plugins.core.widgets.TimelineWidget;
import org.sonar.plugins.core.widgets.TreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
import org.sonar.plugins.core.widgets.actionPlans.ActionPlansWidget;
import org.sonar.plugins.core.widgets.reviews.FalsePositiveReviewsWidget;
import org.sonar.plugins.core.widgets.reviews.MyReviewsWidget;
Lcom4Viewer.class,
TestsViewer.class,
- // filters
+ // measure filters
ProjectFilter.class,
- TreeMapFilter.class,
MyFavouritesFilter.class,
// widgets
ActionPlansWidget.class,
ReviewsMetricsWidget.class,
TreemapWidget.class,
- FilterWidget.class,
+ MeasureFilterListWidget.class,
+ MeasureFilterTreemapWidget.class,
+ WelcomeWidget.class,
// dashboards
- DefaultDashboard.class,
- HotspotsDashboard.class,
- ReviewsDashboard.class,
- TimeMachineDashboard.class,
- ProjectsDashboard.class,
- TreemapDashboard.class,
- MyFavouritesDashboard.class,
+ ProjectDefaultDashboard.class,
+ ProjectHotspotDashboard.class,
+ ProjectReviewsDashboard.class,
+ ProjectTimeMachineDashboard.class,
+ GlobalDefaultDashboard.class,
// chart
XradarChart.class,
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
-import org.sonar.plugins.core.widgets.FilterWidget;
-
-/**
- * Base class for global dashboard containing a single
- * filter widget.
- *
- * @since 3.1
- */
-abstract class AbstractFilterDashboard extends DashboardTemplate {
- @Override
- public final Dashboard createDashboard() {
- Dashboard dashboard = Dashboard.create()
- .setGlobal(true)
- .setLayout(DashboardLayout.ONE_COLUMN);
-
- dashboard
- .addWidget("filter", 1)
- .setProperty(FilterWidget.FILTER, getFilterKey());
-
- doCompleteDashboard(dashboard);
- return dashboard;
- }
-
- /**
- * The key of the filter to display.
- */
- protected abstract String getFilterKey();
-
- /**
- * Override this method to complete dashboard.
- * @param dashboard the dashboard to complete
- */
- protected void doCompleteDashboard(Dashboard dashboard) {
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
-
-/**
- * Default dashboard
- *
- * @since 2.13
- */
-public final class DefaultDashboard extends DashboardTemplate {
-
- @Override
- public String getName() {
- return "Dashboard";
- }
-
- @Override
- public Dashboard createDashboard() {
- Dashboard dashboard = Dashboard.create();
- dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
- addFirstColumn(dashboard);
- addSecondColumn(dashboard);
- return dashboard;
- }
-
- private void addFirstColumn(Dashboard dashboard) {
- dashboard.addWidget("size", 1);
- dashboard.addWidget("comments_duplications", 1);
- dashboard.addWidget("complexity", 1);
- dashboard.addWidget("events", 1);
- dashboard.addWidget("description", 1);
- }
-
- private void addSecondColumn(Dashboard dashboard) {
- dashboard.addWidget("rules", 2);
- dashboard.addWidget("alerts", 2);
- dashboard.addWidget("file_design", 2);
- dashboard.addWidget("package_design", 2);
- dashboard.addWidget("code_coverage", 2);
- }
-
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+import org.sonar.core.measure.MeasureFilterDao;
+import org.sonar.core.measure.MeasureFilterDto;
+import org.sonar.plugins.core.filters.MyFavouritesFilter;
+import org.sonar.plugins.core.filters.ProjectFilter;
+import org.sonar.plugins.core.widgets.MeasureFilterListWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterTreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
+
+/**
+ * Projects global dashboard for Sonar
+ *
+ * @since 3.1
+ */
+public final class GlobalDefaultDashboard extends DashboardTemplate {
+
+ private MeasureFilterDao filterDao;
+
+ public GlobalDefaultDashboard(MeasureFilterDao filterDao) {
+ this.filterDao = filterDao;
+ }
+
+
+ @Override
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.create()
+ .setGlobal(true)
+ .setLayout(DashboardLayout.TWO_COLUMNS);
+
+ dashboard.addWidget(WelcomeWidget.ID, 1);
+
+ MeasureFilterDto filter = findSystemFilter(MyFavouritesFilter.NAME);
+ if (filter != null) {
+ dashboard
+ .addWidget(MeasureFilterListWidget.ID, 1)
+ .setProperty(MeasureFilterListWidget.FILTER_PROPERTY, filter.getId().toString())
+ .setProperty(MeasureFilterListWidget.PAGE_SIZE_PROPERTY, "50");
+ }
+
+ filter = findSystemFilter(ProjectFilter.NAME);
+ if (filter != null) {
+ dashboard
+ .addWidget(MeasureFilterListWidget.ID, 2)
+ .setProperty(MeasureFilterListWidget.FILTER_PROPERTY, filter.getId().toString())
+ .setProperty(MeasureFilterListWidget.PAGE_SIZE_PROPERTY, "20");
+
+ dashboard
+ .addWidget(MeasureFilterTreemapWidget.ID, 2)
+ .setProperty(MeasureFilterListWidget.FILTER_PROPERTY, filter.getId().toString())
+ .setProperty(MeasureFilterTreemapWidget.SIZE_METRIC_PROPERTY, "ncloc")
+ .setProperty(MeasureFilterTreemapWidget.COLOR_METRIC_PROPERTY, "violations_density");
+ }
+
+ return dashboard;
+ }
+
+ @Override
+ public String getName() {
+ return "Projects";
+ }
+
+ private MeasureFilterDto findSystemFilter(String name) {
+ return filterDao.findSystemFilterByName(name);
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
-
-/**
- * Default "Hotspots" dashboard
- *
- * @since 2.13
- */
-public final class HotspotsDashboard extends DashboardTemplate {
-
- private static final String HOTSPOT_METRIC = "hotspot_metric";
- private static final String METRIC_PROPERTY = "metric";
-
- @Override
- public String getName() {
- return "Hotspots";
- }
-
- @Override
- public Dashboard createDashboard() {
- Dashboard dashboard = Dashboard.create();
- dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
-
- addFirstColumn(dashboard);
- addSecondColumn(dashboard);
-
- return dashboard;
- }
-
- private void addFirstColumn(Dashboard dashboard) {
- dashboard.addWidget("hotspot_most_violated_rules", 1);
-
- Dashboard.Widget widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
- widget.setProperty(METRIC_PROPERTY, "test_execution_time");
-
- widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
- widget.setProperty(METRIC_PROPERTY, "complexity");
-
- widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
- widget.setProperty(METRIC_PROPERTY, "duplicated_lines");
- }
-
- private void addSecondColumn(Dashboard dashboard) {
- dashboard.addWidget("hotspot_most_violated_resources", 2);
-
- Dashboard.Widget widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
- widget.setProperty(METRIC_PROPERTY, "uncovered_lines");
-
- widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
- widget.setProperty(METRIC_PROPERTY, "function_complexity");
-
- widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
- widget.setProperty(METRIC_PROPERTY, "public_undocumented_api");
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.plugins.core.filters.MyFavouritesFilter;
-
-/**
- * My favorites global dashboard for Sonar
- *
- * @since 3.1
- */
-public final class MyFavouritesDashboard extends AbstractFilterDashboard {
- @Override
- public String getName() {
- return "My favourites";
- }
-
- @Override
- protected String getFilterKey() {
- return MyFavouritesFilter.NAME;
- }
-
- @Override
- protected void doCompleteDashboard(Dashboard dashboard) {
- dashboard.setActivated(false);
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+
+/**
+ * Default dashboard
+ *
+ * @since 2.13
+ */
+public final class ProjectDefaultDashboard extends DashboardTemplate {
+
+ @Override
+ public String getName() {
+ return "Dashboard";
+ }
+
+ @Override
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.create();
+ dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
+ addFirstColumn(dashboard);
+ addSecondColumn(dashboard);
+ return dashboard;
+ }
+
+ private void addFirstColumn(Dashboard dashboard) {
+ dashboard.addWidget("size", 1);
+ dashboard.addWidget("comments_duplications", 1);
+ dashboard.addWidget("complexity", 1);
+ dashboard.addWidget("events", 1);
+ dashboard.addWidget("description", 1);
+ }
+
+ private void addSecondColumn(Dashboard dashboard) {
+ dashboard.addWidget("rules", 2);
+ dashboard.addWidget("alerts", 2);
+ dashboard.addWidget("file_design", 2);
+ dashboard.addWidget("package_design", 2);
+ dashboard.addWidget("code_coverage", 2);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+
+/**
+ * Default "Hotspots" dashboard
+ *
+ * @since 2.13
+ */
+public final class ProjectHotspotDashboard extends DashboardTemplate {
+
+ private static final String HOTSPOT_METRIC = "hotspot_metric";
+ private static final String METRIC_PROPERTY = "metric";
+
+ @Override
+ public String getName() {
+ return "Hotspots";
+ }
+
+ @Override
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.create();
+ dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
+
+ addFirstColumn(dashboard);
+ addSecondColumn(dashboard);
+
+ return dashboard;
+ }
+
+ private void addFirstColumn(Dashboard dashboard) {
+ dashboard.addWidget("hotspot_most_violated_rules", 1);
+
+ Dashboard.Widget widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
+ widget.setProperty(METRIC_PROPERTY, "test_execution_time");
+
+ widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
+ widget.setProperty(METRIC_PROPERTY, "complexity");
+
+ widget = dashboard.addWidget(HOTSPOT_METRIC, 1);
+ widget.setProperty(METRIC_PROPERTY, "duplicated_lines");
+ }
+
+ private void addSecondColumn(Dashboard dashboard) {
+ dashboard.addWidget("hotspot_most_violated_resources", 2);
+
+ Dashboard.Widget widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
+ widget.setProperty(METRIC_PROPERTY, "uncovered_lines");
+
+ widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
+ widget.setProperty(METRIC_PROPERTY, "function_complexity");
+
+ widget = dashboard.addWidget(HOTSPOT_METRIC, 2);
+ widget.setProperty(METRIC_PROPERTY, "public_undocumented_api");
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+
+/**
+ * Reviews dashboard for Sonar
+ *
+ * @since 2.14
+ */
+public final class ProjectReviewsDashboard extends DashboardTemplate {
+ @Override
+ public String getName() {
+ return "Reviews";
+ }
+
+ @Override
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.create();
+ dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
+ addFirstColumn(dashboard);
+ addSecondColumn(dashboard);
+ return dashboard;
+ }
+
+ private void addFirstColumn(Dashboard dashboard) {
+ dashboard.addWidget("reviews_metrics", 1);
+ dashboard.addWidget("action_plans", 1);
+ dashboard.addWidget("planned_reviews", 1);
+ dashboard.addWidget("unplanned_reviews", 1);
+ }
+
+ private void addSecondColumn(Dashboard dashboard) {
+ dashboard.addWidget("reviews_per_developer", 2);
+ dashboard.addWidget("my_reviews", 2);
+ dashboard.addWidget("project_reviews", 2);
+ dashboard.addWidget("false_positive_reviews", 2);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.Dashboard.Widget;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+
+/**
+ * Time Machine dashboard for Sonar
+ *
+ * @since 3.0
+ */
+public final class ProjectTimeMachineDashboard extends DashboardTemplate {
+
+ private static final String METRIC1 = "metric1";
+ private static final String METRIC2 = "metric2";
+ private static final String METRIC3 = "metric3";
+ private static final String METRIC4 = "metric4";
+ private static final String METRIC5 = "metric5";
+ private static final String METRIC6 = "metric6";
+ private static final String METRIC7 = "metric7";
+
+ @Override
+ public String getName() {
+ return "TimeMachine";
+ }
+
+ @Override
+ public Dashboard createDashboard() {
+ Dashboard dashboard = Dashboard.create();
+ dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
+ addFirstColumn(dashboard);
+ addSecondColumn(dashboard);
+ return dashboard;
+ }
+
+ private void addFirstColumn(Dashboard dashboard) {
+ Widget timelineWidget = dashboard.addWidget("timeline", 1);
+ timelineWidget.setProperty(METRIC1, "complexity");
+ timelineWidget.setProperty(METRIC2, "violations_density");
+ timelineWidget.setProperty(METRIC3, "coverage");
+
+ Widget sizeTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
+ sizeTimeMachineWidget.setProperty(METRIC1, "ncloc");
+ sizeTimeMachineWidget.setProperty(METRIC2, "lines");
+ sizeTimeMachineWidget.setProperty(METRIC3, "statements");
+ sizeTimeMachineWidget.setProperty(METRIC4, "files");
+ sizeTimeMachineWidget.setProperty(METRIC5, "classes");
+ sizeTimeMachineWidget.setProperty(METRIC6, "functions");
+ sizeTimeMachineWidget.setProperty(METRIC7, "accessors");
+
+ Widget commentsTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
+ commentsTimeMachineWidget.setProperty(METRIC1, "comment_lines_density");
+ commentsTimeMachineWidget.setProperty(METRIC2, "comment_lines");
+ commentsTimeMachineWidget.setProperty(METRIC3, "public_documented_api_density");
+ commentsTimeMachineWidget.setProperty(METRIC4, "public_undocumented_api");
+
+ Widget duplicationTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
+ duplicationTimeMachineWidget.setProperty(METRIC1, "duplicated_lines_density");
+ duplicationTimeMachineWidget.setProperty(METRIC2, "duplicated_lines");
+ duplicationTimeMachineWidget.setProperty(METRIC3, "duplicated_blocks");
+ duplicationTimeMachineWidget.setProperty(METRIC4, "duplicated_files");
+ }
+
+ private void addSecondColumn(Dashboard dashboard) {
+ Widget rulesTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
+ rulesTimeMachineWidget.setProperty(METRIC1, "violations");
+ rulesTimeMachineWidget.setProperty(METRIC2, "violation_density");
+ rulesTimeMachineWidget.setProperty(METRIC3, "blocker_violations");
+ rulesTimeMachineWidget.setProperty(METRIC4, "critical_violations");
+ rulesTimeMachineWidget.setProperty(METRIC5, "major_violations");
+ rulesTimeMachineWidget.setProperty(METRIC6, "minor_violations");
+ rulesTimeMachineWidget.setProperty(METRIC7, "info_violations");
+ rulesTimeMachineWidget.setProperty(METRIC7, "weighted_violations");
+
+ Widget complexityTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
+ complexityTimeMachineWidget.setProperty(METRIC1, "complexity");
+ complexityTimeMachineWidget.setProperty(METRIC2, "function_complexity");
+ complexityTimeMachineWidget.setProperty(METRIC3, "class_complexity");
+ complexityTimeMachineWidget.setProperty(METRIC4, "file_complexity");
+
+ Widget testsTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
+ testsTimeMachineWidget.setProperty(METRIC1, "coverage");
+ testsTimeMachineWidget.setProperty(METRIC2, "line_coverage");
+ testsTimeMachineWidget.setProperty(METRIC3, "branch_coverage");
+ testsTimeMachineWidget.setProperty(METRIC4, "test_success_density");
+ testsTimeMachineWidget.setProperty(METRIC5, "test_failures");
+ testsTimeMachineWidget.setProperty(METRIC6, "test_errors");
+ testsTimeMachineWidget.setProperty(METRIC7, "tests");
+ testsTimeMachineWidget.setProperty(METRIC7, "test_execution_time");
+ }
+
+ private Widget addTimeMachineWidgetOnFirstColumn(Dashboard dashboard) {
+ return addTimeMachineWidget(dashboard, 1);
+ }
+
+ private Widget addTimeMachineWidgetOnSecondColumn(Dashboard dashboard) {
+ return addTimeMachineWidget(dashboard, 2);
+ }
+
+ private Widget addTimeMachineWidget(Dashboard dashboard, int columnIndex) {
+ Widget widget = dashboard.addWidget("time_machine", columnIndex);
+ widget.setProperty("displaySparkLine", "true");
+ return widget;
+ }
+
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.plugins.core.filters.ProjectFilter;
-
-/**
- * Projects global dashboard for Sonar
- *
- * @since 3.1
- */
-public final class ProjectsDashboard extends AbstractFilterDashboard {
- @Override
- public String getName() {
- return "Projects";
- }
-
- @Override
- protected String getFilterKey() {
- return ProjectFilter.NAME;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
-
-/**
- * Reviews dashboard for Sonar
- *
- * @since 2.14
- */
-public final class ReviewsDashboard extends DashboardTemplate {
- @Override
- public String getName() {
- return "Reviews";
- }
-
- @Override
- public Dashboard createDashboard() {
- Dashboard dashboard = Dashboard.create();
- dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
- addFirstColumn(dashboard);
- addSecondColumn(dashboard);
- return dashboard;
- }
-
- private void addFirstColumn(Dashboard dashboard) {
- dashboard.addWidget("reviews_metrics", 1);
- dashboard.addWidget("action_plans", 1);
- dashboard.addWidget("planned_reviews", 1);
- dashboard.addWidget("unplanned_reviews", 1);
- }
-
- private void addSecondColumn(Dashboard dashboard) {
- dashboard.addWidget("reviews_per_developer", 2);
- dashboard.addWidget("my_reviews", 2);
- dashboard.addWidget("project_reviews", 2);
- dashboard.addWidget("false_positive_reviews", 2);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.Dashboard.Widget;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
-
-/**
- * Time Machine dashboard for Sonar
- *
- * @since 3.0
- */
-public final class TimeMachineDashboard extends DashboardTemplate {
-
- private static final String METRIC1 = "metric1";
- private static final String METRIC2 = "metric2";
- private static final String METRIC3 = "metric3";
- private static final String METRIC4 = "metric4";
- private static final String METRIC5 = "metric5";
- private static final String METRIC6 = "metric6";
- private static final String METRIC7 = "metric7";
-
- @Override
- public String getName() {
- return "TimeMachine";
- }
-
- @Override
- public Dashboard createDashboard() {
- Dashboard dashboard = Dashboard.create();
- dashboard.setLayout(DashboardLayout.TWO_COLUMNS);
- addFirstColumn(dashboard);
- addSecondColumn(dashboard);
- return dashboard;
- }
-
- private void addFirstColumn(Dashboard dashboard) {
- Widget timelineWidget = dashboard.addWidget("timeline", 1);
- timelineWidget.setProperty(METRIC1, "complexity");
- timelineWidget.setProperty(METRIC2, "violations_density");
- timelineWidget.setProperty(METRIC3, "coverage");
-
- Widget sizeTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
- sizeTimeMachineWidget.setProperty(METRIC1, "ncloc");
- sizeTimeMachineWidget.setProperty(METRIC2, "lines");
- sizeTimeMachineWidget.setProperty(METRIC3, "statements");
- sizeTimeMachineWidget.setProperty(METRIC4, "files");
- sizeTimeMachineWidget.setProperty(METRIC5, "classes");
- sizeTimeMachineWidget.setProperty(METRIC6, "functions");
- sizeTimeMachineWidget.setProperty(METRIC7, "accessors");
-
- Widget commentsTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
- commentsTimeMachineWidget.setProperty(METRIC1, "comment_lines_density");
- commentsTimeMachineWidget.setProperty(METRIC2, "comment_lines");
- commentsTimeMachineWidget.setProperty(METRIC3, "public_documented_api_density");
- commentsTimeMachineWidget.setProperty(METRIC4, "public_undocumented_api");
-
- Widget duplicationTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard);
- duplicationTimeMachineWidget.setProperty(METRIC1, "duplicated_lines_density");
- duplicationTimeMachineWidget.setProperty(METRIC2, "duplicated_lines");
- duplicationTimeMachineWidget.setProperty(METRIC3, "duplicated_blocks");
- duplicationTimeMachineWidget.setProperty(METRIC4, "duplicated_files");
- }
-
- private void addSecondColumn(Dashboard dashboard) {
- Widget rulesTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
- rulesTimeMachineWidget.setProperty(METRIC1, "violations");
- rulesTimeMachineWidget.setProperty(METRIC2, "violation_density");
- rulesTimeMachineWidget.setProperty(METRIC3, "blocker_violations");
- rulesTimeMachineWidget.setProperty(METRIC4, "critical_violations");
- rulesTimeMachineWidget.setProperty(METRIC5, "major_violations");
- rulesTimeMachineWidget.setProperty(METRIC6, "minor_violations");
- rulesTimeMachineWidget.setProperty(METRIC7, "info_violations");
- rulesTimeMachineWidget.setProperty(METRIC7, "weighted_violations");
-
- Widget complexityTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
- complexityTimeMachineWidget.setProperty(METRIC1, "complexity");
- complexityTimeMachineWidget.setProperty(METRIC2, "function_complexity");
- complexityTimeMachineWidget.setProperty(METRIC3, "class_complexity");
- complexityTimeMachineWidget.setProperty(METRIC4, "file_complexity");
-
- Widget testsTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard);
- testsTimeMachineWidget.setProperty(METRIC1, "coverage");
- testsTimeMachineWidget.setProperty(METRIC2, "line_coverage");
- testsTimeMachineWidget.setProperty(METRIC3, "branch_coverage");
- testsTimeMachineWidget.setProperty(METRIC4, "test_success_density");
- testsTimeMachineWidget.setProperty(METRIC5, "test_failures");
- testsTimeMachineWidget.setProperty(METRIC6, "test_errors");
- testsTimeMachineWidget.setProperty(METRIC7, "tests");
- testsTimeMachineWidget.setProperty(METRIC7, "test_execution_time");
- }
-
- private Widget addTimeMachineWidgetOnFirstColumn(Dashboard dashboard) {
- return addTimeMachineWidget(dashboard, 1);
- }
-
- private Widget addTimeMachineWidgetOnSecondColumn(Dashboard dashboard) {
- return addTimeMachineWidget(dashboard, 2);
- }
-
- private Widget addTimeMachineWidget(Dashboard dashboard, int columnIndex) {
- Widget widget = dashboard.addWidget("time_machine", columnIndex);
- widget.setProperty("displaySparkLine", "true");
- return widget;
- }
-
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.sonar.plugins.core.filters.TreeMapFilter;
-
-/**
- * Treemap global dashboard for Sonar
- *
- * @since 3.1
- */
-public final class TreemapDashboard extends AbstractFilterDashboard {
- @Override
- public String getName() {
- return "Treemap";
- }
-
- @Override
- protected String getFilterKey() {
- return TreeMapFilter.NAME;
- }
-}
\ No newline at end of file
import org.sonar.api.web.FilterTemplate;
/**
- * Default myfavourites filter.
+ * Default filter for looking for user favourite resources.
*
* @since 3.1
*/
return Filter.create()
.setDisplayAs(Filter.LIST)
.setFavouritesOnly(true)
- .add(Criterion.createForQualifier("VW", "SVW", "TRK", "BRC", "DIR", "PAC", "FIL", "CLA", "UTS"))
.add(FilterColumn.create("metric", CoreMetrics.ALERT_STATUS_KEY, FilterColumn.DESC, false))
.add(FilterColumn.create("name", null, FilterColumn.ASC, false))
- .add(FilterColumn.create("metric", CoreMetrics.NCLOC_KEY, FilterColumn.DESC, false))
- .add(FilterColumn.create("metric", CoreMetrics.VIOLATIONS_DENSITY_KEY, FilterColumn.DESC, false))
.add(FilterColumn.create("date", null, FilterColumn.DESC, false));
}
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.filters;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.web.Criterion;
-import org.sonar.api.web.Filter;
-import org.sonar.api.web.FilterColumn;
-import org.sonar.api.web.FilterTemplate;
-
-/**
- * Default treemap filter.
- *
- * @since 3.1
- */
-public class TreeMapFilter extends FilterTemplate {
- public static final String NAME = "Treemap";
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Filter createFilter() {
- return Filter.create()
- .setDisplayAs(Filter.TREEMAP)
- .add(Criterion.createForQualifier(Qualifiers.PROJECT))
- .add(FilterColumn.create("name", null, FilterColumn.ASC, false))
- .add(FilterColumn.create("metric", CoreMetrics.NCLOC_KEY, FilterColumn.DESC, false))
- .add(FilterColumn.create("metric", CoreMetrics.VIOLATIONS_DENSITY_KEY, FilterColumn.DESC, false));
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.WidgetCategory;
-import org.sonar.api.web.WidgetProperties;
-import org.sonar.api.web.WidgetProperty;
-import org.sonar.api.web.WidgetPropertyType;
-import org.sonar.api.web.WidgetScope;
-
-import static org.sonar.api.web.WidgetScope.*;
-
-@WidgetCategory({"Filters", "Global"})
-@WidgetScope(GLOBAL)
-@WidgetProperties(
- @WidgetProperty(key = FilterWidget.FILTER, type = WidgetPropertyType.FILTER, optional = false)
-)
-public class FilterWidget extends AbstractRubyTemplate implements RubyRailsWidget {
- public static final String FILTER = "filter";
-
- public String getId() {
- return "filter";
- }
-
- public String getTitle() {
- return "Filter";
- }
-
- @Override
- protected String getTemplatePath() {
- return "/org/sonar/plugins/core/widgets/filter.html.erb";
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.WidgetCategory;
+import org.sonar.api.web.WidgetProperties;
+import org.sonar.api.web.WidgetProperty;
+import org.sonar.api.web.WidgetPropertyType;
+import org.sonar.api.web.WidgetScope;
+
+import static org.sonar.api.web.WidgetScope.GLOBAL;
+
+@WidgetCategory({"Filters", "Global"})
+@WidgetScope(GLOBAL)
+@WidgetProperties({
+ @WidgetProperty(key = MeasureFilterListWidget.FILTER_PROPERTY, type = WidgetPropertyType.FILTER, optional = false),
+ @WidgetProperty(key = MeasureFilterListWidget.PAGE_SIZE_PROPERTY, type = WidgetPropertyType.INTEGER, optional = true)
+}
+)
+public class MeasureFilterListWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+ public static final String FILTER_PROPERTY = "filter";
+ public static final String PAGE_SIZE_PROPERTY = "pageSize";
+ public static final String ID = "measure_filter_list";
+
+ public String getId() {
+ return ID;
+ }
+
+ public String getTitle() {
+ return "Measure Filter as List";
+ }
+
+ @Override
+ protected String getTemplatePath() {
+ return "/org/sonar/plugins/core/widgets/measure_filter_list.html.erb";
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.WidgetCategory;
+import org.sonar.api.web.WidgetProperties;
+import org.sonar.api.web.WidgetProperty;
+import org.sonar.api.web.WidgetPropertyType;
+import org.sonar.api.web.WidgetScope;
+
+import static org.sonar.api.web.WidgetScope.GLOBAL;
+
+@WidgetCategory({"Filters", "Global"})
+@WidgetScope(GLOBAL)
+@WidgetProperties({
+ @WidgetProperty(key = MeasureFilterTreemapWidget.FILTER_PROPERTY, type = WidgetPropertyType.FILTER, optional = false),
+ @WidgetProperty(key = MeasureFilterTreemapWidget.SIZE_METRIC_PROPERTY, type = WidgetPropertyType.METRIC, optional = true),
+ @WidgetProperty(key = MeasureFilterTreemapWidget.COLOR_METRIC_PROPERTY, type = WidgetPropertyType.METRIC, optional = true)
+}
+)
+public class MeasureFilterTreemapWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+ public static final String FILTER_PROPERTY = "filter";
+ public static final String SIZE_METRIC_PROPERTY = "sizeMetric";
+ public static final String COLOR_METRIC_PROPERTY = "colorMetric";
+ public static final String ID = "measure_filter_treemap";
+
+ public String getId() {
+ return ID;
+ }
+
+ public String getTitle() {
+ return "Measure Filter as Treemap";
+ }
+
+ @Override
+ protected String getTemplatePath() {
+ return "/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb";
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.WidgetCategory;
+import org.sonar.api.web.WidgetScope;
+
+import static org.sonar.api.web.WidgetScope.GLOBAL;
+
+@WidgetCategory({"Global"})
+@WidgetScope(GLOBAL)
+public class WelcomeWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+
+ public static final String ID = "welcome";
+
+ public String getId() {
+ return ID;
+ }
+
+ public String getTitle() {
+ return "Welcome";
+ }
+
+ @Override
+ protected String getTemplatePath() {
+ return "/org/sonar/plugins/core/widgets/welcome.html.erb";
+ }
+}
components.page=Components
coverage.page=Coverage
default_dashboards.page=Default Dashboards
-default_filters.page=My Filters
dependencies.page=Dependencies
duplications.page=Duplications
email_configuration.page=Email Settings
measure_filter.name_contains=Name contains
measure_filter.only_favourites=Favourites only
measure_filter.manage_filters=Manage Filters
+measure_filter.display.list=List
+measure_filter.display.treemap=Treemap
+measure_filter.configure_columns=Configure Columns
#------------------------------------------------------------------------------
#
+++ /dev/null
-<%
- @filter=::Filter.find(:first, :conditions => {:kee => widget_properties['filter']})
- @filter_context=Filters.execute(@filter, self, params) unless @filter.ajax_loading?
-
- name=@filter.name
- period=period_names[@filter.period_index - 1] if @filter.period_index
- @widget_title=[h(name), period].compact.join(' - ')
-%>
-
-<%= render :partial => "filters/#{@filter.default_view}", :locals => {:edit_mode => false, :widget => widget} %>
--- /dev/null
+<%
+ filter_id = widget_properties['filter']
+ page_size = widget_properties['pageSize']
+ filter = MeasureFilter.find_by_id(filter_id.to_i) if filter_id
+ if filter
+ filter.load_criteria_from_data
+ filter.set_criteria_value('display', 'list')
+ filter.set_criteria_value('pageSize', page_size) if page_size
+ filter.execute(self, :user => current_user)
+ @widget_title = link_to h(filter.name), {:controller => 'measures', :action => 'filter', :id => filter.id, :display => 'list'}
+%>
+ <%= render :partial => "measures/display_#{filter.display.key}", :locals => {:edit_mode => false, :widget => widget, :filter => filter} %>
+<% end %>
\ No newline at end of file
--- /dev/null
+<%
+ filter_id = widget_properties['filter']
+ size_metric = widget_properties['sizeMetric']
+ color_metric = widget_properties['colorMetric']
+ filter = MeasureFilter.find_by_id(filter_id.to_i) if filter_id
+ if filter
+ filter.load_criteria_from_data
+ filter.set_criteria_value('display', 'treemap')
+ filter.set_criteria_value('tmSize', size_metric.key) if size_metric
+ filter.set_criteria_value('tmColor', color_metric.key) if color_metric
+ filter.execute(self, :user => current_user)
+ @widget_title = link_to h(filter.name), {:controller => 'measures', :action => 'filter', :id => filter.id, :display => 'treemap'}
+%>
+ <%= render :partial => "measures/display_#{filter.display.key}", :locals => {:edit_mode => false, :widget => widget, :filter => filter} %>
+<% end %>
\ No newline at end of file
--- /dev/null
+<h3>Welcome to Sonar Dashboard</h3>
+<p>Since you are able to read this, it means that you have successfully started your Sonar server. Well done!</p>
+<p>If you have not removed this text, it also means that you have not yet played much with Sonar. So here are a few pointers for your next step:</p>
+<ul class="bullet">
+ <li>Do you now want to <a href="http://docs.codehaus.org/x/P4LEBg">run analysis</a> on a project?</li>
+ <li>Maybe start <a href="http://docs.codehaus.org/x/EYDECQ">customizing dashboards</a>?</li>
+ <li>Or simply browse the <a href="http://docs.codehaus.org/x/EoDEBg">complete documentation</a>?</li>
+ <li>If you have a question or an issue, please report it on the <a href="http://www.sonarsource.org/support/support/">mailing list</a>.</li>
+</ul>
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DefaultDashboardTest {
- DefaultDashboard template = new DefaultDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("Dashboard");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_dashboard() {
- Dashboard dashboard = template.createDashboard();
-
- assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
- assertThat(dashboard.getWidgets()).hasSize(10);
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.Dashboard.Widget;
+import org.sonar.core.measure.MeasureFilterDao;
+import org.sonar.core.measure.MeasureFilterDto;
+import org.sonar.plugins.core.CorePlugin;
+import org.sonar.plugins.core.filters.MyFavouritesFilter;
+import org.sonar.plugins.core.filters.ProjectFilter;
+import org.sonar.plugins.core.widgets.MeasureFilterListWidget;
+import org.sonar.plugins.core.widgets.MeasureFilterTreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class GlobalDefaultDashboardTest {
+ GlobalDefaultDashboard template;
+ MeasureFilterDao dao;
+
+ @Before
+ public void init() {
+ dao = mock(MeasureFilterDao.class);
+ template = new GlobalDefaultDashboard(dao);
+ }
+
+ @Test
+ public void should_have_a_name() {
+ assertThat(template.getName()).isEqualTo("Projects");
+ }
+
+ @Test
+ public void should_be_registered_as_an_extension() {
+ assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
+ }
+
+ @Test
+ public void should_create_global_dashboard_with_four_widgets() {
+ when(dao.findSystemFilterByName(MyFavouritesFilter.NAME)).thenReturn(
+ new MeasureFilterDto().setId(100L)
+ );
+ when(dao.findSystemFilterByName(ProjectFilter.NAME)).thenReturn(
+ new MeasureFilterDto().setId(101L)
+ );
+ Dashboard dashboard = template.createDashboard();
+ List<Widget> firstColumn = dashboard.getWidgetsOfColumn(1);
+ assertThat(firstColumn).hasSize(2);
+ assertThat(firstColumn.get(0).getId()).isEqualTo(WelcomeWidget.ID);
+ assertThat(firstColumn.get(1).getId()).isEqualTo(MeasureFilterListWidget.ID);
+ assertThat(firstColumn.get(1).getProperty("filter")).isEqualTo("100");
+
+ List<Widget> secondColumn = dashboard.getWidgetsOfColumn(2);
+ assertThat(secondColumn).hasSize(2);
+ assertThat(secondColumn.get(0).getId()).isEqualTo(MeasureFilterListWidget.ID);
+ assertThat(secondColumn.get(0).getProperty("filter")).isEqualTo("101");
+ assertThat(secondColumn.get(1).getId()).isEqualTo(MeasureFilterTreemapWidget.ID);
+ assertThat(secondColumn.get(1).getProperty("filter")).isEqualTo("101");
+ }
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class HotspotsDashboardTest {
- HotspotsDashboard template = new HotspotsDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("Hotspots");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_dashboard() {
- Dashboard dashboard = template.createDashboard();
-
- assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
- assertThat(dashboard.getWidgets()).hasSize(8);
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import com.google.common.collect.Iterables;
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.Dashboard.Widget;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class MyFavouritesDashboardTest {
- MyFavouritesDashboard template = new MyFavouritesDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("My favourites");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_global_dashboard_with_one_filter() {
- Dashboard dashboard = template.createDashboard();
- Widget widget = Iterables.getOnlyElement(dashboard.getWidgets());
-
- assertThat(dashboard.isGlobal()).isTrue();
- assertThat(dashboard.isActivated()).isFalse();
- assertThat(widget.getId()).isEqualTo("filter");
- assertThat(widget.getProperty("filter")).isEqualTo("My favourites");
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.junit.Test;
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.plugins.core.CorePlugin;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ProjectDefaultDashboardTest {
+ ProjectDefaultDashboard template = new ProjectDefaultDashboard();
+
+ @Test
+ public void should_have_a_name() {
+ assertThat(template.getName()).isEqualTo("Dashboard");
+ }
+
+ @Test
+ public void should_be_registered_as_an_extension() {
+ assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
+ }
+
+ @Test
+ public void should_create_dashboard() {
+ Dashboard dashboard = template.createDashboard();
+
+ assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
+ assertThat(dashboard.getWidgets()).hasSize(10);
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.junit.Test;
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.plugins.core.CorePlugin;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ProjectHotspotDashboardTest {
+ ProjectHotspotDashboard template = new ProjectHotspotDashboard();
+
+ @Test
+ public void should_have_a_name() {
+ assertThat(template.getName()).isEqualTo("Hotspots");
+ }
+
+ @Test
+ public void should_be_registered_as_an_extension() {
+ assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
+ }
+
+ @Test
+ public void should_create_dashboard() {
+ Dashboard dashboard = template.createDashboard();
+
+ assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
+ assertThat(dashboard.getWidgets()).hasSize(8);
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.dashboards;
+
+import org.junit.Test;
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.Dashboard.Widget;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.plugins.core.CorePlugin;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ProjectTimeMachineDashboardTest {
+ ProjectTimeMachineDashboard template = new ProjectTimeMachineDashboard();
+
+ @Test
+ public void should_have_a_name() {
+ assertThat(template.getName()).isEqualTo("TimeMachine");
+ }
+
+ @Test
+ public void should_be_registered_as_an_extension() {
+ assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
+ }
+
+ @Test
+ public void should_create_dashboard() {
+ Dashboard dashboard = template.createDashboard();
+
+ assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
+ assertThat(dashboard.getWidgets()).hasSize(7);
+
+ for (Widget widget : dashboard.getWidgets()) {
+ if (widget.getId().equals("time_machine")) {
+ assertThat(widget.getProperty("displaySparkLine")).isEqualTo("true");
+ }
+ }
+ }
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import com.google.common.collect.Iterables;
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.Dashboard.Widget;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class ProjectsDashboardTest {
- ProjectsDashboard template = new ProjectsDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("Projects");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_global_dashboard_with_one_filter() {
- Dashboard dashboard = template.createDashboard();
- Widget widget = Iterables.getOnlyElement(dashboard.getWidgets());
-
- assertThat(dashboard.isGlobal()).isTrue();
- assertThat(widget.getId()).isEqualTo("filter");
- assertThat(widget.getProperty("filter")).isEqualTo("Projects");
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.Dashboard.Widget;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class TimeMachineDashboardTest {
- TimeMachineDashboard template = new TimeMachineDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("TimeMachine");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_dashboard() {
- Dashboard dashboard = template.createDashboard();
-
- assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
- assertThat(dashboard.getWidgets()).hasSize(7);
-
- for (Widget widget : dashboard.getWidgets()) {
- if (widget.getId().equals("time_machine")) {
- assertThat(widget.getProperty("displaySparkLine")).isEqualTo("true");
- }
- }
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.dashboards;
-
-import com.google.common.collect.Iterables;
-import org.junit.Test;
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.Dashboard.Widget;
-import org.sonar.plugins.core.CorePlugin;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class TreemapDashboardTest {
- TreemapDashboard template = new TreemapDashboard();
-
- @Test
- public void should_have_a_name() {
- assertThat(template.getName()).isEqualTo("Treemap");
- }
-
- @Test
- public void should_be_registered_as_an_extension() {
- assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
- }
-
- @Test
- public void should_create_dashboard() {
- Dashboard dashboard = template.createDashboard();
- Widget widget = Iterables.getOnlyElement(dashboard.getWidgets());
-
- assertThat(dashboard.isGlobal()).isTrue();
- assertThat(widget.getId()).isEqualTo("filter");
- assertThat(widget.getProperty("filter")).isEqualTo("Treemap");
- }
-}
assertThat(template.getName()).isEqualTo("My favourites");
assertThat(filter).isNotNull();
assertThat(filter.isFavouritesOnly()).isTrue();
- assertThat(filter.getCriteria()).hasSize(1);
- assertThat(filter.getColumns()).hasSize(5);
+ assertThat(filter.getCriteria()).isEmpty();
+ assertThat(filter.getColumns()).hasSize(3);
}
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.filters;
-
-import org.junit.Test;
-import org.sonar.api.web.Filter;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class TreeMapFilterTest {
- @Test
- public void should_create_filter() {
- TreeMapFilter template = new TreeMapFilter();
-
- Filter filter = template.createFilter();
-
- assertThat(template.getName()).isEqualTo("Treemap");
- assertThat(filter).isNotNull();
- assertThat(filter.getCriteria()).hasSize(1);
- assertThat(filter.getColumns()).hasSize(3);
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-/**
- * @since 3.1
- */
-public final class CriterionDto {
- private Long id;
- private Long filterId;
- private String family;
- private String key;
- private String operator;
- private String textValue;
- private Float value;
- private Boolean variation;
-
- /**
- * @return the id
- */
- public Long getId() {
- return id;
- }
-
- /**
- * @return the family
- */
- public String getFamily() {
- return family;
- }
-
- /**
- * @return the filter id
- */
- public Long getFilterId() {
- return filterId;
- }
-
- /**
- * @return the key
- */
- public String getKey() {
- return key;
- }
-
- /**
- * @return the operator
- */
- public String getOperator() {
- return operator;
- }
-
- /**
- * @return the text value
- */
- public String getTextValue() {
- return textValue;
- }
-
- /**
- * @return the value
- */
- public Float getValue() {
- return value;
- }
-
- /**
- * @return the variation
- */
- public Boolean getVariation() {
- return variation;
- }
-
- /**
- * @param family the id to set
- */
- public CriterionDto setId(Long id) {
- this.id = id;
- return this;
- }
-
- /**
- * @param family the family to set
- */
- public CriterionDto setFamily(String family) {
- this.family = family;
- return this;
- }
-
- /**
- * @param filterId the filter id to set
- */
- public CriterionDto setFilterId(Long filterId) {
- this.filterId = filterId;
- return this;
- }
-
- /**
- * @param key the key to set
- */
- public CriterionDto setKey(String key) {
- this.key = key;
- return this;
- }
-
- /**
- * @param operator the operator to set
- */
- public CriterionDto setOperator(String operator) {
- this.operator = operator;
- return this;
- }
-
- /**
- * @param textValue the textValue to set
- */
- public CriterionDto setTextValue(String textValue) {
- this.textValue = textValue;
- return this;
- }
-
- /**
- * @param value the value to set
- */
- public CriterionDto setValue(Float value) {
- this.value = value;
- return this;
- }
-
- /**
- * @param variation the variation to set
- */
- public CriterionDto setVariation(Boolean variation) {
- this.variation = variation;
- return this;
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-/**
- * @since 3.1
- */
-public interface CriterionMapper {
- /**
- * Insert a {@link CriterionDto}.
- *
- * @param criterionDto the criterion to insert
- */
- void insert(CriterionDto criterionDto);
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-/**
- * @since 3.1
- */
-public final class FilterColumnDto {
- private Long id;
- private Long filterId;
- private String family;
- private String key;
- private Long orderIndex;
- private String sortDirection;
- private Boolean variation;
-
- /**
- * @return the id
- */
- public Long getId() {
- return id;
- }
-
- /**
- * @return the family
- */
- public String getFamily() {
- return family;
- }
-
- /**
- * @return the filter id
- */
- public Long getFilterId() {
- return filterId;
- }
-
- /**
- * @return the key
- */
- public String getKey() {
- return key;
- }
-
- /**
- * @return the order index
- */
- public Long getOrderIndex() {
- return orderIndex;
- }
-
- /**
- * @return the sort direction
- */
- public String getSortDirection() {
- return sortDirection;
- }
-
- /**
- * @return the variation
- */
- public Boolean getVariation() {
- return variation;
- }
-
- /**
- * @param family the family to set
- */
- public FilterColumnDto setFamily(String family) {
- this.family = family;
- return this;
- }
-
- /**
- * @param family the id to set
- */
- public FilterColumnDto setId(Long id) {
- this.id = id;
- return this;
- }
-
- /**
- * @param filterId the filterId to set
- */
- public FilterColumnDto setFilterId(Long filterId) {
- this.filterId = filterId;
- return this;
- }
-
- /**
- * @param key the key to set
- */
- public FilterColumnDto setKey(String key) {
- this.key = key;
- return this;
- }
-
- /**
- * @param orderIndex the orderIndex to set
- */
- public FilterColumnDto setOrderIndex(Long orderIndex) {
- this.orderIndex = orderIndex;
- return this;
- }
-
- /**
- * @param sortDirection the sortDirection to set
- */
- public FilterColumnDto setSortDirection(String sortDirection) {
- this.sortDirection = sortDirection;
- return this;
- }
-
- /**
- * @param variation the variation to set
- */
- public FilterColumnDto setVariation(Boolean variation) {
- this.variation = variation;
- return this;
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-/**
- * @since 3.1
- */
-public interface FilterColumnMapper {
- /**
- * Insert a {@link FilterColumnDto}.
- *
- * @param filterColumnDto the filter column to insert
- */
- void insert(FilterColumnDto filterColumnDto);
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-import org.apache.ibatis.session.SqlSession;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.MyBatis;
-
-/**
- * @since 3.1
- */
-public class FilterDao implements BatchComponent, ServerComponent {
- private MyBatis mybatis;
-
- public FilterDao(MyBatis mybatis) {
- this.mybatis = mybatis;
- }
-
- public FilterDto findFilter(String name) {
- SqlSession session = mybatis.openSession();
- try {
- FilterMapper mapper = session.getMapper(FilterMapper.class);
- return mapper.findFilter(name);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- public void insert(FilterDto filterDto) {
- SqlSession session = mybatis.openSession();
- FilterMapper filterMapper = session.getMapper(FilterMapper.class);
- CriterionMapper criteriaMapper = session.getMapper(CriterionMapper.class);
- FilterColumnMapper columnMapper = session.getMapper(FilterColumnMapper.class);
- try {
- filterMapper.insert(filterDto);
- for (CriterionDto criteriaDto : filterDto.getCriteria()) {
- criteriaDto.setFilterId(filterDto.getId());
- criteriaMapper.insert(criteriaDto);
- }
- for (FilterColumnDto filterColumnDto : filterDto.getColumns()) {
- filterColumnDto.setFilterId(filterDto.getId());
- columnMapper.insert(filterColumnDto);
- }
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-import com.google.common.collect.Lists;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @since 3.1
- */
-public final class FilterDto {
- private Long id;
- private Long userId;
- private String defaultView;
- private Boolean favourites;
- private String key;
- private String name;
- private Long pageSize;
- private Long periodIndex;
- private Long resourceId;
- private Boolean shared;
- private List<CriterionDto> criteria = Lists.newArrayList();
- private List<FilterColumnDto> filterColumns = Lists.newArrayList();
-
- /**
- * Add a {@link CriterionDto} to the list.
- *
- * @param criterion the criterion to add
- */
- public FilterDto add(CriterionDto criterion) {
- criteria.add(criterion);
- return this;
- }
-
- /**
- * Add a {@link FilterColumnDto} to the list.
- *
- * @param filterColumn the column to add
- */
- public FilterDto add(FilterColumnDto filterColumn) {
- filterColumns.add(filterColumn);
- return this;
- }
-
- /**
- * @return the column list
- */
- public Collection<FilterColumnDto> getColumns() {
- return filterColumns;
- }
-
- /**
- * @return the criterion list
- */
- public Collection<CriterionDto> getCriteria() {
- return criteria;
- }
-
- /**
- * @return the defaut view
- */
- public String getDefaultView() {
- return defaultView;
- }
-
- /**
- * @return <code>true</code> if the filter returns only favourites
- */
- public Boolean getFavourites() {
- return favourites;
- }
-
- /**
- * @return the column list
- */
- public List<FilterColumnDto> getFilterColumns() {
- return filterColumns;
- }
-
- /**
- * @return the id
- */
- public Long getId() {
- return id;
- }
-
- /**
- * @return the key
- */
- public String getKey() {
- return key;
- }
-
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
-
- /**
- * @return the page size
- */
- public Long getPageSize() {
- return pageSize;
- }
-
- /**
- * @return the period index
- */
- public Long getPeriodIndex() {
- return periodIndex;
- }
-
- /**
- * @return the resource id
- */
- public Long getResourceId() {
- return resourceId;
- }
-
- /**
- * @return <code>true</code> if the filter is shared
- */
- public Boolean getShared() {
- return shared;
- }
-
- /**
- * @return the user id
- */
- public Long getUserId() {
- return userId;
- }
-
- /**
- * @return <code>true</code> if the filter displays only favourite resources.
- */
- public Boolean isFavourites() {
- return favourites;
- }
-
- /**
- * @return <code>true</code> if the filter is shared
- */
- public Boolean isShared() {
- return shared;
- }
-
- /**
- * @param defaultView the defaultView to set
- */
- public FilterDto setDefaultView(String defaultView) {
- this.defaultView = defaultView;
- return this;
- }
-
- /**
- * @param favourites the favourites to set
- */
- public FilterDto setFavourites(Boolean favourites) {
- this.favourites = favourites;
- return this;
- }
-
- /**
- * @param key the key to set
- */
- public FilterDto setKey(String key) {
- this.key = key;
- return this;
- }
-
- /**
- * @param name the name to set
- */
- public FilterDto setName(String name) {
- this.name = name;
- return this;
- }
-
- public FilterDto setPageSize(Long pageSize) {
- this.pageSize = pageSize;
- return this;
- }
-
- /**
- * @param shared the shared to set
- */
- public FilterDto setShared(Boolean shared) {
- this.shared = shared;
- return this;
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filter;
-
-/**
- * @since 3.1
- */
-public interface FilterMapper {
- /**
- * Find a {@link FilterDto} by its unique key.
- *
- * @param key the key to search on
- * @return the filter
- */
- FilterDto findFilter(String key);
-
- /**
- * Insert a {@link FilterDto}.
- *
- * @param filterDto the filter to insert
- */
- void insert(FilterDto filterDto);
-}
private Long userId;
private SnapshotDto baseSnapshot;
private String sql;
- private String json;
+ private String data;
Long getUserId() {
return userId;
return this;
}
- String getJson() {
- return json;
+ String getData() {
+ return data;
}
- MeasureFilterContext setJson(String json) {
- this.json = json;
+ MeasureFilterContext setData(String data) {
+ this.data = data;
return this;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
- .append("filter", json)
+ .append("filter", data)
.append("sql", sql)
.append("user", userId)
.toString();
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.core.measure;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.ServerComponent;
+import org.sonar.core.persistence.MyBatis;
+
+/**
+ * @since 3.4
+ */
+public class MeasureFilterDao implements BatchComponent, ServerComponent {
+ private MyBatis mybatis;
+
+ public MeasureFilterDao(MyBatis mybatis) {
+ this.mybatis = mybatis;
+ }
+
+ public MeasureFilterDto findSystemFilterByName(String name) {
+ SqlSession session = mybatis.openSession();
+ try {
+ MeasureFilterMapper mapper = session.getMapper(MeasureFilterMapper.class);
+ return mapper.findSystemFilterByName(name);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void insert(MeasureFilterDto filter) {
+ SqlSession session = mybatis.openSession();
+ MeasureFilterMapper mapper = session.getMapper(MeasureFilterMapper.class);
+ try {
+ mapper.insert(filter);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.measure;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.utils.DateUtils;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-public class MeasureFilterDecoder implements ServerComponent {
- private MetricFinder metricFinder;
- private JSONParser parser = new JSONParser();
-
- public MeasureFilterDecoder(MetricFinder metricFinder) {
- this.metricFinder = metricFinder;
- }
-
- public MeasureFilter decode(String text) throws ParseException {
- MeasureFilter filter = new MeasureFilter();
- JSONObject map = (JSONObject) parser.parse(text);
- parseResourceConditions(filter, map);
- parseMeasureConditions(map, filter);
- parseSorting(map, filter);
- return filter;
- }
-
- private void parseResourceConditions(MeasureFilter filter, JSONObject map) {
- filter.setBaseResourceKey((String) map.get("base"));
- if (map.containsKey("onBaseChildren")) {
- filter.setOnBaseResourceChildren(((Boolean) map.get("onBaseChildren")).booleanValue());
- }
- filter.setResourceScopes((List<String>) map.get("scopes"));
- filter.setResourceQualifiers((List<String>) map.get("qualifiers"));
- filter.setResourceLanguages((List<String>) map.get("languages"));
- filter.setResourceName((String) map.get("name"));
- filter.setResourceKeyRegexp((String) map.get("keyRegexp"));
-
- if (map.containsKey("fromDate")) {
- filter.setFromDate(toDate(map, "fromDate"));
- }
- if (map.containsKey("afterDays")) {
- filter.setFromDate(toDays(map, "afterDays"));
- }
- if (map.containsKey("toDate")) {
- filter.setToDate(toDate(map, "toDate"));
- }
- if (map.containsKey("beforeDays")) {
- filter.setToDate(toDays(map, "beforeDays"));
- }
- if (map.containsKey("favourites")) {
- filter.setUserFavourites(((Boolean) map.get("favourites")).booleanValue());
- }
- }
-
- private void parseSorting(JSONObject map, MeasureFilter filter) {
- if (map.containsKey("sortAsc")) {
- filter.setSortAsc(((Boolean) map.get("sortAsc")).booleanValue());
- }
- String s = (String) map.get("sortField");
- if (s != null) {
- filter.setSortOn(MeasureFilterSort.Field.valueOf(s));
- }
- s = (String) map.get("sortField");
- if (s != null) {
- filter.setSortOn(MeasureFilterSort.Field.valueOf((String) map.get("sortField")));
- }
- s = (String) map.get("sortMetric");
- if (s != null) {
- filter.setSortOnMetric(metricFinder.findByKey(s));
- }
- if (map.containsKey("sortPeriod")) {
- filter.setSortOnPeriod(((Long) map.get("sortPeriod")).intValue());
- }
- }
-
- private void parseMeasureConditions(JSONObject map, MeasureFilter filter) {
- JSONArray conditions = (JSONArray) map.get("conditions");
- if (conditions != null) {
- for (Object obj : conditions) {
- JSONObject c = (JSONObject) obj;
- Metric metric = metricFinder.findByKey((String) c.get("metric"));
- String operator = (String) c.get("op");
- Double value = (Double) c.get("val");
- MeasureFilterCondition condition = new MeasureFilterCondition(metric, MeasureFilterCondition.Operator.fromSql(operator), value);
- if (c.containsKey("period")) {
- condition.setPeriod(((Long) c.get("period")).intValue());
- }
- filter.addCondition(condition);
- }
- }
- }
-
- private static Date toDate(JSONObject map, String key) {
- String date = (String) map.get(key);
- if (date != null) {
- return DateUtils.parseDate(date);
- }
- return null;
- }
-
- private static Date toDays(JSONObject map, String key) {
- int days = ((Long) map.get(key)).intValue();
- Date date = org.apache.commons.lang.time.DateUtils.truncate(new Date(), Calendar.DATE);
- date = org.apache.commons.lang.time.DateUtils.addDays(date, -days);
- return date;
- }
-
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.core.measure;
+
+import java.util.Date;
+
+/**
+ * @since 3.4
+ */
+public class MeasureFilterDto {
+ private Long id;
+ private String name;
+ private Long userId;
+ private Boolean shared;
+ private String description;
+ private String data;
+ private Date createdAt;
+ private Date updatedAt;
+
+ public Long getId() {
+ return id;
+ }
+
+ public MeasureFilterDto setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public MeasureFilterDto setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public MeasureFilterDto setUserId(Long userId) {
+ this.userId = userId;
+ return this;
+ }
+
+ public Boolean isShared() {
+ return shared;
+ }
+
+ public MeasureFilterDto setShared(Boolean shared) {
+ this.shared = shared;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public MeasureFilterDto setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public MeasureFilterDto setData(String data) {
+ this.data = data;
+ return this;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public MeasureFilterDto setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ public Date getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public MeasureFilterDto setUpdatedAt(Date updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+}
package org.sonar.core.measure;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
-import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.SystemUtils;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import java.util.Map;
public class MeasureFilterEngine implements ServerComponent {
- private static final Logger FILTER_LOG = LoggerFactory.getLogger("org.sonar.MEASURE_FILTER");
- private final MeasureFilterDecoder decoder;
private final MeasureFilterFactory factory;
private final MeasureFilterExecutor executor;
- public MeasureFilterEngine(MeasureFilterDecoder decoder, MeasureFilterFactory factory, MeasureFilterExecutor executor) {
- this.decoder = decoder;
+ public MeasureFilterEngine(MeasureFilterFactory factory, MeasureFilterExecutor executor) {
this.executor = executor;
this.factory = factory;
}
- public List<MeasureFilterRow> execute(String filterJson, @Nullable Long userId) throws ParseException {
- return execute(filterJson, userId, FILTER_LOG);
- }
-
- public List<MeasureFilterRow> execute2(Map<String, Object> filterMap, @Nullable Long userId) throws ParseException {
- Logger logger = FILTER_LOG;
- MeasureFilterContext context = new MeasureFilterContext();
- context.setUserId(userId);
- try {
- long start = System.currentTimeMillis();
- MeasureFilter filter = factory.create(filterMap);
- context.setJson(filter.toString());
- List<MeasureFilterRow> rows = executor.execute(filter, context);
- log(context, rows, (System.currentTimeMillis() - start), logger);
- return rows;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to execute filter: " + context, e);
- }
+ public List<MeasureFilterRow> execute(Map<String, Object> filterMap, @Nullable Long userId) throws ParseException {
+ return execute(filterMap, userId, LoggerFactory.getLogger("org.sonar.MEASURE_FILTER"));
}
@VisibleForTesting
- List<MeasureFilterRow> execute(String filterJson, @Nullable Long userId, Logger logger) {
+ List<MeasureFilterRow> execute(Map<String, Object> filterMap, @Nullable Long userId, Logger logger) throws ParseException {
+
MeasureFilterContext context = new MeasureFilterContext();
- context.setJson(filterJson);
context.setUserId(userId);
+ context.setData(filterMap.toString());
try {
long start = System.currentTimeMillis();
- MeasureFilter filter = decoder.decode(filterJson);
+ MeasureFilter filter = factory.create(filterMap);
List<MeasureFilterRow> rows = executor.execute(filter, context);
log(context, rows, (System.currentTimeMillis() - start), logger);
return rows;
if (logger.isDebugEnabled()) {
StringBuilder log = new StringBuilder();
log.append(SystemUtils.LINE_SEPARATOR);
- log.append(" filter: ").append(context.getJson()).append(SystemUtils.LINE_SEPARATOR);
+ log.append(" filter: ").append(context.getData()).append(SystemUtils.LINE_SEPARATOR);
log.append(" sql: ").append(context.getSql()).append(SystemUtils.LINE_SEPARATOR);
log.append("results: ").append(rows.size()).append(" rows in ").append(durationMs).append("ms").append(SystemUtils.LINE_SEPARATOR);
logger.debug(log.toString());
filter.addCondition(condition);
}
}
-// if (map.containsKey("sortPeriod")) {
-// filter.setSortOnPeriod(((Long) map.get("sortPeriod")).intValue());
-// }
return filter;
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.core.measure;
+
+/**
+ * @since 3.4
+ */
+public interface MeasureFilterMapper {
+ MeasureFilterDto findSystemFilterByName(String name);
+
+ void insert(MeasureFilterDto filter);
+}
import org.sonar.core.dashboard.ActiveDashboardDao;
import org.sonar.core.dashboard.DashboardDao;
import org.sonar.core.duplication.DuplicationDao;
-import org.sonar.core.filter.FilterDao;
+import org.sonar.core.measure.MeasureFilterDao;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.purge.PurgeDao;
import org.sonar.core.resource.ResourceDao;
return ImmutableList.of(
ActiveDashboardDao.class,
AuthorDao.class,
- FilterDao.class,
DashboardDao.class,
DuplicationDao.class,
LoadedTemplateDao.class,
+ MeasureFilterDao.class,
PropertiesDao.class,
PurgeDao.class,
ResourceIndexerDao.class,
"characteristics",
"characteristic_edges",
"characteristic_properties",
- "criteria",
"dashboards",
"dependencies",
"duplications_index",
"events",
- "filters",
- "filter_columns",
"groups",
"groups_users",
"group_roles",
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 359;
+ public static final int LAST_VERSION = 361;
public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
import org.sonar.core.dependency.ResourceSnapshotMapper;
import org.sonar.core.duplication.DuplicationMapper;
import org.sonar.core.duplication.DuplicationUnitDto;
-import org.sonar.core.filter.CriterionDto;
-import org.sonar.core.filter.CriterionMapper;
-import org.sonar.core.filter.FilterColumnDto;
-import org.sonar.core.filter.FilterColumnMapper;
-import org.sonar.core.filter.FilterDto;
-import org.sonar.core.filter.FilterMapper;
+import org.sonar.core.measure.MeasureFilterDto;
+import org.sonar.core.measure.MeasureFilterMapper;
import org.sonar.core.properties.PropertiesMapper;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.purge.PurgeMapper;
loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class);
loadAlias(conf, "Author", AuthorDto.class);
- loadAlias(conf, "Filter", FilterDto.class);
- loadAlias(conf, "Criterion", CriterionDto.class);
- loadAlias(conf, "FilterColumn", FilterColumnDto.class);
loadAlias(conf, "Dashboard", DashboardDto.class);
loadAlias(conf, "Dependency", DependencyDto.class);
loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class);
loadAlias(conf, "Group", GroupDto.class);
loadAlias(conf, "GroupRole", GroupRoleDto.class);
loadAlias(conf, "LoadedTemplate", LoadedTemplateDto.class);
+ loadAlias(conf, "MeasureFilter", MeasureFilterDto.class);
loadAlias(conf, "Property", PropertyDto.class);
loadAlias(conf, "PurgeableSnapshot", PurgeableSnapshotDto.class);
loadAlias(conf, "Resource", ResourceDto.class);
loadAlias(conf, "MeasureModel", MeasureModel.class);
loadAlias(conf, "MeasureData", MeasureData.class);
- Class<?>[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, FilterMapper.class, CriterionMapper.class, FilterColumnMapper.class, DashboardMapper.class,
- DependencyMapper.class, DuplicationMapper.class, LoadedTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class,
+ Class<?>[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, DashboardMapper.class,
+ DependencyMapper.class, DuplicationMapper.class, LoadedTemplateMapper.class, MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class,
ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceMapper.class, ResourceSnapshotMapper.class, ReviewCommentMapper.class,
ReviewMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class,
MeasureMapper.class};
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.measure.MeasureFilterMapper">
+
+ <select id="findSystemFilterByName" parameterType="string" resultType="MeasureFilter">
+ select id, name, user_id as "userId", shared, description, data, created_at as "createdAt", updated_at as "updatedAt"
+ from measure_filters WHERE user_id is null and name=#{id}
+ </select>
+
+ <insert id="insert" parameterType="MeasureFilter" useGeneratedKeys="true" keyProperty="id">
+ INSERT INTO measure_filters (name, user_id, shared, description, data, created_at, updated_at)
+ VALUES (#{name}, #{userId}, #{shared}, #{description}, #{data}, #{createdAt}, #{updatedAt})
+ </insert>
+
+ <!-- Oracle -->
+ <insert id="insert" databaseId="oracle" parameterType="MeasureFilter" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ <selectKey order="BEFORE" resultType="Long" keyProperty="id">
+ select measure_filters_seq.NEXTVAL from DUAL
+ </selectKey>
+ INSERT INTO id, measure_filters (name, user_id, shared, description, data, created_at, updated_at)
+ VALUES (#{id}, #{name}, #{userId}, #{shared}, #{description}, #{data}, #{createdAt}, #{updatedAt})
+ </insert>
+
+</mapper>
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('357');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('358');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('359');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('360');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('361');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"PARENT_ID" INTEGER
);
-CREATE TABLE "CRITERIA" (
- "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
- "FILTER_ID" INTEGER,
- "FAMILY" VARCHAR(100),
- "KEE" VARCHAR(100),
- "OPERATOR" VARCHAR(20),
- "VALUE" DOUBLE,
- "TEXT_VALUE" VARCHAR(256),
- "VARIATION" BOOLEAN
-);
-
CREATE TABLE "DEPENDENCIES" (
"ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"FROM_SNAPSHOT_ID" INTEGER,
"RESOURCE_ID" INTEGER
);
-CREATE TABLE "FILTER_COLUMNS" (
- "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
- "FILTER_ID" INTEGER,
- "FAMILY" VARCHAR(100),
- "KEE" VARCHAR(100),
- "SORT_DIRECTION" VARCHAR(5),
- "ORDER_INDEX" INTEGER,
- "VARIATION" BOOLEAN
-);
-
CREATE TABLE "MEASURE_DATA" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"MEASURE_ID" BIGINT,
"ACTIVE" BOOLEAN DEFAULT TRUE
);
-CREATE TABLE "FILTERS" (
- "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
- "NAME" VARCHAR(100),
- "KEE" VARCHAR(100),
- "USER_ID" INTEGER,
- "SHARED" BOOLEAN,
- "FAVOURITES" BOOLEAN,
- "RESOURCE_ID" INTEGER,
- "DEFAULT_VIEW" VARCHAR(20),
- "PAGE_SIZE" INTEGER,
- "PERIOD_INDEX" INTEGER
-);
-
CREATE TABLE "DASHBOARDS" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"USER_ID" INTEGER,
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.filters;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.core.filter.CriterionDto;
-import org.sonar.core.filter.FilterColumnDto;
-import org.sonar.core.filter.FilterDao;
-import org.sonar.core.filter.FilterDto;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class FilterDaoTest extends AbstractDaoTestCase {
- private FilterDao dao;
-
- @Before
- public void createDao() {
- dao = new FilterDao(getMyBatis());
- }
-
- @Test
- public void should_find_filter() {
- setupData("shouldFindFilter");
-
- FilterDto filter = dao.findFilter("Projects");
-
- assertThat(filter.getId()).isEqualTo(1L);
- assertThat(filter.getName()).isEqualTo("Projects");
- assertThat(filter.getKey()).isEqualTo("Projects");
- assertThat(dao.findFilter("<UNKNOWN>")).isNull();
- }
-
- @Test
- public void should_insert() {
- setupData("shouldInsert");
-
- FilterDto filterDto = new FilterDto();
- filterDto.setName("Projects");
- filterDto.setKey("Projects");
- filterDto.setShared(true);
- filterDto.setFavourites(false);
- filterDto.setDefaultView("list");
- filterDto.setPageSize(10L);
-
- CriterionDto criterionDto = new CriterionDto();
- criterionDto.setFamily("family");
- criterionDto.setKey("key");
- criterionDto.setOperator("=");
- criterionDto.setValue(1.5f);
- criterionDto.setTextValue("1.5");
- criterionDto.setVariation(true);
- filterDto.add(criterionDto);
-
- FilterColumnDto filterColumnDto = new FilterColumnDto();
- filterColumnDto.setFamily("family");
- filterColumnDto.setKey("key");
- filterColumnDto.setSortDirection("ASC");
- filterColumnDto.setOrderIndex(2L);
- filterColumnDto.setVariation(true);
- filterDto.add(filterColumnDto);
-
- dao.insert(filterDto);
-
- checkTables("shouldInsert", "filters", "criteria", "filter_columns");
- }
-}
\ No newline at end of file
*/
package org.sonar.core.measure;
+import com.google.common.collect.ImmutableMap;
import org.junit.Test;
+import java.util.Map;
+
import static org.fest.assertions.Assertions.assertThat;
public class MeasureFilterContextTest {
@Test
public void test_toString() {
MeasureFilterContext context = new MeasureFilterContext();
- context.setJson("{}");
+ context.setData("{qualifiers=TRK}");
context.setSql("SELECT *");
context.setUserId(50L);
- assertThat(context.toString()).isEqualTo("MeasureFilterContext[filter={},sql=SELECT *,user=50]");
+ assertThat(context.toString()).isEqualTo("MeasureFilterContext[filter={qualifiers=TRK},sql=SELECT *,user=50]");
}
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.core.measure;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MeasureFilterDaoTest extends AbstractDaoTestCase {
+ private MeasureFilterDao dao;
+
+ @Before
+ public void createDao() {
+ dao = new MeasureFilterDao(getMyBatis());
+ }
+
+ @Test
+ public void should_find_filter() {
+ setupData("shared");
+
+ MeasureFilterDto filter = dao.findSystemFilterByName("Projects");
+
+ assertThat(filter.getId()).isEqualTo(1L);
+ assertThat(filter.getName()).isEqualTo("Projects");
+ }
+
+
+ @Test
+ public void should_not_find_filter() {
+ setupData("shared");
+
+ assertThat(dao.findSystemFilterByName("Unknown")).isNull();
+ }
+
+ @Test
+ public void should_insert() {
+ setupData("shared");
+
+ MeasureFilterDto filterDto = new MeasureFilterDto();
+ filterDto.setName("Project Treemap");
+ filterDto.setUserId(123L);
+ filterDto.setShared(true);
+ filterDto.setDescription("Treemap of projects");
+ filterDto.setData("qualifiers=TRK|display=treemap");
+
+ dao.insert(filterDto);
+
+ checkTables("shouldInsert", new String[]{"created_at", "updated_at"}, "measure_filters");
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.core.measure;
-
-import org.json.simple.parser.ParseException;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-
-import java.util.Date;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class MeasureFilterDecoderTest {
-
- private MetricFinder metricFinder;
-
- @Before
- public void before() {
- metricFinder = mock(MetricFinder.class);
- when(metricFinder.findByKey(anyString())).thenAnswer(new Answer<Metric>() {
- public Metric answer(InvocationOnMock invocationOnMock) throws Throwable {
- return new Metric((String) invocationOnMock.getArguments()[0]);
- }
- });
- }
-
- @Test
- public void should_decode() throws ParseException {
- String json = "{\"base\": \"org.struts\", \"onBaseChildren\": true, \"scopes\": [\"PRJ\"], " +
- "\"qualifiers\": [\"TRK\",\"CLA\"], \"keyRegexp\": \"*foo*\"" +
- "\"languages\": [\"java\", \"php\"], \"name\": \"Struts\", \"fromDate\": \"2012-12-25\", " +
- "\"toDate\": \"2013-01-31\", " +
- "\"favourites\": true, " +
- "\"sortAsc\": true, \"sortField\": \"METRIC\", \"sortMetric\": \"ncloc\", \"sortPeriod\":5, " +
- "\"conditions\":[{\"metric\":\"lines\", \"op\":\">\", \"val\":123.0}]}";
-
- MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json);
-
- assertThat(filter.getBaseResourceKey()).isEqualTo("org.struts");
- assertThat(filter.isOnBaseResourceChildren()).isTrue();
- assertThat(filter.getResourceScopes()).containsOnly("PRJ");
- assertThat(filter.getResourceQualifiers()).containsOnly("TRK", "CLA");
- assertThat(filter.getResourceLanguages()).containsOnly("java", "php");
- assertThat(filter.getResourceName()).isEqualTo("Struts");
- assertThat(filter.getResourceKeyRegexp()).isEqualTo("*foo*");
- assertThat(filter.getFromDate().getYear()).isEqualTo(2012 - 1900);
- assertThat(filter.getToDate().getYear()).isEqualTo(2013 - 1900);
- assertThat(filter.isOnFavourites()).isTrue();
- assertThat(filter.sort().metric().getKey()).isEqualTo("ncloc");
- assertThat(filter.sort().isAsc()).isTrue();
- MeasureFilterCondition condition = filter.getMeasureConditions().get(0);
- assertThat(condition.metric().getKey()).isEqualTo("lines");
- assertThat(condition.operator()).isEqualTo(MeasureFilterCondition.Operator.GREATER);
- assertThat(condition.value()).isEqualTo(123.0);
- }
-
- @Test
- public void should_set_max_date_by_number_of_days() throws ParseException {
- String json = "{\"beforeDays\": 5}";
-
- MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json);
-
- assertThat(filter.getFromDate()).isNull();
- assertThat(filter.getToDate().before(new Date())).isTrue();
- }
-
- @Test
- public void should_set_min_date_by_number_of_days() throws ParseException {
- String json = "{\"afterDays\": 5}";
-
- MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode(json);
-
- assertThat(filter.getToDate()).isNull();
- assertThat(filter.getFromDate().before(new Date())).isTrue();
- }
-
- @Test
- public void test_default_values() throws ParseException {
- MeasureFilter filter = new MeasureFilterDecoder(metricFinder).decode("{}");
-
- assertThat(filter.getBaseResourceKey()).isNull();
- assertThat(filter.isOnBaseResourceChildren()).isFalse();
- assertThat(filter.getResourceScopes()).isEmpty();
- assertThat(filter.getResourceQualifiers()).isEmpty();
- assertThat(filter.getResourceLanguages()).isEmpty();
- assertThat(filter.getResourceName()).isNull();
- assertThat(filter.getResourceKeyRegexp()).isNull();
- assertThat(filter.getFromDate()).isNull();
- assertThat(filter.getToDate()).isNull();
- assertThat(filter.isOnFavourites()).isFalse();
- assertThat(filter.sort().metric()).isNull();
- assertThat(filter.sort().getPeriod()).isNull();
- assertThat(filter.sort().onMeasures()).isFalse();
- assertThat(filter.sort().field()).isEqualTo(MeasureFilterSort.Field.NAME);
- assertThat(filter.sort().isAsc()).isTrue();
- assertThat(filter.getMeasureConditions()).isEmpty();
-
- }
-}
*/
package org.sonar.core.measure;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.json.simple.parser.ParseException;
import org.junit.rules.ExpectedException;
import org.slf4j.Logger;
+import java.util.HashMap;
+import java.util.Map;
+
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.*;
public ExpectedException thrown = ExpectedException.none();
@Test
- public void should_decode_json_and_execute_filter() throws Exception {
- MeasureFilterDecoder decoder = mock(MeasureFilterDecoder.class);
+ public void should_create_and_execute_filter() throws Exception {
+ Map<String,Object> filterMap = ImmutableMap.of("qualifiers", (Object) "TRK");
+ MeasureFilterFactory factory = mock(MeasureFilterFactory.class);
MeasureFilter filter = new MeasureFilter();
- when(decoder.decode("{}")).thenReturn(filter);
+ when(factory.create(filterMap)).thenReturn(filter);
MeasureFilterExecutor executor = mock(MeasureFilterExecutor.class);
Logger logger = mock(Logger.class);
when(logger.isDebugEnabled()).thenReturn(true);
- MeasureFilterEngine engine = new MeasureFilterEngine(decoder, null, executor);
+ MeasureFilterEngine engine = new MeasureFilterEngine(factory, executor);
final long userId = 50L;
- engine.execute("{}", userId, logger);
+ engine.execute(filterMap, userId, logger);
verify(executor).execute(refEq(filter), argThat(new BaseMatcher<MeasureFilterContext>() {
public boolean matches(Object o) {
MeasureFilterContext context = (MeasureFilterContext) o;
- return "{}".equals(context.getJson()) && context.getUserId() == userId;
+ return "{qualifiers=TRK}".equals(context.getData()) && context.getUserId() == userId;
}
public void describeTo(Description description) {
@Test
public void throw_definition_of_filter_on_error() throws Exception {
thrown.expect(IllegalStateException.class);
- thrown.expectMessage("filter=<xml>");
+ thrown.expectMessage("filter={qualifiers=TRK}");
- MeasureFilterDecoder decoder = mock(MeasureFilterDecoder.class);
- when(decoder.decode("<xml>")).thenThrow(new ParseException(0));
+ Map<String,Object> filterMap = ImmutableMap.of("qualifiers", (Object)"TRK");
+ MeasureFilterFactory factory = mock(MeasureFilterFactory.class);
+ when(factory.create(filterMap)).thenThrow(new IllegalArgumentException());
MeasureFilterExecutor executor = mock(MeasureFilterExecutor.class);
- MeasureFilterEngine engine = new MeasureFilterEngine(decoder, null, executor);
- engine.execute("<xml>", 50L);
+ MeasureFilterEngine engine = new MeasureFilterEngine(factory, executor);
+ engine.execute(filterMap, 50L);
}
}
+++ /dev/null
-<dataset>
-
- <filters
- id="1"
- name="Projects"
- kee="Projects"
- user_id="[null]"
- shared="[true]"
- favourites="[false]"
- resource_id="[null]"
- default_view="list"
- page_size="[null]"
- period_index="[null]"
- />
-
- <filters
- id="2"
- name="Treemap"
- kee="Treemap"
- user_id="[null]"
- shared="[true]"
- favourites="[false]"
- resource_id="[null]"
- default_view="treemap"
- page_size="[null]"
- period_index="[null]"
- />
-
-</dataset>
+++ /dev/null
-<dataset>
-
- <filters
- id="1"
- name="Projects"
- kee="Projects"
- user_id="[null]"
- shared="[true]"
- favourites="[false]"
- resource_id="[null]"
- default_view="list"
- page_size="10"
- period_index="[null]"
- />
-
- <criteria
- id="1"
- filter_id="1"
- family="family"
- kee="key"
- operator="="
- value="1.5"
- text_value="1.5"
- variation="[true]"
- />
-
- <filter_columns
- id="1"
- filter_id="1"
- family="family"
- kee="key"
- sort_direction="ASC"
- order_index="2"
- variation="[true]"
- />
-
-</dataset>
+++ /dev/null
-<dataset>
-
-</dataset>
--- /dev/null
+<dataset>
+
+ <measure_filters
+ id="1"
+ name="Projects"
+ user_id="[null]"
+ shared="[true]"
+ description="All projects"
+ data="qualifiers=TRK"
+ created_at="2012-12-25"
+ updated_at="2012-12-25" />
+
+ <measure_filters
+ id="2"
+ name="Files"
+ user_id="[null]"
+ shared="[true]"
+ description="All files"
+ data="qualifiers=FIL"
+ created_at="2012-01-25"
+ updated_at="2012-01-25" />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <measure_filters
+ id="1"
+ name="Projects"
+ user_id="[null]"
+ shared="[true]"
+ description="All projects"
+ data="qualifiers=TRK"
+ created_at="2012-12-25"
+ updated_at="2012-12-25"/>
+
+ <measure_filters
+ id="2"
+ name="Files"
+ user_id="[null]"
+ shared="[true]"
+ description="All files"
+ data="qualifiers=FIL"
+ created_at="2012-01-25"
+ updated_at="2012-01-25"/>
+
+
+ <measure_filters
+ id="3"
+ name="Project Treemap"
+ user_id="123"
+ shared="[true]"
+ description="Treemap of projects"
+ data="qualifiers=TRK|display=treemap"
+ created_at="2012-12-25"
+ updated_at="2012-12-25"/>
+
+</dataset>
* @since 3.1
*/
public final class Criterion {
- public static final String EQ = "=";
- public static final String GT = ">";
- public static final String GTE = ">=";
- public static final String LT = "<";
- public static final String LTE = "<=";
+ public static final String EQ = "eq";
+ public static final String GT = "gt";
+ public static final String GTE = "gte";
+ public static final String LT = "lt";
+ public static final String LTE = "lte";
public static final Set<String> OPERATORS = ImmutableSortedSet.of(EQ, GT, GTE, LT, LTE);
private final String family;
* @throws IllegalArgumentException if {@code displayAs) is not {@value #LIST} or {@value #TREEMAP}
*/
public Filter setDisplayAs(String displayAs) {
- Preconditions.checkArgument(LIST.equals(displayAs) || TREEMAP.equals(displayAs), "Default period should be either %s or %s, not %s", LIST, TREEMAP, displayAs);
+ Preconditions.checkArgument(LIST.equals(displayAs) || TREEMAP.equals(displayAs), "Default display should be either %s or %s, not %s", LIST, TREEMAP, displayAs);
this.displayAs = displayAs;
return this;
}
@Test
public void should_accept_valid_operators() {
- Criterion.createForMetric("", "<=", "", false);
- Criterion.createForMetric("", "<", "", false);
- Criterion.createForMetric("", "=", "", false);
- Criterion.createForMetric("", ">", "", false);
- Criterion.createForMetric("", ">=", "", false);
+ Criterion.createForMetric("", "lte", "", false);
+ Criterion.createForMetric("", "lt", "", false);
+ Criterion.createForMetric("", "eq", "", false);
+ Criterion.createForMetric("", "gt", "", false);
+ Criterion.createForMetric("", "gte", "", false);
}
@Test
public void should_fail_on_invalid_operators() {
exception.expect(IllegalArgumentException.class);
- exception.expectMessage("Valid operators are [<, <=, =, >, >=], not '<>'");
+ exception.expectMessage("Valid operators are [eq, gt, gte, lt, lte], not 'xxx'");
- Criterion.createForMetric("", "<>", "", false);
+ Criterion.createForMetric("", "xxx", "", false);
}
}
}
@Test
- public void should_fail_on_invalid_period() {
+ public void should_fail_on_invalid_display() {
exception.expect(IllegalArgumentException.class);
- exception.expectMessage("Default period should be either list or treemap, not <invalid>");
+ exception.expectMessage("Default display should be either list or treemap, not <invalid>");
Filter.create().setDisplayAs("<invalid>");
}
import org.sonar.core.i18n.GwtI18n;
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.measure.MeasureFilterDecoder;
import org.sonar.core.measure.MeasureFilterEngine;
import org.sonar.core.measure.MeasureFilterExecutor;
import org.sonar.core.measure.MeasureFilterFactory;
import org.sonar.server.startup.JdbcDriverDeployer;
import org.sonar.server.startup.RegisterMetrics;
import org.sonar.server.startup.RegisterNewDashboards;
-import org.sonar.server.startup.RegisterNewFilters;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
import org.sonar.server.startup.RegisterNewProfiles;
import org.sonar.server.startup.RegisterQualityModels;
import org.sonar.server.startup.RegisterRules;
servicesContainer.addSingleton(NewUserNotifier.class);
servicesContainer.addSingleton(SettingsChangeNotifier.class);
servicesContainer.addSingleton(PageDecorations.class);
- servicesContainer.addSingleton(MeasureFilterDecoder.class);
servicesContainer.addSingleton(MeasureFilterFactory.class);
servicesContainer.addSingleton(MeasureFilterExecutor.class);
servicesContainer.addSingleton(MeasureFilterEngine.class);
startupContainer.addSingleton(RegisterQualityModels.class);
startupContainer.addSingleton(DeleteDeprecatedMeasures.class);
startupContainer.addSingleton(GeneratePluginIndex.class);
- startupContainer.addSingleton(RegisterNewFilters.class);
+ startupContainer.addSingleton(RegisterNewMeasureFilters.class);
startupContainer.addSingleton(RegisterNewDashboards.class);
startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
startupContainer.startComponents();
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.server.startup;
-
-import com.google.common.collect.ImmutableList;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.api.web.Criterion;
-import org.sonar.api.web.Filter;
-import org.sonar.api.web.FilterColumn;
-import org.sonar.api.web.FilterTemplate;
-import org.sonar.core.filter.CriterionDto;
-import org.sonar.core.filter.FilterColumnDto;
-import org.sonar.core.filter.FilterDao;
-import org.sonar.core.filter.FilterDto;
-import org.sonar.core.template.LoadedTemplateDao;
-import org.sonar.core.template.LoadedTemplateDto;
-
-import java.util.List;
-
-/**
- * @since 3.1
- */
-public final class RegisterNewFilters {
- private static final Logger LOG = LoggerFactory.getLogger(RegisterNewFilters.class);
-
- private final List<FilterTemplate> filterTemplates;
- private final FilterDao filterDao;
- private final LoadedTemplateDao loadedTemplateDao;
-
- public RegisterNewFilters(FilterTemplate[] filterTemplates, FilterDao filterDao, LoadedTemplateDao loadedTemplateDao) {
- this.filterTemplates = ImmutableList.copyOf(filterTemplates);
- this.filterDao = filterDao;
- this.loadedTemplateDao = loadedTemplateDao;
- }
-
- public void start() {
- TimeProfiler profiler = new TimeProfiler(LOG).start("Register filters");
-
- for (FilterTemplate template : filterTemplates) {
- if (shouldRegister(template.getName())) {
- Filter filter = template.createFilter();
- register(template.getName(), filter);
- }
- }
-
- profiler.stop();
- }
-
- private boolean shouldRegister(String filterName) {
- return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.FILTER_TYPE, filterName) == 0;
- }
-
- protected FilterDto register(String name, Filter filter) {
- FilterDto dto = null;
- if (filterDao.findFilter(name) == null) {
- LOG.info("Register filter: " + name);
- dto = createDtoFromExtension(name, filter);
- filterDao.insert(dto);
- }
- // and save the fact that is has now already been loaded
- loadedTemplateDao.insert(new LoadedTemplateDto(name, LoadedTemplateDto.FILTER_TYPE));
- return dto;
- }
-
- protected FilterDto createDtoFromExtension(String name, Filter filter) {
- FilterDto filterDto = new FilterDto()
- .setName(name)
- .setKey(name)
- .setPageSize(0 == filter.getPageSize() ? null : (long) filter.getPageSize())
- .setShared(true)
- .setFavourites(filter.isFavouritesOnly())
- .setDefaultView(filter.getDisplayAs());
-
- for (Criterion criterion : filter.getCriteria()) {
- filterDto.add(new CriterionDto()
- .setFamily(criterion.getFamily())
- .setKey(criterion.getKey())
- .setOperator(criterion.getOperator())
- .setTextValue(criterion.getTextValue())
- .setValue(criterion.getValue())
- .setVariation(criterion.isVariation()));
- }
-
- long orderIndex = 1L;
- for (FilterColumn column : filter.getColumns()) {
- filterDto.add(new FilterColumnDto()
- .setFamily(column.getFamily())
- .setKey(column.getKey())
- .setOrderIndex(orderIndex++)
- .setSortDirection(column.getSortDirection())
- .setVariation(column.isVariation()));
- }
-
- return filterDto;
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.server.startup;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.api.web.Criterion;
+import org.sonar.api.web.Filter;
+import org.sonar.api.web.FilterColumn;
+import org.sonar.api.web.FilterTemplate;
+import org.sonar.core.measure.MeasureFilterDao;
+import org.sonar.core.measure.MeasureFilterDto;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.core.template.LoadedTemplateDto;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @since 3.1
+ */
+public final class RegisterNewMeasureFilters {
+ private static final Logger LOG = LoggerFactory.getLogger(RegisterNewMeasureFilters.class);
+
+ private final List<FilterTemplate> filterTemplates;
+ private final MeasureFilterDao filterDao;
+ private final LoadedTemplateDao loadedTemplateDao;
+
+ public RegisterNewMeasureFilters(FilterTemplate[] filterTemplates, MeasureFilterDao filterDao, LoadedTemplateDao loadedTemplateDao) {
+ this.filterTemplates = ImmutableList.copyOf(filterTemplates);
+ this.filterDao = filterDao;
+ this.loadedTemplateDao = loadedTemplateDao;
+ }
+
+ public void start() {
+ TimeProfiler profiler = new TimeProfiler(LOG).start("Register measure filters");
+
+ for (FilterTemplate template : filterTemplates) {
+ if (shouldRegister(template.getName())) {
+ Filter filter = template.createFilter();
+ register(template.getName(), filter);
+ }
+ }
+
+ profiler.stop();
+ }
+
+ private boolean shouldRegister(String filterName) {
+ return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.FILTER_TYPE, filterName) == 0;
+ }
+
+ protected MeasureFilterDto register(String name, Filter filter) {
+ MeasureFilterDto dto = null;
+ if (filterDao.findSystemFilterByName(name) == null) {
+ LOG.info("Register measure filter: " + name);
+ dto = createDtoFromExtension(name, filter);
+ filterDao.insert(dto);
+ }
+ // and save the fact that is has now already been loaded
+ loadedTemplateDao.insert(new LoadedTemplateDto(name, LoadedTemplateDto.FILTER_TYPE));
+ return dto;
+ }
+
+ protected MeasureFilterDto createDtoFromExtension(String name, Filter filter) {
+ Date now = new Date();
+ String data = toData(filter);
+ return new MeasureFilterDto()
+ .setName(name)
+ .setShared(true)
+ .setUserId(null)
+ .setCreatedAt(now)
+ .setUpdatedAt(now)
+ .setData(data);
+ }
+
+ static String toData(Filter filter) {
+ List<String> fields = Lists.newArrayList();
+
+ fields.add("display=" + filter.getDisplayAs());
+ if (filter.isFavouritesOnly()) {
+ fields.add("onFavourites=true");
+ }
+ if (filter.getPageSize() > 0) {
+ fields.add("pageSize=" + filter.getPageSize());
+ }
+
+ int metricCriterionId = 1;
+ for (Criterion criterion : filter.getCriteria()) {
+ if ("qualifier".equals(criterion.getFamily())) {
+ fields.add("qualifiers=" + criterion.getTextValue());
+ } else if ("name".equals(criterion.getFamily())) {
+ fields.add("nameSearch=" + criterion.getTextValue());
+ } else if ("key".equals(criterion.getFamily())) {
+ fields.add("keyRegexp=" + criterion.getTextValue());
+ } else if ("language".equals(criterion.getFamily())) {
+ fields.add("languages=" + criterion.getTextValue());
+ } else if ("date".equals(criterion.getFamily())) {
+ if ("<".equals(criterion.getOperator())) {
+ fields.add("ageMaxDays=" + criterion.getValue());
+ } else if (">".equals(criterion.getOperator())) {
+ fields.add("ageMinDays=" + criterion.getValue());
+ }
+ } else if ("direct-children".equals(criterion.getFamily()) && "true".equals(criterion.getTextValue())) {
+ fields.add("onBaseComponents=true");
+ } else if ("metric".equals(criterion.getFamily()) && StringUtils.isNotBlank(criterion.getKey())
+ && StringUtils.isNotBlank(criterion.getOperator()) && criterion.getValue() != null) {
+ fields.add("c" + metricCriterionId + "_metric=" + criterion.getKey());
+ fields.add("c" + metricCriterionId + "_op=" + criterion.getOperator());
+ fields.add("c" + metricCriterionId + "_val=" + criterion.getValue());
+ metricCriterionId += 1;
+ }
+ }
+ List<String> columnFields = Lists.newArrayList();
+ for (FilterColumn column : filter.getColumns()) {
+ String columnKey = column.getFamily();
+ if (StringUtils.isNotBlank(column.getKey()) && !column.isVariation()) {
+ columnKey += ":" + column.getKey();
+ }
+ columnFields.add(columnKey);
+ }
+ if (!columnFields.isEmpty()) {
+ fields.add("cols=" + Joiner.on(",").join(columnFields));
+ }
+ return Joiner.on("|").join(fields);
+ }
+}
return getContainer().getComponentByType(componentType);
}
- public List<MeasureFilterRow> executeMeasureFilter(String json, @Nullable Long userId) throws ParseException {
- return get(MeasureFilterEngine.class).execute(json, userId);
- }
-
- public List<MeasureFilterRow> executeMeasureFilter2(Map<String,Object> map, @Nullable Long userId) throws ParseException {
- return get(MeasureFilterEngine.class).execute2(map, userId);
+ public List<MeasureFilterRow> executeMeasureFilter(Map<String,Object> map, @Nullable Long userId) throws ParseException {
+ return get(MeasureFilterEngine.class).execute(map, userId);
}
public Collection<ResourceType> getResourceTypesForFilter() {
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 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
-#
-class FiltersController < ApplicationController
- include FiltersHelper
- helper MetricsHelper
- helper FiltersHelper
-
- SECTION=Navigation::SECTION_CONFIGURATION
-
- verify :method => :post, :only => [:create, :delete, :up, :down, :activate, :deactivate, :up_column, :down_column, :add_column, :delete_column, :set_sorted_column, :set_view, :set_columns, :set_page_size], :redirect_to => {:action => :index}
- before_filter :login_required, :except => %w(index treemap list)
-
- def manage
- if is_admin?
- @filters = ::Filter.find(:all, :conditions => ['user_id=? or (shared=? and user_id is null)', current_user.id, true])
- else
- @filters = ::Filter.find(:all, :conditions => {:user_id => current_user.id})
- end
- @filters.sort! { |a, b| a.name.downcase <=> b.name.downcase }
- end
-
- def list
- @filter=::Filter.find(params[:id])
- @filter_context=Filters.execute(@filter, self, params)
-
- render :partial => 'list', :locals => {:edit_mode => params[:edit_mode], :update_id => params[:update_id]}
- end
-
- def new
- @filter=::Filter.new()
- @filter.criteria<<Criterion.new_for_qualifiers(%w(TRK))
- end
-
- def create
- @filter=::Filter.new()
- load_filter_from_params(@filter, params)
- @filter.user_id=current_user.id
- @filter.kee=[@filter.name, current_user.id.to_s].join('.')
- @filter.columns.build(:family => 'name', :order_index => 1, :sort_direction => 'ASC')
- @filter.columns.build(:family => 'metric', :kee => 'ncloc', :order_index => 2, :variation => @filter.period?)
- @filter.columns.build(:family => 'metric', :kee => 'violations_density', :order_index => 3, :variation => @filter.period?)
- @filter.columns.build(:family => 'date', :order_index => 4)
-
- column_index=0
- @filter.measure_criteria.each do |criterion|
- unless @filter.column(criterion.family, criterion.kee)
- @filter.columns.build(:family => criterion.family, :kee => criterion.kee, :order_index => 3+column_index, :sort_direction => (column_index==0 ? 'ASC' : nil))
- column_index+=1
- end
- end
-
- if @filter.valid?
- @filter.save
-
- flash[:notice]='Filter saved'
-
- if params[:preview]=='true'
- redirect_to :action => 'edit', :id => @filter.id
- else
- redirect_to :action => 'manage', :id => @filter.id
- end
- else
- render :action => 'new'
- end
- end
-
- def edit
- @filter=::Filter.find(params[:id])
- access_denied unless @filter.authorized_to_edit?(self)
-
- @filter_context=Filters.execute(@filter, self, params)
- render :action => 'new'
- end
-
- def update
- @filter=::Filter.find(params[:id])
- access_denied unless @filter.authorized_to_edit?(self)
-
- load_filter_from_params(@filter, params)
-
- if @filter.save
- flash[:notice]='Filter updated'
- if params[:preview]=='true'
- redirect_to :action => 'edit', :id => @filter.id
- else
- redirect_to :action => 'manage', :id => @filter.id
- end
- else
- render :action => 'new', :id => @filter.id
- end
- end
-
- def delete
- @filter=::Filter.find(params[:id])
- access_denied unless @filter.authorized_to_edit?(self)
-
- if @filter
- if WidgetProperty.find(:first, :conditions => {:kee => 'filter', :text_value => @filter.kee})
- @filter.destroy
- flash[:warning]='Filter deleted. It was used in at least one dashboard'
- else
- @filter.destroy
- flash[:notice]='Filter deleted'
- end
- end
-
- redirect_to :action => 'manage'
- end
-
- #---------------------------------------------------------------------
- #
- # COLUMNS
- #
- #---------------------------------------------------------------------
- def delete_column
- column=FilterColumn.find(params[:id])
- filter=column.filter
-
- access_denied unless filter.authorized_to_edit?(self)
-
- if column.deletable?
- column.destroy
- redirect_to :action => 'edit', :id => filter.id
- else
- flash[:error]='Unknown column'
- redirect_to :action => 'manage'
- end
- end
-
- def add_column
- filter=::Filter.find(params[:id])
- access_denied unless filter.authorized_to_edit?(self)
- filter.clean_columns_order() # clean the columns which are badly ordered (see SONAR-1902)
-
- fields=params[:column].split(',')
- family=fields[0]
- if family=='metric'
- filter.columns.create(:family => fields[0], :kee => Metric.by_id(fields[1]).name, :order_index => filter.columns.size + 1, :variation => params[:column_type]=='variation')
- elsif family.present?
- filter.columns.create(:family => family, :order_index => filter.columns.size + 1)
- end
- redirect_to :action => 'edit', :id => filter.id
- end
-
- def left_column
- column=FilterColumn.find(params[:id])
- filter=column.filter
-
- access_denied unless filter.authorized_to_edit?(self)
-
- filter.clean_columns_order() # clean the columns which are badly ordered (see SONAR-1902)
- target_column=filter.column_by_id(params[:id].to_i)
- if target_column.order_index>1
- target_column.order_index-=1
- target_column.save
- old_left_col=filter.columns[target_column.order_index-1]
- old_left_col.order_index+=1
- old_left_col.save
- end
- redirect_to :action => 'edit', :id => filter.id
- end
-
- def right_column
- column=FilterColumn.find(params[:id])
- filter=column.filter
-
- access_denied unless filter.authorized_to_edit?(self)
-
- filter.clean_columns_order() # clean the columns which are badly ordered (see SONAR-1902)
- target_column=filter.column_by_id(params[:id].to_i)
- if target_column.order_index>=1 && target_column.order_index<filter.columns.size
- target_column.order_index+=1
- target_column.save
- old_right_col=filter.columns[target_column.order_index-1]
- old_right_col.order_index-=1
- old_right_col.save
- end
- redirect_to :action => 'edit', :id => filter.id
- end
-
- def set_sorted_column
- column=FilterColumn.find(params[:id])
- filter=column.filter
-
- access_denied unless filter.authorized_to_edit?(self)
-
- filter.columns.each do |col|
- if col==column
- col.sort_direction=params[:sort]
- else
- col.sort_direction=nil
- end
- col.save!
- end
- redirect_to :action => 'edit', :id => filter.id
- end
-
-
- #---------------------------------------------------------------------
- #
- # CUSTOMIZE DISPLAY
- #
- #---------------------------------------------------------------------
- def set_view
- filter=::Filter.find(params[:id])
- access_denied unless filter.authorized_to_edit?(self)
-
- filter.default_view=params[:view]
- filter.save
- redirect_to :action => :edit, :id => filter.id
- end
-
- def set_columns
- filter=::Filter.find(params[:id])
- access_denied unless filter.authorized_to_edit?(self)
-
- filter.columns.clear
- params[:columns].each do |colstring|
- column=::FilterColumn.create_from_string(colstring)
- filter.columns<<column if column
- end
- filter.save
- redirect_to :action => :edit, :id => filter.id
- end
-
- def set_page_size
- filter=::Filter.find(params[:id])
- access_denied unless filter.authorized_to_edit?(self)
-
- size=[::Filter::MAX_PAGE_SIZE, params[:size].to_i].min
- size=[::Filter::MIN_PAGE_SIZE, size].max
- filter.page_size=size
- filter.save
- redirect_to :action => :edit, :id => filter.id
- end
-
- #---------------------------------------------------------------------
- #
- # RESOURCE EXPLORER (POPUP)
- #
- #---------------------------------------------------------------------
- def search_path
- if params[:search].present?
- if params[:search].size<3
- flash[:warning]='Please type at least 3 characters'
- redirect_to :action => :search_path
-
- else
- snapshots=Snapshot.find(:all, :include => [:project, {:root_snapshot => :project}, {:parent_snapshot => :project}],
- :conditions => ['snapshots.status=? AND snapshots.islast=? AND snapshots.scope=? AND projects.person_id IS NULL AND projects.scope=? AND UPPER(projects.long_name) LIKE ?', 'P', true, 'PRJ', 'PRJ', "%#{params[:search].upcase}%"])
- snapshots=select_authorized(:user, snapshots)
-
- @snapshots_by_qualifier = {}
- snapshots.each do |snapshot|
- @snapshots_by_qualifier[snapshot.qualifier]||=[]
- @snapshots_by_qualifier[snapshot.qualifier]<<snapshot
- end
- end
- end
- params[:layout]='false'
- end
-
-
- #---------------------------------------------------------------------
- #
- # TREEMAP
- #
- #---------------------------------------------------------------------
- def treemap
- @filter=::Filter.find(params[:id])
- access_denied unless @filter.authorized_to_execute?(self)
-
- @size_metric=Metric.by_key(params[:size_metric])
- @color_metric=Metric.by_key(params[:color_metric])
- params[:metric_ids]=[@size_metric, @color_metric]
-
- @filter_context=Filters.execute(@filter, self, params)
-
- @width=(params[:width]||'800').to_i
- @height=(params[:height]||'500').to_i
-
- @treemap = Sonar::Treemap.new(@filter.id, @size_metric, @width, @height, {
- :color_metric => @color_metric,
- :period_index => @filter_context.period_index,
- :measures_by_snapshot => @filter_context.measures_by_snapshot
- })
-
- render :action => "treemap", :layout => false
- end
-
-
- #---------------------------------------------------------------------
- #
- # PRIVATE METHODS
- #
- #---------------------------------------------------------------------
-
- private
-
- def load_filter_from_params(filter, params)
- filter.name=params[:name]
- filter.shared=(params[:shared].present? && is_admin?)
- filter.favourites=params[:favourites].present?
- filter.resource_id=(params[:path_id].present? ? Project.by_key(params[:path_id]).id : nil)
- filter.period_index=params[:period_index].to_i
- filter.criteria=[]
- filter.criteria<<Criterion.new_for_qualifiers(params['qualifiers'])
- filter.criteria<<Criterion.new(:family => 'date', :operator => params['date_operator'], :value => params['date_value']) if params['date_operator'].present?
- filter.criteria<<Criterion.new(:family => 'key', :operator => '=', :text_value => params['key_regexp']) if params['key_regexp'].present?
- filter.criteria<<Criterion.new(:family => 'name', :operator => '=', :text_value => params['name_regexp']) if params['name_regexp'].present?
- filter.criteria<<Criterion.new(:family => 'language', :operator => '=', :text_value => params['languages'].join(',')) if params['languages']
- filter.criteria<<Criterion.new(:family => 'direct-children', :operator => '=', :text_value => 'true') if params['direct-children'].present?
-
- if params[:criteria]
- if params[:criteria]['0']['metric_id'].present?
- filter.criteria<<Criterion.new_for_metric(params[:criteria]['0'])
- end
- if params[:criteria]['1']['metric_id'].present?
- filter.criteria<<Criterion.new_for_metric(params[:criteria]['1'])
- end
- if params[:criteria]['2']['metric_id'].present?
- filter.criteria<<Criterion.new_for_metric(params[:criteria]['2'])
- end
- end
- end
-end
text_field_tag key, value, {:size => 25}.update(html_options)
elsif type==PropertyType::TYPE_FILTER
- user_filters = options_key(value, ::Filter.find(:all, :conditions => ['user_id=?', current_user.id]).sort_by(&:id))
- shared_filters = options_key(value, ::Filter.find(:all, :conditions => ['(user_id<>? or user_id is null) and shared=?', current_user.id, true]).sort_by(&:id))
+ user_filters = options_id(value, current_user.measure_filters)
+ shared_filters = options_id(value, MeasureFilter.find(:all, :conditions => ['(user_id<>? or user_id is null) and shared=?', current_user.id, true]).sort_by(&:name))
filters_combo = select_tag key, option_group('My Filters', user_filters) + option_group('Shared Filters', shared_filters), html_options
- filter_link = link_to message('widget.filter.edit'), {:controller => :filters, :action => :manage}, :class => 'link-action'
+ filter_link = link_to message('widget.filter.edit'), {:controller => 'measures', :action => 'manage'}, :class => 'link-action'
"#{filters_combo} #{filter_link}"
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 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
-#
-class Criterion < ActiveRecord::Base
- set_table_name 'criteria'
-
- validates_inclusion_of :operator, :in => ['<','>', '=', '<=', '>='], :if => :on_metric?, :message => 'Select an operator'
- validates_presence_of :kee, :if => :on_metric?
- validates_numericality_of :value, :if => :on_metric?, :message => 'Value must be a number'
-
- validates_inclusion_of :operator, :in => ['='], :if => :on_qualifier?
-
- validates_inclusion_of :operator, :in => ['='], :if => :on_language?
-
- validates_inclusion_of :operator, :in => ['<','>='], :if => :on_date?
- validates_numericality_of :value, :allow_nil => false, :only_integer => true, :greater_than_or_equal_to => 1, :if => :on_date?
-
- validates_presence_of :text_value, :if => :on_key?
- validates_presence_of :text_value, :if => :on_name?
-
- belongs_to :filter
-
- def key
- kee
- end
-
- def on_metric?
- family=='metric'
- end
-
- def metric
- Metric.by_key(kee)
- end
-
- def on_name?
- family=='name'
- end
-
- def on_key?
- family=='key'
- end
-
- def on_qualifier?
- family=='qualifier'
- end
-
- def on_language?
- family=='language'
- end
-
- def on_date?
- family=='date'
- end
-
- def text_values
- text_value ? text_value.split(',') : []
- end
-
- def self.new_for_qualifiers(values)
- values=[] if values.nil?
- new(:family => 'qualifier', :operator => '=', :text_value => values.join(','))
- end
-
- def self.new_for_metric(options)
- metric=Metric.by_id(options['metric_id'])
- new(:family => 'metric', :operator => options['operator'], :kee => (metric ? metric.name : nil), :value => options['value'], :variation => (options['type']=='variation'))
- end
-
-end
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 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
-#
-class Filter < ActiveRecord::Base
- VIEW_LIST='list'
- VIEW_TREEMAP='treemap'
- TREEMAP_PAGE_SIZE=200
- DEFAULT_PAGE_SIZE=50
- MAX_PAGE_SIZE=200
- MIN_PAGE_SIZE=5
-
- belongs_to :user
- belongs_to :resource, :class_name => 'Project', :foreign_key => 'resource_id'
- has_many :columns, :class_name => 'FilterColumn', :dependent => :destroy, :validate => true, :order => 'order_index'
- has_many :criteria, :class_name => 'Criterion', :dependent => :destroy, :validate => true
-
- validates_length_of :name, :within => 1..100
- validates_uniqueness_of :name, :scope => :user_id, :if => Proc.new { |filter| filter.user_id }
- validates_inclusion_of :default_view, :in => ['list', 'treemap'], :allow_nil => true
- validates_uniqueness_of :kee
-
- def criterion(family, key=nil)
- criteria.each do |criterion|
- if criterion.family==family && criterion.key==key
- return criterion if ((key.nil? && criterion.key.nil?) || (key && key==criterion.key))
- end
- end
- nil
- end
-
- def key
- kee
- end
-
- def measure_criteria
- @measure_criteria ||=
- begin
- criteria.select { |c| c.on_metric? && c.metric }
- end
- end
-
- def first_column
- columns.size>0 ? columns[0] : nil
- end
-
- def last_column
- columns.size>0 ? columns[-1] : nil
- end
-
- def column(family, key=nil)
- columns.each do |col|
- if col.family==family
- return col if ((key.nil? && col.key.nil?) || (key && key==col.key))
- end
- end
- nil
- end
-
- def measure_columns
- columns.select { |col| col.metric }
- end
-
- def sorted_column
- @sorted_column ||=
- begin
- default_view==VIEW_TREEMAP ? nil : (columns.to_a.find { |c| c.sort_direction }||column('name') )
- end
- end
-
- def sorted_column=(col_or_id)
- if col_or_id.is_a?(Fixnum)
- @sorted_column=columns.to_a.find { |c| c.id==col_or_id }
- else
- @sorted_column=col_or_id
- end
- end
-
- def display_links?
- column('links')
- end
-
- def default_view
- read_attribute(:default_view) || VIEW_LIST
- end
-
- def page_size
- if default_view==VIEW_TREEMAP
- TREEMAP_PAGE_SIZE
- else
- read_attribute(:page_size) || DEFAULT_PAGE_SIZE
- end
- end
-
- def ajax_loading?
- default_view==VIEW_TREEMAP
- end
-
- def projects_homepage?
- name=='Projects'
- end
-
- def advanced_search?
- @advanced_search ||=
- begin
- !(criterion('language').nil?) || favourites || !(criterion('name').nil?) || !(criterion('key').nil?) || !(criterion('date').nil?) || period?
- end
- end
-
- def period_index=(vi)
- if vi && vi>0
- write_attribute(:period_index, vi)
- else
- write_attribute(:period_index, nil)
- end
- end
-
- def period?
- period_index && period_index>0
- end
-
- def column_by_id(col_id)
- columns.each do |col|
- return col if col.id==col_id
- end
- nil
- end
-
- def clean_columns_order
- columns.each_with_index do |col, index|
- col.order_index=index+1
- col.save
- end
- reload
- end
-
- def authorized_to_execute?(authenticated_system)
- shared || (user==authenticated_system.current_user)
- end
-
- def authorized_to_edit?(authenticated_system)
- if authenticated_system.logged_in?
- (user && user==authenticated_system.current_user) || (!user && authenticated_system.is_admin?)
- else
- false
- end
- end
-
- def display_direct_children_option?
- resource_id != nil
- end
-
- def on_direct_children?
- if resource_id
- c = criterion('direct-children')
- c ? c.text_value=='true' : false
- else
- false
- end
- end
-
- def display_path_data?
- # accepted limitation. Should be configurable in the section "Display"
- on_direct_children?
- end
-
- protected
-
- def before_validation
- # the name column is mandatory
- if self.column('name').nil?
- self.columns.insert(0, FilterColumn.new(:family => 'name'))
- end
-
- # one column must be sorted
- sorted_col=self.columns.to_a.find { |c| c.sort_direction }
- unless sorted_col
- column('name').sort_direction='ASC'
- end
-
- # sanitize orders
- self.columns.each_with_index do |col, index|
- col.order_index=index+1
- end
- true
- end
-
- def after_save
- self.columns.each do |col|
- col.save
- end
- end
-
-end
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 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
-#
-class FilterColumn < ActiveRecord::Base
-
- FAMILIES=['date','language','name','links','version','key','metric']
-
- belongs_to :filter
- validates_inclusion_of :sort_direction, :in => %w( ASC DESC ), :allow_nil => true
-
- def self.create_from_string(string)
- if FAMILIES.include?(string)
- FilterColumn.new(:family => string)
- else
- metric=Metric.by_key(string)
- metric ? FilterColumn.new(:family => 'metric', :kee => metric.key) : nil
- end
- end
-
- def key
- kee
- end
-
- def name
- if on_metric?
- Api::Utils.message("metric.#{kee}.name", :default => (metric ? metric.short_name : kee))
- else
- Api::Utils.message("filters.col.#{family}", :default => kee)
- end
- end
-
- def display_name
- name
- end
-
- def metric
- @metric ||=
- begin
- on_metric? ? Metric.by_key(kee) : nil
- end
- end
-
- def on_language?
- family=='language'
- end
-
- def on_version?
- family=='version'
- end
-
- def on_name?
- family=='name'
- end
-
- def on_date?
- family=='date'
- end
-
- def on_links?
- family=='links'
- end
-
- def on_metric?
- family=='metric'
- end
-
- def on_profile?
- family=='profile'
- end
-
- def on_key?
- family=='key'
- end
-
- def deletable?
- !on_name?
- end
-
- def sorted?
- sort_direction=='ASC' || sort_direction=='DESC'
- end
-
- def ascending?
- sort_direction=='ASC'
- end
-
- def ascending2?
- sort_direction=='ASC'
- end
-
- def descending?
- sort_direction=='DESC'
- end
-
- def ascending=(asc)
- write_attribute(:sort_direction, (asc ? 'ASC' : 'DESC'))
- end
-
- def sortable?
- !on_links?
- end
-
- def small_width?
- on_metric? && metric && (metric.val_type==Metric::VALUE_TYPE_LEVEL || metric.val_type==Metric::VALUE_TYPE_BOOLEAN)
- end
-end
+++ /dev/null
- #
- # Sonar, entreprise quality control tool.
- # Copyright (C) 2008-2012 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 {library}; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- #
- class FilterContext
- attr_accessor :filter, :page_size, :page_id, :security_exclusions, :period_index, :sorted_column_id, :ascending_sort
-
- def initialize(filter, options={})
- @filter = filter
- @page_size=options[:page_size] || @filter.page_size
- @page_id=(options[:page_id] ? options[:page_id].to_i : 1)
- @sorted_column_id=(options[:sort].blank? ? nil : options[:sort].to_i)
- @ascending_sort=(options[:asc].blank? ? nil : options[:asc]=='true')
- @period_index = (options[:period] ? options[:period].to_i : @filter.period_index )
- @metric_ids=(options[:metric_ids] || @filter.columns.map{|col| col.metric ? col.metric.id : nil}.compact.uniq)
- end
-
- def process_results(snapshot_ids, security_exclusions)
- @sids=snapshot_ids
- @security_exclusions=security_exclusions
-
- from=(@page_id-1) * @page_size
- to=(@page_id*@page_size)-1
- to=@sids.size-1 if to>=@sids.size
-
- @measures_by_snapshot={}
- @page_snapshots=[]
- @snapshots_by_id={}
- @links_by_pid={}
- if from<@sids.size
- #
- # load snapshots and resources
- #
- @page_sids=@sids[from..to]
- @page_snapshots=Snapshot.find(:all, :include => ['project'], :conditions => ['id in (?)', @page_sids])
- @page_snapshots.each{|s| @snapshots_by_id[s.id]=s}
-
- if @page_sids.size>0
- #
- # load measures
- #
- if @metric_ids.size>0
- measures=ProjectMeasure.find(:all, :conditions => ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id in (?) and metric_id in (?)', @page_sids, @metric_ids])
-
- measures.each do |m|
- snapshot=@snapshots_by_id[m.snapshot_id]
- @measures_by_snapshot[snapshot]||={}
- @measures_by_snapshot[snapshot][m.metric]=m
- end
- end
-
- #
- # load links
- #
- if @filter.display_links?
- pids=@page_snapshots.map{|snapshot| snapshot.project_id}
- ProjectLink.find(:all, :conditions => {:project_id => pids}, :order => 'link_type').each do |link|
- @links_by_pid[link.project_id] ||= []
- @links_by_pid[link.project_id]<<link
- end
- end
- end
- end
- self
- end
-
-
- def size
- @sids.size
- end
-
- def empty?
- @page_sids.nil? || @page_sids.empty?
- end
-
- def page_count
- result=@sids.size / @page_size
- result+=1 if (@sids.size % @page_size > 0)
- result
- end
-
- def page_sorted_snapshot_ids
- @page_sids
- end
-
- def snapshots
- @page_snapshots
- end
-
- def snapshot(sid)
- @snapshots_by_id[sid]
- end
-
- def measure(snapshot, metric)
- if metric
- hash=@measures_by_snapshot[snapshot]
- hash ? hash[metric] : nil
- else
- nil
- end
- end
-
- def measures_by_snapshot
- @measures_by_snapshot
- end
-
- def links(resource_id)
- @links_by_pid[resource_id] || []
- end
-
- def security_exclusions?
- @security_exclusions==true
- end
-
- def selected_period?
- @period_index && @period_index>0
- end
-
-
-
- private
-
- def extract_snapshot_ids(filter_rows)
- sids=[]
- project_ids=filter_rows.map{|row| row.getResourceRootId()}.compact.uniq
- authorized_pids=select_authorized(:user, project_ids)
- filter_rows.each do |row|
- if authorized_pids.include?(row.getResourceRootId())
- sids<<row.getSnapshotId()
- end
- end
- sids
- end
- end
\ No newline at end of file
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 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
-#
-class Filters
-
- def self.execute(filter, authenticated_system, options={})
- filter_context = FilterContext.new(filter, options)
-
- filter_json={}
-
- #----- FILTER ON RESOURCES
- if filter.resource_id
- filter_json[:base]=filter.resource.key
- end
-
- if filter.favourites
- filter_json[:favourites]=true
- end
-
- date_criterion=filter.criterion('date')
- if date_criterion
- if date_criterion.operator=='<'
- filter_json[:beforeDays]=date_criterion.value.to_i
- else
- filter_json[:afterDays]=date_criterion.value.to_i
- end
- end
-
- key_criterion=filter.criterion('key')
- if key_criterion
- filter_json[:keyRegexp]=key_criterion.text_value
- end
-
- name_criterion=filter.criterion('name')
- if name_criterion
- filter_json[:name]=name_criterion.text_value
- end
-
- qualifier_criterion=filter.criterion('qualifier')
- if qualifier_criterion
- filter_json[:qualifiers]=qualifier_criterion.text_values
- end
-
- filter_json[:onBaseChildren]=filter.on_direct_children?
-
- language_criterion=filter.criterion('language')
- if language_criterion
- filter_json[:languages]=language_criterion.text_values
- end
-
-
- #----- FILTER ON MEASURES
- filter_json[:conditions]=filter.measure_criteria.map do |c|
- hash = {:metric => c.metric.key, :op => c.operator, :val => c.value}
- if c.variation
- hash[:period] = filter_context.period_index || -1
- end
- hash
- end
-
-
- #----- SORTED COLUMN
- if filter_context.sorted_column_id
- filter.sorted_column=filter_context.sorted_column_id
- end
- if filter.sorted_column
- filter_json[:sortField]=filter.sorted_column.family.upcase
- if filter.sorted_column.on_metric? && filter.sorted_column.metric
- filter_json[:sortMetric]=filter.sorted_column.metric.key
- if filter.sorted_column.variation
- filter_json[:sortPeriod]=filter_context.period_index || -1
- end
- end
- end
-
-
- #----- SORTING DIRECTION
- if filter.sorted_column
- if filter_context.ascending_sort.nil?
- filter_json[:sortAsc]=filter.sorted_column.ascending?
- else
- filter.sorted_column.ascending=filter_context.ascending_sort
- filter_json[:sortAsc]=filter.sorted_column.ascending?
- end
-
- if filter_context.ascending_sort
- filter.sorted_column.ascending=filter_context.ascending_sort
- end
- filter_json[:sortAsc]=filter.sorted_column.ascending?
- end
-
- #----- EXECUTION
- user=authenticated_system.current_user
- rows=Api::Utils.java_facade.executeMeasureFilter(filter_json.to_json, user ? user.id : nil)
- snapshot_ids=extract_snapshot_ids(rows, authenticated_system)
-
- has_security_exclusions=(snapshot_ids.size < rows.size)
- filter_context.process_results(snapshot_ids, has_security_exclusions)
- filter_context
- end
-
- private
-
- def self.extract_snapshot_ids(rows, authenticated_system)
- sids=[]
- project_ids=rows.map { |row| row.getResourceRootId() }.compact.uniq
- authorized_pids=authenticated_system.select_authorized(:user, project_ids)
- rows.each do |row|
- if authorized_pids.include?(row.getResourceRootId())
- sids<<row.getSnapshotId()
- end
- end
- sids
- end
-end
\ No newline at end of file
def set_criteria_value(key, value)
@criteria ||= {}
if key
- if value && !value.empty? && value!=['']
+ if value && value!='' && value!=['']
+ value = value.to_s if value.is_a?(Fixnum)
@criteria[key.to_s]=value
else
@criteria.delete(key)
init_results
init_display(options)
user = options[:user]
- rows=Api::Utils.java_facade.executeMeasureFilter2(criteria, (user ? user.id : nil))
+ rows=Api::Utils.java_facade.executeMeasureFilter(criteria, (user ? user.id : nil))
snapshot_ids = filter_authorized_snapshot_ids(rows, controller)
load_results(snapshot_ids)
self
end
-
private
def init_results
KEY = :treemap
- attr_reader :height, :id, :size, :size_metric, :color_metric
+ attr_reader :id, :size, :size_metric, :color_metric
def initialize(filter, options)
super(filter, options)
@color_metric = Metric.by_key(@filter.criteria('tmColor'))
@html_id = options[:html_id]
@filter.metrics=([@size_metric, @color_metric].compact)
- @height = (@filter.criteria('tmHeight')||'600').to_i
@id_count = 0
filter.set_criteria_value('sort', "metric:#{@size_metric.key}") if @size_metric
output = Sonar::HtmlOutput.new do |o|
# width in percents
o.width = 100
- o.height = @height
+ o.height = 100
o.full_html = false
o.details_at_depth = 1
end
html = ''
html += "<div style=\""
html += "overflow:hidden;position:absolute;"
- html += "left:#{node.bounds.x1}%; top:#{node.bounds.y1}px;"
- html += "width:#{node.bounds.width}%;height: #{node.bounds.height}px;"
+ html += "left:#{node.bounds.x1}%; top:#{node.bounds.y1}%;"
+ html += "width:#{node.bounds.width}%;height: #{node.bounds.height}%;"
html += "background-color:#FFF;\">"
- html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: #{node.bounds.height-4}px;
+ html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: 100%;
border: 1px solid #{node.color};' alt=\"#{node.tooltip}\" title=\"#{node.tooltip}\""
if node.leaf
html += "l=1 "
+++ /dev/null
-<script>
- function reset_criterion(id) {
- Form.Element.clear('metric-' + id);
- Form.Element.clear('op-' + id);
- Form.Element.clear('val-' + id);
- Form.Element.clear('type-' + id);
- }
-</script>
-<select name="criteria[<%= id -%>][metric_id]" id="metric-<%= id -%>">
- <option value=""><%= message('select_a_metric') -%></option>
- <% Metric.domains.each do |domain| %>
- <optgroup label="<%= h domain -%>">
- <% Metric.by_domain(domain).select{|m| !m.data? && !m.hidden?}.each do |metric| %>
- <option value="<%= metric.id -%>" <%= 'selected' if (criterion && criterion.metric==metric) -%>><%= metric.short_name %></option>
- <% end %>
- </optgroup>
- <% end %>
-</select>
-<select name="criteria[<%= id -%>][type]" id="type-<%= id -%>">
- <option value="value" <%= 'selected' unless (criterion && criterion.variation) -%>><%= message('value') -%></option>
- <option value="variation" <%= 'selected' if criterion && criterion.variation -%>><%= message('variation') -%></option>
-</select>
-<select name="criteria[<%= id -%>][operator]" id="op-<%= id -%>">
- <option value=""></option>
- <option value="<" <%= 'selected' if (criterion && criterion.operator=='<') -%>><%= message('less_than') -%></option>
- <option value="<=" <%= 'selected' if (criterion && criterion.operator=='<=') -%>><%= message('less_or_equals') -%></option>
- <option value="=" <%= 'selected' if (criterion && criterion.operator=='=') -%>><%= message('equals') -%></option>
- <option value=">" <%= 'selected' if (criterion && criterion.operator=='>') -%>><%= message('greater_than') -%></option>
- <option value=">=" <%= 'selected' if (criterion && criterion.operator=='>=') -%>><%= message('greater_or_equals') -%></option>
-</select>
-<input type="text" name="criteria[<%= id -%>][value]" size="5" value="<%= criterion.value if criterion -%>" id="val-<%= id -%>"/>
-<a href="#" onClick="reset_criterion(<%= id -%>);return false;"><%= message('reset_verb') -%></a>
\ No newline at end of file
+++ /dev/null
-<tr>
- <td class="keyCell">
- <%= message('filters.add_column') -%>:
- </td>
- <td>
- <form id="add_column_form" action="<%= url_for :action => 'add_column', :id => @filter.id -%>" method="post">
- <select name="column_type" id="select_column_type">
- <option value="value" selected><%= message('value') -%></option>
- <option value="variation"><%= message('variation') -%></option>
- </select>
-
- <select name="column" id="select_column">
- <option value="" selected></option>
- <% Metric.domains(false).each do |domain| %>
- <optgroup label="<%= Metric.domain_for(domain) -%>">
- <% Metric.by_domain(domain, false).each do |metric| %>
- <% if metric.display? %><option value="metric,<%= metric.id -%>"><%= metric.short_name -%></option><% end %>
- <% end %>
- <% if domain=='General' %>
- <% unless @filter.column('date') %><option value="date"><%= message('build_date') -%></option><% end %>
- <% unless @filter.column('key') %><option value="key"><%= message('key') -%></option><% end %>
- <% unless @filter.column('language') %><option value="language"><%= message('language') -%></option><% end %>
- <% unless @filter.column('links') %><option value="links"><%= message('links') -%></option><% end %>
- <% unless @filter.column('name') %><option value="name"><%= message('name') -%></option><% end %>
- <% unless @filter.column('version') %><option value="version"><%= message('version') -%></option><% end %>
- <% end %>
- </optgroup>
- <% end %>
- </select>
- <input type="submit" id="add_column_button" value="<%= message('add_verb') -%>"/>
- </form>
- </td>
-</tr>
-<tr>
- <td class="keyCell"><%= message('filters.default_sorted_column') -%>:</td>
- <td>
- <form id="sorted_column_form" action="<%= url_for :action => 'set_sorted_column' -%>" method="post">
- <select name="id">
- <%
- default_sorted_column=@filter.sorted_column
- @filter.columns.each do |column|
- %>
- <option value="<%= column.id -%>" <%= 'selected' if column==default_sorted_column -%>><%= 'Variation of ' if column.variation -%><%= column.name -%></option>
- <% end %>
- </select>
- <select name="sort">
- <option value="ASC" <%= 'selected' if default_sorted_column && default_sorted_column.ascending? -%>><%= message('ascending') -%></option>
- <option value="DESC" <%= 'selected' if default_sorted_column && default_sorted_column.descending? -%>><%= message('descending') -%></option>
- </select>
- <input type="submit" id="add_column_submit" value="<%= message('change_verb') -%>" />
- </form>
- </td>
-</tr>
-<tr>
- <td class="keyCell"><%= message('page_size') -%>:</td>
- <td>
- <form id="page_size_form" action="<%= url_for :action => 'set_page_size' -%>" method="post">
- <input type="hidden" name="id" value="<%= @filter.id -%>"/>
- <input type="text" name="size" value="<%= @filter.page_size -%>" maxsize="3" size="3"/>
- <input type="submit" id="set_page_size_submit" value="<%= message('change_verb') -%>"/>
- <span class="comments"><%= message('min') -%> <%= ::Filter::MIN_PAGE_SIZE -%>, <%= message('max').downcase -%> <%= ::Filter::MAX_PAGE_SIZE -%></span>
- </td>
-</tr>
\ No newline at end of file
+++ /dev/null
-<%
- metrics=treemap_metrics(@filter)
- size_metric=metrics[0]
- color_metric=metrics[1]
-%>
-<form class="admin" action="<%= url_for :action => 'set_columns', :id => @filter.id -%>" method="POST">
- <tr>
- <td class="keyCell"><%= message('size') -%>:</td>
- <td>
- <%= select_tag 'columns[]', options_grouped_by_domain(Sonar::Treemap.size_metrics(), size_metric.key),
- :id => 'size_metric' %>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('color') -%>:</td>
- <td>
- <%= select_tag 'columns[]', options_grouped_by_domain(Sonar::Treemap.color_metrics, color_metric.key),
- :id => 'color_metric' %>
- </td>
- </tr>
- <tr>
- <td class="keyCell"> </td>
- <td>
- <input type="submit" value="<%= message('change_verb') -%>">
- </td>
- </tr>
-</form>
\ No newline at end of file
+++ /dev/null
-<% filter=@filter_context.filter %>
-<% @edit_mode=edit_mode %>
-
-<% unless defined? update_id %>
- <% if defined? widget %>
- <% update_id=widget.id %>
- <% else %>
- <% end %>
-<% end %>
-
-<div id="filter-<%= update_id -%>">
-<table class="data nowrap width100" id="results">
- <thead id="results-head">
- <tr>
- <th width="1%"></th>
- <% filter.columns.each do |column| %>
- <th <%= 'width=1% nowrap' if column.small_width? -%> class="<%= column_align(column) -%>">
- <%= column_title(column, filter, update_id) %>
- </th>
- <% end %>
- </tr>
- <% if edit_mode %>
- <tr class="admin"><th></th>
- <% filter.columns.each do |column| %>
- <th nowrap class="<%= column_align(column) -%>">
- <%= link_to image_tag("controls/resultset_previous.png"), {:action => 'left_column', :id => column.id}, :title => message('move_left'), :method => :post if filter.first_column!=column %>
- <%= link_to image_tag("bin_closed.png"), {:action => 'delete_column', :id => column.id}, :title => message('remove_column'), :method => :post if column.deletable? %>
- <%= link_to image_tag("controls/resultset_next.png"), {:action => 'right_column', :id => column.id}, :title => message('move_right'), :method => :post if filter.last_column!=column %>
- </th>
- <% end %>
- </tr>
- <% end %>
- </thead>
-
- <tfoot>
- <tr>
- <td colspan="<%= filter.columns.size + 1 -%>">
- <div id="filter-pages-<%= update_id -%>">
- <span id="results_count"><%= message('x_results', :params => [@filter_context.size]) -%></span>
-
- <%
- if @filter_context.page_count>1
- max_pages = @filter_context.page_count
- current_page = @filter_context.page_id
- start_page = 1
- end_page = max_pages
- if max_pages > 20
- if current_page < 12
- start_page = 1
- end_page = 20
- elsif current_page > max_pages-10
- start_page = max_pages-20
- end_page = max_pages
- else
- start_page = current_page-10
- end_page = current_page+9
- end
- end
- %>
- |
- <% if max_pages > 20 && start_page > 1 %>
- <%= goto_page message('paging_first'), filter, update_id, :page_id => 1 %>
- <% end %>
-
- <% if current_page>start_page %>
- <%= goto_page message('paging_previous'), filter, update_id, :page_id => current_page-1 %>
- <% else %>
- <%= message('paging_previous') -%>
- <% end %>
-
- <% for index in start_page..end_page %>
- <% if index==current_page %>
- <%= index.to_s -%>
- <% else %>
- <%= goto_page index.to_s, filter, update_id, :page_id => index %>
- <% end %>
- <% end %>
-
- <% if current_page<end_page %>
- <%= goto_page message('paging_next'), filter, update_id, :page_id => current_page+1 %>
- <% else %>
- <%= message('paging_next') -%>
- <% end %>
-
- <% if max_pages > 20 && end_page < max_pages %>
- <%= goto_page message('paging_last'), filter, update_id, :page_id => max_pages %>
- <% end %>
- <% end %>
-
- <% if @filter.projects_homepage? %>
- <a href="<%= url_for :controller => :feeds, :action => 'projects', :id => EventCategory::KEY_ALERT -%>" class="nolink"><%= image_tag 'rss-12x12.png' %></a>
- <a href="<%= url_for :controller => :feeds, :action => 'projects', :id => EventCategory::KEY_ALERT -%>" class="action"><%= message('alerts_feed') -%></a>
- <% end %>
- </div>
- <div id="filter-loading-<%= update_id -%>" style="display: none"><%= image_tag 'loading.gif' %></div>
-
- </td>
- </tr>
- </tfoot>
-
- <tbody>
- <%
- if @filter_context.filter.display_path_data?
- root_snapshot = Snapshot.find(:first, :include => 'project', :conditions => ['projects.id=? and islast=?', @filter_context.filter.resource_id, true])
- if root_snapshot && has_role?(:user, root_snapshot)
- %>
- <tr class="highlight">
- <td><% if logged_in? %><%= link_to_favourite(root_snapshot.project) -%><% end %></td>
- <% filter.columns.each do |column| %>
- <td class="<%= column_align(column) -%>">
- <% if column.on_metric?
- measure=root_snapshot.measure(column.metric)
- %>
- <% if column.variation %>
- <%= format_variation(measure, :index => @filter_context.period_index, :style => 'light') -%>
- <% else %>
- <%= format_measure(measure) -%>
- <% if @filter_context.selected_period? %>
- <%= format_variation(measure, :index => @filter_context.period_index) -%>
- <% else %>
- <%= trend_icon(measure, :empty => true) -%>
- <% end %>
- <% end %>
- <% elsif column.on_name? %><%= qualifier_icon(root_snapshot) %> <%= link_to_resource(root_snapshot.project, h(root_snapshot.project.name(true)), {:filter => true, :title => root_snapshot.project.key, :period => @filter_context.period_index}) %>
- <% elsif column.on_date? %><%= human_short_date(root_snapshot.created_at) %>
- <% end %>
- </td>
- <% end %>
- </tr>
- <% end
- end
- %>
-
- <% if @filter_context.empty? %>
- <tr class="even"><td colspan="<%= 1+filter.columns.size -%>"><%= message('no_results') -%></td></tr>
- <% else %>
- <%
- @filter_context.page_sorted_snapshot_ids.each do |snapshot_id|
- snapshot=@filter_context.snapshot(snapshot_id)
- %>
- <tr class="<%= cycle('even','odd') -%>">
- <td><% if logged_in? %><%= link_to_favourite(snapshot.project) -%><% end %></td>
- <% filter.columns.each do |column| %>
- <td class="<%= column_align(column) -%>">
- <% if column.on_metric? && column.metric
- measure = @filter_context.measure(snapshot, column.metric)
- %>
- <% if column.variation || column.metric.on_new_code? %>
- <%= format_variation(measure, :index => @filter_context.period_index, :style => 'light') -%>
- <% else %>
- <%= format_measure(measure) -%>
- <% if @filter_context.selected_period? %>
- <%= format_variation(measure, :index => @filter_context.period_index) -%>
- <% else %>
- <%= trend_icon(measure, :empty => true) -%>
- <% end %>
- <% end %>
- <% elsif column.on_name? %>
- <%= qualifier_icon(snapshot) %> <%= link_to_resource(snapshot.project, snapshot.project.name(true), {:filter => true, :title => snapshot.project.key, :period => @filter_context.period_index}) %>
- <% elsif column.on_version? %><%= h snapshot.version %>
- <% elsif column.on_language? %><%= snapshot.project.language %>
- <% elsif column.on_date? %><%= human_short_date(snapshot.created_at) %>
- <% elsif column.on_key? %><span class="small"><%= snapshot.project.kee -%></span>
- <% elsif column.on_links?
- @filter_context.links(snapshot.project_id).select {|link| link.href.start_with?('http')}.each do |link| %>
- <%= link_to(image_tag(link.icon, :alt => link.name), link.href, :class => 'nolink', :popup => true) unless link.custom? %>
- <% end
- end %>
- </td>
- <% end %>
- </tr>
- <% end %>
- <% end %>
- </tbody>
-</table>
-<% if @filter_context.security_exclusions? %>
- <br/>
- <p class="notes"><%= message('results_not_display_due_to_security') -%></p>
-<% end %>
-</div>
+++ /dev/null
-<% if @filter.period? %>
- <%= message('filters.treemap_not_supported_for_period_selection') -%>
-<% else %>
- <% metrics=treemap_metrics(@filter) %>
-
- <%= render :partial => 'treemap/treemap_container', :locals => {
- :treemap_id => (defined? widget) ? widget.id : @filter.id,
- :size_metric => metrics[0],
- :color_metric => metrics[1],
- :height_in_percents => 50.0,
- :context_type => 'filter',
- :context_id => @filter.id
- } -%>
-<% end %>
+++ /dev/null
-<%= render :partial => 'filters/tabs', :locals => {:selected_tab=> @active.filter.id } %>
-<%= render :partial => "filters/customize_#{@filter.default_view}" -%>
\ No newline at end of file
+++ /dev/null
-<div class="line-block">
-<% if logged_in? %>
- <ul style="float: right" class="operations">
- <li>
- <a href="<%= url_for :action => 'new' -%>"><%= message('filters.add_filter') -%></a>
- </li>
- </ul>
-<% end %>
- <h1 class="marginbottom10"><%= message('default_filters.page') -%></h1>
-</div>
-
-<div class="admin_page">
- <table class="data" id="actives">
- <thead>
- <tr>
- <th><%= message('name') -%></th>
- <th><%= message('shared') -%></th>
- <th class="right"><%= message('operations') -%></th>
- </tr>
- </thead>
- <tbody>
- <% if @filters.empty? %>
- <tr class="even">
- <td colspan="3"><%= message('filters.no_filters') -%></td>
- </tr>
- <% else %>
- <% @filters.each do |filter| %>
- <tr id="active-<%= u filter.name -%>" class="<%= cycle('even', 'odd', :name => 'actives') -%>">
- <td>
- <%= filter.name -%>
- </td>
- <td>
- <%= boolean_icon(filter.shared, {:display_false => false}) -%>
- </td>
- <td class="thin nowrap right">
- <% if filter.authorized_to_edit?(self) %>
- <%= link_to message('edit'), {:action => :edit, :id => filter.id}, :id => "edit-#{u filter.name}", :class => 'link-action' %>
-
- <%= link_to message('delete'), {:action => :delete, :id => filter.id}, :method => :post, :confirm => message('filters.do_you_want_to_delete'), :id => "delete-#{u filter.name}", :class => 'link-action link-red' %>
- <% end %>
- </td>
- </tr>
- <% end %>
- <% end %>
- </tbody>
- </table>
-</div>
+++ /dev/null
-<h1><%= message('filters.new') -%></h1>
-
-<div class="admin">
- <form id="filter_form" name="filter_form" action="<%= url_for :action => (@filter.id ? 'update' : 'create'), :id => @filter.id -%>" method="post">
- <input type="hidden" name="preview" value=""/>
- <%= error_messages_for 'filter', :header_message => nil, :class => 'formError', :message => nil %>
- <table class="form">
- <tbody>
- <tr>
- <td class="keyCell"><%= message('name') -%>:</td>
- <td>
- <input type="text" name="name" id="name" value="<%= @filter.name -%>" class="spaced"/>
- <% if is_admin? %>
- <span class="spacer"></span>
- <label for="shared"><%= message('shared') -%>:</label>
- <input type="checkbox" name="shared" id="shared" <%= 'checked' if @filter.shared -%> />
- <% end %>
- </td>
- </tr>
- </tbody>
- <tbody id="simple-form">
- <tr>
- <td class="keyCell"><%= message('path') -%>:</td>
- <td>
- <b><span id="path_name"><%= @filter.resource ? @filter.resource.path_name : params[:path_name] -%></span></b>
- <input type="hidden" name="path_id" id="path_id" value="<%= @filter.resource ? @filter.resource.id : params[:path_id] -%>"/>
- <a onclick="searchPopup(this);return false;" href="<%= url_for :action => :search_path, :search => (@filter.resource ? @filter.resource.name : nil) -%>" id="open-path-popup"><%= message('search_verb') -%></a>
- <a href="#" onClick="resetPath();return false;" id="reset_path_link" style="<%= 'display: none' unless @filter.resource -%>"><%= message('reset_verb') -%></a>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('filters.search_for') -%>:</td>
- <td>
- <div id="direct-children-option" style="<%= 'display: none' unless @filter.display_direct_children_option? -%>">
- <input type="checkbox" name="direct-children" value="true" <%= 'checked' if @filter.on_direct_children? -%> id="direct-children-checkbox" onclick="onDirectChildrenChange()"/>
- <label for="direct-children-checkbox"><%= message('filters.directChildrenCriterion') -%></label>
- </div>
-
- <% qualifiers=(@filter.criterion('qualifier') ? @filter.criterion('qualifier').text_values : []) %>
- <% for desc in controller.java_facade.getResourceTypesForFilter()
- qualifier = desc.getQualifier() %>
- <input type="checkbox" name="qualifiers[]" value="<%= qualifier -%>" <%= 'checked' if qualifiers.include?(qualifier) -%> id="q-<%= qualifier -%>" onclick="onQualifierChange()"/>
- <label for="q-<%= qualifier -%>"><%= message("qualifiers.#{qualifier}") -%></label>
- <span class="spacer"> </span>
- <% end %>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('filters.criteria') -%>:</td>
- <td>
- <%= render :partial => 'filters/criterion', :locals => {:id => '0', :criterion => (@filter.measure_criteria.size>0 ? @filter.measure_criteria[0] : nil)} %>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('and').downcase -%>:</td>
- <td>
- <%= render :partial => 'filters/criterion', :locals => {:id => '1', :criterion => (@filter.measure_criteria.size>1 ? @filter.measure_criteria[1] : nil)} %>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('and').downcase -%>:</td>
- <td>
- <%= render :partial => 'filters/criterion', :locals => {:id => '2', :criterion => (@filter.measure_criteria.size>2 ? @filter.measure_criteria[2] : nil)} %>
- </td>
- </tr>
- <% unless @filter.advanced_search? %>
- <tr id="advanced-search-link">
- <td colspan="2">
- <a href="#" onClick="$('advanced-search').show();$('advanced-search-link').hide();return false;"><%= message('filters.advanced_search') -%></a>
- </td>
- </tr>
- <% end %>
- </tbody>
- <tbody id="advanced-search" style="<%= 'display: none' unless @filter.advanced_search? -%>">
- <tr>
- <td class="keyCell"><%= message('filters.default_period') -%>:</td>
- <td>
- <select id="period_index" name="period_index">
- <option value=""><%= message('none') -%></option>
- <% period_names.each_with_index do |name, index| %>
- <option value="<%= index+1 -%>" <%= 'selected' if @filter.period_index==index+1 -%>><%= name -%></option>
- <% end %>
- </select>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= message('language') -%>:</td>
- <td>
- <% languages=(@filter.criterion('language') ? @filter.criterion('language').text_values : []) %>
- <% controller.java_facade.getLanguages().each do |language| %>
- <input type="checkbox" name="languages[]" value="<%= language.getKey() -%>" <%= 'checked' if languages.include?(language.getKey()) -%> id="lang-<%= language.getKey() -%>"> </input>
- <label for="lang-<%= language.getKey() -%>"><%= language.getName() -%></label>
- <% end %>
- <span class="comments"><%= message('filters.when_no_language_no_filter_apply') -%></span>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><%= image_tag 'star.png' %>
- <label for="favourites"><%= message('filters.favourite_only') -%>:</label></td>
- <td>
- <input type="checkbox" name="favourites" id="favourites" <%= 'checked' if @filter.favourites -%> />
- </td>
- </tr>
- <tr>
- <td class="keyCell"><label for="key_regexp"><%= message('filters.key_like') -%>:</label></td>
- <td>
- <% key_regexp_criterion=@filter.criterion('key') %>
- <input type="text" name="key_regexp" id="key_regexp" value="<%= key_regexp_criterion.text_value if key_regexp_criterion -%>"/>
- <span class="comments"><%= message('filters.use_star_to_match') -%></span>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><label for="name_regexp"><%= message('filters.name_contains') -%>:</label></td>
- <td>
- <% name_regexp_criterion=@filter.criterion('name') %>
- <input type="text" name="name_regexp" id="name_regexp" value="<%= name_regexp_criterion.text_value if name_regexp_criterion -%>"/>
- </td>
- </tr>
- <tr>
- <td class="keyCell"><label for="date"><%= message('filters.build_date') -%>:</label></td>
- <td>
- <% date_criterion = @filter.criterion('date') %>
- <select id="date_operator" name="date_operator">
- <option value=""></option>
- <option value="<" <%= 'selected' if (date_criterion && date_criterion.operator=='<') -%>><%= message('filters.prior_to_last') -%></option>
- <option value=">=" <%= 'selected' if (date_criterion && date_criterion.operator=='>=') -%>><%= message('filters.during_last') -%></option>
- </select>
- <input type="text" name="date_value" id="date_value" size="3" value="<%= date_criterion.value.to_i if date_criterion -%>"/> <%= message('days').downcase -%>
- </td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <td colspan="2">
- <input type="submit" value="<%= message('save_and_preview') -%>" onclick="filter_form.preview.value='true';return true;" id="submit_save_preview"/>
- <span class="spacer"> </span>
- <input type="submit" value="<%= message('save_and_close') -%>" id="submit_save_close"/>
- <span class="spacer"> </span>
- <% if @filter.id
- confirmation_message = message('filters.do_you_want_to_delete')
- %>
- <input name="delete" class="red-button" value="<%= message('delete') -%>" type="button"
- onclick="if (confirm('<%= confirmation_message -%>')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = '<%= url_for :action => 'delete', :id => @filter.id %>';f.submit(); };return false;">
- <span class="spacer"> </span>
- <a href="<%= url_for :action => :manage, :name => @filter.name -%>"><%= message('cancel') -%></a>
- <% else %>
- <a href="<%= url_for :action => :manage -%>"><%= message('cancel') -%></a>
- <% end %>
- </td>
- </tr>
- </tbody>
- </table>
- </form>
-</div>
-<br/>
-
-<% if @filter_context %>
- <h1><%= message('filters.display_form.title') -%></h1>
-
- <div class="admin">
- <table class="form" id="view-form">
- <tr>
- <td class="keyCell"><%= message('filters.display_form.as') -%>:</td>
- <td>
- <form action="<%= url_for :action => :set_view, :id => @filter.id -%>" method="POST">
- <input type="radio" name="view" value="list" <%= 'checked' if @filter.default_view==::Filter::VIEW_LIST -%> id="view-list" onClick="$('view-loading').show();submit();"/>
- <label for="view-list"><%= message('filters.display_form.table') -%></label>
- <span class="spacer"> </span>
- <input type="radio" name="view" value="treemap" <%= 'checked' if @filter.default_view==::Filter::VIEW_TREEMAP -%> id="view-treemap" onClick="$('view-loading').show();submit();"/>
- <label for="view-treemap"><%= message('filters.display_form.treemap') -%></label>
- <span class="spacer"> </span>
- <%= image_tag 'loading.gif', :id => 'view-loading', :style => 'display: none' %>
- </form>
- </td>
- </tr>
- <%= render :partial => "customize_#{@filter.default_view}" %>
- </table>
- </div>
- <br/>
- <%= render :partial => "#{@filter.default_view}", :locals => {:edit_mode => true} %>
-<% end %>
-
-<script>
- function setPath(resourceId, resourceLabel) {
- $('path_id').value = resourceId;
- $('path_name').innerText = resourceLabel;
- $('path_name').textContent = resourceLabel;
- $('reset_path_link').show();
- $('direct-children-option').show();
- return true;
- }
-
- function resetPath() {
- $('path_name').innerText = '';
- $('path_name').innerHTML = '';
- $('path_id').clear();
- $('reset_path_link').hide();
- $('direct-children-checkbox').checked = false;
- $('direct-children-option').hide();
- return true;
- }
-
- function onQualifierChange() {
- $('direct-children-checkbox').checked = false;
- return true;
- }
-
- function onDirectChildrenChange() {
- var formElements = $('filter_form').elements;
- if ($F('direct-children-checkbox') != null) {
- for (var i = 0; i < formElements.length; i++) {
- if (formElements[i].name == 'qualifiers[]') {
- formElements[i].checked = false;
- }
- }
- }
- return true;
- }
-
- function searchPopup(elt, text) {
- newwindow = window.open(elt.href, 'search', 'height=500,width=700,scrollbars=1,resizable=1');
- if (window.focus) {
- newwindow.focus();
- }
- return false;
- }
-
- $('name').focus();
-</script>
+++ /dev/null
-<h1><%= message('search_verb') -%></h1>
-<br/>
-
-<form action="<%= url_for :action => :search_path -%>" method="post" id="search_form">
- <input type="text" name="search" id="search" value="<%= params[:search] -%>"/>
- <input type="submit" value="<%= message('search_verb') -%>" id="search_submit"/><br/>
-
- <p class="note"><%= message('filters.search_by_name') -%></p>
-</form>
-<br/>
-
-<% if @snapshots_by_qualifier %>
- <script>
- function selectPath(pid, label) {
- window.opener.setPath(pid, label);
- window.close();
- }
- </script>
-
- <table id="results" class="data">
- <thead>
- <tr>
- <th width="16"></th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <% if @snapshots_by_qualifier.empty? %>
- <tr class="even">
- <td colspan="3"><%= message('no_results') -%></td>
- </tr>
-
- <% else
- controller.java_facade.getResourceTypes().each do |resource_type|
- snapshots = @snapshots_by_qualifier[resource_type.getQualifier()]
- if snapshots
- snapshots = Api::Utils.insensitive_sort(snapshots) do |snapshot|
- snapshot.project.long_name
- end
- snapshots.each do |snapshot|
- %>
- <tr class="<%= cycle('even', 'odd') -%>">
- <td><%= qualifier_icon(snapshot) -%></td>
- <td>
- <% path_name=snapshot.path_name %>
- <%= path_name -%>
- </td>
- <td>
- <a id="select-<%= u(snapshot.project.key) -%>" href="#" onClick="selectPath(<%= snapshot.project_id-%>, '<%= escape_javascript(path_name) -%>')"><%= message('select_verb') -%></a>
- </td>
- </tr>
- <%
- end
- end
- end
- end
- %>
- </tbody>
- </table>
-<% end %>
-<script>
- $('search').focus();
-</script>
\ No newline at end of file
<br/>
<a href="<%= ApplicationController.root_context -%>/account/index" class="link-action"><%= message('layout.user_panel.my_profile') -%></a>
–
- <a href="<%= ApplicationController.root_context -%>/filters/manage" class="link-action"><%= message('default_filters.page') -%></a>
- –
<a href="<%= ApplicationController.root_context -%>/sessions/logout" class="link-action" onclick="if (sonarRecentHistory) { sonarRecentHistory.clear(); }"><%= message('layout.logout') -%></a>
<% else %>
<b><%= message('layout.user_panel.anonymous_user') -%></b>
:mean_color => Color::RGB.from_html("4D05B1"), # purple
:max_color => Color::RGB.from_html("2360BF") # blue
}
- size_measure_values = @filter.results.map do |result|
- size_measure = result.measure(@filter.display.size_metric)
+ size_measure_values = filter.results.map do |result|
+ size_measure = result.measure(filter.display.size_metric)
size_measure.value if size_measure
end.compact
min_size_value=(size_measure_values.empty? ? 0.0 : size_measure_values.min)
max_size_value=(size_measure_values.empty? ? 0.0 : size_measure_values.max)
- @filter.results.each do |result|
- size_measure=result.measure(@filter.display.size_metric)
+ filter.results.each do |result|
+ size_measure=result.measure(filter.display.size_metric)
if size_measure && size_measure.value
- color_measure=result.measure(@filter.display.color_metric)
+ color_measure=result.measure(filter.display.color_metric)
- title="#{result.snapshot.resource.long_name} | #{@filter.display.size_metric.short_name}: #{size_measure.formatted_value}"
+ title="#{result.snapshot.resource.long_name} | #{filter.display.size_metric.short_name}: #{size_measure.formatted_value}"
if color_measure && color_measure.value
- title += " | #{@filter.display.color_metric.short_name}: #{color_measure.formatted_value}"
+ title += " | #{filter.display.color_metric.short_name}: #{color_measure.formatted_value}"
end
%>
<a href="<%= ApplicationController.root_context -%>/dashboard/index/<%= result.snapshot.resource_id -%>" title="<%= title -%>"><span style="font-size: <%= cloud_font_size(size_measure.value, min_size_value, max_size_value) -%>%;color: <%= MeasureColor.color(color_measure, color_options).html -%>"><%= result.snapshot.resource.name %></span></a>
<%
display_favourites = logged_in?
- colspan = @filter.display.columns.size
+ colspan = filter.display.columns.size
colspan += 1 if display_favourites
table_columns = []
table_columns << '' if display_favourites
- table_columns.concat(@filter.display.columns.map{|c| c.key})
+ table_columns.concat(filter.display.columns.map{|c| c.key})
if edit_mode
content_for :script do
%>
<% if display_favourites %>
<th class="thin"></th>
<% end %>
- <% @filter.display.columns.each do |column| %>
- <%= list_column_html(@filter, column) -%>
+ <% filter.display.columns.each do |column| %>
+ <%= list_column_html(filter, column) -%>
<% end %>
</tr>
</thead>
<% if display_favourites %>
<td></td>
<% end %>
- <% @filter.display.columns.each_with_index do |column, index| %>
+ <% filter.display.columns.each_with_index do |column, index| %>
<td class="nowrap <%= column.align -%>" index="<%= index -%>">
<a href="javascript:leftCol(<%= index -%>)" title="<%= message('move_left') -%>"><%= image_tag("controls/resultset_previous.png") -%></a>
<a href="javascript:deleteCol(<%= index -%>)" title="<%= message('delete_column') -%>"><%= image_tag("cross-gray.png") -%></a>
<% end %>
<% end %>
- <% if @filter.base_result %>
+ <% if filter.base_result %>
<tr class="highlight">
<% if display_favourites %>
- <td class="thin"><%= link_to_favourite(@filter.base_result.snapshot.resource) -%></td>
+ <td class="thin"><%= link_to_favourite(filter.base_result.snapshot.resource) -%></td>
<% end %>
- <% @filter.display.columns.each do |column| %>
+ <% filter.display.columns.each do |column| %>
<td class="<%= column.align -%>">
- <%= list_cell_html(column, @filter.base_result) -%>
+ <%= list_cell_html(column, filter.base_result) -%>
</td>
<% end %>
</tr>
<% end %>
- <% @filter.results.each do |result| %>
+ <% filter.results.each do |result| %>
<tr class="<%= cycle 'even', 'odd' -%>">
<% if display_favourites %>
<td class="thin"><%= link_to_favourite(result.snapshot.resource) -%></td>
<% end %>
- <% @filter.display.columns.each do |column| %>
+ <% filter.display.columns.each do |column| %>
<td class="<%= column.align -%>">
<%= list_cell_html(column, result) -%>
</td>
</tr>
<% end %>
- <% if @filter.results.empty? %>
+ <% if filter.results.empty? %>
<tr class="even">
<td colspan="<%= colspan -%>"><%= message 'no_data' -%></td>
</tr>
<% end %>
</tbody>
- <%= render :partial => 'utils/tfoot_pagination', :locals => {:pagination => @filter.pagination, :colspan => colspan} %>
+ <%= render :partial => 'utils/tfoot_pagination', :locals => {:pagination => filter.pagination, :colspan => colspan} %>
</table>
\ No newline at end of file
-<% if edit_mode %>
- <table class="spaced width100 admin">
- <tr>
- <td valign="top" class="thin nowrap">
- <span class="comments"><%= message('size') -%></span>
- <br/>
- <%= metric_select_tag 'tmSize', Metric.all.select { |m| m.treemap_size? },
- :html_id => 'select-tm-size',
- :selected_key => @filter.display.size_metric.key -%>
- </td>
- <td valign="top" class="thin nowrap">
- <span class="comments"><%= message('color') -%></span>
- <span id="tm-gradient" class="note"></span>
- <br/>
- <%= metric_select_tag 'tmColor', Metric.all.select { |m| m.treemap_color? },
- :html_id => 'select-tm-color',
- :allow_empty => true,
- :selected_key => (@filter.display.color_metric ? @filter.display.color_metric.key : nil) -%>
+<table class="spaced width100">
+ <tr>
+ <td valign="top" class="thin nowrap">
+ <span class="comments"><%= message('size') -%></span>
+ <br/>
+ <%= metric_select_tag 'tmSize', Metric.all.select { |m| m.treemap_size? },
+ :html_id => 'select-tm-size',
+ :selected_key => filter.display.size_metric.key -%>
+ </td>
+ <td valign="top" class="thin nowrap">
+ <span class="comments"><%= message('color') -%></span>
+ <% if filter.display.color_metric %>
+ <span id="tm-gradient" class="note">
+ <%= render :partial => 'treemap/gradient', :locals => {:metric => filter.display.color_metric} %>
+ </span>
+ <% end %>
+ <br/>
+ <%= metric_select_tag 'tmColor', Metric.all.select { |m| m.treemap_color? },
+ :html_id => 'select-tm-color',
+ :allow_empty => true,
+ :selected_key => (filter.display.color_metric ? filter.display.color_metric.key : nil) -%>
- <button id="update-treemap">Update</button>
- </td>
- <td class="right" valign="bottom">
- <a href="#" class="button" id="exit-edit">Done</a>
- </td>
- </tr>
- </table>
- <% content_for :script do %>
- <script>
- $j(document).ready(function () {
- $j("#update-treemap").on("click", function (e) {
- var url = removeUrlAttr(decodeURI(window.location.href), 'tmSize');
- url = removeUrlAttr(url, 'tmColor');
- url += '&tmSize=' + $j('#select-tm-size').val();
- var color = $j('#select-tm-color').val();
- if (color != null && color != '') {
- url += '&tmColor=' + color;
- }
- window.location = url;
- });
- $j("#exit-edit").on("click", function (e) {
- window.location = removeUrlAttr(decodeURI(window.location.href), 'edit');
- });
+ <button id="update-treemap">Update</button>
+ </td>
+ <td></td>
+ </tr>
+</table>
+<% content_for :script do %>
+ <script>
+ $j(document).ready(function () {
+ $j("#update-treemap").on("click", function (e) {
+ var url = removeUrlAttr(decodeURI(window.location.href), 'tmSize');
+ url = removeUrlAttr(url, 'tmColor');
+ url += '&tmSize=' + $j('#select-tm-size').val();
+ var color = $j('#select-tm-color').val();
+ if (color != null && color != '') {
+ url += '&tmColor=' + color;
+ }
+ window.location = url;
});
- </script>
- <% end %>
+ $j("#exit-edit").on("click", function (e) {
+ window.location = removeUrlAttr(decodeURI(window.location.href), 'edit');
+ });
+ });
+ </script>
<% end %>
-<div class="treemap" style="width: 100%; height:<%= @filter.display.height %>px;">
- <%= @filter.display.html -%>
+<div class="treemap" style="width: 100%; height: 500px;">
+ <%= filter.display.html -%>
</div>
\ No newline at end of file
<% if @filter.results && @filter.display %>
<div class="page-split-right">
<div id="content">
+ <div class="line-block marginbottom10">
+ <ul class="operations">
+ <%
+ edit_mode = (params[:edit]=='true')
+ if @filter.display.key==:list && !edit_mode
+ %>
+ <li>
+ <a id="edit" href="<%= url_for params.merge({:edit => true, :id => @filter.id}) -%>"><%= message('measure_filter.configure_columns') -%></a>
+ </li>
+ <% end %>
+ <li class="last">
+ Display as:
+ <% MeasureFilterDisplay.keys.each do |display_key| %>
+ <%= link_to_if display_key!=@filter.display.key, message("measure_filter.display.#{display_key}"), params.merge(:action => 'search', :display => display_key, :id => @filter.id) -%>
+ <% end %>
+ </li>
+ </ul>
+ <div class="page_title" style="padding-left: 10px">
+ <% if @filter.description.present? %>
+ <%= h @filter.description -%>
+ <% end %>
+ </div>
+ </div>
- <% if @filter.description.present? %>
- <p><%= h @filter.description -%></p>
- <% end %>
-
- <%
- edit_mode = (params[:edit]=='true')
- unless edit_mode
- %>
- <table class="width100">
- <tr>
- <td class="left">
- Display as:
- <% MeasureFilterDisplay.keys.each do |display_key| %>
- <%= link_to_if display_key!=@filter.display.key, display_key, params.merge(:action => 'search', :display => display_key, :id => @filter.id) -%>
- <% end %>
- <td class="right">
- <a id="edit" href="<%= url_for params.merge({:edit => true, :id => @filter.id}) -%>" class="button"><%= message('configure') -%></a>
- </td>
- </tr>
- </table>
- <% end %>
<% if @filter.security_exclusions %>
<p class="notes"><%= message('results_not_display_due_to_security') -%></p>
<% end %>
- <%= render :partial => "measures/display_#{@filter.display.class::KEY}", :locals => {:edit_mode => edit_mode} -%>
+
+ <%= render :partial => "measures/display_#{@filter.display.class::KEY}", :locals => {:filter => @filter, :edit_mode => edit_mode} -%>
</div>
</div>
<% end %>
add_column :filters, :period_index, :integer, :null => true
add_column :filter_columns, :variation, :boolean, :null => true
add_column :criteria, :variation, :boolean, :null => true
- ::Filter.reset_column_information
- Criterion.reset_column_information
- FilterColumn.reset_column_information
end
end
end
def self.up
- dashboard_per_filter = create_global_dahboards()
+ dashboard_per_filter = create_global_dashboards()
activate_dashboards(dashboard_per_filter)
drop_table('active_filters')
end
- def self.create_global_dahboards
+ def self.create_global_dashboards
dashboards = {}
Filter.find(:all).each do |filter|
class WidgetProperty < ActiveRecord::Base
end
+ class Filter < ActiveRecord::Base
+ end
+
def self.up
keys = add_key_column_to_filters()
use_key_in_widget_properties(keys)
set_table_name 'filters'
end
-
def self.up
old_filters = Filter.find(:all)
say_with_time "Moving #{old_filters.size} measure filters" do
if old_column.kee
column_key += ":#{old_column.kee}"
column_key += ":#{old_filter.period_index}" if old_column.variation && old_filter.period_index
- columns << column_key
end
+ columns << column_key
if old_column.sort_direction=='ASC'
asc = true
sort = column_key
--- /dev/null
+#
+# Sonar, open source software quality management tool.
+# Copyright (C) 2008-2012 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
+#
+
+#
+# Sonar 3.4
+#
+class MoveFilterWidgets < ActiveRecord::Migration
+
+ class MeasureFilter < ActiveRecord::Base
+ end
+
+ def self.up
+
+ end
+
+end
--- /dev/null
+#
+# Sonar, open source software quality management tool.
+# Copyright (C) 2008-2012 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
+#
+
+#
+# Sonar 3.4
+#
+class DropFilterTables < ActiveRecord::Migration
+
+ def self.up
+ drop_table('filter_columns')
+ drop_table('criteria')
+ drop_table('filters')
+ end
+
+end
.treemap a {
color: #FFF;
- text-decoration: none;
+ text-decoration: underline;
font-size: 12px;
padding: 1px;
- text-decoration: underline;
}
/* ------------------- MESSAGES ------------------- */
.table > tbody > tr > td {
line-height: 16px;
padding: 4px 5px;
- vertical-align: top;
+ vertical-align: middle;
}
.table > tfoot > tr > td {
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.server.startup;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.web.Criterion;
-import org.sonar.api.web.Filter;
-import org.sonar.api.web.FilterColumn;
-import org.sonar.api.web.FilterTemplate;
-import org.sonar.core.filter.CriterionDto;
-import org.sonar.core.filter.FilterColumnDto;
-import org.sonar.core.filter.FilterDao;
-import org.sonar.core.filter.FilterDto;
-import org.sonar.core.template.LoadedTemplateDao;
-import org.sonar.core.template.LoadedTemplateDto;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.test.MoreConditions.contains;
-
-public class RegisterNewFiltersTest {
- private RegisterNewFilters register;
- private FilterDao filterDao;
- private LoadedTemplateDao loadedTemplateDao;
- private FilterTemplate filterTemplate;
-
- @Before
- public void init() {
- filterDao = mock(FilterDao.class);
- loadedTemplateDao = mock(LoadedTemplateDao.class);
- filterTemplate = mock(FilterTemplate.class);
-
- register = new RegisterNewFilters(new FilterTemplate[] {filterTemplate}, filterDao, loadedTemplateDao);
- }
-
- @Test
- public void should_insert_filters_on_start() {
- when(loadedTemplateDao.countByTypeAndKey(eq(LoadedTemplateDto.FILTER_TYPE), anyString())).thenReturn(0);
- when(filterTemplate.createFilter()).thenReturn(Filter.create());
-
- register.start();
-
- verify(filterDao).insert(any(FilterDto.class));
- verify(loadedTemplateDao).insert(any(LoadedTemplateDto.class));
- }
-
- @Test
- public void should_insert_nothing_if_templates_are_alreday_loaded() {
- when(loadedTemplateDao.countByTypeAndKey(eq(LoadedTemplateDto.FILTER_TYPE), anyString())).thenReturn(1);
-
- register.start();
-
- verify(filterDao, never()).insert(any(FilterDto.class));
- verify(loadedTemplateDao, never()).insert(any(LoadedTemplateDto.class));
- }
-
- @Test
- public void should_register_filter() {
- when(filterTemplate.createFilter()).thenReturn(Filter.create());
-
- FilterDto filterDto = register.register("Fake", filterTemplate.createFilter());
-
- assertThat(filterDto).isNotNull();
- verify(filterDao).insert(filterDto);
- verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.FILTER_TYPE)));
- }
-
- @Test
- public void should_not_recreate_filter() {
- when(filterDao.findFilter("Fake")).thenReturn(new FilterDto());
-
- FilterDto filterDto = register.register("Fake", null);
-
- assertThat(filterDto).isNull();
- verify(filterDao, never()).insert(filterDto);
- verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.FILTER_TYPE)));
- }
-
- @Test
- public void should_create_dto_from_extension() {
- when(filterTemplate.createFilter()).thenReturn(Filter.create()
- .setFavouritesOnly(false)
- .setDisplayAs("list")
- .add(Criterion.createForMetric("complexity", Criterion.LT, 12f, false))
- .add(Criterion.createForMetric("LCOM4", Criterion.GTE, "5", true))
- .add(FilterColumn.create("metric", "distance", "ASC", false))
- .add(FilterColumn.create("metric", "instability", "DESC", true))
- );
-
- FilterDto dto = register.createDtoFromExtension("Fake", filterTemplate.createFilter());
-
- assertThat(dto.getName()).isEqualTo("Fake");
- assertThat(dto.getKey()).isEqualTo("Fake");
- assertThat(dto.isShared()).isTrue();
- assertThat(dto.isFavourites()).isFalse();
- assertThat(dto.getDefaultView()).isEqualTo("list");
- assertThat(dto.getPageSize()).isNull();
-
- assertThat(dto.getCriteria()).hasSize(2);
- assertThat(dto.getCriteria()).satisfies(contains(new CriterionDto().setFamily("metric").setKey("complexity").setOperator("<").setValue(12f).setVariation(false)));
- assertThat(dto.getCriteria()).satisfies(contains(new CriterionDto().setFamily("metric").setKey("LCOM4").setOperator(">=").setTextValue("5").setVariation(true)));
-
- assertThat(dto.getColumns()).hasSize(2);
- assertThat(dto.getColumns()).satisfies(contains(new FilterColumnDto().setFamily("metric").setKey("distance").setOrderIndex(1L).setSortDirection("ASC").setVariation(false)));
- assertThat(dto.getColumns()).satisfies(contains(new FilterColumnDto().setFamily("metric").setKey("instability").setOrderIndex(2L).setSortDirection("DESC").setVariation(true)));
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.server.startup;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.web.Criterion;
+import org.sonar.api.web.Filter;
+import org.sonar.api.web.FilterColumn;
+import org.sonar.api.web.FilterTemplate;
+import org.sonar.core.measure.MeasureFilterDao;
+import org.sonar.core.measure.MeasureFilterDto;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.core.template.LoadedTemplateDto;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class RegisterNewMeasureFiltersTest {
+ private RegisterNewMeasureFilters registerMeasure;
+ private MeasureFilterDao filterDao;
+ private LoadedTemplateDao loadedTemplateDao;
+ private FilterTemplate filterTemplate;
+
+ @Before
+ public void init() {
+ filterDao = mock(MeasureFilterDao.class);
+ loadedTemplateDao = mock(LoadedTemplateDao.class);
+ filterTemplate = mock(FilterTemplate.class);
+
+ registerMeasure = new RegisterNewMeasureFilters(new FilterTemplate[]{filterTemplate}, filterDao, loadedTemplateDao);
+ }
+
+ @Test
+ public void should_insert_filters_on_start() {
+ when(loadedTemplateDao.countByTypeAndKey(eq(LoadedTemplateDto.FILTER_TYPE), anyString())).thenReturn(0);
+ when(filterTemplate.createFilter()).thenReturn(Filter.create());
+
+ registerMeasure.start();
+
+ verify(filterDao).insert(any(MeasureFilterDto.class));
+ verify(loadedTemplateDao).insert(any(LoadedTemplateDto.class));
+ }
+
+ @Test
+ public void should_insert_nothing_if_templates_are_alreday_loaded() {
+ when(loadedTemplateDao.countByTypeAndKey(eq(LoadedTemplateDto.FILTER_TYPE), anyString())).thenReturn(1);
+
+ registerMeasure.start();
+
+ verify(filterDao, never()).insert(any(MeasureFilterDto.class));
+ verify(loadedTemplateDao, never()).insert(any(LoadedTemplateDto.class));
+ }
+
+ @Test
+ public void should_register_filter() {
+ when(filterTemplate.createFilter()).thenReturn(Filter.create());
+
+ MeasureFilterDto filterDto = registerMeasure.register("Fake", filterTemplate.createFilter());
+
+ assertThat(filterDto).isNotNull();
+ verify(filterDao).insert(filterDto);
+ verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.FILTER_TYPE)));
+ }
+
+ @Test
+ public void should_not_recreate_filter() {
+ when(filterDao.findSystemFilterByName("Fake")).thenReturn(new MeasureFilterDto());
+
+ MeasureFilterDto filterDto = registerMeasure.register("Fake", null);
+
+ assertThat(filterDto).isNull();
+ verify(filterDao, never()).insert(filterDto);
+ verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.FILTER_TYPE)));
+ }
+
+ @Test
+ public void should_create_dto_from_extension() {
+ when(filterTemplate.createFilter()).thenReturn(Filter.create()
+ .setFavouritesOnly(false)
+ .setDisplayAs("list")
+ .add(Criterion.createForMetric("complexity", Criterion.LT, 12f, false))
+ .add(Criterion.createForMetric("lcom4", Criterion.GTE, 5f, false))
+ .add(FilterColumn.create("metric", "distance", "ASC", false))
+ );
+
+ MeasureFilterDto dto = registerMeasure.createDtoFromExtension("Fake", filterTemplate.createFilter());
+
+ assertThat(dto.getName()).isEqualTo("Fake");
+ assertThat(dto.isShared()).isTrue();
+ assertThat(dto.getData()).doesNotContain("onFavourites=true");
+ assertThat(dto.getData()).contains("display=list");
+ assertThat(dto.getData()).contains("c1_metric=complexity");
+ assertThat(dto.getData()).contains("c1_op=lt");
+ assertThat(dto.getData()).contains("c1_val=12.0");
+ assertThat(dto.getData()).contains("c2_metric=lcom4");
+ assertThat(dto.getData()).contains("c2_op=gte");
+ assertThat(dto.getData()).contains("c2_val=5.0");
+ assertThat(dto.getData()).contains("cols=metric:distance");
+ }
+}