@@ -27,7 +27,7 @@ import java.sql.ResultSet; | |||
import java.sql.SQLException; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
import java.util.function.Consumer; | |||
import javax.annotation.CheckForNull; | |||
import org.apache.commons.dbutils.DbUtils; | |||
import org.apache.commons.io.IOUtils; | |||
@@ -45,7 +45,7 @@ public class FileSourceDao implements Dao { | |||
} | |||
@CheckForNull | |||
public FileSourceDto selectTest(DbSession dbSession, String fileUuid) { | |||
public FileSourceDto selectTestByFileUuid(DbSession dbSession, String fileUuid) { | |||
return mapper(dbSession).select(fileUuid, Type.TEST); | |||
} | |||
@@ -74,7 +74,7 @@ public class FileSourceDao implements Dao { | |||
} | |||
} | |||
public <T> void readLineHashesStream(DbSession dbSession, String fileUuid, Function<Reader, T> function) { | |||
public void readLineHashesStream(DbSession dbSession, String fileUuid, Consumer<Reader> consumer) { | |||
Connection connection = dbSession.getConnection(); | |||
PreparedStatement pstmt = null; | |||
ResultSet rs = null; | |||
@@ -87,7 +87,7 @@ public class FileSourceDao implements Dao { | |||
if (rs.next()) { | |||
reader = rs.getCharacterStream(1); | |||
if (reader != null) { | |||
function.apply(reader); | |||
consumer.accept(reader); | |||
} | |||
} | |||
} catch (SQLException e) { |
@@ -206,7 +206,7 @@ public class FileSourceDto { | |||
} | |||
/** | |||
* Compressed value of serialized protobuf message {@link org.sonar.db.protobuf.DbFileSources.Data} | |||
* Decompressed value of serialized protobuf message {@link org.sonar.db.protobuf.DbFileSources.Data} | |||
*/ | |||
public DbFileSources.Data getSourceData() { | |||
return decodeSourceData(binaryData); |
@@ -21,7 +21,7 @@ package org.sonar.db.source; | |||
import java.io.IOException; | |||
import java.io.Reader; | |||
import java.util.function.Function; | |||
import java.util.function.Consumer; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.io.IOUtils; | |||
import org.junit.Rule; | |||
@@ -63,7 +63,7 @@ public class FileSourceDaoTest { | |||
public void select_line_hashes() { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
ReaderToStringFunction fn = new ReaderToStringFunction(); | |||
ReaderToStringConsumer fn = new ReaderToStringConsumer(); | |||
underTest.readLineHashesStream(dbTester.getSession(), "FILE1_UUID", fn); | |||
assertThat(fn.result).isEqualTo("ABC\\nDEF\\nGHI"); | |||
@@ -73,7 +73,7 @@ public class FileSourceDaoTest { | |||
public void no_line_hashes_on_unknown_file() { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
ReaderToStringFunction fn = new ReaderToStringFunction(); | |||
ReaderToStringConsumer fn = new ReaderToStringConsumer(); | |||
underTest.readLineHashesStream(dbTester.getSession(), "unknown", fn); | |||
assertThat(fn.result).isNull(); | |||
@@ -83,7 +83,7 @@ public class FileSourceDaoTest { | |||
public void no_line_hashes_when_only_test_data() { | |||
dbTester.prepareDbUnit(getClass(), "no_line_hashes_when_only_test_data.xml"); | |||
ReaderToStringFunction fn = new ReaderToStringFunction(); | |||
ReaderToStringConsumer fn = new ReaderToStringConsumer(); | |||
underTest.readLineHashesStream(dbTester.getSession(), "FILE1_UUID", fn); | |||
assertThat(fn.result).isNull(); | |||
@@ -115,15 +115,15 @@ public class FileSourceDaoTest { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
underTest.insert(session, new FileSourceDto() | |||
.setProjectUuid("PRJ_UUID") | |||
.setFileUuid("FILE2_UUID") | |||
.setBinaryData("FILE2_BINARY_DATA".getBytes()) | |||
.setDataHash("FILE2_DATA_HASH") | |||
.setSrcHash("FILE2_HASH") | |||
.setDataType(Type.SOURCE) | |||
.setCreatedAt(1500000000000L) | |||
.setUpdatedAt(1500000000001L) | |||
.setRevision("123456789")); | |||
.setProjectUuid("PRJ_UUID") | |||
.setFileUuid("FILE2_UUID") | |||
.setBinaryData("FILE2_BINARY_DATA".getBytes()) | |||
.setDataHash("FILE2_DATA_HASH") | |||
.setSrcHash("FILE2_HASH") | |||
.setDataType(Type.SOURCE) | |||
.setCreatedAt(1500000000000L) | |||
.setUpdatedAt(1500000000001L) | |||
.setRevision("123456789")); | |||
session.commit(); | |||
assertThat(underTest.selectLineHashes(dbTester.getSession(), "FILE2_UUID")).isEmpty(); | |||
@@ -134,25 +134,23 @@ public class FileSourceDaoTest { | |||
dbTester.prepareDbUnit(getClass(), "shared.xml"); | |||
underTest.insert(session, new FileSourceDto() | |||
.setProjectUuid("PRJ_UUID") | |||
.setFileUuid("FILE2_UUID") | |||
.setBinaryData("FILE2_BINARY_DATA".getBytes()) | |||
.setDataHash("FILE2_DATA_HASH") | |||
.setSrcHash("FILE2_HASH") | |||
.setDataType(Type.SOURCE) | |||
.setCreatedAt(1500000000000L) | |||
.setUpdatedAt(1500000000001L) | |||
.setRevision("123456789")); | |||
.setProjectUuid("PRJ_UUID") | |||
.setFileUuid("FILE2_UUID") | |||
.setBinaryData("FILE2_BINARY_DATA".getBytes()) | |||
.setDataHash("FILE2_DATA_HASH") | |||
.setSrcHash("FILE2_HASH") | |||
.setDataType(Type.SOURCE) | |||
.setCreatedAt(1500000000000L) | |||
.setUpdatedAt(1500000000001L) | |||
.setRevision("123456789")); | |||
session.commit(); | |||
boolean[] flag = {false}; | |||
underTest.readLineHashesStream(dbTester.getSession(), "FILE2_UUID", new Function<Reader, Void>() { | |||
@Nullable | |||
underTest.readLineHashesStream(dbTester.getSession(), "FILE2_UUID", new Consumer<Reader>() { | |||
@Override | |||
public Void apply(@Nullable Reader input) { | |||
public void accept(@Nullable Reader input) { | |||
fail("function must never been called since there is no data to read"); | |||
flag[0] = true; | |||
return null; | |||
} | |||
}); | |||
assertThat(flag[0]).isFalse(); | |||
@@ -179,15 +177,14 @@ public class FileSourceDaoTest { | |||
"project_uuid", "file_uuid", "data_hash", "line_hashes", "src_hash", "created_at", "updated_at", "data_type", "revision"); | |||
} | |||
private static class ReaderToStringFunction implements Function<Reader, String> { | |||
private static class ReaderToStringConsumer implements Consumer<Reader> { | |||
String result = null; | |||
@Override | |||
public String apply(Reader input) { | |||
public void accept(Reader input) { | |||
try { | |||
result = IOUtils.toString(input); | |||
return IOUtils.toString(input); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} |
@@ -53,7 +53,7 @@ public interface BatchReportReader { | |||
CloseableIterator<ScannerReport.LineCoverage> readComponentCoverage(int fileRef); | |||
/** | |||
* Reads file source line by line. Return an absent optional if the file doest not exist | |||
* Reads a file's source code, line by line. Returns an absent optional if the file does not exist | |||
*/ | |||
Optional<CloseableIterator<String>> readFileSource(int fileRef); | |||
@@ -62,4 +62,6 @@ public interface BatchReportReader { | |||
CloseableIterator<ScannerReport.CoverageDetail> readCoverageDetails(int testFileRef); | |||
CloseableIterator<ScannerReport.ContextProperty> readContextProperties(); | |||
CloseableIterator<ScannerReport.LineSgnificantCode> readComponentSignificantCode(int fileRef); | |||
} |
@@ -36,6 +36,7 @@ import org.apache.commons.io.LineIterator; | |||
import org.sonar.core.util.CloseableIterator; | |||
import org.sonar.core.util.LineReaderIterator; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode; | |||
public class BatchReportReaderImpl implements BatchReportReader { | |||
@@ -254,4 +255,10 @@ public class BatchReportReaderImpl implements BatchReportReader { | |||
fileInputStream.close(); | |||
} | |||
} | |||
@Override | |||
public CloseableIterator<LineSgnificantCode> readComponentSignificantCode(int fileRef) { | |||
ensureInitialized(); | |||
return delegate.readComponentSignificantCode(fileRef); | |||
} | |||
} |
@@ -19,9 +19,9 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.issue; | |||
import com.google.common.base.Optional; | |||
import com.google.common.base.Strings; | |||
import java.util.Date; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.utils.log.Logger; |
@@ -139,7 +139,7 @@ public class IssueCreationDateCalculator extends IssueVisitor { | |||
} | |||
private Optional<ScmInfo> getScmInfo(Component component) { | |||
return toJavaUtilOptional(scmInfoRepository.getScmInfo(component)); | |||
return scmInfoRepository.getScmInfo(component); | |||
} | |||
private static Optional<Changeset> getChangeset(Component component, ScmInfo scmInfo, DefaultIssue issue) { |
@@ -165,7 +165,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N | |||
return; | |||
} | |||
Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file); | |||
java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file); | |||
if (!scmInfoOptional.isPresent()) { | |||
LOG.trace(String.format("No changeset for file %s. Dev cost will be zero.", file.getKey())); | |||
return; |
@@ -49,7 +49,7 @@ public class ScmInfoDbLoader { | |||
return Optional.empty(); | |||
} | |||
LOGGER.trace("Reading SCM info from db for file '{}'", uuid.get()); | |||
LOGGER.trace("Reading SCM info from DB for file '{}'", uuid.get()); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
FileSourceDto dto = dbClient.fileSourceDao().selectSourceByFileUuid(dbSession, uuid.get()); | |||
if (dto == null) { |
@@ -19,7 +19,7 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.scm; | |||
import com.google.common.base.Optional; | |||
import java.util.Optional; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
/** |
@@ -58,18 +58,14 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { | |||
} | |||
@Override | |||
public com.google.common.base.Optional<ScmInfo> getScmInfo(Component component) { | |||
public Optional<ScmInfo> getScmInfo(Component component) { | |||
requireNonNull(component, "Component cannot be null"); | |||
if (component.getType() != Component.Type.FILE) { | |||
return com.google.common.base.Optional.absent(); | |||
return Optional.empty(); | |||
} | |||
return toGuavaOptional(scmInfoCache.computeIfAbsent(component, this::getScmInfoForComponent)); | |||
} | |||
private static com.google.common.base.Optional<ScmInfo> toGuavaOptional(Optional<ScmInfo> scmInfo) { | |||
return com.google.common.base.Optional.fromNullable(scmInfo.orElse(null)); | |||
return scmInfoCache.computeIfAbsent(component, this::getScmInfoForComponent); | |||
} | |||
private Optional<ScmInfo> getScmInfoForComponent(Component component) { | |||
@@ -77,7 +73,7 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { | |||
if (changesets == null) { | |||
LOGGER.trace("No SCM info for file '{}'", component.getKey()); | |||
// SCM not available. It might have been available before - don't keep author and revision. | |||
// SCM not available. It might have been available before - copy information for unchanged lines but don't keep author and revision. | |||
return generateAndMergeDb(component, false); | |||
} | |||
@@ -111,6 +107,12 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { | |||
return Changeset.newChangesetBuilder().setDate(changeset.getDate()).build(); | |||
} | |||
/** | |||
* Get SCM information in the DB, if it exists, and use it for lines that didn't change. It optionally removes author and revision | |||
* information (only keeping change dates). | |||
* If the information is not present in the DB or some lines don't match existing lines in the DB, | |||
* we generate change dates based on the analysis date. | |||
*/ | |||
private Optional<ScmInfo> generateAndMergeDb(Component file, boolean keepAuthorAndRevision) { | |||
Optional<DbScmInfo> dbInfoOpt = scmInfoDbLoader.getScmInfo(file); | |||
if (!dbInfoOpt.isPresent()) { | |||
@@ -125,7 +127,7 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { | |||
} | |||
// generate date for new/changed lines | |||
int[] matchingLines = sourceLinesDiff.getMatchingLines(file); | |||
int[] matchingLines = sourceLinesDiff.computeMatchingLines(file); | |||
return Optional.of(GeneratedScmInfo.create(analysisMetadata.getAnalysisDate(), matchingLines, scmInfo)); | |||
} |
@@ -25,6 +25,7 @@ import java.util.List; | |||
import org.sonar.core.hash.SourceHashComputer; | |||
import org.sonar.core.hash.SourceLinesHashesComputer; | |||
import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.LineReader; | |||
public class ComputeFileSourceData { | |||
@@ -50,12 +51,13 @@ public class ComputeFileSourceData { | |||
return data; | |||
} | |||
private void read(Data data, String source, boolean hasNextLine) { | |||
data.linesHashesComputer.addLine(source); | |||
data.sourceHashComputer.addLine(source, hasNextLine); | |||
private void read(Data data, String lineSource, boolean hasNextLine) { | |||
data.linesHashesComputer.addLine(lineSource); | |||
data.sourceHashComputer.addLine(lineSource, hasNextLine); | |||
DbFileSources.Line.Builder lineBuilder = data.fileSourceBuilder.addLinesBuilder() | |||
.setSource(source) | |||
DbFileSources.Line.Builder lineBuilder = data.fileSourceBuilder | |||
.addLinesBuilder() | |||
.setSource(lineSource) | |||
.setLine(currentLine); | |||
for (LineReader lineReader : lineReaders) { | |||
lineReader.read(lineBuilder); |
@@ -78,7 +78,7 @@ public class LastCommitVisitor extends PathAwareVisitorAdapter<LastCommitVisitor | |||
// since previous analysis (optimization to decrease execution of blame commands). In this case | |||
// the date is loaded from database, as it did not change from previous analysis. | |||
Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file); | |||
java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(file); | |||
if (scmInfoOptional.isPresent()) { | |||
ScmInfo scmInfo = scmInfoOptional.get(); | |||
path.current().addDate(scmInfo.getLatestChangeset().getDate()); |
@@ -28,5 +28,5 @@ public interface SourceLinesDiff { | |||
* @return an array with one entry for each line in the left side. Those entries point either to a line in the right side, or to 0, | |||
* in which case it means the line was added. | |||
*/ | |||
int[] getMatchingLines(Component component); | |||
int[] computeMatchingLines(Component component); | |||
} |
@@ -28,15 +28,8 @@ import org.sonar.api.utils.log.Loggers; | |||
public class SourceLinesDiffFinder { | |||
private static final Logger LOG = Loggers.get(SourceLinesDiffFinder.class); | |||
private final List<String> left; | |||
private final List<String> right; | |||
public SourceLinesDiffFinder(List<String> left, List<String> right) { | |||
this.left = left; | |||
this.right = right; | |||
} | |||
public int[] findMatchingLines() { | |||
public int[] findMatchingLines(List<String> left, List<String> right) { | |||
int[] index = new int[right.size()]; | |||
int dbLine = left.size(); |
@@ -19,7 +19,7 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.sonar.core.hash.SourceLinesHashesComputer; | |||
import org.sonar.core.util.CloseableIterator; | |||
@@ -42,17 +42,25 @@ public class SourceLinesDiffImpl implements SourceLinesDiff { | |||
} | |||
@Override | |||
public int[] getMatchingLines(Component component) { | |||
public int[] computeMatchingLines(Component component) { | |||
List<String> database; | |||
List<String> database = getDBLines(component); | |||
List<String> report = getReportLines(component); | |||
return new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
} | |||
private List<String> getDBLines(Component component) { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
database = fileSourceDao.selectLineHashes(dbSession, component.getUuid()); | |||
List<String> database = fileSourceDao.selectLineHashes(dbSession, component.getUuid()); | |||
if (database == null) { | |||
database = new ArrayList<>(); | |||
return Collections.emptyList(); | |||
} | |||
return database; | |||
} | |||
} | |||
List<String> report; | |||
private List<String> getReportLines(Component component) { | |||
SourceLinesHashesComputer linesHashesComputer = new SourceLinesHashesComputer(); | |||
try (CloseableIterator<String> lineIterator = sourceLinesRepository.readLines(component)) { | |||
while (lineIterator.hasNext()) { | |||
@@ -60,10 +68,7 @@ public class SourceLinesDiffImpl implements SourceLinesDiff { | |||
linesHashesComputer.addLine(line); | |||
} | |||
} | |||
report = linesHashesComputer.getLineHashes(); | |||
return new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
return linesHashesComputer.getLineHashes(); | |||
} | |||
} |
@@ -39,7 +39,7 @@ public class SourceLinesRepositoryImpl implements SourceLinesRepository { | |||
@Override | |||
public CloseableIterator<String> readLines(Component file) { | |||
requireNonNull(file, "Component should not be bull"); | |||
requireNonNull(file, "Component should not be null"); | |||
checkArgument(file.getType() == FILE, "Component '%s' is not a file", file); | |||
Optional<CloseableIterator<String>> linesIteratorOptional = reportReader.readFileSource(file.getReportAttributes().getRef()); | |||
@@ -90,7 +90,7 @@ public class SourceLinesRepositoryImpl implements SourceLinesRepository { | |||
@Override | |||
protected String doNext() { | |||
throw new UnsupportedOperationException("No implemented because hasNext and next are override"); | |||
throw new UnsupportedOperationException("Not implemented because hasNext() and next() are overriden"); | |||
} | |||
@Override |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import java.util.Iterator; | |||
import javax.annotation.CheckForNull; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import com.google.common.base.Function; | |||
import com.google.common.base.Predicate; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import com.google.common.collect.ImmutableMap; | |||
import java.util.Iterator; | |||
@@ -30,12 +30,12 @@ import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
import org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.RangeOffsetConverterException; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.RangeOffsetConverterException; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static java.lang.String.format; | |||
import static org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.OFFSET_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.SYMBOLS_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.OFFSET_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.SYMBOLS_SEPARATOR; | |||
public class HighlightingLineReader implements LineReader { | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import org.sonar.db.protobuf.DbFileSources; | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.db.protobuf.DbFileSources; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import com.google.common.collect.HashMultimap; | |||
import com.google.common.collect.Lists; | |||
@@ -34,10 +34,11 @@ import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.RangeOffsetConverterException; | |||
import static java.lang.String.format; | |||
import static org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.OFFSET_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.SYMBOLS_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.OFFSET_SEPARATOR; | |||
import static org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.SYMBOLS_SEPARATOR; | |||
public class SymbolsLineReader implements LineReader { | |||
@@ -0,0 +1,23 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2018 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -251,7 +251,7 @@ public class NewCoverageMeasuresStep implements ComputationStep { | |||
@Override | |||
public void initialize(CounterInitializationContext context) { | |||
Component fileComponent = context.getLeaf(); | |||
Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(fileComponent); | |||
java.util.Optional<ScmInfo> scmInfoOptional = scmInfoRepository.getScmInfo(fileComponent); | |||
if (!scmInfoOptional.isPresent() || !context.hasPeriod()) { | |||
return; | |||
} |
@@ -109,7 +109,7 @@ public class NewSizeMeasuresStep implements ComputationStep { | |||
@Override | |||
public void initialize(CounterInitializationContext context) { | |||
Component leaf = context.getLeaf(); | |||
Optional<ScmInfo> scmInfo = scmInfoRepository.getScmInfo(leaf); | |||
java.util.Optional<ScmInfo> scmInfo = scmInfoRepository.getScmInfo(leaf); | |||
if (!scmInfo.isPresent() || !context.hasPeriod()) { | |||
return; | |||
} |
@@ -19,12 +19,12 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.step; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.ImmutableMap; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
@@ -48,14 +48,14 @@ import org.sonar.server.computation.task.projectanalysis.scm.Changeset; | |||
import org.sonar.server.computation.task.projectanalysis.scm.ScmInfo; | |||
import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepository; | |||
import org.sonar.server.computation.task.projectanalysis.source.ComputeFileSourceData; | |||
import org.sonar.server.computation.task.projectanalysis.source.CoverageLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.DuplicationLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.HighlightingLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.LineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter; | |||
import org.sonar.server.computation.task.projectanalysis.source.ScmLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepository; | |||
import org.sonar.server.computation.task.projectanalysis.source.SymbolsLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.CoverageLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.DuplicationLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.HighlightingLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.LineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.ScmLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.SymbolsLineReader; | |||
import org.sonar.server.computation.task.step.ComputationStep; | |||
import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER; | |||
@@ -220,10 +220,7 @@ public class PersistFileSourcesStep implements ComputationStep { | |||
@CheckForNull | |||
public Changeset getLatestChangeWithRevision() { | |||
if (scmLineReader == null) { | |||
return null; | |||
} | |||
return scmLineReader.getLatestChangeWithRevision(); | |||
return scmLineReader == null ? null : scmLineReader.getLatestChangeWithRevision(); | |||
} | |||
} | |||
@@ -33,10 +33,12 @@ public class SourceService { | |||
private final DbClient dbClient; | |||
private final HtmlSourceDecorator htmlDecorator; | |||
private final Function<DbFileSources.Line, String> lineToHtml; | |||
public SourceService(DbClient dbClient, HtmlSourceDecorator htmlDecorator) { | |||
this.dbClient = dbClient; | |||
this.htmlDecorator = htmlDecorator; | |||
this.lineToHtml = lineToHtml(); | |||
} | |||
/** | |||
@@ -57,7 +59,7 @@ public class SourceService { | |||
} | |||
public Optional<Iterable<String>> getLinesAsHtml(DbSession dbSession, String fileUuid, int from, int toInclusive) { | |||
return getLines(dbSession, fileUuid, from, toInclusive, lineToHtml()); | |||
return getLines(dbSession, fileUuid, from, toInclusive, lineToHtml); | |||
} | |||
private <E> Optional<Iterable<E>> getLines(DbSession dbSession, String fileUuid, int from, int toInclusive, Function<DbFileSources.Line, E> function) { |
@@ -25,7 +25,7 @@ import java.io.IOException; | |||
import java.io.OutputStreamWriter; | |||
import java.io.Reader; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.function.Function; | |||
import java.util.function.Consumer; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
@@ -75,7 +75,7 @@ public class HashAction implements SourcesWsAction { | |||
response.stream().setMediaType("text/plain"); | |||
try (OutputStreamWriter writer = new OutputStreamWriter(response.stream().output(), StandardCharsets.UTF_8)) { | |||
HashFunction hashFunction = new HashFunction(writer, componentKey); | |||
HashConsumer hashFunction = new HashConsumer(writer, componentKey); | |||
dbClient.fileSourceDao().readLineHashesStream(session, component.uuid(), hashFunction); | |||
if (!hashFunction.hasData()) { | |||
response.noContent(); | |||
@@ -84,26 +84,25 @@ public class HashAction implements SourcesWsAction { | |||
} | |||
} | |||
private static class HashFunction implements Function<Reader, Void> { | |||
private static class HashConsumer implements Consumer<Reader> { | |||
private final OutputStreamWriter writer; | |||
private final String componentKey; | |||
private boolean hasData = false; | |||
public HashFunction(OutputStreamWriter writer, String componentKey) { | |||
public HashConsumer(OutputStreamWriter writer, String componentKey) { | |||
this.writer = writer; | |||
this.componentKey = componentKey; | |||
} | |||
@Override | |||
public Void apply(Reader input) { | |||
public void accept(Reader input) { | |||
try { | |||
hasData = true; | |||
CharStreams.copy(input, writer); | |||
} catch (IOException e) { | |||
throw new IllegalStateException(String.format("Can't read line hashes of file '%s'", componentKey), e); | |||
} | |||
return null; | |||
} | |||
public boolean hasData() { |
@@ -363,7 +363,7 @@ public class IssueCreationDateCalculatorTest { | |||
private void noScm() { | |||
when(scmInfoRepository.getScmInfo(component)) | |||
.thenReturn(Optional.absent()); | |||
.thenReturn(java.util.Optional.empty()); | |||
} | |||
private void withScm(long blame) { | |||
@@ -376,7 +376,7 @@ public class IssueCreationDateCalculatorTest { | |||
if (scmInfo == null) { | |||
scmInfo = mock(ScmInfo.class); | |||
when(scmInfoRepository.getScmInfo(component)) | |||
.thenReturn(Optional.of(scmInfo)); | |||
.thenReturn(java.util.Optional.empty()); | |||
} | |||
} | |||
@@ -83,7 +83,7 @@ public class ScmInfoDbLoaderTest { | |||
assertThat(scmInfo.getAllChangesets()).hasSize(1); | |||
assertThat(scmInfo.fileHash()).isEqualTo(hash); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'FILE_UUID'"); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'FILE_UUID'"); | |||
} | |||
@Test | |||
@@ -101,7 +101,7 @@ public class ScmInfoDbLoaderTest { | |||
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get(); | |||
assertThat(scmInfo.getAllChangesets()).hasSize(1); | |||
assertThat(scmInfo.fileHash()).isEqualTo(hash); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'mergeFileUuid'"); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'mergeFileUuid'"); | |||
} | |||
@Test | |||
@@ -111,7 +111,7 @@ public class ScmInfoDbLoaderTest { | |||
Optional<DbScmInfo> scmInfo = underTest.getScmInfo(FILE); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'FILE_UUID'"); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'FILE_UUID'"); | |||
assertThat(scmInfo).isEmpty(); | |||
} | |||
@@ -50,7 +50,6 @@ import org.sonar.server.computation.task.projectanalysis.source.SourceHashReposi | |||
import org.sonar.server.computation.task.projectanalysis.source.SourceLinesDiff; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.guava.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||
@@ -93,7 +92,7 @@ public class ScmInfoRepositoryImplTest { | |||
public void return_empty_if_component_is_not_file() { | |||
Component c = mock(Component.class); | |||
when(c.getType()).thenReturn(Type.DIRECTORY); | |||
assertThat(underTest.getScmInfo(c)).isAbsent(); | |||
assertThat(underTest.getScmInfo(c)).isEmpty(); | |||
} | |||
@Test | |||
@@ -205,7 +204,7 @@ public class ScmInfoRepositoryImplTest { | |||
@Test | |||
public void generate_scm_info_for_new_and_changed_lines_when_report_is_empty() { | |||
createDbScmInfoWithOneLine("hash"); | |||
when(diff.getMatchingLines(FILE)).thenReturn(new int[] {1, 0, 0}); | |||
when(diff.computeMatchingLines(FILE)).thenReturn(new int[] {1, 0, 0}); | |||
addFileSourceInReport(3); | |||
ScmInfo scmInfo = underTest.getScmInfo(FILE).get(); | |||
assertThat(scmInfo.getAllChangesets()).hasSize(3); | |||
@@ -215,7 +214,7 @@ public class ScmInfoRepositoryImplTest { | |||
assertChangeset(scmInfo.getChangesetForLine(3), null, null, analysisDate.getTime()); | |||
verify(dbLoader).getScmInfo(FILE); | |||
verify(diff).getMatchingLines(FILE); | |||
verify(diff).computeMatchingLines(FILE); | |||
verifyNoMoreInteractions(dbLoader); | |||
verifyZeroInteractions(sourceHashRepository); | |||
verifyNoMoreInteractions(diff); | |||
@@ -235,7 +234,7 @@ public class ScmInfoRepositoryImplTest { | |||
BatchReportReader batchReportReader = mock(BatchReportReader.class); | |||
ScmInfoRepositoryImpl underTest = new ScmInfoRepositoryImpl(batchReportReader, analysisMetadata, dbLoader, diff, sourceHashRepository); | |||
assertThat(underTest.getScmInfo(component)).isAbsent(); | |||
assertThat(underTest.getScmInfo(component)).isEmpty(); | |||
verifyZeroInteractions(batchReportReader, dbLoader); | |||
} |
@@ -19,9 +19,9 @@ | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.scm; | |||
import com.google.common.base.Optional; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.IntStream; | |||
import org.junit.rules.ExternalResource; | |||
@@ -42,7 +42,7 @@ public class ScmInfoRepositoryRule extends ExternalResource implements ScmInfoRe | |||
public Optional<ScmInfo> getScmInfo(Component component) { | |||
checkNotNull(component, "Component cannot be bull"); | |||
ScmInfo scmInfo = scmInfoByFileRef.get(component.getReportAttributes().getRef()); | |||
return Optional.fromNullable(scmInfo); | |||
return Optional.ofNullable(scmInfo); | |||
} | |||
public ScmInfoRepositoryRule setScmInfo(int fileRef, Changeset... changesetList) { |
@@ -22,6 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.source; | |||
import com.google.common.collect.Lists; | |||
import org.junit.Test; | |||
import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.LineReader; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static org.assertj.core.api.Assertions.assertThat; |
@@ -23,7 +23,8 @@ import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.RangeOffsetConverterException; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.RangeOffsetConverterException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -43,7 +43,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 3"); | |||
report.add("line - 4"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 3, 4, 5); | |||
} | |||
@@ -74,7 +74,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add(" }\n"); | |||
report.add("}\n"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 5, 6, 7); | |||
} | |||
@@ -92,7 +92,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 2"); | |||
report.add("line - 3"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(0, 0, 3, 4); | |||
} | |||
@@ -111,7 +111,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 2 - modified"); | |||
report.add("line - 3 - modified"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 0, 0); | |||
} | |||
@@ -134,7 +134,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 4"); | |||
report.add("line - 5"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 0, 0, 5, 6); | |||
} | |||
@@ -153,7 +153,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 1"); | |||
report.add("line - 2"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(0, 0, 1, 2, 3); | |||
} | |||
@@ -174,7 +174,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 2"); | |||
report.add("line - 3"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 0, 0, 3, 4); | |||
} | |||
@@ -193,7 +193,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - new"); | |||
report.add("line - new"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 3, 0, 0); | |||
} | |||
@@ -212,7 +212,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 1"); | |||
report.add("line - 2"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 3); | |||
} | |||
@@ -233,7 +233,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 4"); | |||
report.add("line - 5"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(1, 2, 5, 6); | |||
} | |||
@@ -250,7 +250,7 @@ public class SourceLinesDiffFinderTest { | |||
report.add("line - 2"); | |||
report.add("line - 3"); | |||
int[] diff = new SourceLinesDiffFinder(database, report).findMatchingLines(); | |||
int[] diff = new SourceLinesDiffFinder().findMatchingLines(database, report); | |||
assertThat(diff).containsExactly(3, 4); | |||
} |
@@ -82,7 +82,7 @@ public class SourceLinesDiffImplTest { | |||
setFileContentInReport(FILE_REF, CONTENT); | |||
Component component = fileComponent(FILE_REF); | |||
assertThat(underTest.getMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7); | |||
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7); | |||
} | |||
@@ -92,7 +92,7 @@ public class SourceLinesRepositoryImplTest { | |||
@Test | |||
public void fail_with_NPE_to_read_lines_on_null_component() { | |||
thrown.expect(NullPointerException.class); | |||
thrown.expectMessage("Component should not be bull"); | |||
thrown.expectMessage("Component should not be null"); | |||
underTest.readLines(null); | |||
} |
@@ -17,12 +17,13 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import java.util.Collections; | |||
import org.junit.Test; | |||
import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.CoverageLineReader; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static org.assertj.core.api.Assertions.assertThat; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.Arrays; | |||
@@ -32,6 +32,7 @@ import org.sonar.server.computation.task.projectanalysis.duplication.Duplication | |||
import org.sonar.server.computation.task.projectanalysis.duplication.InProjectDuplicate; | |||
import org.sonar.server.computation.task.projectanalysis.duplication.InnerDuplicate; | |||
import org.sonar.server.computation.task.projectanalysis.duplication.TextBlock; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.DuplicationLineReader; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
@@ -32,7 +32,9 @@ import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.scanner.protocol.output.ScannerReport.SyntaxHighlightingRule.HighlightingType; | |||
import org.sonar.scanner.protocol.output.ScannerReport.TextRange; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
import org.sonar.server.computation.task.projectanalysis.source.RangeOffsetConverter.RangeOffsetConverterException; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.HighlightingLineReader; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter.RangeOffsetConverterException; | |||
import static com.google.common.collect.ImmutableMap.of; | |||
import static org.assertj.core.api.Assertions.assertThat; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import com.google.common.collect.ImmutableMap; | |||
import java.util.Collections; | |||
@@ -27,6 +27,7 @@ import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.server.computation.task.projectanalysis.scm.Changeset; | |||
import org.sonar.server.computation.task.projectanalysis.scm.ScmInfo; | |||
import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoImpl; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.ScmLineReader; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.task.projectanalysis.source; | |||
package org.sonar.server.computation.task.projectanalysis.source.linereader; | |||
import java.util.Arrays; | |||
import org.junit.Rule; | |||
@@ -27,6 +27,8 @@ import org.sonar.db.protobuf.DbFileSources; | |||
import org.sonar.scanner.protocol.output.ScannerReport; | |||
import org.sonar.scanner.protocol.output.ScannerReport.TextRange; | |||
import org.sonar.server.computation.task.projectanalysis.component.Component; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.RangeOffsetConverter; | |||
import org.sonar.server.computation.task.projectanalysis.source.linereader.SymbolsLineReader; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.doThrow; |
@@ -104,7 +104,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
public void no_test_in_database_and_batch_report() { | |||
underTest.execute(); | |||
assertThat(dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1)).isNull(); | |||
assertThat(dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1)).isNull(); | |||
assertThat(log.logs()).isEmpty(); | |||
} | |||
@@ -121,7 +121,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
assertThat(db.countRowsOfTable("file_sources")).isEqualTo(1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1); | |||
assertThat(dto.getCreatedAt()).isEqualTo(now); | |||
assertThat(dto.getUpdatedAt()).isEqualTo(now); | |||
assertThat(dto.getProjectUuid()).isEqualTo(PROJECT_UUID); | |||
@@ -142,7 +142,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
underTest.execute(); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1); | |||
assertThat(dto.getCreatedAt()).isEqualTo(now); | |||
assertThat(dto.getUpdatedAt()).isEqualTo(now); | |||
assertThat(dto.getProjectUuid()).isEqualTo(PROJECT_UUID); | |||
@@ -168,7 +168,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
underTest.execute(); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1); | |||
assertThat(dto.getFileUuid()).isEqualTo(TEST_FILE_UUID_1); | |||
List<DbFileSources.Test> tests = dto.getTestData(); | |||
assertThat(tests).hasSize(1); | |||
@@ -203,7 +203,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
underTest.execute(); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1); | |||
List<Integer> coveredLines = dto.getTestData().get(0).getCoveredFile(0).getCoveredLineList(); | |||
assertThat(coveredLines).containsOnly(1, 2, 3, 4); | |||
} | |||
@@ -225,7 +225,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
.setCreatedAt(100_000) | |||
.setUpdatedAt(100_000)); | |||
db.getSession().commit(); | |||
assertThat(dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1)).isNotNull(); | |||
assertThat(dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1)).isNotNull(); | |||
ScannerReport.Test newBatchTest = newTest(1); | |||
reportReader.putTests(TEST_FILE_REF_1, Arrays.asList(newBatchTest)); | |||
@@ -237,7 +237,7 @@ public class PersistTestsStepTest extends BaseStepTest { | |||
underTest.execute(); | |||
// ASSERT | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTest(db.getSession(), TEST_FILE_UUID_1); | |||
FileSourceDto dto = dbClient.fileSourceDao().selectTestByFileUuid(db.getSession(), TEST_FILE_UUID_1); | |||
assertThat(dto.getCreatedAt()).isEqualTo(100_000); | |||
assertThat(dto.getUpdatedAt()).isEqualTo(now); | |||
assertThat(dto.getTestData()).hasSize(1); |
@@ -19,9 +19,9 @@ | |||
*/ | |||
package org.sonar.core.hash; | |||
import com.google.common.collect.ImmutableList; | |||
import java.security.MessageDigest; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.apache.commons.codec.binary.Hex; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
@@ -52,7 +52,7 @@ public class SourceLinesHashesComputer { | |||
} | |||
public List<String> getLineHashes() { | |||
return ImmutableList.copyOf(lineHashes); | |||
return Collections.unmodifiableList(lineHashes); | |||
} | |||
private String computeHash(String line) { |
@@ -120,6 +120,19 @@ public class ScannerReportReader { | |||
return file.exists(); | |||
} | |||
public CloseableIterator<ScannerReport.LineSgnificantCode> readComponentSignificantCode(int fileRef) { | |||
File file = fileStructure.fileFor(FileStructure.Domain.SGNIFICANT_CODE, fileRef); | |||
if (fileExists(file)) { | |||
return Protobuf.readStream(file, ScannerReport.LineSgnificantCode.parser()); | |||
} | |||
return emptyCloseableIterator(); | |||
} | |||
public boolean hasSignificantCode(int fileRef) { | |||
File file = fileStructure.fileFor(FileStructure.Domain.SGNIFICANT_CODE, fileRef); | |||
return fileExists(file); | |||
} | |||
public CloseableIterator<ScannerReport.SyntaxHighlightingRule> readComponentSyntaxHighlighting(int fileRef) { | |||
File file = fileStructure.fileFor(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, fileRef); | |||
if (fileExists(file)) { |