You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PersistEventsStep.java 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube 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. * SonarQube 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.step;
  21. import com.google.common.base.Function;
  22. import javax.annotation.Nonnull;
  23. import org.sonar.api.utils.System2;
  24. import org.sonar.db.event.EventDto;
  25. import org.sonar.db.DbSession;
  26. import org.sonar.db.MyBatis;
  27. import org.sonar.server.computation.batch.BatchReportReader;
  28. import org.sonar.server.computation.component.Component;
  29. import org.sonar.server.computation.component.DbIdsRepository;
  30. import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
  31. import org.sonar.server.computation.component.TreeRootHolder;
  32. import org.sonar.server.computation.event.Event;
  33. import org.sonar.server.computation.event.EventRepository;
  34. import org.sonar.server.db.DbClient;
  35. import static com.google.common.collect.Iterables.transform;
  36. public class PersistEventsStep implements ComputationStep {
  37. private final DbClient dbClient;
  38. private final System2 system2;
  39. private final BatchReportReader reportReader;
  40. private final TreeRootHolder treeRootHolder;
  41. private final EventRepository eventRepository;
  42. private final DbIdsRepository dbIdsRepository;
  43. public PersistEventsStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, BatchReportReader reportReader,
  44. EventRepository eventRepository, DbIdsRepository dbIdsRepository) {
  45. this.dbClient = dbClient;
  46. this.system2 = system2;
  47. this.treeRootHolder = treeRootHolder;
  48. this.reportReader = reportReader;
  49. this.eventRepository = eventRepository;
  50. this.dbIdsRepository = dbIdsRepository;
  51. }
  52. @Override
  53. public void execute() {
  54. final DbSession session = dbClient.openSession(false);
  55. try {
  56. long analysisDate = reportReader.readMetadata().getAnalysisDate();
  57. new PersistEventComponentVisitor(session, analysisDate).visit(treeRootHolder.getRoot());
  58. session.commit();
  59. } finally {
  60. MyBatis.closeQuietly(session);
  61. }
  62. }
  63. private void processComponent(Component component, DbSession session, long analysisDate) {
  64. processEvents(session, component, analysisDate);
  65. saveVersionEvent(session, component, analysisDate);
  66. }
  67. private void processEvents(DbSession session, final Component component, final Long analysisDate) {
  68. Function<Event, EventDto> eventToEventDto = new Function<Event, EventDto>() {
  69. @Override
  70. public EventDto apply(@Nonnull Event event) {
  71. return newBaseEvent(component, analysisDate)
  72. .setName(event.getName())
  73. .setCategory(convertCategory(event.getCategory()))
  74. .setDescription(event.getDescription())
  75. .setData(event.getData());
  76. }
  77. };
  78. // FIXME bulk insert
  79. for (EventDto batchEventDto : transform(eventRepository.getEvents(component), eventToEventDto)) {
  80. dbClient.eventDao().insert(session, batchEventDto);
  81. }
  82. }
  83. private void saveVersionEvent(DbSession session, Component component, Long analysisDate) {
  84. String version = component.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. private EventDto newBaseEvent(Component component, Long analysisDate) {
  101. return new EventDto()
  102. .setComponentUuid(component.getUuid())
  103. .setSnapshotId(dbIdsRepository.getSnapshotId(component))
  104. .setCreatedAt(system2.now())
  105. .setDate(analysisDate);
  106. }
  107. private static String convertCategory(Event.Category category) {
  108. switch (category) {
  109. case ALERT:
  110. return EventDto.CATEGORY_ALERT;
  111. case PROFILE:
  112. return EventDto.CATEGORY_PROFILE;
  113. default:
  114. throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
  115. }
  116. }
  117. @Override
  118. public String getDescription() {
  119. return "Persist component links";
  120. }
  121. private class PersistEventComponentVisitor extends DepthTraversalTypeAwareVisitor {
  122. private final DbSession session;
  123. private final long analysisDate;
  124. public PersistEventComponentVisitor(DbSession session, long analysisDate) {
  125. super(Component.Type.FILE, Order.PRE_ORDER);
  126. this.session = session;
  127. this.analysisDate = analysisDate;
  128. }
  129. @Override
  130. public void visitProject(Component project) {
  131. processComponent(project, session, analysisDate);
  132. }
  133. @Override
  134. public void visitModule(Component module) {
  135. processComponent(module, session, analysisDate);
  136. }
  137. @Override
  138. public void visitDirectory(Component directory) {
  139. processComponent(directory, session, analysisDate);
  140. }
  141. @Override
  142. public void visitFile(Component file) {
  143. processComponent(file, session, analysisDate);
  144. }
  145. }
  146. }