Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

SizeMeasuresStep.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 SonarSource SA
  4. * mailto:info 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.ce.task.projectanalysis.step;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import java.util.Optional;
  25. import org.sonar.ce.task.projectanalysis.component.Component;
  26. import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
  27. import org.sonar.ce.task.projectanalysis.component.PathAwareCrawler;
  28. import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
  29. import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
  30. import org.sonar.ce.task.projectanalysis.formula.Formula;
  31. import org.sonar.ce.task.projectanalysis.formula.FormulaExecutorComponentVisitor;
  32. import org.sonar.ce.task.projectanalysis.measure.Measure;
  33. import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
  34. import org.sonar.ce.task.projectanalysis.metric.Metric;
  35. import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
  36. import org.sonar.ce.task.step.ComputationStep;
  37. import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
  38. import static org.sonar.api.measures.CoreMetrics.FILES_KEY;
  39. import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY;
  40. import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES_KEY;
  41. import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC_KEY;
  42. import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
  43. import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
  44. import static org.sonar.api.measures.CoreMetrics.STATEMENTS_KEY;
  45. import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
  46. import static org.sonar.ce.task.projectanalysis.formula.SumFormula.createIntSumFormula;
  47. import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
  48. /**
  49. * Compute size measures
  50. */
  51. public class SizeMeasuresStep implements ComputationStep {
  52. private static final CounterStackElementFactory COUNTER_STACK_ELEMENT_FACTORY = new CounterStackElementFactory();
  53. private static final List<Formula> AGGREGATED_SIZE_MEASURE_FORMULAS = Collections.unmodifiableList(Arrays.asList(
  54. createIntSumFormula(GENERATED_LINES_KEY),
  55. createIntSumFormula(NCLOC_KEY),
  56. createIntSumFormula(GENERATED_NCLOC_KEY),
  57. createIntSumFormula(FUNCTIONS_KEY),
  58. createIntSumFormula(STATEMENTS_KEY),
  59. createIntSumFormula(CLASSES_KEY)));
  60. private final TreeRootHolder treeRootHolder;
  61. private final MetricRepository metricRepository;
  62. private final MeasureRepository measureRepository;
  63. public SizeMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) {
  64. this.treeRootHolder = treeRootHolder;
  65. this.metricRepository = metricRepository;
  66. this.measureRepository = measureRepository;
  67. }
  68. @Override
  69. public void execute(ComputationStep.Context context) {
  70. new PathAwareCrawler<>(new FileAndDirectoryMeasureVisitor(
  71. metricRepository.getByKey(FILES_KEY),
  72. metricRepository.getByKey(LINES_KEY)))
  73. .visit(treeRootHolder.getRoot());
  74. new PathAwareCrawler<>(FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
  75. .buildFor(AGGREGATED_SIZE_MEASURE_FORMULAS))
  76. .visit(treeRootHolder.getRoot());
  77. }
  78. @Override
  79. public String getDescription() {
  80. return "Compute size measures";
  81. }
  82. private class FileAndDirectoryMeasureVisitor extends PathAwareVisitorAdapter<Counter> {
  83. private final Metric fileMetric;
  84. private final Metric linesMetric;
  85. public FileAndDirectoryMeasureVisitor(Metric fileMetric, Metric linesMetric) {
  86. super(CrawlerDepthLimit.LEAVES, POST_ORDER, COUNTER_STACK_ELEMENT_FACTORY);
  87. this.fileMetric = fileMetric;
  88. this.linesMetric = linesMetric;
  89. }
  90. @Override
  91. public void visitProject(Component project, Path<Counter> path) {
  92. createMeasures(project, path.current());
  93. }
  94. @Override
  95. public void visitDirectory(Component directory, Path<Counter> path) {
  96. int mainfileCount = path.current().files;
  97. if (mainfileCount > 0) {
  98. measureRepository.add(directory, fileMetric, newMeasureBuilder().create(mainfileCount));
  99. measureRepository.add(directory, linesMetric, newMeasureBuilder().create(path.current().lines));
  100. path.parent().files += mainfileCount;
  101. path.parent().lines += path.current().lines;
  102. }
  103. }
  104. private void createMeasures(Component directory, Counter counter) {
  105. if (counter.files > 0) {
  106. measureRepository.add(directory, fileMetric, newMeasureBuilder().create(counter.files));
  107. measureRepository.add(directory, linesMetric, newMeasureBuilder().create(counter.lines));
  108. }
  109. }
  110. @Override
  111. public void visitFile(Component file, Path<Counter> path) {
  112. if (file.getFileAttributes().isUnitTest()) {
  113. return;
  114. }
  115. int lines = file.getFileAttributes().getLines();
  116. measureRepository.add(file, fileMetric, newMeasureBuilder().create(1));
  117. measureRepository.add(file, linesMetric, newMeasureBuilder().create(lines));
  118. path.parent().lines += lines;
  119. path.parent().files += 1;
  120. }
  121. @Override
  122. public void visitView(Component view, Path<Counter> path) {
  123. createMeasures(view, path.current());
  124. }
  125. @Override
  126. public void visitSubView(Component subView, Path<Counter> path) {
  127. createMeasures(subView, path.current());
  128. path.parent().aggregate(path.current());
  129. }
  130. @Override
  131. public void visitProjectView(Component projectView, Path<Counter> path) {
  132. path.parent().files += getIntValue(projectView, this.fileMetric);
  133. path.parent().lines += getIntValue(projectView, this.linesMetric);
  134. }
  135. private int getIntValue(Component component, Metric metric) {
  136. Optional<Measure> fileMeasure = measureRepository.getRawMeasure(component, metric);
  137. return fileMeasure.map(Measure::getIntValue).orElse(0);
  138. }
  139. }
  140. private static class Counter {
  141. private int lines = 0;
  142. private int files = 0;
  143. void aggregate(Counter counter) {
  144. files += counter.files;
  145. lines += counter.lines;
  146. }
  147. }
  148. private static class CounterStackElementFactory extends PathAwareVisitorAdapter.SimpleStackElementFactory<Counter> {
  149. @Override
  150. public Counter createForAny(Component component) {
  151. return new Counter();
  152. }
  153. @Override
  154. public Counter createForFile(Component file) {
  155. return null;
  156. }
  157. @Override
  158. public Counter createForProjectView(Component projectView) {
  159. return null;
  160. }
  161. }
  162. }