]> source.dussan.org Git - sonarqube.git/blob
ed708af42a10fdd291ec68527fd612c4b3d7579a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.computation.task.projectanalysis.step;
21
22 import org.sonar.api.issue.IssueComment;
23 import org.sonar.api.utils.System2;
24 import org.sonar.core.issue.DefaultIssue;
25 import org.sonar.core.issue.DefaultIssueComment;
26 import org.sonar.core.issue.FieldDiffs;
27 import org.sonar.db.issue.IssueChangeDto;
28 import org.sonar.db.issue.IssueChangeMapper;
29 import org.sonar.db.issue.IssueDto;
30 import org.sonar.db.issue.IssueMapper;
31 import org.sonar.server.computation.task.projectanalysis.issue.UpdateConflictResolver;
32 import org.sonar.db.DbSession;
33 import org.sonar.db.MyBatis;
34 import org.sonar.server.computation.task.projectanalysis.issue.IssueCache;
35 import org.sonar.server.computation.task.projectanalysis.issue.RuleRepository;
36 import org.sonar.db.DbClient;
37 import org.sonar.core.util.CloseableIterator;
38 import org.sonar.server.computation.task.step.ComputationStep;
39
40 public class PersistIssuesStep implements ComputationStep {
41
42   private final DbClient dbClient;
43   private final System2 system2;
44   private final UpdateConflictResolver conflictResolver;
45   private final RuleRepository ruleRepository;
46   private final IssueCache issueCache;
47
48   public PersistIssuesStep(DbClient dbClient, System2 system2, UpdateConflictResolver conflictResolver,
49     RuleRepository ruleRepository, IssueCache issueCache) {
50     this.dbClient = dbClient;
51     this.system2 = system2;
52     this.conflictResolver = conflictResolver;
53     this.ruleRepository = ruleRepository;
54     this.issueCache = issueCache;
55   }
56
57   @Override
58   public void execute() {
59     DbSession session = dbClient.openSession(true);
60     IssueMapper mapper = session.getMapper(IssueMapper.class);
61     IssueChangeMapper changeMapper = session.getMapper(IssueChangeMapper.class);
62
63     CloseableIterator<DefaultIssue> issues = issueCache.traverse();
64     try {
65       while (issues.hasNext()) {
66         DefaultIssue issue = issues.next();
67         boolean saved = false;
68         if (issue.isNew()) {
69           Integer ruleId = ruleRepository.getByKey(issue.ruleKey()).getId();
70           IssueDto dto = IssueDto.toDtoForComputationInsert(issue, ruleId, system2.now());
71           mapper.insert(dto);
72           saved = true;
73         } else if (issue.isChanged()) {
74           IssueDto dto = IssueDto.toDtoForUpdate(issue, system2.now());
75           int updateCount = mapper.updateIfBeforeSelectedDate(dto);
76           if (updateCount == 0) {
77             // End-user and scan changed the issue at the same time.
78             // See https://jira.sonarsource.com/browse/SONAR-4309
79             conflictResolver.resolve(issue, mapper);
80           }
81           saved = true;
82         }
83         if (saved) {
84           insertChanges(changeMapper, issue);
85         }
86       }
87       session.flushStatements();
88       session.commit();
89     } finally {
90       MyBatis.closeQuietly(session);
91       issues.close();
92     }
93   }
94
95   private static void insertChanges(IssueChangeMapper mapper, DefaultIssue issue) {
96     for (IssueComment comment : issue.comments()) {
97       DefaultIssueComment c = (DefaultIssueComment) comment;
98       if (c.isNew()) {
99         IssueChangeDto changeDto = IssueChangeDto.of(c);
100         mapper.insert(changeDto);
101       }
102     }
103     FieldDiffs diffs = issue.currentChange();
104     if (!issue.isNew() && diffs != null) {
105       IssueChangeDto changeDto = IssueChangeDto.of(issue.key(), diffs);
106       mapper.insert(changeDto);
107     }
108   }
109
110   @Override
111   public String getDescription() {
112     return "Persist issues";
113   }
114 }