import org.sonar.db.qualityprofile.QProfileEditUsersDao;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileExportDao;
+import org.sonar.db.report.RegulatoryReportDao;
import org.sonar.db.rule.RuleDao;
import org.sonar.db.rule.RuleRepositoryDao;
import org.sonar.db.scannercache.ScannerAnalysisCacheDao;
QualityGateUserPermissionsDao.class,
QualityProfileDao.class,
QualityProfileExportDao.class,
+ RegulatoryReportDao.class,
RoleDao.class,
RuleDao.class,
RuleRepositoryDao.class,
import org.sonar.db.qualityprofile.QProfileEditUsersDao;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileExportDao;
+import org.sonar.db.report.RegulatoryReportDao;
import org.sonar.db.rule.RuleDao;
import org.sonar.db.rule.RuleRepositoryDao;
import org.sonar.db.scannercache.ScannerAnalysisCacheDao;
private final PermissionTemplateDao permissionTemplateDao;
private final PermissionTemplateCharacteristicDao permissionTemplateCharacteristicDao;
private final IssueDao issueDao;
+ private final RegulatoryReportDao regulatoryReportDao;
private final IssueChangeDao issueChangeDao;
private final CeActivityDao ceActivityDao;
private final CeQueueDao ceQueueDao;
qualityGateGroupPermissionsDao = getDao(map, QualityGateGroupPermissionsDao.class);
projectQgateAssociationDao = getDao(map, ProjectQgateAssociationDao.class);
duplicationDao = getDao(map, DuplicationDao.class);
+ regulatoryReportDao = getDao(map, RegulatoryReportDao.class);
notificationQueueDao = getDao(map, NotificationQueueDao.class);
metricDao = getDao(map, MetricDao.class);
groupDao = getDao(map, GroupDao.class);
return issueDao;
}
+ public RegulatoryReportDao regulatoryReportDao() {
+ return regulatoryReportDao;
+ }
+
public IssueChangeDao issueChangeDao() {
return issueChangeDao;
}
import org.sonar.db.qualityprofile.QProfileEditUsersMapper;
import org.sonar.db.qualityprofile.QualityProfileExportMapper;
import org.sonar.db.qualityprofile.QualityProfileMapper;
+import org.sonar.db.report.RegulatoryReportMapper;
import org.sonar.db.rule.RuleMapper;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleRepositoryMapper;
QualityGateUserPermissionsMapper.class,
QualityProfileMapper.class,
QualityProfileExportMapper.class,
+ RegulatoryReportMapper.class,
RoleMapper.class,
RuleMapper.class,
RuleRepositoryMapper.class,
return ofNullable(mapper(dbSession).selectByBranch(projectUuid, branchUuid));
}
+ public NewCodePeriodDto selectBestMatchForBranch(DbSession dbSession, String projectUuid, String branchUuid) {
+ return selectByBranch(dbSession, projectUuid, branchUuid)
+ .or(() -> selectByProject(dbSession, projectUuid)
+ .or(() -> selectGlobal(dbSession)))
+ .orElse(NewCodePeriodDto.defaultInstance());
+ }
+
public Set<String> selectBranchesReferencing(DbSession dbSession, String projectUuid, String referenceBranchName) {
return mapper(dbSession).selectBranchesReferencing(projectUuid, referenceBranchName);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.report;
+
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import org.sonar.api.rules.RuleType;
+import org.sonar.db.rule.RuleDto;
+
+public class IssueFindingDto {
+ private String kee;
+ private String message;
+ private int type;
+ private String severity;
+ private boolean isManualSeverity;
+ private String ruleKey;
+ private String ruleRepository;
+ private String ruleName;
+ private String status;
+ private String resolution;
+ private String fileName;
+ private Integer line;
+ private String securityStandards;
+ private boolean isNewCodeReferenceIssue;
+ private long creationDate;
+
+ public String getStatus() {
+ return status;
+ }
+
+ @CheckForNull
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public String getKey() {
+ return kee;
+ }
+
+ public Set<String> getSecurityStandards() {
+ return RuleDto.deserializeSecurityStandardsString(securityStandards);
+ }
+
+ public boolean isManualSeverity() {
+ return isManualSeverity;
+ }
+
+ @CheckForNull
+ public String getResolution() {
+ return resolution;
+ }
+
+ @CheckForNull
+ public String getMessage() {
+ return message;
+ }
+
+ public RuleType getType() {
+ return RuleType.valueOf(type);
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public String getRuleRepository() {
+ return ruleRepository;
+ }
+
+ @CheckForNull
+ public String getFileName() {
+ return fileName;
+ }
+
+ @CheckForNull
+ public Integer getLine() {
+ return line;
+ }
+
+ public boolean isNewCodeReferenceIssue() {
+ return isNewCodeReferenceIssue;
+ }
+
+ public long getCreationDate() {
+ return creationDate;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.report;
+
+import org.apache.ibatis.session.ResultHandler;
+import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
+
+public class RegulatoryReportDao implements Dao {
+ public void scrollIssues(DbSession dbSession, String branchUuid, ResultHandler<IssueFindingDto> handler) {
+ mapper(dbSession).scrollIssues(branchUuid, handler);
+ }
+
+ private static RegulatoryReportMapper mapper(DbSession dbSession) {
+ return dbSession.getMapper(RegulatoryReportMapper.class);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.report;
+
+import org.apache.ibatis.session.ResultHandler;
+
+public interface RegulatoryReportMapper {
+ void scrollIssues(String branchUuid, ResultHandler<IssueFindingDto> handler);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.report;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.db.report.RegulatoryReportMapper">
+ <sql id="issueColumns">
+ i.kee as kee,
+ i.severity as severity,
+ i.manual_severity as isManualSeverity,
+ i.message as message,
+ i.line as line,
+ i.status as status,
+ i.resolution as resolution,
+ p.kee as componentKey,
+ p.path as fileName,
+ i.issue_type as type,
+ r.plugin_name as ruleRepository,
+ r.plugin_rule_key as ruleKey,
+ r.security_standards as securityStandards,
+ r.name as ruleName,
+ i.issue_creation_date as creationDate,
+ <include refid="org.sonar.db.issue.IssueMapper.isNewCodeReferenceIssue"/>
+ </sql>
+
+ <select id="scrollIssues" parameterType="String" resultType="org.sonar.db.report.IssueFindingDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+ select
+ <include refid="issueColumns"/>
+ from issues i
+ inner join rules r on r.uuid=i.rule_uuid
+ inner join components p on p.uuid=i.component_uuid
+ left join new_code_reference_issues n on i.kee = n.issue_key
+ where i.project_uuid=#{branchUuid,jdbcType=VARCHAR}
+ and i.status !='CLOSED'
+ </select>
+
+</mapper>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.report;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.issue.IssueDto;
+import org.sonar.db.rule.RuleDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+
+public class RegulatoryReportDaoTest {
+ private static final String PROJECT_UUID = "prj_uuid";
+ private static final String PROJECT_KEY = "prj_key";
+ private static final String FILE_UUID = "file_uuid";
+ private static final String FILE_KEY = "file_key";
+
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ private final RegulatoryReportDao underTest = db.getDbClient().regulatoryReportDao();
+ private ComponentDto project;
+ private RuleDto rule;
+ private ComponentDto file;
+
+ @Before
+ public void prepare() {
+ rule = db.rules().insertRule();
+ project = db.components().insertPrivateProject(t -> t.setProjectUuid(PROJECT_UUID).setUuid(PROJECT_UUID).setDbKey(PROJECT_KEY));
+ file = db.components().insertComponent(newFileDto(project).setUuid(FILE_UUID).setDbKey(FILE_KEY));
+ }
+
+ @Test
+ public void scrollIssues_returns_all_non_closed_issues_for_project() {
+ IssueDto issue1 = db.issues().insertIssue(rule, project, file, i -> i.setStatus("OPEN").setResolution(null));
+ IssueDto issue2 = db.issues().insertIssue(rule, project, file, i -> i.setStatus("CONFIRMED").setResolution(null));
+ IssueDto issue3 = db.issues().insertIssue(rule, project, file, i -> i.setStatus("RESOLVED").setResolution(RESOLUTION_WONT_FIX));
+
+ // not returned
+ IssueDto issue4 = db.issues().insertIssue(rule, project, file, i -> i.setStatus("CLOSED").setResolution(null));
+ ComponentDto otherProject = db.components().insertPrivateProject();
+ ComponentDto otherFile = db.components().insertComponent(newFileDto(otherProject));
+ IssueDto issue5 = db.issues().insertIssue(rule, otherProject, otherFile);
+
+ List<IssueFindingDto> issues = new ArrayList<>();
+ underTest.scrollIssues(db.getSession(), PROJECT_UUID, result -> issues.add(result.getResultObject()));
+ assertThat(issues).extracting(IssueFindingDto::getKey).containsOnly(issue1.getKey(), issue2.getKey(), issue3.getKey());
+
+ // check fields
+ IssueFindingDto issue = issues.stream().filter(i -> i.getKey().equals(issue1.getKey())).findFirst().get();
+ assertThat(issue.getFileName()).isEqualTo(file.path());
+ assertThat(issue.getRuleName()).isEqualTo(rule.getName());
+ assertThat(issue.getRuleKey()).isEqualTo(rule.getRuleKey());
+ assertThat(issue.getRuleRepository()).isEqualTo(rule.getRepositoryKey());
+ assertThat(issue.getMessage()).isEqualTo(issue1.getMessage());
+ assertThat(issue.getLine()).isEqualTo(issue1.getLine());
+ assertThat(issue.getSeverity()).isEqualTo(issue1.getSeverity());
+ assertThat(issue.getType().getDbConstant()).isEqualTo(issue1.getType());
+ assertThat(issue.getSecurityStandards()).isEqualTo(rule.getSecurityStandards());
+ assertThat(issue.isManualSeverity()).isEqualTo(issue1.isManualSeverity());
+ }
+}
db.commit();
}
+ public void insertNewCodeReferenceIssue(IssueDto issue) {
+ db.getDbClient().issueDao().insertAsNewCodeOnReferenceBranch(db.getSession(), IssueTesting.newCodeReferenceIssue(issue));
+ db.commit();
+ }
+
}
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import javax.inject.Inject;
import org.apache.commons.io.FileUtils;
import org.sonar.api.SonarRuntime;
import org.sonar.api.utils.MessageException;
import static org.sonar.server.plugins.PluginType.BUNDLED;
import static org.sonar.server.plugins.PluginType.EXTERNAL;
-import javax.inject.Inject;
-
public class PluginJarLoader {
private static final Logger LOG = Loggers.get(PluginJarLoader.class);
private void addDefaultNewCodeDefinition(Builder protobuf) {
try (DbSession dbSession = dbClient.openSession(false)) {
Optional<NewCodePeriodDto> period = dbClient.newCodePeriodDao().selectGlobal(dbSession);
- setAttribute(protobuf, "Default New Code Definition", parseDefaultNewCodeDefinition(period));
+ setAttribute(protobuf, "Default New Code Definition", parseDefaultNewCodeDefinition(period.orElse(NewCodePeriodDto.defaultInstance())));
}
}
return abbreviate(value, MAX_VALUE_LENGTH);
}
- private static String parseDefaultNewCodeDefinition(Optional<NewCodePeriodDto> period) {
- if (!period.isPresent()) {
- return "PREVIOUS_VERSION";
+ private static String parseDefaultNewCodeDefinition(NewCodePeriodDto period) {
+ if (period.getValue() == null) {
+ return period.getType().name();
}
- if (period.get().getValue() == null) {
- return period.get().getType().name();
- }
-
- return period.get().getType().name() + ": " + period.get().getValue();
+ return period.getType().name() + ": " + period.getValue();
}
}