]> source.dussan.org Git - sonarqube.git/blob
3ede645767aad95874fc5318bd7dc6995b99921d
[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 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;
38
39 import static com.google.common.collect.Iterables.transform;
40
41 public class PersistEventsStep implements ComputationStep {
42
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;
48
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;
56   }
57
58   @Override
59   public void execute() {
60     final DbSession session = dbClient.openSession(false);
61     try {
62       long analysisDate = analysisMetadataHolder.getAnalysisDate();
63       new DepthTraversalTypeAwareCrawler(new PersistEventComponentVisitor(session, analysisDate))
64         .visit(treeRootHolder.getRoot());
65       session.commit();
66     } finally {
67       MyBatis.closeQuietly(session);
68     }
69   }
70
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());
77     // FIXME bulk insert
78     for (EventDto batchEventDto : transform(eventRepository.getEvents(component), eventToEventDto)) {
79       dbClient.eventDao().insert(session, batchEventDto);
80     }
81   }
82
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)
88         .setName(version)
89         .setCategory(EventDto.CATEGORY_VERSION));
90     }
91   }
92
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());
97       }
98     }
99   }
100
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);
107   }
108
109   private static String convertCategory(Event.Category category) {
110     switch (category) {
111       case ALERT:
112         return EventDto.CATEGORY_ALERT;
113       case PROFILE:
114         return EventDto.CATEGORY_PROFILE;
115       default:
116         throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
117     }
118   }
119
120   @Override
121   public String getDescription() {
122     return "Persist events";
123   }
124
125   private class PersistEventComponentVisitor extends TypeAwareVisitorAdapter {
126     private final DbSession session;
127     private final long analysisDate;
128
129     public PersistEventComponentVisitor(DbSession session, long analysisDate) {
130       super(CrawlerDepthLimit.PROJECT, ComponentVisitor.Order.PRE_ORDER);
131       this.session = session;
132       this.analysisDate = analysisDate;
133     }
134
135     @Override
136     public void visitProject(Component project) {
137       processEvents(session, project, analysisDate);
138       saveVersionEvent(session, project, analysisDate);
139     }
140
141   }
142 }