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