]> source.dussan.org Git - sonarqube.git/blob
a7ce30c32fe0d820136161aadce8ffaf28013f58
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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.batch;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.util.NoSuchElementException;
27 import java.util.Optional;
28 import javax.annotation.CheckForNull;
29 import org.apache.commons.io.FileUtils;
30 import org.apache.commons.io.IOUtils;
31 import org.apache.commons.io.LineIterator;
32 import org.sonar.core.util.CloseableIterator;
33 import org.sonar.core.util.LineReaderIterator;
34 import org.sonar.scanner.protocol.output.FileStructure;
35 import org.sonar.scanner.protocol.output.ScannerReport;
36 import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode;
37 import org.sonar.scanner.protocol.output.ScannerReportReader;
38
39 import static java.nio.charset.StandardCharsets.UTF_8;
40
41 public class BatchReportReaderImpl implements BatchReportReader {
42
43   private final BatchReportDirectoryHolder batchReportDirectoryHolder;
44   private ScannerReportReader delegate;
45   // caching of metadata which are read often
46   private ScannerReport.Metadata metadata;
47
48   public BatchReportReaderImpl(BatchReportDirectoryHolder batchReportDirectoryHolder) {
49     this.batchReportDirectoryHolder = batchReportDirectoryHolder;
50   }
51
52   private void ensureInitialized() {
53     if (this.delegate == null) {
54       FileStructure fileStructure = new FileStructure(batchReportDirectoryHolder.getDirectory());
55       this.delegate = new ScannerReportReader(fileStructure);
56     }
57   }
58
59   @Override
60   public ScannerReport.Metadata readMetadata() {
61     ensureInitialized();
62     if (this.metadata == null) {
63       this.metadata = delegate.readMetadata();
64     }
65     return this.metadata;
66   }
67
68   @CheckForNull
69   @Override
70   public InputStream getAnalysisCache() {
71     ensureInitialized();
72     return delegate.getAnalysisCache();
73   }
74
75   @Override
76   public CloseableIterator<String> readScannerLogs() {
77     ensureInitialized();
78     File file = delegate.getFileStructure().analysisLog();
79     if (!file.exists()) {
80       return CloseableIterator.emptyCloseableIterator();
81     }
82     try {
83       InputStreamReader reader = new InputStreamReader(FileUtils.openInputStream(file), UTF_8);
84       return new LineReaderIterator(reader);
85     } catch (IOException e) {
86       throw new IllegalStateException("Fail to open file " + file, e);
87     }
88   }
89
90   @Override
91   public CloseableIterator<ScannerReport.ActiveRule> readActiveRules() {
92     ensureInitialized();
93     return delegate.readActiveRules();
94   }
95
96   @Override
97   public CloseableIterator<ScannerReport.AdHocRule> readAdHocRules() {
98     ensureInitialized();
99     return delegate.readAdHocRules();
100   }
101
102   @Override
103   public CloseableIterator<ScannerReport.Measure> readComponentMeasures(int componentRef) {
104     ensureInitialized();
105     return delegate.readComponentMeasures(componentRef);
106   }
107
108   @Override
109   @CheckForNull
110   public ScannerReport.Changesets readChangesets(int componentRef) {
111     ensureInitialized();
112     return delegate.readChangesets(componentRef);
113   }
114
115   @Override
116   public ScannerReport.Component readComponent(int componentRef) {
117     ensureInitialized();
118     return delegate.readComponent(componentRef);
119   }
120
121   @Override
122   public CloseableIterator<ScannerReport.Issue> readComponentIssues(int componentRef) {
123     ensureInitialized();
124     return delegate.readComponentIssues(componentRef);
125   }
126
127   @Override
128   public CloseableIterator<ScannerReport.ExternalIssue> readComponentExternalIssues(int componentRef) {
129     ensureInitialized();
130     return delegate.readComponentExternalIssues(componentRef);
131   }
132
133   @Override
134   public CloseableIterator<ScannerReport.Duplication> readComponentDuplications(int componentRef) {
135     ensureInitialized();
136     return delegate.readComponentDuplications(componentRef);
137   }
138
139   @Override
140   public CloseableIterator<ScannerReport.CpdTextBlock> readCpdTextBlocks(int componentRef) {
141     ensureInitialized();
142     return delegate.readCpdTextBlocks(componentRef);
143   }
144
145   @Override
146   public CloseableIterator<ScannerReport.Symbol> readComponentSymbols(int componentRef) {
147     ensureInitialized();
148     return delegate.readComponentSymbols(componentRef);
149   }
150
151   @Override
152   public CloseableIterator<ScannerReport.SyntaxHighlightingRule> readComponentSyntaxHighlighting(int fileRef) {
153     ensureInitialized();
154     return delegate.readComponentSyntaxHighlighting(fileRef);
155   }
156
157   @Override
158   public CloseableIterator<ScannerReport.LineCoverage> readComponentCoverage(int fileRef) {
159     ensureInitialized();
160     return delegate.readComponentCoverage(fileRef);
161   }
162
163   @Override
164   public Optional<CloseableIterator<String>> readFileSource(int fileRef) {
165     ensureInitialized();
166     File file = delegate.readFileSource(fileRef);
167     if (file == null) {
168       return Optional.empty();
169     }
170
171     try {
172       return Optional.of(new CloseableLineIterator(IOUtils.lineIterator(FileUtils.openInputStream(file), UTF_8)));
173     } catch (IOException e) {
174       throw new IllegalStateException("Fail to traverse file: " + file, e);
175     }
176   }
177
178   private static class CloseableLineIterator extends CloseableIterator<String> {
179     private final LineIterator lineIterator;
180
181     public CloseableLineIterator(LineIterator lineIterator) {
182       this.lineIterator = lineIterator;
183     }
184
185     @Override
186     public boolean hasNext() {
187       return lineIterator.hasNext();
188     }
189
190     @Override
191     public String next() {
192       return lineIterator.next();
193     }
194
195     @Override
196     protected String doNext() {
197       // never called anyway
198       throw new NoSuchElementException("Empty closeable Iterator has no element");
199     }
200
201     @Override
202     protected void doClose() throws IOException {
203       lineIterator.close();
204     }
205   }
206
207   @Override
208   public CloseableIterator<ScannerReport.ContextProperty> readContextProperties() {
209     ensureInitialized();
210     return delegate.readContextProperties();
211   }
212
213   @Override
214   public Optional<CloseableIterator<LineSgnificantCode>> readComponentSignificantCode(int fileRef) {
215     ensureInitialized();
216     return Optional.ofNullable(delegate.readComponentSignificantCode(fileRef));
217   }
218
219   @Override
220   public Optional<ScannerReport.ChangedLines> readComponentChangedLines(int fileRef) {
221     ensureInitialized();
222     return Optional.ofNullable(delegate.readComponentChangedLines(fileRef));
223   }
224
225   @Override
226   public CloseableIterator<ScannerReport.AnalysisWarning> readAnalysisWarnings() {
227     ensureInitialized();
228     return delegate.readAnalysisWarnings();
229   }
230 }