]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6236 Migrate existing dashboards to use the new issue widgets
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Thu, 12 Mar 2015 16:56:46 +0000 (17:56 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 18 Mar 2015 12:19:47 +0000 (13:19 +0100)
15 files changed:
server/sonar-server/src/main/java/org/sonar/server/dashboard/db/WidgetDao.java
server/sonar-server/src/main/java/org/sonar/server/dashboard/db/WidgetPropertyDao.java
server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
server/sonar-server/src/main/java/org/sonar/server/startup/RegisterDashboards.java
server/sonar-server/src/main/java/org/sonar/server/startup/RenameIssueWidgets.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/startup/RegisterDashboardsTest.java
server/sonar-server/src/test/java/org/sonar/server/startup/RenameIssueWidgetsTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/after.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/before.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/empty.xml [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/dashboard/WidgetMapper.java
sonar-core/src/main/java/org/sonar/core/dashboard/WidgetPropertyMapper.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java
sonar-core/src/main/resources/org/sonar/core/dashboard/WidgetPropertyMapper.xml

index ca7b10d9e5f5975a3c4c0c7070ef6edf86c3cad8..d6d12e4c0f5b0a739d4cd717973b9762e5833774 100644 (file)
@@ -38,7 +38,17 @@ public class WidgetDao extends BaseDao<WidgetMapper, WidgetDto, Long> {
     return mapper(session).selectById(widgetId);
   }
 
+  @Override
+  protected WidgetDto doUpdate(DbSession session, WidgetDto item) {
+    mapper(session).update(item);
+    return item;
+  }
+
   public Collection<WidgetDto> findByDashboard(DbSession session, long dashboardKey) {
     return mapper(session).selectByDashboard(dashboardKey);
   }
+
+  public Collection<WidgetDto> findAll(DbSession session) {
+    return mapper(session).selectAll();
+  }
 }
index ae85a6fd3862119278fa6c41f8d84eb583d0365f..9aeead48d6ab9b9e5081fc76686a48955ec0541f 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.server.db.BaseDao;
 
 import java.util.Collection;
+import java.util.List;
 
 public class WidgetPropertyDao extends BaseDao<WidgetPropertyMapper, WidgetPropertyDto, Long> {
 
@@ -33,6 +34,12 @@ public class WidgetPropertyDao extends BaseDao<WidgetPropertyMapper, WidgetPrope
     super(WidgetPropertyMapper.class, system2);
   }
 
+  @Override
+  protected WidgetPropertyDto doInsert(DbSession session, WidgetPropertyDto item) {
+    mapper(session).insert(item);
+    return item;
+  }
+
   @Override
   protected WidgetPropertyDto doGetNullableByKey(DbSession session, Long propertyId) {
     return mapper(session).selectById(propertyId);
@@ -42,4 +49,8 @@ public class WidgetPropertyDao extends BaseDao<WidgetPropertyMapper, WidgetPrope
     return mapper(session).selectByDashboard(dashboardKey);
   }
 
+  public void deleteByWidgetIds(DbSession session, List<Long> widgetIdsWithPropertiesToDelete) {
+    mapper(session).deleteByWidgetIds(widgetIdsWithPropertiesToDelete);
+  }
+
 }
index a0056e420647eb5fd4e9df94a9e276a072c25517..fe5106cc7d60f585fddb3bb380d0299342e7c0d4 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.db;
 import org.sonar.api.ServerComponent;
 import org.sonar.core.issue.db.ActionPlanDao;
 import org.sonar.core.issue.db.IssueChangeDao;
+import org.sonar.core.issue.db.IssueFilterDao;
 import org.sonar.core.persistence.DaoComponent;
 import org.sonar.core.persistence.Database;
 import org.sonar.core.persistence.DbSession;
@@ -82,6 +83,7 @@ public class DbClient implements ServerComponent {
   private final UserDao userDao;
   private final GroupDao groupDao;
   private final IssueDao issueDao;
+  private final IssueFilterDao issueFilterDao;
   private final IssueChangeDao issueChangeDao;
   private final ActionPlanDao actionPlanDao;
   private final AnalysisReportDao analysisReportDao;
@@ -118,6 +120,7 @@ public class DbClient implements ServerComponent {
     userDao = getDao(map, UserDao.class);
     groupDao = getDao(map, GroupDao.class);
     issueDao = getDao(map, IssueDao.class);
+    issueFilterDao = getDao(map, IssueFilterDao.class);
     issueChangeDao = getDao(map, IssueChangeDao.class);
     actionPlanDao = getDao(map, ActionPlanDao.class);
     analysisReportDao = getDao(map, AnalysisReportDao.class);
@@ -151,6 +154,10 @@ public class DbClient implements ServerComponent {
     return issueDao;
   }
 
+  public IssueFilterDao issueFilterDao() {
+    return issueFilterDao;
+  }
+
   public IssueChangeDao issueChangeDao() {
     return issueChangeDao;
   }
index 6542ea824c637d920bbef8c1f33bc3d684a8a967..1d9da7f47f44bfd3085053c8c782d2245bc492c4 100644 (file)
@@ -709,6 +709,7 @@ class ServerComponents {
     startupContainer.addSingleton(RegisterServletFilters.class);
     startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class);
     startupContainer.addSingleton(ReportQueueCleaner.class);
+    startupContainer.addSingleton(RenameIssueWidgets.class);
 
     DoPrivileged.execute(new DoPrivileged.Task() {
       @Override
index baea633bb32acee09e5a12de022d22c340ab94ea..084820d0a64c056af0c67a90b4625d2ec4eef0ea 100644 (file)
@@ -27,14 +27,10 @@ import org.sonar.api.utils.log.Loggers;
 import org.sonar.api.utils.log.Profiler;
 import org.sonar.api.web.Dashboard;
 import org.sonar.api.web.DashboardTemplate;
-import org.sonar.core.dashboard.ActiveDashboardDao;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.DashboardDao;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetPropertyDto;
+import org.sonar.core.dashboard.*;
 import org.sonar.core.template.LoadedTemplateDao;
 import org.sonar.core.template.LoadedTemplateDto;
+import org.sonar.server.issue.filter.RegisterIssueFilters;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -55,7 +51,7 @@ public class RegisterDashboards implements Startable {
   private final LoadedTemplateDao loadedTemplateDao;
 
   public RegisterDashboards(DashboardTemplate[] dashboardTemplatesArray, DashboardDao dashboardDao,
-    ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) {
+    ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao, RegisterIssueFilters startupDependency) {
     this.dashboardTemplates = Lists.newArrayList(dashboardTemplatesArray);
     this.dashboardDao = dashboardDao;
     this.activeDashboardDao = activeDashboardDao;
@@ -65,8 +61,8 @@ public class RegisterDashboards implements Startable {
   /**
    * Used when no plugin is defining some DashboardTemplate
    */
-  public RegisterDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) {
-    this(new DashboardTemplate[] {}, dashboardDao, activeDashboardDao, loadedTemplateDao);
+  public RegisterDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao, RegisterIssueFilters registerIssueFilters) {
+    this(new DashboardTemplate[] {}, dashboardDao, activeDashboardDao, loadedTemplateDao, registerIssueFilters);
   }
 
   @Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/RenameIssueWidgets.java b/server/sonar-server/src/main/java/org/sonar/server/startup/RenameIssueWidgets.java
new file mode 100644 (file)
index 0000000..e0fbf82
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.startup;
+
+import com.google.common.collect.Lists;
+import org.picocontainer.Startable;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.dashboard.WidgetDto;
+import org.sonar.core.dashboard.WidgetPropertyDto;
+import org.sonar.core.issue.db.IssueFilterDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.template.LoadedTemplateDto;
+import org.sonar.server.db.DbClient;
+
+import java.util.List;
+
+public class RenameIssueWidgets implements Startable {
+
+  private static final String PROJECT_ISSUE_FILTER_WIDGET_KEY = "project_issue_filter";
+  private static final String FILTER_PROPERTY = "filter";
+  private static final String DISTRIBUTION_AXIS_PROPERTY = "distributionAxis";
+
+  private final DbClient dbClient;
+
+  public RenameIssueWidgets(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public void start() {
+    DbSession session = dbClient.openSession(false);
+
+    try {
+      if (dbClient.loadedTemplateDao().countByTypeAndKey(LoadedTemplateDto.ONE_SHOT_TASK_TYPE, getClass().getSimpleName()) != 0) {
+        // Already done
+        return;
+      }
+
+      IssueFilterDto unresolvedIssues = dbClient.issueFilterDao().selectProvidedFilterByName("Unresolved Issues");
+      IssueFilterDto hiddenDebt = dbClient.issueFilterDao().selectProvidedFilterByName("False Positive and Won't Fix Issues");
+      IssueFilterDto myUnresolvedIssues = dbClient.issueFilterDao().selectProvidedFilterByName("My Unresolved Issues");
+
+      if (unresolvedIssues == null || hiddenDebt == null || myUnresolvedIssues == null) {
+        // One of the filter has been deleted, no need to do anything
+        return;
+      }
+
+      Loggers.get(getClass()).info("Replacing issue related widgets with issue filter widgets");
+
+      List<Long> widgetIdsWithPropertiesToDelete = Lists.newArrayList();
+      List<WidgetPropertyDto> widgetPropertiesToCreate = Lists.newArrayList();
+
+      for (WidgetDto widget : dbClient.widgetDao().findAll(session)) {
+        switch (widget.getWidgetKey()) {
+          case "false_positive_reviews":
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(FILTER_PROPERTY)
+                .setTextValue(hiddenDebt.getId().toString()));
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(DISTRIBUTION_AXIS_PROPERTY)
+                .setTextValue("resolutions"));
+            updateWidget(session, widgetIdsWithPropertiesToDelete, widget);
+            break;
+          case "my_reviews":
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(FILTER_PROPERTY)
+                .setTextValue(myUnresolvedIssues.getId().toString()));
+            updateWidget(session, widgetIdsWithPropertiesToDelete, widget);
+            break;
+          case "reviews_per_developer":
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(FILTER_PROPERTY)
+                .setTextValue(unresolvedIssues.getId().toString()));
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(DISTRIBUTION_AXIS_PROPERTY)
+                .setTextValue("assignees"));
+            updateWidget(session, widgetIdsWithPropertiesToDelete, widget);
+            break;
+          case "unresolved_issues_statuses":
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(FILTER_PROPERTY)
+                .setTextValue(unresolvedIssues.getId().toString()));
+            widgetPropertiesToCreate.add(
+              new WidgetPropertyDto()
+                .setWidgetId(widget.getId())
+                .setPropertyKey(DISTRIBUTION_AXIS_PROPERTY)
+                .setTextValue("statuses"));
+            updateWidget(session, widgetIdsWithPropertiesToDelete, widget);
+            break;
+          default:
+            // Nothing to do, move along
+            break;
+        }
+      }
+
+      dbClient.widgetPropertyDao().deleteByWidgetIds(session, widgetIdsWithPropertiesToDelete);
+      dbClient.widgetPropertyDao().insert(session, widgetPropertiesToCreate);
+
+      dbClient.loadedTemplateDao().insert(new LoadedTemplateDto()
+        .setType(LoadedTemplateDto.ONE_SHOT_TASK_TYPE)
+        .setKey(getClass().getSimpleName()), session);
+
+      session.commit();
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private void updateWidget(DbSession session, List<Long> widgetIdsWithPropertiesToDelete, WidgetDto widget) {
+    dbClient.widgetDao().update(session,
+      widget.setWidgetKey(PROJECT_ISSUE_FILTER_WIDGET_KEY)
+        .setConfigured(true));
+    widgetIdsWithPropertiesToDelete.add(widget.getId());
+  }
+
+  @Override
+  public void stop() {
+    // do nothing
+  }
+
+}
index 64988ba63bdd53e05af41d931b089aaa4e54e53e..5ababc6e7215c0263635ad03efd2449a6141f929 100644 (file)
@@ -27,12 +27,7 @@ import org.mockito.ArgumentMatcher;
 import org.sonar.api.web.Dashboard;
 import org.sonar.api.web.DashboardLayout;
 import org.sonar.api.web.DashboardTemplate;
-import org.sonar.core.dashboard.ActiveDashboardDao;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.DashboardDao;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetPropertyDto;
+import org.sonar.core.dashboard.*;
 import org.sonar.core.template.LoadedTemplateDao;
 import org.sonar.core.template.LoadedTemplateDto;
 
@@ -64,7 +59,7 @@ public class RegisterDashboardsTest {
     fakeDashboardTemplate = mock(DashboardTemplate.class);
 
     task = new RegisterDashboards(new DashboardTemplate[]{fakeDashboardTemplate}, dashboardDao,
-      activeDashboardDao, loadedTemplateDao);
+      activeDashboardDao, loadedTemplateDao, null);
   }
 
   @Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/RenameIssueWidgetsTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/RenameIssueWidgetsTest.java
new file mode 100644 (file)
index 0000000..95047b5
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.startup;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.issue.db.IssueFilterDao;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.server.dashboard.db.WidgetDao;
+import org.sonar.server.dashboard.db.WidgetPropertyDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.test.DbTests;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@Category(DbTests.class)
+public class RenameIssueWidgetsTest {
+
+  @Rule
+  public DbTester dbTester = new DbTester();
+
+  @Test
+  public void should_rename_widgets() throws Exception {
+    dbTester.prepareDbUnit(this.getClass(), "before.xml");
+
+    doStart();
+
+    dbTester.assertDbUnit(this.getClass(), "after.xml", "widgets", "widget_properties", "loaded_templates");
+  }
+
+  @Test
+  public void should_skip_when_filter_removed() throws Exception {
+    dbTester.prepareDbUnit(this.getClass(), "empty.xml");
+
+    doStart();
+  }
+
+  @Test
+  public void should_skip_when_already_executed() throws Exception {
+    dbTester.prepareDbUnit(this.getClass(), "after.xml");
+
+    doStart();
+  }
+
+  private void doStart() {
+    System2 system2 = mock(System2.class);
+    when(system2.now()).thenReturn(DateUtils.parseDateTime("2003-03-23T01:23:45+0100").getTime());
+
+    RenameIssueWidgets task = new RenameIssueWidgets(
+      new DbClient(
+        dbTester.database(),
+        dbTester.myBatis(),
+        new WidgetDao(system2),
+        new WidgetPropertyDao(system2),
+        new IssueFilterDao(dbTester.myBatis()),
+        new LoadedTemplateDao(dbTester.myBatis())
+      ));
+
+    task.start();
+    task.stop();
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/after.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/after.xml
new file mode 100644 (file)
index 0000000..ab8310d
--- /dev/null
@@ -0,0 +1,81 @@
+<dataset>
+
+  <issue_filters
+      id="1"
+      name="Unresolved Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolved=false"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+  <issue_filters
+      id="2"
+      name="False Positive and Won't Fix Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolutions=FALSE-POSITIVE,WONTFIX"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+  <issue_filters
+      id="3"
+      name="My Unresolved Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolved=false|assignees=__me__"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+
+  <widgets id="1" dashboard_id="1" widget_key="polop" name="[null]" description="[null]"
+     column_index="1" row_index="1" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+  <widget_properties id="1" widget_id="1" kee="palap" text_value="pulup"/>
+
+
+  <!-- 'False Positive Issues' - replaced by project_issue_filter w/ 'False Positive and Won't Fix Issues' filter -->
+  <widgets id="2" dashboard_id="1" widget_key="project_issue_filter" name="[null]" description="[null]"
+     column_index="1" row_index="2" configured="true" created_at="[null]" updated_at="2003-03-23 01:23:45" resource_id="[null]"/>
+
+  <!-- filter = 'False Positive and Won't Fix Issues' -->
+  <widget_properties id="3" widget_id="2" kee="filter" text_value="2"/>
+  <!-- distributionAxis is 'resolutions' -->
+  <widget_properties id="4" widget_id="2" kee="distributionAxis" text_value="resolutions"/>
+
+
+  <!-- 'My Unresolved Issues' - replaced by project_issue_filter w/ 'My Unresolved Issues' filter -->
+  <widgets id="3" dashboard_id="1" widget_key="project_issue_filter" name="[null]" description="[null]"
+     column_index="1" row_index="3" configured="true" created_at="[null]" updated_at="2003-03-23 01:23:45" resource_id="[null]"/>
+
+  <!-- filter = 'My Unresolved Issues' -->
+  <widget_properties id="5" widget_id="3" kee="filter" text_value="3"/>
+  <!-- distributionAxis is 'default', no other config -->
+
+
+  <!-- 'Unresolved Issues Per Developer' - replaced by project_issue_filter w/ 'Unresolved Issues' filter -->
+  <widgets id="4" dashboard_id="1" widget_key="project_issue_filter" name="[null]" description="[null]"
+     column_index="1" row_index="4" configured="true" created_at="[null]" updated_at="2003-03-23 01:23:45" resource_id="[null]"/>
+
+  <!-- filter = 'Unresolved Issues' -->
+  <widget_properties id="6" widget_id="4" kee="filter" text_value="1"/>
+  <!-- distributionAxis is 'assignees' -->
+  <widget_properties id="7" widget_id="4" kee="distributionAxis" text_value="assignees"/>
+
+
+  <!-- 'Unresolved Issues Per Status' - replaced by project_issue_filter w/ 'Unresolved Issues' filter -->
+  <widgets id="5" dashboard_id="1" widget_key="project_issue_filter" name="[null]" description="[null]"
+     column_index="1" row_index="5" configured="true" created_at="[null]" updated_at="2003-03-23 01:23:45" resource_id="[null]"/>
+
+  <!-- filter = 'Unresolved Issues' -->
+  <widget_properties id="8" widget_id="5" kee="filter" text_value="1"/>
+  <!-- distributionAxis is 'assignees' -->
+  <widget_properties id="9" widget_id="5" kee="distributionAxis" text_value="statuses"/>
+
+
+  <loaded_templates id="1" template_type="ONE_SHOT_TASK" kee="RenameIssueWidgets"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/before.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/before.xml
new file mode 100644 (file)
index 0000000..d22705c
--- /dev/null
@@ -0,0 +1,65 @@
+<dataset>
+
+  <issue_filters
+      id="1"
+      name="Unresolved Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolved=false"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+  <issue_filters
+      id="2"
+      name="False Positive and Won't Fix Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolutions=FALSE-POSITIVE,WONTFIX"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+  <issue_filters
+      id="3"
+      name="My Unresolved Issues"
+      user_login="[null]"
+      shared="[true]"
+      description="[null]"
+      data="resolved=false|assignees=__me__"
+      created_at="2011-04-25 01:15:00"
+      updated_at="2011-04-25 01:15:00" />
+
+
+  <!-- Will not be modified -->
+  <widgets id="1" dashboard_id="1" widget_key="polop" name="[null]" description="[null]"
+     column_index="1" row_index="1" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+  <widget_properties id="1" widget_id="1" kee="palap" text_value="pulup"/>
+  
+
+
+  <!-- 'False Positive Issues' - replaced by project_issue_filter w/ 'False Positive and Won't Fix Issues' filter -->
+  <widgets id="2" dashboard_id="1" widget_key="false_positive_reviews" name="[null]" description="[null]"
+     column_index="1" row_index="2" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+
+  <!-- 'My Unresolved Issues' - replaced by project_issue_filter w/ 'My Unresolved Issues' filter -->
+  <widgets id="3" dashboard_id="1" widget_key="my_reviews" name="[null]" description="[null]"
+     column_index="1" row_index="3" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+  <!-- config for 'My Unresolved Issues' - will be deleted -->
+  <widget_properties id="2" widget_id="3" kee="numberOfLines" text_value="20"/>
+
+
+  <!-- 'Unresolved Issues Per Developer' - replaced by project_issue_filter w/ 'Unresolved Issues' filter -->
+  <widgets id="4" dashboard_id="1" widget_key="reviews_per_developer" name="[null]" description="[null]"
+     column_index="1" row_index="4" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+
+  <!-- 'Unresolved Issues Per Status' - replaced by project_issue_filter w/ 'Unresolved Issues' filter -->
+  <widgets id="5" dashboard_id="1" widget_key="unresolved_issues_statuses" name="[null]" description="[null]"
+     column_index="1" row_index="5" configured="true" created_at="[null]" updated_at="[null]" resource_id="[null]"/>
+
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/empty.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RenameIssueWidgetsTest/empty.xml
new file mode 100644 (file)
index 0000000..871dedc
--- /dev/null
@@ -0,0 +1,3 @@
+<dataset>
+
+</dataset>
index 4cb08989823d787715f73bc5d3d6d4208c4c7cf2..20bde27df8a1883fc436ce4e2e0721a896517c1c 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.core.dashboard;
 import org.apache.ibatis.annotations.Insert;
 import org.apache.ibatis.annotations.Options;
 import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
 
 import java.util.Collection;
 
@@ -43,4 +44,21 @@ public interface WidgetMapper {
 
   @Select("select " + COLUMNS + " from widgets where dashboard_id=#{id}")
   Collection<WidgetDto> selectByDashboard(long dashboardKey);
+
+  @Select("select " + COLUMNS + " from widgets")
+  Collection<WidgetDto> selectAll();
+
+  @Update("UPDATE widgets SET " +
+    "dashboard_id=#{dashboardId}, " +
+    "widget_key=#{widgetKey}, " +
+    "name=#{name}, " +
+    "description=#{description}, " +
+    "column_index=#{columnIndex}, " +
+    "row_index=#{rowIndex}, " +
+    "configured=#{configured}, " +
+    "created_at=#{createdAt}, " +
+    "updated_at=#{updatedAt}, " +
+    "resource_id=#{resourceId} " +
+    "WHERE id=#{id}")
+  void update(WidgetDto item);
 }
index eef4681890482b0d9db9584b16ad1aa0b973c845..43a473f1ff6110bc6d5129fc632d20e6a8c5f555 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.ibatis.annotations.Select;
 import javax.annotation.CheckForNull;
 
 import java.util.Collection;
+import java.util.List;
 
 public interface WidgetPropertyMapper {
 
@@ -42,4 +43,6 @@ public interface WidgetPropertyMapper {
   @Select("select " + COLUMNS + " from widget_properties wp " +
     "inner join widgets w on w.id=wp.widget_id where w.dashboard_id=#{id}")
   Collection<WidgetPropertyDto> selectByDashboard(long dashboardKey);
+
+  void deleteByWidgetIds(List<Long> widgetIds);
 }
index a8c253e61b394d2e3f7b56e81a0e1768adc0c70b..770c503de03d6c06d379e61297480e875fad699b 100644 (file)
@@ -23,6 +23,7 @@ package org.sonar.core.issue.db;
 import org.apache.ibatis.session.SqlSession;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.ServerComponent;
+import org.sonar.core.persistence.DaoComponent;
 import org.sonar.core.persistence.MyBatis;
 
 import javax.annotation.CheckForNull;
@@ -32,7 +33,7 @@ import java.util.List;
 /**
  * @since 3.7
  */
-public class IssueFilterDao implements BatchComponent, ServerComponent {
+public class IssueFilterDao implements BatchComponent, ServerComponent, DaoComponent {
 
   private final MyBatis mybatis;
 
index ed1109dc856448b65623595e560df28348335751..e4744f930753bd1333e49fb0db3a164deddb1c99 100644 (file)
@@ -3,4 +3,10 @@
 
 <mapper namespace="org.sonar.core.dashboard.WidgetPropertyMapper">
 
+  <delete id="deleteByWidgetIds" parameterType="map">
+  DELETE FROM widget_properties
+  WHERE widget_id IN
+    <foreach collection="list" open="(" close=")" item="wid" separator=",">#{wid}</foreach>
+  </delete>
+
 </mapper>