From 67119fa339119ccdd0cd22feb9ac70af73531b21 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Fri, 18 May 2012 15:10:10 +0200 Subject: [PATCH] SONAR-3016 Draft of new extension point for filter template --- .../java/org/sonar/core/filter/FilterDao.java | 57 +++++++ .../java/org/sonar/core/filter/FilterDto.java | 152 ++++++++++++++++++ .../org/sonar/core/filter/FilterMapper.java | 29 ++++ .../org/sonar/core/persistence/DaoUtils.java | 9 +- .../org/sonar/core/persistence/MyBatis.java | 6 + .../core/template/LoadedTemplateDto.java | 10 +- .../sonar/core/filter/FilterMapper-oracle.xml | 20 +++ .../org/sonar/core/filter/FilterMapper.xml | 17 ++ .../org/sonar/core/filters/FilterDaoTest.java | 67 ++++++++ .../sonar/core/persistence/DaoUtilsTest.java | 11 +- .../FilterDaoTest/shouldFindFilter.xml | 27 ++++ .../FilterDaoTest/shouldInsert-result.xml | 15 ++ .../filters/FilterDaoTest/shouldInsert.xml | 3 + .../main/java/org/sonar/api/web/Filter.java | 40 +++++ .../org/sonar/api/web/FilterTemplate.java | 42 +++++ .../org/sonar/server/platform/Platform.java | 3 + .../server/startup/RegisterNewFilters.java | 108 +++++++++++++ .../startup/RegisterNewDashboardsTest.java | 2 +- .../startup/RegisterNewFiltersTest.java | 124 ++++++++++++++ 19 files changed, 728 insertions(+), 14 deletions(-) create mode 100644 sonar-core/src/main/java/org/sonar/core/filter/FilterDao.java create mode 100644 sonar-core/src/main/java/org/sonar/core/filter/FilterDto.java create mode 100644 sonar-core/src/main/java/org/sonar/core/filter/FilterMapper.java create mode 100644 sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper-oracle.xml create mode 100644 sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper.xml create mode 100644 sonar-core/src/test/java/org/sonar/core/filters/FilterDaoTest.java create mode 100644 sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldFindFilter.xml create mode 100644 sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert-result.xml create mode 100644 sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert.xml create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/web/Filter.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/web/FilterTemplate.java create mode 100644 sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java create mode 100644 sonar-server/src/test/java/org/sonar/server/startup/RegisterNewFiltersTest.java diff --git a/sonar-core/src/main/java/org/sonar/core/filter/FilterDao.java b/sonar-core/src/main/java/org/sonar/core/filter/FilterDao.java new file mode 100644 index 00000000000..be2f7b75504 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/filter/FilterDao.java @@ -0,0 +1,57 @@ +/* + * 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 mapper = session.getMapper(FilterMapper.class); + try { + mapper.insert(filterDto); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/filter/FilterDto.java b/sonar-core/src/main/java/org/sonar/core/filter/FilterDto.java new file mode 100644 index 00000000000..1075788ae1a --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/filter/FilterDto.java @@ -0,0 +1,152 @@ +/* + * 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.base.Objects; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * @since 3.1 + */ +public final class FilterDto { + private Long id; + private String name; + private Long userId; + private boolean shared; + private boolean favourites; + private Long resourceId; + private String defaultView; + private Long pageSize; + private Long periodIndex; + + public Long getId() { + return id; + } + + public FilterDto setId(Long id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public FilterDto setName(String name) { + this.name = name; + return this; + } + + public Long getUserId() { + return userId; + } + + public FilterDto setUserId(Long userId) { + this.userId = userId; + return this; + } + + public boolean isShared() { + return shared; + } + + public FilterDto setShared(boolean shared) { + this.shared = shared; + return this; + } + + public boolean isFavourites() { + return favourites; + } + + public FilterDto setFavourites(boolean favourites) { + this.favourites = favourites; + return this; + } + + public Long getResourceId() { + return resourceId; + } + + public FilterDto setResourceId(Long resourceId) { + this.resourceId = resourceId; + return this; + } + + public String getDefaultView() { + return defaultView; + } + + public FilterDto setDefaultView(String defaultView) { + this.defaultView = defaultView; + return this; + } + + public Long getPageSize() { + return pageSize; + } + + public FilterDto setPageSize(Long pageSize) { + this.pageSize = pageSize; + return this; + } + + public Long getPeriodIndex() { + return periodIndex; + } + + public FilterDto setPeriodIndex(Long periodIndex) { + this.periodIndex = periodIndex; + return this; + } + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FilterDto other = (FilterDto) o; + return Objects.equal(id, other.id) && + Objects.equal(name, other.name) && + Objects.equal(userId, other.userId) && + Objects.equal(shared, other.shared) && + Objects.equal(favourites, other.favourites) && + Objects.equal(resourceId, other.resourceId) && + Objects.equal(defaultView, other.defaultView) && + Objects.equal(pageSize, other.pageSize) && + Objects.equal(periodIndex, other.periodIndex); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/filter/FilterMapper.java b/sonar-core/src/main/java/org/sonar/core/filter/FilterMapper.java new file mode 100644 index 00000000000..75920978d57 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/filter/FilterMapper.java @@ -0,0 +1,29 @@ +/* + * 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 { + FilterDto findFilter(String name); + + void insert(FilterDto filterDto); +} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java index 58678318d35..e31a623cc97 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java @@ -19,9 +19,11 @@ */ package org.sonar.core.persistence; +import com.google.common.collect.ImmutableList; 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.properties.PropertiesDao; import org.sonar.core.purge.PurgeDao; import org.sonar.core.resource.ResourceDao; @@ -32,8 +34,6 @@ import org.sonar.core.rule.RuleDao; import org.sonar.core.template.LoadedTemplateDao; import org.sonar.core.user.AuthorDao; -import java.util.Arrays; -import java.util.Collections; import java.util.List; public final class DaoUtils { @@ -42,9 +42,10 @@ public final class DaoUtils { } public static List> getDaoClasses() { - return Collections.unmodifiableList(Arrays.asList( + return ImmutableList.of( ActiveDashboardDao.class, AuthorDao.class, + FilterDao.class, DashboardDao.class, DuplicationDao.class, LoadedTemplateDao.class, @@ -54,6 +55,6 @@ public final class DaoUtils { ResourceDao.class, ReviewCommentDao.class, ReviewDao.class, - RuleDao.class)); + RuleDao.class); } } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index 76bc1663da6..7c71f71ebc1 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -19,6 +19,10 @@ */ package org.sonar.core.persistence; +import org.sonar.core.filter.FilterDto; +import org.sonar.core.filter.FilterMapper; + + import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.builder.xml.XMLMapperBuilder; @@ -86,6 +90,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class); loadAlias(conf, "Author", AuthorDto.class); + loadAlias(conf, "Filter", FilterDto.class); loadAlias(conf, "Dashboard", DashboardDto.class); loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class); loadAlias(conf, "LoadedTemplate", LoadedTemplateDto.class); @@ -103,6 +108,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadMapper(conf, ActiveDashboardMapper.class); loadMapper(conf, AuthorMapper.class); + loadMapper(conf, FilterMapper.class); loadMapper(conf, DashboardMapper.class); loadMapper(conf, DuplicationMapper.class); loadMapper(conf, LoadedTemplateMapper.class); diff --git a/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDto.java b/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDto.java index 443ea7b48d4..eb6d4ef3205 100644 --- a/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDto.java +++ b/sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDto.java @@ -19,9 +19,12 @@ */ package org.sonar.core.template; +import com.google.common.base.Objects; + public final class LoadedTemplateDto { public static final String DASHBOARD_TYPE = "DASHBOARD"; + public static final String FILTER_TYPE = "FILTER"; private Long id; private String key; @@ -70,11 +73,8 @@ public final class LoadedTemplateDto { if (o == null || getClass() != o.getClass()) { return false; } - LoadedTemplateDto that = (LoadedTemplateDto) o; - if (id != null ? !id.equals(that.id) : that.id != null) { - return false; - } - return true; + LoadedTemplateDto other = (LoadedTemplateDto) o; + return Objects.equal(id, other.id) && Objects.equal(key, other.key) && Objects.equal(type, other.type); } @Override diff --git a/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper-oracle.xml b/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper-oracle.xml new file mode 100644 index 00000000000..854b0749ff8 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper-oracle.xml @@ -0,0 +1,20 @@ + + + + + + + + + + select filters_seq.NEXTVAL from DUAL + + INSERT INTO filters (id, name, user_id, shared, favourites, resource_id, default_view, page_size, period_index) + VALUES (#{id}, #{name, jdbcType=VARCHAR}, #{userId, jdbcType=FLOAT}, #{shared}, #{favourites}, #{resourceId, jdbcType=INTEGER}, #{defaultView, jdbcType=VARCHAR}, + #{pageSize, jdbcType=INTEGER}, #{periodIndex, jdbcType=INTEGER}) + + + diff --git a/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper.xml b/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper.xml new file mode 100644 index 00000000000..bd5859e55f4 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/filter/FilterMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + INSERT INTO filters (name, user_id, shared, favourites, resource_id, default_view, page_size, period_index) + VALUES (#{name, jdbcType=VARCHAR}, #{userId, jdbcType=FLOAT}, #{shared}, #{favourites}, #{resourceId, jdbcType=INTEGER}, #{defaultView, jdbcType=VARCHAR}, + #{pageSize, jdbcType=INTEGER}, #{periodIndex, jdbcType=INTEGER}) + + + diff --git a/sonar-core/src/test/java/org/sonar/core/filters/FilterDaoTest.java b/sonar-core/src/test/java/org/sonar/core/filters/FilterDaoTest.java new file mode 100644 index 00000000000..3ba871e4ba8 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/filters/FilterDaoTest.java @@ -0,0 +1,67 @@ +/* + * 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.FilterDao; +import org.sonar.core.filter.FilterDto; +import org.sonar.core.persistence.DaoTestCase; + +import static org.fest.assertions.Assertions.assertThat; + +public class FilterDaoTest extends DaoTestCase { + 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.getUserId()).isNull(); + assertThat(dao.findFilter("")).isNull(); + } + + @Test + public void should_insert() { + setupData("shouldInsert"); + + FilterDto filterDto = new FilterDto(); + filterDto.setName("Projects"); + filterDto.setUserId(null); + filterDto.setShared(true); + filterDto.setFavourites(false); + filterDto.setResourceId(null); + filterDto.setDefaultView("list"); + filterDto.setPageSize(10L); + filterDto.setPeriodIndex(1L); + + dao.insert(filterDto); + + checkTables("shouldInsert", "filters"); + } +} \ No newline at end of file diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/DaoUtilsTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/DaoUtilsTest.java index a3e97e5d008..760c3e8df32 100644 --- a/sonar-core/src/test/java/org/sonar/core/persistence/DaoUtilsTest.java +++ b/sonar-core/src/test/java/org/sonar/core/persistence/DaoUtilsTest.java @@ -21,13 +21,16 @@ package org.sonar.core.persistence; import org.junit.Test; -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertThat; +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; public class DaoUtilsTest { @Test - public void testGetDaoClasses() { - assertThat(DaoUtils.getDaoClasses().size(), greaterThan(1)); + public void should_list_all_dao_classes() { + List> daoClasses = DaoUtils.getDaoClasses(); + + assertThat(daoClasses.size()).isGreaterThan(1); } } diff --git a/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldFindFilter.xml b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldFindFilter.xml new file mode 100644 index 00000000000..ae940cc01ab --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldFindFilter.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert-result.xml b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert-result.xml new file mode 100644 index 00000000000..5bef3836c4b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert-result.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert.xml b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert.xml new file mode 100644 index 00000000000..871dedcb5e9 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/filters/FilterDaoTest/shouldInsert.xml @@ -0,0 +1,3 @@ + + + diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Filter.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Filter.java new file mode 100644 index 00000000000..5c65c30febf --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Filter.java @@ -0,0 +1,40 @@ +/* + * 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.api.web; + +/** + * Definition of a filter. + *

+ * Its name can be retrieved using the i18n mechanism, using the keys "dashboard.<id>.name". + * + * @since 3.1 + */ +public class Filter { + private Filter() { + // The factory method should be used + } + + /** + * Creates a new {@link Filter}. + */ + public static Filter create() { + return new Filter(); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/FilterTemplate.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/FilterTemplate.java new file mode 100644 index 00000000000..79e6ca7b43a --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/FilterTemplate.java @@ -0,0 +1,42 @@ +/* + * 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.api.web; + +import org.sonar.api.ServerExtension; + +/** + * This extension point must be implemented to define a new filter. + * + * @since 3.1 + */ +public abstract class FilterTemplate implements ServerExtension { + + /** + * Returns the {@link Filter} object that represents the filter to use. + * + * @return the filter + */ + public abstract Filter createFilter(); + + /** + * Filter name + */ + public abstract String getName(); +} diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 1cb75afae82..f07f53324f9 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -19,6 +19,8 @@ */ package org.sonar.server.platform; +import org.sonar.server.startup.RegisterNewFilters; + import org.apache.commons.configuration.BaseConfiguration; import org.slf4j.LoggerFactory; import org.sonar.api.Plugins; @@ -245,6 +247,7 @@ public final class Platform { startupContainer.addSingleton(RegisterQualityModels.class); startupContainer.addSingleton(DeleteDeprecatedMeasures.class); startupContainer.addSingleton(GeneratePluginIndex.class); + startupContainer.addSingleton(RegisterNewFilters.class); startupContainer.addSingleton(RegisterNewDashboards.class); startupContainer.startComponents(); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java new file mode 100644 index 00000000000..4cb131361fb --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewFilters.java @@ -0,0 +1,108 @@ +/* + * 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.Filter; +import org.sonar.api.web.FilterTemplate; +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.Comparator; +import java.util.List; + +/** + * @since 3.1 + */ +public final class RegisterNewFilters { + + private static final Logger LOG = LoggerFactory.getLogger(RegisterNewFilters.class); + + private List filterTemplates; + private FilterDao filterDao; + private 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; + this.loadedTemplateDao = loadedTemplateDao; + } + + public void start() { + TimeProfiler profiler = new TimeProfiler().start("Register filters"); + + for (FilterTemplate template : filterTemplates) { + if (shouldRegister(template.getName())) { + Filter filter = template.createFilter(); + FilterDto dto = register(template.getName(), filter); + } + } + + profiler.stop(); + } + + protected 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) { + 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(); + filterDto.setName(name); + + // filterDto.setShared(); + // filterDto.setFavourites(); + // filterDto.setResourceId(); + // filterDto.setDefaultView(); + // filterDto.setPageSize(); + // filterDto.setPeriodIndex(); + + return filterDto; + } + + protected static class FilterDtoComparator implements Comparator { + public int compare(FilterDto f1, FilterDto f2) { + return f1.getName().compareToIgnoreCase(f2.getName()); + } + } +} \ No newline at end of file diff --git a/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewDashboardsTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewDashboardsTest.java index 2dab3525f2e..d64f29acba1 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewDashboardsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewDashboardsTest.java @@ -88,7 +88,7 @@ public class RegisterNewDashboardsTest { assertNotNull(dashboardDto); verify(dashboardDao).insert(dashboardDto); - verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("fake-dashboard", LoadedTemplateDto.DASHBOARD_TYPE))); + verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.DASHBOARD_TYPE))); } @Test diff --git a/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewFiltersTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewFiltersTest.java new file mode 100644 index 00000000000..e1e7c751eef --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/startup/RegisterNewFiltersTest.java @@ -0,0 +1,124 @@ +/* + * 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.mockito.Mockito; +import org.sonar.api.web.Filter; +import org.sonar.api.web.FilterTemplate; +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.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class RegisterNewFiltersTest { + private RegisterNewFilters register; + private FilterDao filterDao; + private LoadedTemplateDao loadedTemplateDao; + private FilterTemplate fakeFilterTemplate; + + @Before + public void init() { + filterDao = Mockito.mock(FilterDao.class); + loadedTemplateDao = Mockito.mock(LoadedTemplateDao.class); + + fakeFilterTemplate = new FakeFilter(); + + register = new RegisterNewFilters(new FilterTemplate[] {fakeFilterTemplate}, filterDao, loadedTemplateDao); + } + + @Test + public void should_start() { + register.start(); + + verify(filterDao).insert(any(FilterDto.class)); + verify(loadedTemplateDao).insert(any(LoadedTemplateDto.class)); + } + + @Test + public void should_register_filter_if_not_already_loaded() { + when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.FILTER_TYPE, "Fake")).thenReturn(0); + + boolean shouldRegister = register.shouldRegister("Fake"); + + assertThat(shouldRegister).isTrue(); + } + + @Test + public void should_not_register_if_already_loaded() { + when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.FILTER_TYPE, "Fake")).thenReturn(1); + + boolean shouldRegister = register.shouldRegister("Fake"); + + assertThat(shouldRegister).isFalse(); + } + + @Test + public void should_register_filter() { + FilterDto filterDto = register.register("Fake", fakeFilterTemplate.createFilter()); + + assertThat(filterDto).isNotNull(); + verify(filterDao).insert(filterDto); + verify(loadedTemplateDao).insert(eq(new LoadedTemplateDto("Fake", LoadedTemplateDto.FILTER_TYPE))); + } + + @Test + public void should_create_dto_from_extension() { + FilterDto dto = register.createDtoFromExtension("Fake", fakeFilterTemplate.createFilter()); + + assertThat(dto.getUserId()).isNull(); + assertThat(dto.getName()).isEqualTo("Fake"); + } + + @Test + public void should_compare_filter() { + FilterDto f1 = new FilterDto().setName("foo"); + FilterDto f2 = new FilterDto().setName("Bar"); + + List filterDtos = Arrays.asList(f1, f2); + Collections.sort(filterDtos, new RegisterNewFilters.FilterDtoComparator()); + + assertThat(filterDtos).onProperty("name").containsExactly("Bar", "foo"); + } + + public class FakeFilter extends FilterTemplate { + @Override + public String getName() { + return "Fake"; + } + + @Override + public Filter createFilter() { + Filter filter = Filter.create(); + return filter; + } + } +} -- 2.39.5