3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.step;
22 import com.google.common.base.Function;
23 import org.sonar.api.utils.System2;
24 import org.sonar.db.DbClient;
25 import org.sonar.db.DbSession;
26 import org.sonar.db.MyBatis;
27 import org.sonar.db.event.EventDto;
28 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
29 import org.sonar.server.computation.task.projectanalysis.component.Component;
30 import org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor;
31 import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
32 import org.sonar.server.computation.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
33 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
34 import org.sonar.server.computation.task.projectanalysis.component.TypeAwareVisitorAdapter;
35 import org.sonar.server.computation.task.projectanalysis.event.Event;
36 import org.sonar.server.computation.task.projectanalysis.event.EventRepository;
37 import org.sonar.server.computation.task.step.ComputationStep;
39 import static com.google.common.collect.Iterables.transform;
41 public class PersistEventsStep implements ComputationStep {
43 private final DbClient dbClient;
44 private final System2 system2;
45 private final AnalysisMetadataHolder analysisMetadataHolder;
46 private final TreeRootHolder treeRootHolder;
47 private final EventRepository eventRepository;
49 public PersistEventsStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder,
50 EventRepository eventRepository) {
51 this.dbClient = dbClient;
52 this.system2 = system2;
53 this.treeRootHolder = treeRootHolder;
54 this.analysisMetadataHolder = analysisMetadataHolder;
55 this.eventRepository = eventRepository;
59 public void execute() {
60 final DbSession session = dbClient.openSession(false);
62 long analysisDate = analysisMetadataHolder.getAnalysisDate();
63 new DepthTraversalTypeAwareCrawler(new PersistEventComponentVisitor(session, analysisDate))
64 .visit(treeRootHolder.getRoot());
67 MyBatis.closeQuietly(session);
71 private void processEvents(DbSession session, Component component, Long analysisDate) {
72 Function<Event, EventDto> eventToEventDto = event -> newBaseEvent(component, analysisDate)
73 .setName(event.getName())
74 .setCategory(convertCategory(event.getCategory()))
75 .setDescription(event.getDescription())
76 .setData(event.getData());
78 for (EventDto batchEventDto : transform(eventRepository.getEvents(component), eventToEventDto)) {
79 dbClient.eventDao().insert(session, batchEventDto);
83 private void saveVersionEvent(DbSession session, Component component, Long analysisDate) {
84 String version = component.getReportAttributes().getVersion();
85 if (version != null) {
86 deletePreviousEventsHavingSameVersion(session, version, component);
87 dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
89 .setCategory(EventDto.CATEGORY_VERSION));
93 private void deletePreviousEventsHavingSameVersion(DbSession session, String version, Component component) {
94 for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) {
95 if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(version)) {
96 dbClient.eventDao().delete(session, dto.getId());
101 private EventDto newBaseEvent(Component component, Long analysisDate) {
102 return new EventDto()
103 .setAnalysisUuid(analysisMetadataHolder.getUuid())
104 .setComponentUuid(component.getUuid())
105 .setCreatedAt(system2.now())
106 .setDate(analysisDate);
109 private static String convertCategory(Event.Category category) {
112 return EventDto.CATEGORY_ALERT;
114 return EventDto.CATEGORY_PROFILE;
116 throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
121 public String getDescription() {
122 return "Persist events";
125 private class PersistEventComponentVisitor extends TypeAwareVisitorAdapter {
126 private final DbSession session;
127 private final long analysisDate;
129 public PersistEventComponentVisitor(DbSession session, long analysisDate) {
130 super(CrawlerDepthLimit.PROJECT, ComponentVisitor.Order.PRE_ORDER);
131 this.session = session;
132 this.analysisDate = analysisDate;
136 public void visitProject(Component project) {
137 processEvents(session, project, analysisDate);
138 saveVersionEvent(session, project, analysisDate);