diff options
Diffstat (limited to 'sonar-core')
40 files changed, 825 insertions, 149 deletions
diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml index 3682bc1fb64..98cc5cb0017 100644 --- a/sonar-core/pom.xml +++ b/sonar-core/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar</artifactId> - <version>5.1-SNAPSHOT</version> + <version>5.2-SNAPSHOT</version> </parent> <artifactId>sonar-core</artifactId> diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentLinkDto.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentLinkDto.java new file mode 100644 index 00000000000..e8c416b9332 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentLinkDto.java @@ -0,0 +1,91 @@ +/* + * 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.core.component; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * Component links should be merge in a 'links' column (using protobuf for instance) of the projects table. + * But to do this we'll have to wait for the measure filters page (where links are displayed) to be rewritten in JS/WS (because it's in Rails for the moment). + */ +public class ComponentLinkDto { + + public static final String TYPE_HOME_PAGE = "homepage"; + public static final String TYPE_CI = "ci"; + public static final String TYPE_ISSUE_TRACKER = "issue"; + public static final String TYPE_SOURCES = "scm"; + public static final String TYPE_SOURCES_DEV = "scm_dev"; + + public static final List<String> PROVIDED_TYPES = ImmutableList.of(TYPE_HOME_PAGE, TYPE_CI, TYPE_ISSUE_TRACKER, TYPE_SOURCES, TYPE_SOURCES_DEV); + + private Long id; + private String componentUuid; + private String type; + private String name; + private String href; + + public String getName() { + return name; + } + + public ComponentLinkDto setName(String name) { + this.name = name; + return this; + } + + public String getComponentUuid() { + return componentUuid; + } + + public ComponentLinkDto setComponentUuid(String componentUuid) { + this.componentUuid = componentUuid; + return this; + } + + public String getHref() { + return href; + } + + public ComponentLinkDto setHref(String href) { + this.href = href; + return this; + } + + public Long getId() { + return id; + } + + public ComponentLinkDto setId(Long id) { + this.id = id; + return this; + } + + public String getType() { + return type; + } + + public ComponentLinkDto setType(String type) { + this.type = type; + return this; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentLinkMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentLinkMapper.java new file mode 100644 index 00000000000..464a998fc7f --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentLinkMapper.java @@ -0,0 +1,37 @@ +/* + * 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.core.component.db; + +import org.sonar.core.component.ComponentLinkDto; + +import java.util.List; + +public interface ComponentLinkMapper { + + List<ComponentLinkDto> selectByComponentUuid(String componentUuid); + + void insert(ComponentLinkDto dto); + + void update(ComponentLinkDto dto); + + void delete(long id); + +} diff --git a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java index 2d35e2c67e7..a6711488e2d 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java +++ b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java @@ -60,6 +60,16 @@ public class CorePropertyDefinitions { .subCategory(CoreProperties.SUBCATEGORY_LOOKNFEEL) .build(), + // ISSUES + PropertyDefinition.builder(CoreProperties.DEFAULT_ISSUE_ASSIGNEE) + .name("Default Assignee") + .description("New issues will be assigned to this user each time it is not possible to determine the user who is the author of the issue.") + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_ISSUES) + .onQualifiers(Qualifiers.PROJECT) + .type(PropertyType.USER_LOGIN) + .build(), + // BATCH PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY) diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFilter.java b/sonar-core/src/main/java/org/sonar/core/event/EventDto.java index ed32dd31ee8..f505c3a569b 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFilter.java +++ b/sonar-core/src/main/java/org/sonar/core/event/EventDto.java @@ -18,103 +18,115 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.core.issue; +package org.sonar.core.event; -import java.util.Date; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; -public class DefaultIssueFilter { +public class EventDto { + + public static final String CATEGORY_VERSION = "Version"; + public static final String CATEGORY_ALERT = "Alert"; + public static final String CATEGORY_PROFILE = "Profile"; private Long id; + private String name; - private String user; - private boolean shared = false; + private String description; - private String data; - private Date createdAt; - private Date updatedAt; - public DefaultIssueFilter() { + private String category; - } + private Long date; - public static DefaultIssueFilter create(String name) { - DefaultIssueFilter issueFilter = new DefaultIssueFilter(); - Date now = new Date(); - issueFilter.setName(name); - issueFilter.setCreatedAt(now).setUpdatedAt(now); - return issueFilter; - } + private Long createdAt; + + private String data; - public Long id() { + private Long snapshotId; + + private String componentUuid; + + public Long getId() { return id; } - public DefaultIssueFilter setId(Long id) { + public EventDto setId(Long id) { this.id = id; return this; } - public String name() { - return name; + public String getCategory() { + return category; } - public DefaultIssueFilter setName(String name) { - this.name = name; + public EventDto setCategory(String category) { + this.category = category; return this; } - public String user() { - return user; + public String getComponentUuid() { + return componentUuid; } - public DefaultIssueFilter setUser(String user) { - this.user = user; + public EventDto setComponentUuid(String componentUuid) { + this.componentUuid = componentUuid; return this; } - public boolean shared() { - return shared; + public Long getCreatedAt() { + return createdAt; } - public DefaultIssueFilter setShared(boolean shared) { - this.shared = shared; + public EventDto setCreatedAt(Long createdAt) { + this.createdAt = createdAt; return this; } - public String description() { - return description; + @CheckForNull + public String getData() { + return data; } - public DefaultIssueFilter setDescription(String description) { - this.description = description; + public EventDto setData(@Nullable String data) { + this.data = data; return this; } - public String data() { - return data; + public Long getDate() { + return date; } - public DefaultIssueFilter setData(String data) { - this.data = data; + public EventDto setDate(Long date) { + this.date = date; return this; } - public Date createdAt() { - return createdAt; + @CheckForNull + public String getDescription() { + return description; } - public DefaultIssueFilter setCreatedAt(Date createdAt) { - this.createdAt = createdAt; + public EventDto setDescription(@Nullable String description) { + this.description = description; return this; } - public Date updatedAt() { - return updatedAt; + public String getName() { + return name; } - public DefaultIssueFilter setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; + public EventDto setName(String name) { + this.name = name; return this; } + public Long getSnapshotId() { + return snapshotId; + } + + public EventDto setSnapshotId(Long snapshotId) { + this.snapshotId = snapshotId; + return this; + } } diff --git a/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java b/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java new file mode 100644 index 00000000000..831b5dd3160 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java @@ -0,0 +1,44 @@ +/* + * 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.core.event.db; + +import org.apache.ibatis.annotations.Param; +import org.sonar.core.event.EventDto; + +import javax.annotation.CheckForNull; + +import java.util.List; + +public interface EventMapper { + + List<EventDto> selectByComponentUuid(String uuid); + + void insert(EventDto dto); + + void delete(long id); + + /** + * TODO Used by PastSnapshotFinderByVersion. Should be dropped soon. + */ + @CheckForNull + Long findSnapshotIdOfPreviousVersion(@Param("componentId") long componentId, @Param("currentVersion") String currentVersion); + +} diff --git a/sonar-core/src/main/java/org/sonar/core/event/db/package-info.java b/sonar-core/src/main/java/org/sonar/core/event/db/package-info.java new file mode 100644 index 00000000000..7651f0b3db9 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/event/db/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +@ParametersAreNonnullByDefault +package org.sonar.core.event.db; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-core/src/main/java/org/sonar/core/event/package-info.java b/sonar-core/src/main/java/org/sonar/core/event/package-info.java new file mode 100644 index 00000000000..a11358f5f24 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/event/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +@ParametersAreNonnullByDefault +package org.sonar.core.event; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java index 1548dc84444..a8c253e61b3 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java @@ -69,6 +69,15 @@ public class IssueFilterDao implements BatchComponent, ServerComponent { } } + public IssueFilterDto selectProvidedFilterByName(String name) { + SqlSession session = mybatis.openSession(false); + try { + return getMapper(session).selectProvidedFilterByName(name); + } finally { + MyBatis.closeQuietly(session); + } + } + public List<IssueFilterDto> selectSharedFilters() { SqlSession session = mybatis.openSession(false); try { diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java index e3809fb10be..bbc14f41bd8 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java @@ -19,8 +19,6 @@ */ package org.sonar.core.issue.db; -import org.sonar.core.issue.DefaultIssueFilter; - import javax.annotation.Nullable; import java.util.Date; @@ -39,6 +37,12 @@ public class IssueFilterDto { private Date createdAt; private Date updatedAt; + public IssueFilterDto() { + Date now = new Date(); + createdAt = updatedAt = now; + shared = false; + } + public Long getId() { return id; } @@ -110,28 +114,4 @@ public class IssueFilterDto { this.updatedAt = updatedAt; return this; } - - public DefaultIssueFilter toIssueFilter() { - return new DefaultIssueFilter() - .setId(id) - .setName(name) - .setUser(userLogin) - .setDescription(description) - .setShared(shared) - .setData(data) - .setCreatedAt(createdAt) - .setUpdatedAt(updatedAt); - } - - public static IssueFilterDto toIssueFilter(DefaultIssueFilter issueFilter) { - return new IssueFilterDto() - .setId(issueFilter.id()) - .setName(issueFilter.name()) - .setUserLogin(issueFilter.user()) - .setDescription(issueFilter.description()) - .setShared(issueFilter.shared()) - .setData(issueFilter.data()) - .setCreatedAt(issueFilter.createdAt()) - .setUpdatedAt(issueFilter.updatedAt()); - } } diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java index fd0479f4132..b5e8eb93fac 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java @@ -37,9 +37,12 @@ public interface IssueFilterMapper { List<IssueFilterDto> selectSharedFilters(); + IssueFilterDto selectProvidedFilterByName(String name); + void insert(IssueFilterDto filter); void update(IssueFilterDto filter); void delete(long id); + } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index 48459ea8fc6..72d79512ceb 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 796; + public static final int LAST_VERSION = 905; /** * List of all the tables.n 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 2fceabc00f2..85873f4fc45 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 @@ -35,11 +35,9 @@ import org.sonar.api.database.model.MeasureModel; import org.sonar.core.activity.db.ActivityDto; import org.sonar.core.activity.db.ActivityMapper; import org.sonar.core.cluster.WorkQueue; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.FilePathWithHashDto; -import org.sonar.core.component.SnapshotDto; -import org.sonar.core.component.UuidWithProjectUuidDto; +import org.sonar.core.component.*; import org.sonar.core.component.db.ComponentIndexMapper; +import org.sonar.core.component.db.ComponentLinkMapper; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.component.db.SnapshotMapper; import org.sonar.core.computation.db.AnalysisReportDto; @@ -52,6 +50,8 @@ import org.sonar.core.dependency.ResourceSnapshotDto; import org.sonar.core.dependency.ResourceSnapshotMapper; import org.sonar.core.duplication.DuplicationMapper; import org.sonar.core.duplication.DuplicationUnitDto; +import org.sonar.core.event.EventDto; +import org.sonar.core.event.db.EventMapper; import org.sonar.core.graph.jdbc.GraphDto; import org.sonar.core.graph.jdbc.GraphDtoMapper; import org.sonar.core.issue.db.*; @@ -133,6 +133,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class); loadAlias(conf, "Author", AuthorDto.class); loadAlias(conf, "Component", ComponentDto.class); + loadAlias(conf, "ComponentLink", ComponentLinkDto.class); loadAlias(conf, "Dashboard", DashboardDto.class); loadAlias(conf, "Dependency", DependencyDto.class); loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class); @@ -185,6 +186,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "IdUuidPair", IdUuidPair.class); loadAlias(conf, "FilePathWithHash", FilePathWithHashDto.class); loadAlias(conf, "UuidWithProjectUuid", UuidWithProjectUuidDto.class); + loadAlias(conf, "Event", EventDto.class); // AuthorizationMapper has to be loaded before IssueMapper because this last one used it loadMapper(conf, "org.sonar.core.user.AuthorizationMapper"); @@ -203,8 +205,8 @@ public class MyBatis implements BatchComponent, ServerComponent { NotificationQueueMapper.class, CharacteristicMapper.class, GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class, - ProjectQgateAssociationMapper.class, - AnalysisReportMapper.class, ComponentIndexMapper.class, + ProjectQgateAssociationMapper.class, EventMapper.class, + AnalysisReportMapper.class, ComponentIndexMapper.class, ComponentLinkMapper.class, Migration45Mapper.class, Migration50Mapper.class }; loadMappers(conf, mappers); diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeCommands.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeCommands.java index 687788e415d..438f416177c 100644 --- a/sonar-core/src/main/java/org/sonar/core/purge/PurgeCommands.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeCommands.java @@ -63,8 +63,8 @@ class PurgeCommands { // possible missing optimization: filter requests according to resource scope profiler.start("deleteResourceLinks (project_links)"); - for (List<Long> partResourceIds : componentIdPartitions) { - purgeMapper.deleteResourceLinks(partResourceIds); + for (List<String> componentUuidPartition : componentUuidsPartitions) { + purgeMapper.deleteResourceLinks(componentUuidPartition); } session.commit(); profiler.stop(); @@ -125,9 +125,9 @@ class PurgeCommands { session.commit(); profiler.stop(); - profiler.start("deleteResourceEvents (events)"); - for (List<Long> partResourceIds : componentIdPartitions) { - purgeMapper.deleteResourceEvents(partResourceIds); + profiler.start("deleteComponentEvents (events)"); + for (List<String> componentUuidPartition : componentUuidsPartitions) { + purgeMapper.deleteComponentEvents(componentUuidPartition); } session.commit(); profiler.stop(); diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java index 643cb15c4a9..2dda5e52837 100644 --- a/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java @@ -22,6 +22,7 @@ package org.sonar.core.purge; import org.apache.ibatis.annotations.Param; import javax.annotation.Nullable; + import java.util.List; public interface PurgeMapper { @@ -66,7 +67,7 @@ public interface PurgeMapper { void setSnapshotIsLastToFalse(long resourceId); - void deleteResourceLinks(@Param("resourceIds") List<Long> resourceIds); + void deleteResourceLinks(@Param("componentUuids") List<String> componentUuids); void deleteResourceProperties(@Param("resourceIds") List<Long> resourceIds); @@ -78,7 +79,7 @@ public interface PurgeMapper { void deleteResourceManualMeasures(@Param("resourceIds") List<Long> resourceIds); - void deleteResourceEvents(@Param("resourceIds") List<Long> resourceIds); + void deleteComponentEvents(@Param("componentUuids") List<String> componentUuids); void deleteResourceActionPlans(@Param("resourceIds") List<Long> resourceIds); 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 d0a52bc1c66..1f935f1c924 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 @@ -29,6 +29,7 @@ public final class LoadedTemplateDto { public static final String PERMISSION_TEMPLATE_TYPE = "PERM_TEMPLATE"; public static final String QUALITY_GATE_TYPE = "QUALITY_GATE"; public static final String ONE_SHOT_TASK_TYPE = "ONE_SHOT_TASK"; + public static final String ISSUE_FILTER_TYPE = "ISSUE_FILTER"; private Long id; private String key; diff --git a/sonar-core/src/main/java/org/sonar/core/user/UserDao.java b/sonar-core/src/main/java/org/sonar/core/user/UserDao.java index 0cff129eb8a..97f7e6a26cd 100644 --- a/sonar-core/src/main/java/org/sonar/core/user/UserDao.java +++ b/sonar-core/src/main/java/org/sonar/core/user/UserDao.java @@ -68,20 +68,21 @@ public class UserDao implements BatchComponent, ServerComponent, DaoComponent { public UserDto selectActiveUserByLogin(String login) { DbSession session = mybatis.openSession(false); try { - return selectActiveUserByLogin(login, session); + return selectActiveUserByLogin(session, login); } finally { MyBatis.closeQuietly(session); } } - public UserDto selectActiveUserByLogin(String login, DbSession session) { + @CheckForNull + public UserDto selectActiveUserByLogin(DbSession session, String login) { UserMapper mapper = session.getMapper(UserMapper.class); return mapper.selectUserByLogin(login); } public List<UserDto> selectUsersByLogins(List<String> logins) { List<UserDto> users = Lists.newArrayList(); - SqlSession session = mybatis.openSession(false); + DbSession session = mybatis.openSession(false); try { users.addAll(selectUsersByLogins(session, logins)); } finally { @@ -90,7 +91,7 @@ public class UserDao implements BatchComponent, ServerComponent, DaoComponent { return users; } - public List<UserDto> selectUsersByLogins(SqlSession session, List<String> logins) { + public List<UserDto> selectUsersByLogins(DbSession session, List<String> logins) { List<UserDto> users = Lists.newArrayList(); if (!logins.isEmpty()) { UserMapper mapper = session.getMapper(UserMapper.class); diff --git a/sonar-core/src/main/java/org/sonar/core/util/MultiSets.java b/sonar-core/src/main/java/org/sonar/core/util/MultiSets.java new file mode 100644 index 00000000000..05c93b572b2 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/util/MultiSets.java @@ -0,0 +1,62 @@ +/* + * 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.core.util; + +import com.google.common.collect.Multiset; +import com.google.common.collect.Ordering; +import com.google.common.primitives.Ints; + +import java.util.List; + +/** + * Utility class heavily inspired by Guava + */ +public class MultiSets { + + private static final Ordering<Multiset.Entry<?>> DECREASING_COUNT_ORDERING = new NonNullOrdering<Multiset.Entry<?>>() { + @Override + public int doCompare(Multiset.Entry<?> entry1, Multiset.Entry<?> entry2) { + return Ints.compare(entry2.getCount(), entry1.getCount()); + } + }; + + private MultiSets() { + + } + + /** + * Returns a copy of {@code multiset} as a {@link List} whose iteration order is + * highest count first, with ties broken by the iteration order of the original multiset. + */ + public static <E> List<Multiset.Entry<E>> listOrderedByHighestCounts(Multiset<E> multiset) { + return DECREASING_COUNT_ORDERING.sortedCopy(multiset.entrySet()); + } + + private abstract static class NonNullOrdering<T> extends Ordering<T> { + + @Override + public int compare(T left, T right) { + return doCompare(left, right); + } + + public abstract int doCompare(T left, T right); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/util/NonNullInputFunction.java b/sonar-core/src/main/java/org/sonar/core/util/NonNullInputFunction.java index a99652beb58..9ec5fbb4ec2 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/NonNullInputFunction.java +++ b/sonar-core/src/main/java/org/sonar/core/util/NonNullInputFunction.java @@ -20,10 +20,11 @@ package org.sonar.core.util; import com.google.common.base.Function; -import com.google.common.base.Preconditions; import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkArgument; + /** * Guava Function that does not accept null input elements * @since 5.1 @@ -32,7 +33,7 @@ public abstract class NonNullInputFunction<F,T> implements Function<F, T> { @Override public final T apply(@Nullable F input) { - Preconditions.checkArgument(input != null, "Null inputs are not allowed in this function"); + checkArgument(input != null, "Null inputs are not allowed in this function"); return doApply(input); } diff --git a/sonar-core/src/main/resources/META-INF/persistence.xml b/sonar-core/src/main/resources/META-INF/persistence.xml index 099bd1c8c9e..c4fe7406836 100644 --- a/sonar-core/src/main/resources/META-INF/persistence.xml +++ b/sonar-core/src/main/resources/META-INF/persistence.xml @@ -17,8 +17,6 @@ <class>org.sonar.api.database.model.ResourceModel</class> <class>org.sonar.api.rules.Rule</class> <class>org.sonar.api.rules.RuleParam</class> - <class>org.sonar.api.resources.ProjectLink</class> - <class>org.sonar.api.batch.Event</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentLinkMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentLinkMapper.xml new file mode 100644 index 00000000000..9d87b6078d7 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentLinkMapper.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="org.sonar.core.component.db.ComponentLinkMapper"> + + <sql id="componentLinkColumns"> + p.id, + p.component_uuid as "componentUuid", + p.link_type as "type", + p.name as name, + p.href as href + </sql> + + <select id="selectByComponentUuid" parameterType="String" resultType="ComponentLink"> + SELECT + <include refid="componentLinkColumns"/> + FROM project_links p + <where> + AND p.component_uuid=#{uuid} + </where> + </select> + + <insert id="insert" parameterType="ComponentLink" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> + INSERT INTO project_links (component_uuid, link_type, name, href) + VALUES (#{componentUuid,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{href,jdbcType=VARCHAR}) + </insert> + + <insert id="update" parameterType="ComponentLink" useGeneratedKeys="false"> + UPDATE project_links SET component_uuid=#{componentUuid,jdbcType=VARCHAR}, link_type=#{type,jdbcType=VARCHAR}, name=#{name,jdbcType=VARCHAR}, href=#{href,jdbcType=VARCHAR} + WHERE id=#{id} + </insert> + + <delete id="delete"> + DELETE FROM project_links WHERE id=#{id} + </delete> + +</mapper> + diff --git a/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml b/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml new file mode 100644 index 00000000000..0c6dc2d3eb7 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="org.sonar.core.event.db.EventMapper"> + + <sql id="eventColumns"> + e.id, + e.name, + e.category, + e.description, + e.event_data as "data", + e.event_date as "date", + e.component_uuid as "componentUuid", + e.snapshot_id as "snapshotId", + e.created_at as "createdAt" + </sql> + + <select id="selectByComponentUuid" parameterType="String" resultType="Event"> + SELECT <include refid="eventColumns"/> + FROM events e + <where> + AND e.component_uuid=#{uuid} + </where> + </select> + + <insert id="insert" parameterType="Event" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> + INSERT INTO events (name, category, description, event_data, event_date, component_uuid, snapshot_id, created_at) + VALUES (#{name}, #{category}, #{description}, #{data}, #{date}, #{componentUuid}, #{snapshotId}, #{createdAt}) + </insert> + + <delete id="delete"> + DELETE FROM events WHERE id=#{id} + </delete> + + <select id="findSnapshotIdOfPreviousVersion" parameterType="map" resultType="long"> + SELECT s.id + FROM snapshots s, events e, projects p + <where> + AND p.id=#{componentId} + AND p.uuid=e.component_uuid + AND e.name <> #{currentVersion} + AND e.category='Version' + AND s.id = e.snapshot_id + </where> + ORDER BY e.event_date DESC + LIMIT 1 + </select> + + <!-- SQL Server --> + <select id="findSnapshotIdOfPreviousVersion" parameterType="map" resultType="long" databaseId="mssql"> + SELECT TOP 1 s.id + FROM snapshots s, events e, projects p + <where> + AND p.id=#{componentId} + AND p.uuid=e.component_uuid + AND e.name <> #{currentVersion} + AND e.category='Version' + AND s.id = e.snapshot_id + </where> + ORDER BY e.event_date DESC + </select> + + <!-- Oracle --> + <select id="findSnapshotIdOfPreviousVersion" parameterType="map" resultType="long" databaseId="oracle"> + SELECT * FROM (SELECT s.id + FROM snapshots s, events e, projects p + <where> + AND p.id=#{componentId} + AND p.uuid=e.component_uuid + AND e.name <> #{currentVersion} + AND e.category='Version' + AND s.id = e.snapshot_id + </where> + ORDER BY e.event_date DESC + ) + WHERE ROWNUM <= 1 + </select> + +</mapper> + diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml index 078620f535b..75e324a9e6e 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml @@ -40,6 +40,14 @@ where filters.shared=${_true} </select> + <select id="selectProvidedFilterByName" parameterType="String" resultType="IssueFilter"> + select <include refid="issueFilterColumns"/> + from issue_filters filters + where filters.user_login is null + and filters.shared=${_true} + and filters.name=#{name} + </select> + <insert id="insert" parameterType="IssueFilter" keyColumn="id" useGeneratedKeys="true" keyProperty="id" > INSERT INTO issue_filters (name, user_login, shared, description, data, created_at, updated_at) VALUES (#{name}, #{userLogin}, #{shared}, #{description}, #{data}, #{createdAt}, #{updatedAt}) diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index 5a090866dec..e931f701f0a 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -323,6 +323,12 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('793'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('794'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('795'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('796'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('900'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('901'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('902'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('903'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('904'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('905'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl index cc273b5b07e..95fa86aa4e7 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl @@ -164,7 +164,7 @@ CREATE TABLE "WIDGET_PROPERTIES" ( CREATE TABLE "EVENTS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "NAME" VARCHAR(400), - "RESOURCE_ID" INTEGER, + "COMPONENT_UUID" VARCHAR(50), "SNAPSHOT_ID" INTEGER, "CATEGORY" VARCHAR(50), "EVENT_DATE" BIGINT NOT NULL, @@ -202,7 +202,7 @@ CREATE TABLE "PROPERTIES" ( CREATE TABLE "PROJECT_LINKS" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), - "PROJECT_ID" INTEGER NOT NULL, + "COMPONENT_UUID" VARCHAR(50), "LINK_TYPE" VARCHAR(20), "NAME" VARCHAR(128), "HREF" VARCHAR(2048) NOT NULL @@ -599,7 +599,7 @@ CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS" ("NAME"); CREATE INDEX "EVENTS_SNAPSHOT_ID" ON "EVENTS" ("SNAPSHOT_ID"); -CREATE INDEX "EVENTS_RESOURCE_ID" ON "EVENTS" ("RESOURCE_ID"); +CREATE INDEX "EVENTS_COMPONENT_UUID" ON "EVENTS" ("COMPONENT_UUID"); CREATE INDEX "WIDGETS_WIDGETKEY" ON "WIDGETS" ("WIDGET_KEY"); diff --git a/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml index 38d83162163..6ba17308f50 100644 --- a/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml @@ -197,9 +197,9 @@ </delete> <delete id="deleteResourceLinks" parameterType="map"> - delete from project_links where project_id in - <foreach collection="resourceIds" open="(" close=")" item="resourceId" separator=","> - #{resourceId} + delete from project_links where component_uuid in + <foreach collection="componentUuids" open="(" close=")" item="componentUuid" separator=","> + #{componentUuid} </foreach> </delete> @@ -238,10 +238,10 @@ </foreach> </delete> - <delete id="deleteResourceEvents" parameterType="map"> - delete from events where resource_id in - <foreach collection="resourceIds" open="(" close=")" item="resourceId" separator=","> - #{resourceId} + <delete id="deleteComponentEvents" parameterType="map"> + delete from events where component_uuid in + <foreach collection="componentUuids" open="(" close=")" item="componentUuid" separator=","> + #{componentUuid} </foreach> </delete> diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 446194a2bc3..5e0548eaa65 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -88,6 +88,7 @@ load_verb=Load login=Login major=Major max=Max +max_items_reached=Only the first {0} components are displayed me=Me min=Min minor=Minor @@ -156,6 +157,7 @@ template=Template title=Title to=To to.downcase=to +total=Total treemap=Treemap true=True type=Type @@ -395,7 +397,7 @@ qualifiers.update.DEV=Update Developer project_links.homepage=Home project_links.ci=Continuous integration -project_links.issue=Issues +project_links.issue=Bug Tracker project_links.scm=Sources project_links.scm_ro=Read-only connection project_links.scm_dev=Developer connection @@ -717,6 +719,13 @@ issue.technical_debt_deleted=Rule not configured to generate technical debt esti issue.creation_date=Created issues.return_to_list=Return to List issues.issues_limit_reached=For usability reasons, only the {0} issues are displayed. +issues.home.recent_issues=Recent Issues +issues.home.my_recent_issues=My Recent Issues +issues.home.over_last_week=Over Last Week +issues.home.my_filters=My Filters +issues.home.projects=Projects +issues.home.authors=Authors +issues.home.tags=Tags #------------------------------------------------------------------------------ @@ -981,6 +990,7 @@ property.category.general.differentialViews=Differential Views property.category.general.localization=Localization property.category.general.databaseCleaner=Database Cleaner property.category.general.looknfeel=Look & Feel +property.category.general.issues=Issues property.category.security=Security property.category.security.encryption=Encryption property.category.java=Java @@ -1322,32 +1332,6 @@ widget.hotspot_metric.property.title.name=Title widget.hotspot_metric.property.metric.name=Metric widget.hotspot_metric.property.numberOfLines.name=Number of lines -widget.hotspot_most_violated_rules.name=Most Violated Rules -widget.hotspot_most_violated_rules.name_when_period=Most new violated rules -widget.hotspot_most_violated_rules.description=Shows the rules that are the most violated. -widget.hotspot_most_violated_rules.no_violation_for_severity=No result -widget.hotspot_most_violated_rules.any_severity=Any severity -widget.hotspot_most_violated_rules.property.numberOfLines.name=Number of lines -widget.hotspot_most_violated_rules.property.defaultSeverity.name=Default severity -widget.hotspot_most_violated_rules.property.defaultSeverity.desc=If selected, severity used to initialize the dropdown list of widget - -widget.my_reviews.name=My Unresolved Issues -widget.my_reviews.description=Shows unresolved issues assigned to the current user. -widget.my_reviews.property.numberOfLines.name=Number of lines -widget.my_reviews.property.numberOfLines.desc=Maximum number of issues displayed at the same time. - -widget.false_positive_reviews.name=False Positives Issues -widget.false_positive_reviews.description=Shows all the false positives found on the project. -widget.false_positive_reviews.property.numberOfLines.name=Number of lines -widget.false_positive_reviews.property.numberOfLines.desc=Maximum number of issues displayed at the same time. - -widget.reviews_per_developer.name=Unresolved Issues per Assignee -widget.reviews_per_developer.description=Shows the number of unresolved issues per assignee. -widget.reviews_per_developer.not_assigned=Not assigned - -widget.unresolved_issues_statuses.name=Unresolved Issues by Status -widget.unresolved_issues_statuses.description=Displays the number of unresolved issues according to their status: Open, Reopened and Confirmed. - widget.action_plans.name=Action Plans widget.action_plans.description=Shows all the open action plans of the project. widget.action_plans.property.showResolvedIssues.name=Show Resolved Issues @@ -1358,9 +1342,41 @@ widget.action_plans.x_unresolved_issues={0} unresolved issues widget.issue_filter.name=Issue Filter widget.issue_filter.description=Displays the result of a pre-configured issue filter. widget.issue_filter.property.filter.name=Filter -widget.issue_filter.property.numberOfLines.name=Page size +widget.issue_filter.property.distributionAxis.name=Distribution Axis widget.issue_filter.property.displayFilterDescription.name=Display Filter Description widget.issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. +widget.issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. +widget.issue_filter.property.distributionAxis.option.severities.name=By Severity +widget.issue_filter.property.distributionAxis.option.projectUuids.name=By Project +widget.issue_filter.property.distributionAxis.option.statuses.name=By Status +widget.issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date +widget.issue_filter.property.distributionAxis.option.actionPlans.name=By Action Plan +widget.issue_filter.property.distributionAxis.option.assignees.name=By Assignee +widget.issue_filter.property.distributionAxis.option.tags.name=By Tag +widget.issue_filter.property.distributionAxis.option.rules.name=By Rule +widget.issue_filter.property.distributionAxis.option.resolutions.name=By Resolution +widget.issue_filter.property.distributionAxis.option.languages.name=By Language +widget.issue_filter.property.distributionAxis.option.reporters.name=By Reporter +widget.issue_filter.property.distributionAxis.option.authors.name=By Author + +widget.project_issue_filter.name=Project Issue Filter +widget.project_issue_filter.description=Displays the result of a pre-configured issue filter applied to the project. +widget.project_issue_filter.property.filter.name=Filter +widget.project_issue_filter.property.distributionAxis.name=Distribution Axis +widget.project_issue_filter.property.displayFilterDescription.name=Display Filter Description +widget.project_issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. +widget.project_issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. +widget.project_issue_filter.property.distributionAxis.option.severities.name=By Severity +widget.project_issue_filter.property.distributionAxis.option.statuses.name=By Status +widget.project_issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date +widget.project_issue_filter.property.distributionAxis.option.actionPlans.name=By Action Plan +widget.project_issue_filter.property.distributionAxis.option.assignees.name=By Assignee +widget.project_issue_filter.property.distributionAxis.option.tags.name=By Tag +widget.project_issue_filter.property.distributionAxis.option.rules.name=By Rule +widget.project_issue_filter.property.distributionAxis.option.resolutions.name=By Resolution +widget.project_issue_filter.property.distributionAxis.option.languages.name=By Language +widget.project_issue_filter.property.distributionAxis.option.reporters.name=By Reporter +widget.project_issue_filter.property.distributionAxis.option.authors.name=By Author widget.issue_tag_cloud.name=Project Issue Tag Cloud widget.issue_tag_cloud.title=Issue Tag Cloud @@ -2032,6 +2048,7 @@ notification.dispatcher.ChangesOnMyIssue=Changes in issues assigned to me or rep notification.dispatcher.NewIssues=New issues notification.dispatcher.NewAlerts=New quality gate status notification.dispatcher.NewFalsePositiveIssue=Issues resolved as false positive or won't fix +notification.dispatcher.SQ-MyNewIssues=My New Issues #------------------------------------------------------------------------------ @@ -2801,7 +2818,6 @@ errors.type.notInteger=Value '{0}' must be an integer. errors.type.notFloat=Value '{0}' must be an floating point number. errors.type.notInOptions=Value '{0}' must be one of : {1}. - #------------------------------------------------------------------------------ # # HELP @@ -2883,6 +2899,7 @@ component_viewer.show_full_source=Show Full Source component_viewer.show_raw_source=Show Raw Source component_viewer.more_actions=More Actions component_viewer.new_window=Open in New Window +component_viewer.open_in_workspace=Open in Workspace component_viewer.get_permalink=Get Permalink component_viewer.covered_lines=Covered Lines component_viewer.issues_limit_reached=For usability reasons, only the {0} first issues will be fully displayed. Remaining issues will simply be underlined. diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentLinkDtoTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentLinkDtoTest.java new file mode 100644 index 00000000000..bca227fa782 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentLinkDtoTest.java @@ -0,0 +1,49 @@ +/* + * 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.core.component; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ComponentLinkDtoTest { + + @Test + public void test_getters_and_setters() throws Exception { + ComponentLinkDto dto = new ComponentLinkDto() + .setId(1L) + .setComponentUuid("ABCD") + .setType("homepage") + .setName("Home") + .setHref("http://www.sonarqube.org"); + + assertThat(dto.getId()).isEqualTo(1L); + assertThat(dto.getComponentUuid()).isEqualTo("ABCD"); + assertThat(dto.getType()).isEqualTo("homepage"); + assertThat(dto.getName()).isEqualTo("Home"); + assertThat(dto.getHref()).isEqualTo("http://www.sonarqube.org"); + } + + @Test + public void test_provided_types() throws Exception { + assertThat(ComponentLinkDto.PROVIDED_TYPES).hasSize(5); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/event/EventDtoTest.java b/sonar-core/src/test/java/org/sonar/core/event/EventDtoTest.java new file mode 100644 index 00000000000..63c8e8e85a5 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/event/EventDtoTest.java @@ -0,0 +1,52 @@ +/* + * 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.core.event; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EventDtoTest { + + @Test + public void test_getters_and_setters() throws Exception { + EventDto dto = new EventDto() + .setId(1L) + .setName("1.0") + .setCategory("Version") + .setDescription("Version 1.0") + .setData("some data") + .setDate(1413407091086L) + .setComponentUuid("ABCD") + .setSnapshotId(1000L) + .setCreatedAt(1225630680000L); + + assertThat(dto.getId()).isEqualTo(1L); + assertThat(dto.getName()).isEqualTo("1.0"); + assertThat(dto.getCategory()).isEqualTo("Version"); + assertThat(dto.getDescription()).isEqualTo("Version 1.0"); + assertThat(dto.getData()).isEqualTo("some data"); + assertThat(dto.getComponentUuid()).isEqualTo("ABCD"); + assertThat(dto.getSnapshotId()).isEqualTo(1000L); + assertThat(dto.getCreatedAt()).isEqualTo(1225630680000L); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java index da240bd11e0..621246ef967 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java @@ -78,6 +78,15 @@ public class IssueFilterDaoTest extends AbstractDaoTestCase { } @Test + public void should_select_provided_by_name() { + setupData("should_select_provided_by_name"); + + assertThat(dao.selectProvidedFilterByName("Unresolved Issues").getName()).isEqualTo("Unresolved Issues"); + assertThat(dao.selectProvidedFilterByName("My Unresolved Issues").getName()).isEqualTo("My Unresolved Issues"); + assertThat(dao.selectProvidedFilterByName("Unknown Filter")).isNull(); + } + + @Test public void should_insert() { setupData("shared"); diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java b/sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java index 9f827de7751..a4838a8be52 100644 --- a/sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java +++ b/sonar-core/src/test/java/org/sonar/core/persistence/DbTester.java @@ -37,7 +37,9 @@ import org.dbunit.database.DatabaseConfig; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.CompositeDataSet; import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.ITable; import org.dbunit.dataset.ReplacementDataSet; +import org.dbunit.dataset.filter.DefaultColumnFilter; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.ext.mssql.InsertIdentityOperation; import org.dbunit.operation.DatabaseOperation; @@ -281,17 +283,27 @@ public class DbTester extends ExternalResource { } public void assertDbUnit(Class testClass, String filename, String... tables) { + assertDbUnit(testClass, filename, new String[0], tables); + } + + public void assertDbUnit(Class testClass, String filename, String[] excludedColumnNames, String... tables) { IDatabaseConnection connection = null; try { connection = dbUnitConnection(); IDataSet dataSet = connection.createDataSet(); String path = "/" + testClass.getName().replace('.', '/') + "/" + filename; - IDataSet expectedDataSet = dbUnitDataSet(testClass.getResourceAsStream(path)); + InputStream inputStream = testClass.getResourceAsStream(path); + if (inputStream == null) { + throw new IllegalStateException(String.format("File '%s' does not exist", path)); + } + IDataSet expectedDataSet = dbUnitDataSet(inputStream); for (String table : tables) { DiffCollectingFailureHandler diffHandler = new DiffCollectingFailureHandler(); - Assertion.assertEquals(expectedDataSet.getTable(table), dataSet.getTable(table), diffHandler); + ITable filteredTable = DefaultColumnFilter.excludedColumnsTable(dataSet.getTable(table), excludedColumnNames); + ITable filteredExpectedTable = DefaultColumnFilter.excludedColumnsTable(expectedDataSet.getTable(table), excludedColumnNames); + Assertion.assertEquals(filteredExpectedTable, filteredTable, diffHandler); // Evaluate the differences and ignore some column values List diffList = diffHandler.getDiffList(); for (Object o : diffList) { diff --git a/sonar-core/src/test/java/org/sonar/core/util/MultiSetsTest.java b/sonar-core/src/test/java/org/sonar/core/util/MultiSetsTest.java new file mode 100644 index 00000000000..c7f40b0c83b --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/util/MultiSetsTest.java @@ -0,0 +1,49 @@ +/* + * 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.core.util; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import org.junit.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MultiSetsTest { + @Test + public void order_with_highest_count_first() throws Exception { + Multiset<String> multiset = HashMultiset.create(); + add(multiset, "seneca", 10); + add(multiset, "plato", 5); + add(multiset, "confucius", 3); + + List<Multiset.Entry<String>> orderedEntries = MultiSets.listOrderedByHighestCounts(multiset); + + assertThat(orderedEntries).extracting("element").containsExactly("seneca", "plato", "confucius"); + } + + private void add(Multiset<String> multiset, String element, int times) { + for (int i = 0; i < times; i++) { + multiset.add(element); + } + } +} diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_provided_by_name.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_provided_by_name.xml new file mode 100644 index 00000000000..d2b7e3009ed --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_provided_by_name.xml @@ -0,0 +1,58 @@ +<dataset> + + <!-- This one must be found --> + <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" /> + + <!-- This one must NOT be found: belongs to admin --> + <issue_filters + id="2" + name="Unresolved Issues" + user_login="admin" + shared="[true]" + description="[null]" + data="resolved=false" + created_at="2011-04-25 01:15:00" + updated_at="2011-04-25 01:15:00" /> + + <!-- This one must NOT be found: not shared --> + <issue_filters + id="3" + name="Unresolved Issues" + user_login="[null]" + shared="[false]" + description="[null]" + data="resolved=false" + created_at="2011-04-25 01:15:00" + updated_at="2011-04-25 01:15:00" /> + + <!-- This one must be found --> + <issue_filters + id="4" + 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" /> + + <!-- This one must NOT be found: not shared --> + <issue_filters + id="5" + name="Unknown Filter" + user_login="[null]" + shared="[false]" + description="[null]" + data="resolved=false" + created_at="2011-04-25 01:15:00" + updated_at="2011-04-25 01:15:00" /> + +</dataset> diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml index 060dbfb065b..374c0652a83 100644 --- a/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml +++ b/sonar-core/src/test/resources/org/sonar/core/persistence/PreviewDatabaseFactoryTest/should_create_database.xml @@ -22,9 +22,9 @@ <project_measures id="1" value="10" metric_id="1" snapshot_id="1000" /> - <events id="1" name="1.0-SNAPSHOT" resource_id="123" event_data="[null]"/> - <events id="2" name="2.0-SNAPSHOT" resource_id="123" event_data="[null]" /> - <events id="3" name="1.0-SNAPSHOT" resource_id="456" event_data="[null]" /> + <events id="1" name="1.0-SNAPSHOT" component_uuid="123" event_data="[null]"/> + <events id="2" name="2.0-SNAPSHOT" component_uuid="123" event_data="[null]" /> + <events id="3" name="1.0-SNAPSHOT" component_uuid="456" event_data="[null]" /> <users id="1" login="julien" name="Julien" crypted_password="foo" active="1" /> <users id="2" login="simon" name="Simon" active="1" /> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml index 2f30df757d0..00363eb0100 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteResource.xml @@ -15,7 +15,7 @@ build_date="1228222680000" version="[null]" path="[null]"/> - <events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]" + <events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> <issues id="1" kee="ABCDE" component_uuid="1" project_uuid="1" status="CLOSED" resolution="[null]" line="200" diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml index f7a0a3a81b3..e6e06a96fa9 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot-result.xml @@ -25,7 +25,7 @@ <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" parent_dependency_id="[null]" project_snapshot_id="1" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> - <events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]" + <events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> <duplications_index id="1" project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml index 45eaee58163..a4cabcfff0d 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldDeleteSnapshot.xml @@ -24,7 +24,7 @@ <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" parent_dependency_id="[null]" project_snapshot_id="1" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> - <events id="1" name="Version 1.0" resource_id="1" snapshot_id="1" category="VERSION" description="[null]" + <events id="1" name="Version 1.0" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> <duplications_index id="1" project_snapshot_id="1" snapshot_id="1" hash="bb" index_in_file="0" start_line="0" end_line="0"/> @@ -57,7 +57,7 @@ <dependencies id="3" from_resource_id="5" from_snapshot_id="5" to_resource_id="300" to_snapshot_id="300" parent_dependency_id="[null]" project_snapshot_id="5" dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> - <events id="2" name="Version 1.0" resource_id="5" snapshot_id="5" category="VERSION" description="[null]" + <events id="2" name="Version 1.0" component_uuid="5" snapshot_id="5" category="VERSION" description="[null]" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> <duplications_index id="2" project_snapshot_id="5" snapshot_id="5" hash="bb" index_in_file="0" start_line="0" end_line="0"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml index 4a45a7fc405..8ca10cdab74 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot-result.xml @@ -41,7 +41,7 @@ Note that measures, events and reviews are not deleted. <!--parent_dependency_id="[null]" project_snapshot_id="2"--> <!--dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/>--> - <events id="1" resource_id="1" snapshot_id="1" + <events id="1" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> @@ -80,7 +80,7 @@ Note that measures, events and reviews are not deleted. parent_dependency_id="[null]" project_snapshot_id="2" dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> - <events id="2" resource_id="2" snapshot_id="2" + <events id="2" component_uuid="2" snapshot_id="2" category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml index 6c6e5bd44c2..00253585b49 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeCommandsTest/shouldPurgeSnapshot.xml @@ -26,7 +26,7 @@ parent_dependency_id="[null]" project_snapshot_id="2" dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> - <events id="1" resource_id="1" snapshot_id="1" + <events id="1" component_uuid="1" snapshot_id="1" category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> @@ -64,7 +64,7 @@ parent_dependency_id="[null]" project_snapshot_id="2" dep_usage="USES" dep_weight="1" from_scope="LIB" to_scope="PRJ"/> - <events id="2" resource_id="2" snapshot_id="2" + <events id="2" component_uuid="2" snapshot_id="2" category="VERSION" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml index 78e14ead2a7..6a924f7f98a 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldSelectPurgeableSnapshots.xml @@ -55,7 +55,7 @@ period5_mode="[null]" period5_param="[null]" period5_date="[null]" depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000" version="[null]" path="[null]"/> - <events id="2" resource_id="1" snapshot_id="5" + <events id="2" component_uuid="1" snapshot_id="5" category="Version" description="[null]" name="Version 1.0" event_date="1228222680000" created_at="1228222680000" event_data="[null]"/> |