]> source.dussan.org Git - sonarqube.git/commitdiff
Create 'My Favourites' Dashboard through extension point.
authorDavid Gageot <david@gageot.net>
Fri, 25 May 2012 06:45:45 +0000 (08:45 +0200)
committerDavid Gageot <david@gageot.net>
Fri, 25 May 2012 06:59:32 +0000 (08:59 +0200)
The dashboard is created but not activated.

18 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/AbstractFilterDashboard.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboard.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectsDashboard.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/TreemapDashboard.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboardTest.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/dashboard/ActiveDashboardDto.java
sonar-core/src/main/java/org/sonar/core/dashboard/WidgetDto.java
sonar-core/src/main/java/org/sonar/core/dashboard/WidgetPropertyDto.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-derby.sql
sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterNewDashboards.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java
sonar-server/src/main/webapp/WEB-INF/db/migrate/305_ignore_loaded_dashboards.rb
sonar-server/src/test/java/org/sonar/server/startup/RegisterNewDashboardsTest.java
sonar-server/src/test/java/org/sonar/server/startup/RegisterNewFiltersTest.java
sonar-testing-harness/src/main/java/org/sonar/test/MoreConditions.java
sonar-testing-harness/src/test/java/org/sonar/test/MoreConditionsTest.java

index 21f7e163bc67cd099f0f7f1624e283c8152b3eba..b2d3748cff1c8a094e4012a8bf1bad60fba7972d 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.plugins.core;
 
+import org.sonar.plugins.core.dashboards.MyFavouritesDashboard;
+
 import com.google.common.collect.Lists;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.Extension;
@@ -344,6 +346,7 @@ public final class CorePlugin extends SonarPlugin {
     extensions.add(TimeMachineDashboard.class);
     extensions.add(ProjectsDashboard.class);
     extensions.add(TreemapDashboard.class);
+    extensions.add(MyFavouritesDashboard.class);
 
     // chart
     extensions.add(XradarChart.class);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/AbstractFilterDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/AbstractFilterDashboard.java
new file mode 100644 (file)
index 0000000..7f824f9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.widgets.FilterWidget;
+
+import org.sonar.api.web.Dashboard.Widget;
+
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.api.web.DashboardTemplate;
+
+/**
+ * Base class for global dashboard containing a single
+ * filter widget.
+ *
+ * @since 3.1
+ */
+abstract class AbstractFilterDashboard extends DashboardTemplate {
+  protected abstract String getFilterKey();
+
+  @Override
+  public Dashboard createDashboard() {
+    Dashboard dashboard = Dashboard.create()
+        .setGlobal(true)
+        .setLayout(DashboardLayout.ONE_COLUMN);
+
+    Widget filterWidget = dashboard.addWidget("filter", 1)
+        .setProperty(FilterWidget.FILTER, getFilterKey());
+
+    return dashboard;
+  }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboard.java
new file mode 100644 (file)
index 0000000..8e0e658
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 new MyFavouritesFilter().getName();
+  }
+
+  @Override
+  public Dashboard createDashboard() {
+    return super.createDashboard().setActivated(false);
+  }
+}
\ No newline at end of file
index 3483cee48669bb4f1c1229a1bda89d821e34e266..49fd4f3043a93963d4a8975738b2983ffd2c5d54 100644 (file)
  */
 package org.sonar.plugins.core.dashboards;
 
-import org.sonar.plugins.core.widgets.FilterWidget;
-
-import org.sonar.api.web.Dashboard.Widget;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
+import org.sonar.plugins.core.filters.ProjectFilter;
 
 /**
  * Projects global dashboard for Sonar
  *
  * @since 3.1
  */
-public final class ProjectsDashboard extends DashboardTemplate {
+public final class ProjectsDashboard extends AbstractFilterDashboard {
   @Override
   public String getName() {
     return "Projects";
   }
 
   @Override
-  public Dashboard createDashboard() {
-    Dashboard dashboard = Dashboard.create();
-    dashboard.setGlobal(true);
-    dashboard.setLayout(DashboardLayout.ONE_COLUMN);
-
-    Widget filterWidget = dashboard.addWidget("filter", 1);
-    filterWidget.setProperty(FilterWidget.FILTER, "Projects");
-
-    return dashboard;
+  protected String getFilterKey() {
+    return new ProjectFilter().getName();
   }
 }
\ No newline at end of file
index f782704c4eb81e7e786f1595fc886fb4d79b7d58..29bf58530bba89ad2a1df4e050703fe74fbf6da5 100644 (file)
  */
 package org.sonar.plugins.core.dashboards;
 
-import org.sonar.plugins.core.widgets.FilterWidget;
-
-import org.sonar.api.web.Dashboard.Widget;
-
-import org.sonar.api.web.Dashboard;
-import org.sonar.api.web.DashboardLayout;
-import org.sonar.api.web.DashboardTemplate;
+import org.sonar.plugins.core.filters.TreeMapFilter;
 
 /**
  * Treemap global dashboard for Sonar
  *
  * @since 3.1
  */
-public final class TreemapDashboard extends DashboardTemplate {
+public final class TreemapDashboard extends AbstractFilterDashboard {
   @Override
   public String getName() {
     return "Treemap";
   }
 
   @Override
-  public Dashboard createDashboard() {
-    Dashboard dashboard = Dashboard.create();
-    dashboard.setGlobal(true);
-    dashboard.setLayout(DashboardLayout.ONE_COLUMN);
-
-    Widget filterWidget = dashboard.addWidget("filter", 1);
-    filterWidget.setProperty(FilterWidget.FILTER, "Treemap");
-
-    return dashboard;
+  protected String getFilterKey() {
+    return new TreeMapFilter().getName();
   }
 }
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboardTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/MyFavouritesDashboardTest.java
new file mode 100644 (file)
index 0000000..d3cd570
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 org.sonar.plugins.core.filters.MyFavouritesFilter;
+import org.sonar.plugins.core.widgets.FilterWidget;
+
+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(new FilterWidget().getId());
+    assertThat(widget.getProperty("filter")).isEqualTo(new MyFavouritesFilter().getName());
+  }
+}
index a4cc714262dca098359c4cb71e40b011745ab841..8df7d3a460d848554dd2af6726222eb658bb4957 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.core.dashboard;
 
-public final class ActiveDashboardDto {
+import com.google.common.base.Objects;
 
+public final class ActiveDashboardDto {
   private Long id;
   private Long dashboardId;
   private Long userId;
@@ -36,8 +37,9 @@ public final class ActiveDashboardDto {
   /**
    * @param id the id to set
    */
-  public void setId(Long id) {
+  public ActiveDashboardDto setId(Long id) {
     this.id = id;
+    return this;
   }
 
   /**
@@ -50,8 +52,9 @@ public final class ActiveDashboardDto {
   /**
    * @param dashboardId the dashboardId to set
    */
-  public void setDashboardId(Long dashboardId) {
+  public ActiveDashboardDto setDashboardId(Long dashboardId) {
     this.dashboardId = dashboardId;
+    return this;
   }
 
   /**
@@ -64,8 +67,9 @@ public final class ActiveDashboardDto {
   /**
    * @param userId the userId to set
    */
-  public void setUserId(Long userId) {
+  public ActiveDashboardDto setUserId(Long userId) {
     this.userId = userId;
+    return this;
   }
 
   /**
@@ -78,8 +82,9 @@ public final class ActiveDashboardDto {
   /**
    * @param orderIndex the orderIndex to set
    */
-  public void setOrderIndex(Integer orderIndex) {
+  public ActiveDashboardDto setOrderIndex(Integer orderIndex) {
     this.orderIndex = orderIndex;
+    return this;
   }
 
   @Override
@@ -92,11 +97,10 @@ public final class ActiveDashboardDto {
     }
     ActiveDashboardDto that = (ActiveDashboardDto) o;
     return !(id != null ? !id.equals(that.id) : that.id != null);
-
   }
 
   @Override
   public int hashCode() {
-    return id != null ? id.hashCode() : 0;
+    return Objects.hashCode(id);
   }
 }
index 87c62115f542322cf600e94a3c5e3846d1f602bb..2674481299c30471d71d31731e23750916f9e438 100644 (file)
@@ -26,7 +26,6 @@ import java.util.Date;
 import java.util.List;
 
 public final class WidgetDto {
-
   private Long id;
   private Long dashboardId;
   private String key;
@@ -50,8 +49,9 @@ public final class WidgetDto {
   /**
    * @param id the id to set
    */
-  public void setId(Long id) {
+  public WidgetDto setId(Long id) {
     this.id = id;
+    return this;
   }
 
   /**
@@ -64,8 +64,9 @@ public final class WidgetDto {
   /**
    * @param dashboardId the dashboardId to set
    */
-  public void setDashboardId(Long dashboardId) {
+  public WidgetDto setDashboardId(Long dashboardId) {
     this.dashboardId = dashboardId;
+    return this;
   }
 
   /**
@@ -78,8 +79,9 @@ public final class WidgetDto {
   /**
    * @param key the key to set
    */
-  public void setKey(String key) {
+  public WidgetDto setKey(String key) {
     this.key = key;
+    return this;
   }
 
   /**
@@ -92,8 +94,9 @@ public final class WidgetDto {
   /**
    * @param name the name to set
    */
-  public void setName(String name) {
+  public WidgetDto setName(String name) {
     this.name = name;
+    return this;
   }
 
   /**
@@ -106,8 +109,9 @@ public final class WidgetDto {
   /**
    * @param description the description to set
    */
-  public void setDescription(String description) {
+  public WidgetDto setDescription(String description) {
     this.description = description;
+    return this;
   }
 
   /**
@@ -120,8 +124,9 @@ public final class WidgetDto {
   /**
    * @param columnIndex the columnIndex to set
    */
-  public void setColumnIndex(Integer columnIndex) {
+  public WidgetDto setColumnIndex(Integer columnIndex) {
     this.columnIndex = columnIndex;
+    return this;
   }
 
   /**
@@ -134,8 +139,9 @@ public final class WidgetDto {
   /**
    * @param rowIndex the rowIndex to set
    */
-  public void setRowIndex(Integer rowIndex) {
+  public WidgetDto setRowIndex(Integer rowIndex) {
     this.rowIndex = rowIndex;
+    return this;
   }
 
   /**
@@ -148,8 +154,9 @@ public final class WidgetDto {
   /**
    * @param configured the configured to set
    */
-  public void setConfigured(boolean configured) {
+  public WidgetDto setConfigured(boolean configured) {
     this.configured = configured;
+    return this;
   }
 
   /**
@@ -162,8 +169,9 @@ public final class WidgetDto {
   /**
    * @param createdAt the createdAt to set
    */
-  public void setCreatedAt(Date createdAt) {
+  public WidgetDto setCreatedAt(Date createdAt) {
     this.createdAt = createdAt;
+    return this;
   }
 
   /**
@@ -176,8 +184,9 @@ public final class WidgetDto {
   /**
    * @param updatedAt the updatedAt to set
    */
-  public void setUpdatedAt(Date updatedAt) {
+  public WidgetDto setUpdatedAt(Date updatedAt) {
     this.updatedAt = updatedAt;
+    return this;
   }
 
   /**
@@ -190,8 +199,9 @@ public final class WidgetDto {
   /**
    * @param widgetPropertyDto the widgetProperty to set
    */
-  public void addWidgetProperty(WidgetPropertyDto widgetPropertyDto) {
+  public WidgetDto addWidgetProperty(WidgetPropertyDto widgetPropertyDto) {
     widgetPropertyDtos.add(widgetPropertyDto);
+    return this;
   }
 
   /**
@@ -206,8 +216,8 @@ public final class WidgetDto {
    * @param resourceId the resourceId to set
    * @since 3.1
    */
-  public void setResourceId(Integer resourceId) {
+  public WidgetDto setResourceId(Integer resourceId) {
     this.resourceId = resourceId;
+    return this;
   }
-
 }
index e622804f3ab02fdbe52fd9d50d8f3b90bf33a6c4..d2450c61e0ad1d1f69621d7828acf8da4c58f3be 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.core.dashboard;
 
 public final class WidgetPropertyDto {
-
   private Long id;
   private Long widgetId;
   private String key;
@@ -36,8 +35,9 @@ public final class WidgetPropertyDto {
   /**
    * @param id the id to set
    */
-  public void setId(Long id) {
+  public WidgetPropertyDto setId(Long id) {
     this.id = id;
+    return this;
   }
 
   /**
@@ -50,8 +50,9 @@ public final class WidgetPropertyDto {
   /**
    * @param widgetId the widgetId to set
    */
-  public void setWidgetId(Long widgetId) {
+  public WidgetPropertyDto setWidgetId(Long widgetId) {
     this.widgetId = widgetId;
+    return this;
   }
 
   /**
@@ -64,8 +65,9 @@ public final class WidgetPropertyDto {
   /**
    * @param key the key to set
    */
-  public void setKey(String key) {
+  public WidgetPropertyDto setKey(String key) {
     this.key = key;
+    return this;
   }
 
   /**
@@ -78,8 +80,8 @@ public final class WidgetPropertyDto {
   /**
    * @param value the value to set
    */
-  public void setValue(String value) {
+  public WidgetPropertyDto setValue(String value) {
     this.value = value;
+    return this;
   }
-
 }
index 52fd3ebd7b6f0a3efb120beefe1cdddeaf4acb1b..07abf09b976a2ea65ab2aef779ba2bd4df936f16 100644 (file)
@@ -1,14 +1,5 @@
 -- All the rows inserted during Rails migrations. Rows inserted during server startup tasks (Java) are excluded : rules, profiles, metrics, ...
 
-INSERT INTO DASHBOARDS(ID, USER_ID, NAME, DESCRIPTION, COLUMN_LAYOUT, SHARED, IS_GLOBAL) VALUES (1, null, 'My favourites', null, '100%', true, true);
-ALTER TABLE DASHBOARDS ALTER COLUMN ID RESTART WITH 2;
-
-INSERT INTO WIDGETS(ID, DASHBOARD_ID, WIDGET_KEY, NAME, DESCRIPTION, COLUMN_INDEX, ROW_INDEX, CONFIGURED, RESOURCE_ID) VALUES (1, 1, 'filter', 'Filter', null, 1, 1, true , null);
-ALTER TABLE WIDGETS ALTER COLUMN ID RESTART WITH 2;
-
-INSERT INTO WIDGET_PROPERTIES(ID, WIDGET_ID, KEE, TEXT_VALUE) VALUES (1, 1, 'filter', 'My favourites');
-ALTER TABLE WIDGET_PROPERTIES ALTER COLUMN ID RESTART WITH 2;
-
 INSERT INTO GROUP_ROLES(ID, GROUP_ID, RESOURCE_ID, ROLE) VALUES (1, 1, null, 'admin');
 INSERT INTO GROUP_ROLES(ID, GROUP_ID, RESOURCE_ID, ROLE) VALUES (2, 1, null, 'default-admin');
 INSERT INTO GROUP_ROLES(ID, GROUP_ID, RESOURCE_ID, ROLE) VALUES (3, 2, null, 'default-user');
index e914142116e2902e02f6b214ecf47beaedb3967e..6b6a60c24a1e1f0a1c36cd854aafe0d940a58d57 100644 (file)
@@ -41,6 +41,7 @@ public final class Dashboard {
   private DashboardLayout layout = DashboardLayout.TWO_COLUMNS;
   private ListMultimap<Integer, Widget> widgetsByColumn = ArrayListMultimap.create();
   private boolean global = false;
+  private boolean activated = true;
 
   private Dashboard() {
   }
@@ -137,6 +138,27 @@ public final class Dashboard {
     return this;
   }
 
+  /**
+   * A dashboard can be activated for all anonymous users or users who haven't configured their own dashboards.
+   * <p>Before version 3.1 every dashboard created through this extension point was automatically activated.
+   * This is still the default behavior.</p>
+   *
+   * @since 3.1
+   */
+  public boolean isActivated() {
+    return activated;
+  }
+
+  /**
+   * Set whether the dashboard is activated for all anonymous users or users who haven't configured their own dashboards.
+   *
+   * @since 3.1
+   */
+  public Dashboard setActivated(boolean activated) {
+    this.activated = activated;
+    return this;
+  }
+
   /**
    * Note that this class is an inner class to avoid confusion with the extension point org.sonar.api.web.Widget.
    */
@@ -176,5 +198,4 @@ public final class Dashboard {
       return id;
     }
   }
-
 }
index e284678871a999656fc767669554d8cd3fff5d52..d601f2de2c50086a7fc075f24c973b0f5c0688d8 100644 (file)
 package org.sonar.server.startup;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.utils.TimeProfiler;
 import org.sonar.api.web.Dashboard;
 import org.sonar.api.web.DashboardTemplate;
-import org.sonar.core.dashboard.*;
+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.template.LoadedTemplateDao;
 import org.sonar.core.template.LoadedTemplateDto;
 
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 import java.util.Map.Entry;
@@ -39,18 +43,13 @@ import java.util.Map.Entry;
  * @since 2.13
  */
 public final class RegisterNewDashboards {
-
   private static final Logger LOG = LoggerFactory.getLogger(RegisterNewDashboards.class);
   static final String DEFAULT_DASHBOARD_NAME = "Dashboard";
 
-  private List<DashboardTemplate> dashboardTemplates;
-  private DashboardDao dashboardDao;
-  private ActiveDashboardDao activeDashboardDao;
-  private LoadedTemplateDao loadedTemplateDao;
-
-  public RegisterNewDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) {
-    this(new DashboardTemplate[] {}, dashboardDao, activeDashboardDao, loadedTemplateDao);
-  }
+  private final List<DashboardTemplate> dashboardTemplates;
+  private final DashboardDao dashboardDao;
+  private final ActiveDashboardDao activeDashboardDao;
+  private final LoadedTemplateDao loadedTemplateDao;
 
   public RegisterNewDashboards(DashboardTemplate[] dashboardTemplatesArray, DashboardDao dashboardDao,
       ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) {
@@ -68,7 +67,7 @@ public final class RegisterNewDashboards {
       if (shouldRegister(template.getName())) {
         Dashboard dashboard = template.createDashboard();
         DashboardDto dto = register(template.getName(), dashboard);
-        if (dto != null) {
+        if ((dto != null) && (dashboard.isActivated())) {
           registeredDashboards.add(dto);
         }
       }
@@ -81,17 +80,18 @@ public final class RegisterNewDashboards {
 
   protected void activate(List<DashboardDto> loadedDashboards) {
     int nextOrderIndex = activeDashboardDao.selectMaxOrderIndexForNullUser() + 1;
-    Collections.sort(loadedDashboards, new DashboardComparator());
-    for (DashboardDto dashboardDto : loadedDashboards) {
+
+    for (DashboardDto dashboardDto : new DashboardOrdering().sortedCopy(loadedDashboards)) {
       activate(dashboardDto, nextOrderIndex++);
     }
   }
 
   private void activate(DashboardDto dashboardDto, int index) {
-    ActiveDashboardDto activeDashboardDto = new ActiveDashboardDto();
-    activeDashboardDto.setDashboardId(dashboardDto.getId());
-    activeDashboardDto.setOrderIndex(index);
+    ActiveDashboardDto activeDashboardDto = new ActiveDashboardDto()
+        .setDashboardId(dashboardDto.getId())
+        .setOrderIndex(index);
     activeDashboardDao.insert(activeDashboardDto);
+
     LOG.info("New dashboard '" + dashboardDto.getName() + "' registered");
   }
 
@@ -108,36 +108,36 @@ public final class RegisterNewDashboards {
 
   protected DashboardDto createDtoFromExtension(String name, Dashboard dashboard) {
     Date now = new Date();
-    DashboardDto dashboardDto = new DashboardDto();
-    dashboardDto.setName(name);
-    dashboardDto.setDescription(dashboard.getDescription());
-    dashboardDto.setColumnLayout(dashboard.getLayout().getCode());
-    dashboardDto.setShared(true);
-    dashboardDto.setGlobal(dashboard.isGlobal());
-    dashboardDto.setCreatedAt(now);
-    dashboardDto.setUpdatedAt(now);
+
+    DashboardDto dashboardDto = new DashboardDto()
+        .setName(name)
+        .setDescription(dashboard.getDescription())
+        .setColumnLayout(dashboard.getLayout().getCode())
+        .setShared(true)
+        .setGlobal(dashboard.isGlobal())
+        .setCreatedAt(now)
+        .setUpdatedAt(now);
 
     for (int columnIndex = 1; columnIndex <= dashboard.getLayout().getColumns(); columnIndex++) {
       List<Dashboard.Widget> widgets = dashboard.getWidgetsOfColumn(columnIndex);
       for (int rowIndex = 1; rowIndex <= widgets.size(); rowIndex++) {
         Dashboard.Widget widget = widgets.get(rowIndex - 1);
-        WidgetDto widgetDto = new WidgetDto();
-        widgetDto.setKey(widget.getId());
-        widgetDto.setColumnIndex(columnIndex);
-        widgetDto.setRowIndex(rowIndex);
-        widgetDto.setConfigured(true);
-        widgetDto.setCreatedAt(now);
-        widgetDto.setUpdatedAt(now);
+        WidgetDto widgetDto = new WidgetDto()
+            .setKey(widget.getId())
+            .setColumnIndex(columnIndex)
+            .setRowIndex(rowIndex)
+            .setConfigured(true)
+            .setCreatedAt(now)
+            .setUpdatedAt(now);
         dashboardDto.addWidget(widgetDto);
 
         for (Entry<String, String> property : widget.getProperties().entrySet()) {
-          WidgetPropertyDto propDto = new WidgetPropertyDto();
-          propDto.setKey(property.getKey());
-          propDto.setValue(property.getValue());
+          WidgetPropertyDto propDto = new WidgetPropertyDto()
+              .setKey(property.getKey())
+              .setValue(property.getValue());
           widgetDto.addWidgetProperty(propDto);
         }
       }
-
     }
     return dashboardDto;
   }
@@ -146,7 +146,8 @@ public final class RegisterNewDashboards {
     return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.DASHBOARD_TYPE, dashboardName) == 0;
   }
 
-  protected static class DashboardComparator implements Comparator<DashboardDto> {
+  private static class DashboardOrdering extends Ordering<DashboardDto> {
+    @Override
     public int compare(DashboardDto d1, DashboardDto d2) {
       // the default dashboard must be the first one to be activated
       if (d1.getName().equals(DEFAULT_DASHBOARD_NAME)) {
@@ -158,5 +159,4 @@ public final class RegisterNewDashboards {
       return d1.getName().compareTo(d2.getName());
     }
   }
-
 }
index 01e33d0fb6c8f9a6b422d7524a8ef1f9188230ea..470a2eeaad51538768911e6393308d2828d8b4ef 100644 (file)
@@ -46,13 +46,6 @@ public final class RegisterNewFilters {
   private final FilterDao filterDao;
   private final LoadedTemplateDao loadedTemplateDao;
 
-  /**
-   * Constructor used in case there is no {@link FilterTemplate}.
-   */
-  public RegisterNewFilters(FilterDao filterDao, LoadedTemplateDao loadedTemplateDao) {
-    this(new FilterTemplate[0], filterDao, loadedTemplateDao);
-  }
-
   public RegisterNewFilters(FilterTemplate[] filterTemplates, FilterDao filterDao, LoadedTemplateDao loadedTemplateDao) {
     this.filterTemplates = ImmutableList.copyOf(filterTemplates);
     this.filterDao = filterDao;
index 75dd8c7a7be8e05bf41540889a09dda7b34e48c8..88bd4213c6d92e37013951ff9aa6955005ec44cb 100644 (file)
@@ -31,6 +31,7 @@ class IgnoreLoadedDashboards < ActiveRecord::Migration
   def self.up
     mark_dashboard_as_loaded('Projects')
     mark_dashboard_as_loaded('Treemap')
+    mark_dashboard_as_loaded('My Favourites')
   end
 
   def self.mark_dashboard_as_loaded(name)
index b7c9c82993c34d6520ba979052aae737b4b35314..89959de4dcde59045976e9bed5f2b87afc343f45 100644 (file)
  */
 package org.sonar.server.startup;
 
-import com.google.common.collect.Lists;
+import com.google.common.collect.Iterables;
 import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentMatcher;
 import org.sonar.api.web.Dashboard;
 import org.sonar.api.web.DashboardLayout;
 import org.sonar.api.web.DashboardTemplate;
@@ -36,22 +36,20 @@ import org.sonar.core.dashboard.WidgetPropertyDto;
 import org.sonar.core.template.LoadedTemplateDao;
 import org.sonar.core.template.LoadedTemplateDto;
 
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.List;
 
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.argThat;
 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 RegisterNewDashboardsTest {
-
   private RegisterNewDashboards task;
   private DashboardDao dashboardDao;
   private ActiveDashboardDao activeDashboardDao;
@@ -63,16 +61,18 @@ public class RegisterNewDashboardsTest {
     dashboardDao = mock(DashboardDao.class);
     activeDashboardDao = mock(ActiveDashboardDao.class);
     loadedTemplateDao = mock(LoadedTemplateDao.class);
+    fakeDashboardTemplate = mock(DashboardTemplate.class);
 
-    fakeDashboardTemplate = new FakeDashboard();
-
-    task = new RegisterNewDashboards(new DashboardTemplate[]{fakeDashboardTemplate}, dashboardDao,
+    task = new RegisterNewDashboards(new DashboardTemplate[] {fakeDashboardTemplate}, dashboardDao,
         activeDashboardDao, loadedTemplateDao);
   }
 
   @Test
   public void testStart() {
+    when(fakeDashboardTemplate.createDashboard()).thenReturn(Dashboard.create());
+
     task.start();
+
     verify(dashboardDao).insert(any(DashboardDto.class));
     verify(loadedTemplateDao).insert(any(LoadedTemplateDto.class));
     verify(activeDashboardDao).insert(any(ActiveDashboardDto.class));
@@ -81,116 +81,100 @@ public class RegisterNewDashboardsTest {
   @Test
   public void shouldNotRegister() {
     when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.DASHBOARD_TYPE, "Fake")).thenReturn(1);
-    assertThat(task.shouldRegister("Fake"), is(false));
+
+    assertThat(task.shouldRegister("Fake")).isFalse();
   }
 
   @Test
   public void shouldRegisterDashboard() {
     when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.DASHBOARD_TYPE, "Fake")).thenReturn(0);
-    assertThat(task.shouldRegister("Fake"), is(true));
+
+    assertThat(task.shouldRegister("Fake")).isTrue();
   }
 
   @Test
-  public void testRegisterDashboard() {
+  public void should_register_and_activate_dashboard() {
+    when(fakeDashboardTemplate.createDashboard()).thenReturn(Dashboard.create());
+
     DashboardDto dashboardDto = task.register("Fake", fakeDashboardTemplate.createDashboard());
 
-    assertNotNull(dashboardDto);
-    verify(dashboardDao).insert(dashboardDto);
+    verify(dashboardDao).insert(any(DashboardDto.class));
     verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.DASHBOARD_TYPE)));
   }
 
   @Test
-  public void shouldCreateDtoFromExtension() {
-    DashboardDto dto = task.createDtoFromExtension("Fake", fakeDashboardTemplate.createDashboard());
-    assertThat(dto.getUserId(), is(nullValue()));
-    assertThat(dto.getName(), is("Fake"));
-    assertThat(dto.getDescription(), nullValue());
-    assertThat(dto.getColumnLayout(), is("30%-70%"));
-    assertThat(dto.getShared(), is(true));
-    assertThat(dto.getGlobal(), is(true));
-    assertNotNull(dto.getCreatedAt());
-    assertNotNull(dto.getUpdatedAt());
-
-    WidgetDto widgetDto = dto.getWidgets().iterator().next();
-    assertThat(widgetDto.getKey(), is("fake-widget"));
-    assertThat(widgetDto.getDescription(), is(nullValue()));
-    assertThat(widgetDto.getColumnIndex(), is(1));
-    assertThat(widgetDto.getRowIndex(), is(1));
-    assertThat(widgetDto.getConfigured(), is(true));
-    assertNotNull(widgetDto.getCreatedAt());
-    assertNotNull(widgetDto.getUpdatedAt());
-
-    WidgetPropertyDto widgetPropertyDto = widgetDto.getWidgetProperties().iterator().next();
-    assertThat(widgetPropertyDto.getKey(), is("fake-property"));
-    assertThat(widgetPropertyDto.getValue(), is("fake_metric"));
-  }
+  public void should_activate_dashboard() {
+    Dashboard dashboard = Dashboard.create();
+    when(fakeDashboardTemplate.createDashboard()).thenReturn(dashboard);
 
-  @Test
-  public void shouldCompareDashboards() throws Exception {
-    DashboardDto d1 = new DashboardDto().setName("Foo");
-    DashboardDto d2 = new DashboardDto().setName("Bar");
-    List<DashboardDto> dashboardDtos = Lists.newArrayList(d1, d2);
-    Collections.sort(dashboardDtos, new RegisterNewDashboards.DashboardComparator());
+    task.start();
 
-    assertThat(dashboardDtos.get(0).getName(), is("Bar"));
+    verify(activeDashboardDao).insert(any(ActiveDashboardDto.class));
   }
 
   @Test
-  public void shouldActivateDashboards() throws Exception {
-    DashboardDto d1 = new DashboardDto().setName("Foo").setId(14L);
-    DashboardDto d2 = new DashboardDto().setName("Bar").setId(16L);
-    List<DashboardDto> loadedDashboards = Lists.newArrayList(d1, d2);
+  public void should_disable_activation() {
+    Dashboard dashboard = Dashboard.create();
+    dashboard.setActivated(false);
+    when(fakeDashboardTemplate.createDashboard()).thenReturn(dashboard);
+
+    task.start();
 
-    when(activeDashboardDao.selectMaxOrderIndexForNullUser()).thenReturn(4);
+    verify(activeDashboardDao, never()).insert(any(ActiveDashboardDto.class));
+  }
 
-    task.activate(loadedDashboards);
+  @Test
+  public void shouldCreateDtoFromExtension() {
+    Dashboard dashboard = Dashboard.create()
+        .setGlobal(true)
+        .setLayout(DashboardLayout.TWO_COLUMNS_30_70);
+    Dashboard.Widget widget = dashboard.addWidget("fake-widget", 1);
+    widget.setProperty("fake-property", "fake_metric");
+    when(fakeDashboardTemplate.createDashboard()).thenReturn(dashboard);
 
-    verify(activeDashboardDao).insert(argThat(matchActiveDashboard(16L, 5)));
-    verify(activeDashboardDao).insert(argThat(matchActiveDashboard(14L, 6)));
+    DashboardDto dto = task.createDtoFromExtension("Fake", fakeDashboardTemplate.createDashboard());
+    assertThat(dto.getUserId()).isNull();
+    assertThat(dto.getName()).isEqualTo("Fake");
+    assertThat(dto.getDescription()).isNull();
+    assertThat(dto.getColumnLayout()).isEqualTo("30%-70%");
+    assertThat(dto.getShared()).isTrue();
+    assertThat(dto.getGlobal()).isTrue();
+    assertThat(dto.getCreatedAt()).isNotNull();
+    assertThat(dto.getUpdatedAt()).isNotNull();
+
+    WidgetDto widgetDto = Iterables.getOnlyElement(dto.getWidgets());
+    assertThat(widgetDto.getKey()).isEqualTo("fake-widget");
+    assertThat(widgetDto.getDescription()).isNull();
+    assertThat(widgetDto.getColumnIndex()).isEqualTo(1);
+    assertThat(widgetDto.getRowIndex()).isEqualTo(1);
+    assertThat(widgetDto.getConfigured()).isTrue();
+    assertThat(widgetDto.getCreatedAt()).isNotNull();
+    assertThat(widgetDto.getUpdatedAt()).isNotNull();
+
+    assertThat(widgetDto.getWidgetProperties()).satisfies(contains(new WidgetPropertyDto().setKey("fake-property").setValue("fake_metric")));
   }
 
   @Test
-  public void defaultDashboardShouldBeTheFirstActivatedDashboard() throws Exception {
-    DashboardDto defaultDashboard = new DashboardDto()
-      .setName(RegisterNewDashboards.DEFAULT_DASHBOARD_NAME)
-      .setId(10L);
-    DashboardDto other = new DashboardDto()
-      .setName("Bar")
-      .setId(11L);
-    List<DashboardDto> dashboards = Lists.newArrayList(other, defaultDashboard);
+  public void defaultDashboardShouldBeTheFirstActivatedDashboard() {
+    DashboardDto defaultDashboard = new DashboardDto().setId(10L).setName(RegisterNewDashboards.DEFAULT_DASHBOARD_NAME);
+    DashboardDto second = new DashboardDto().setId(11L).setName("Bar");
+    DashboardDto third = new DashboardDto().setId(12L).setName("Foo");
+    List<DashboardDto> dashboards = Arrays.asList(third, defaultDashboard, second);
 
     task.activate(dashboards);
 
-    verify(activeDashboardDao).insert(argThat(matchActiveDashboard(10L, 1)));
-    verify(activeDashboardDao).insert(argThat(matchActiveDashboard(11L, 2)));
+    verify(activeDashboardDao).insert(argThat(matchActiveDashboardDto(10L, 1)));
+    verify(activeDashboardDao).insert(argThat(matchActiveDashboardDto(11L, 2)));
+    verify(activeDashboardDao).insert(argThat(matchActiveDashboardDto(12L, 3)));
   }
 
-  private BaseMatcher<ActiveDashboardDto> matchActiveDashboard(final long dashboardId, final int orderId) {
-    return new BaseMatcher<ActiveDashboardDto>() {
+  private BaseMatcher<ActiveDashboardDto> matchActiveDashboardDto(final long dashboardId, final int orderId) {
+    return new ArgumentMatcher<ActiveDashboardDto>() {
+      @Override
       public boolean matches(Object o) {
         ActiveDashboardDto dto = (ActiveDashboardDto) o;
         return dto.getDashboardId() == dashboardId && dto.getOrderIndex() == orderId;
       }
-
-      public void describeTo(Description description) {
-      }
     };
   }
-
-  public class FakeDashboard extends DashboardTemplate {
-    @Override
-    public String getName() {
-      return "Fake";
-    }
-
-    @Override
-    public Dashboard createDashboard() {
-      Dashboard dashboard = Dashboard.create();
-      dashboard.setGlobal(true);
-      dashboard.setLayout(DashboardLayout.TWO_COLUMNS_30_70);
-      Dashboard.Widget widget = dashboard.addWidget("fake-widget", 1);
-      widget.setProperty("fake-property", "fake_metric");
-      return dashboard;
-    }
-  }
 }
index e4debe6d2cbd2cc9f33c95aabadb78f11a806dd6..e19969742d104beaa26a70cb0f59863c52bab903 100644 (file)
@@ -68,15 +68,6 @@ public class RegisterNewFiltersTest {
     verify(loadedTemplateDao).insert(any(LoadedTemplateDto.class));
   }
 
-  @Test
-  public void should_insert_nothing_if_no_template_is_available() {
-    register = new RegisterNewFilters(filterDao, loadedTemplateDao);
-    register.start();
-
-    verify(filterDao, never()).insert(any(FilterDto.class));
-    verify(loadedTemplateDao, never()).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);
index c06b78a65e60b4d3e3f21799a8eaf4c6996c9f25..0f4b24b5a5d8398dbd58d55bc38ae83777abcb94 100644 (file)
@@ -59,4 +59,13 @@ public final class MoreConditions {
       }
     };
   }
+
+  public static Condition<Object> reflectionEqualTo(final Object expected) {
+    return new Condition<Object>() {
+      @Override
+      public boolean matches(Object actual) {
+        return EqualsBuilder.reflectionEquals(expected, actual);
+      }
+    };
+  }
 }
index ad83811e9990d2c6e5f6492d25e9db015fb28335..6cdd18b53ad7ae4cd80617a9d5c647fc48fdadf5 100644 (file)
@@ -24,6 +24,8 @@ import org.junit.Test;
 import java.util.Arrays;
 import java.util.Collection;
 
+import static org.sonar.test.MoreConditions.reflectionEqualTo;
+
 import static org.fest.assertions.Assertions.assertThat;
 import static org.sonar.test.MoreConditions.contains;
 import static org.sonar.test.MoreConditions.equalsIgnoreEOL;
@@ -77,6 +79,24 @@ public class MoreConditionsTest {
     assertThat(collection).doesNotSatisfy(contains(new Bean("", "")));
   }
 
+  @Test
+  public void should_compare_using_reflection() {
+    Bean bean1 = new Bean("key1", "value1");
+    Bean bean2 = new Bean("key2", "value2");
+
+    assertThat(bean1).is(reflectionEqualTo(bean1));
+    assertThat(bean2).is(reflectionEqualTo(bean2));
+    assertThat(bean1).isNot(reflectionEqualTo(bean2));
+    assertThat(bean2).isNot(reflectionEqualTo(bean1));
+    assertThat(bean1).isNot(reflectionEqualTo(null));
+    assertThat(bean2).isNot(reflectionEqualTo(null));
+    assertThat(bean1).isNot(reflectionEqualTo(new Object()));
+    assertThat(bean2).isNot(reflectionEqualTo(new Object()));
+    assertThat(bean1).isNot(reflectionEqualTo(new Bean("key1", "value2")));
+    assertThat(bean1).isNot(reflectionEqualTo(new Bean("key2", "value1")));
+    assertThat(bean1).isNot(reflectionEqualTo(new Bean("", "")));
+  }
+
   static final class Bean {
     final String key;
     final String value;