diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2016-11-10 17:51:08 +0100 |
---|---|---|
committer | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2016-11-10 17:51:08 +0100 |
commit | f613b749354c6268d902f58f71b32879399c7548 (patch) | |
tree | a9a6ebeac1959ce941dbcd0bf307ef7a06033981 | |
parent | cb010a0100bceb937d43fb4ff44bba281afa27f9 (diff) | |
download | sonarqube-f613b749354c6268d902f58f71b32879399c7548.tar.gz sonarqube-f613b749354c6268d902f58f71b32879399c7548.zip |
fix quality flaws
9 files changed, 115 insertions, 91 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistFileSourcesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistFileSourcesStep.java index 88b03689fb6..778c6c9292a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistFileSourcesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistFileSourcesStep.java @@ -29,8 +29,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.ObjectUtils; -import org.apache.ibatis.session.ResultContext; -import org.apache.ibatis.session.ResultHandler; import org.sonar.api.utils.System2; import org.sonar.core.util.CloseableIterator; import org.sonar.db.DbClient; @@ -112,12 +110,9 @@ public class PersistFileSourcesStep implements ComputationStep { public void visitProject(Component project) { this.projectUuid = project.getUuid(); session.select("org.sonar.db.source.FileSourceMapper.selectHashesForProject", ImmutableMap.of("projectUuid", projectUuid, "dataType", Type.SOURCE), - new ResultHandler() { - @Override - public void handleResult(ResultContext context) { - FileSourceDto dto = (FileSourceDto) context.getResultObject(); - previousFileSourcesByUuid.put(dto.getFileUuid(), dto); - } + context -> { + FileSourceDto dto = (FileSourceDto) context.getResultObject(); + previousFileSourcesByUuid.put(dto.getFileUuid(), dto); }); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistTestsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistTestsStep.java index 5db2e83ad00..757edb83eca 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistTestsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistTestsStep.java @@ -153,7 +153,7 @@ public class PersistTestsStep implements ComputationStep { } private boolean checkIfThereAreUnprocessedCoverageDetails(Multimap<String, DbFileSources.Test.Builder> testsByName, - Table<String, String, DbFileSources.Test.CoveredFile.Builder> coveredFilesByName, String componentKey) { + Table<String, String, DbFileSources.Test.CoveredFile.Builder> coveredFilesByName, String componentKey) { Set<String> unprocessedCoverageDetailNames = new HashSet<>(coveredFilesByName.rowKeySet()); unprocessedCoverageDetailNames.removeAll(testsByName.keySet()); boolean hasUnprocessedCoverage = !unprocessedCoverageDetailNames.isEmpty(); @@ -164,7 +164,7 @@ public class PersistTestsStep implements ComputationStep { } private List<DbFileSources.Test> addCoveredFilesToTests(Multimap<String, DbFileSources.Test.Builder> testsByName, - Table<String, String, DbFileSources.Test.CoveredFile.Builder> coveredFilesByName) { + Table<String, String, DbFileSources.Test.CoveredFile.Builder> coveredFilesByName) { List<DbFileSources.Test> tests = new ArrayList<>(); for (DbFileSources.Test.Builder test : testsByName.values()) { Collection<DbFileSources.Test.CoveredFile.Builder> coveredFiles = coveredFilesByName.row(test.getName()).values(); @@ -215,27 +215,32 @@ public class PersistTestsStep implements ComputationStep { try (CloseableIterator<ScannerReport.CoverageDetail> coverageIterator = reportReader.readCoverageDetails(testFileRef)) { while (coverageIterator.hasNext()) { ScannerReport.CoverageDetail batchCoverageDetail = coverageIterator.next(); + String testName = batchCoverageDetail.getTestName(); for (ScannerReport.CoverageDetail.CoveredFile batchCoveredFile : batchCoverageDetail.getCoveredFileList()) { - String testName = batchCoverageDetail.getTestName(); - String mainFileUuid = getUuid(batchCoveredFile.getFileRef()); - DbFileSources.Test.CoveredFile.Builder existingDbCoveredFile = nameToCoveredFiles.get(testName, mainFileUuid); - List<Integer> batchCoveredLines = batchCoveredFile.getCoveredLineList(); - if (existingDbCoveredFile == null) { - DbFileSources.Test.CoveredFile.Builder dbCoveredFile = DbFileSources.Test.CoveredFile.newBuilder() - .setFileUuid(getUuid(batchCoveredFile.getFileRef())) - .addAllCoveredLine(batchCoveredLines); - nameToCoveredFiles.put(testName, mainFileUuid, dbCoveredFile); - } else { - List<Integer> remainingBatchCoveredLines = new ArrayList<>(batchCoveredLines); - remainingBatchCoveredLines.removeAll(existingDbCoveredFile.getCoveredLineList()); - existingDbCoveredFile.addAllCoveredLine(batchCoveredLines); - } + loadCoverageFile(batchCoveredFile, testName, nameToCoveredFiles); } } } return nameToCoveredFiles; } + private void loadCoverageFile(ScannerReport.CoverageDetail.CoveredFile batchCoveredFile, String testName, Table<String, String, + DbFileSources.Test.CoveredFile.Builder> nameToCoveredFiles) { + String mainFileUuid = getUuid(batchCoveredFile.getFileRef()); + DbFileSources.Test.CoveredFile.Builder existingDbCoveredFile = nameToCoveredFiles.get(testName, mainFileUuid); + List<Integer> batchCoveredLines = batchCoveredFile.getCoveredLineList(); + if (existingDbCoveredFile == null) { + DbFileSources.Test.CoveredFile.Builder dbCoveredFile = DbFileSources.Test.CoveredFile.newBuilder() + .setFileUuid(getUuid(batchCoveredFile.getFileRef())) + .addAllCoveredLine(batchCoveredLines); + nameToCoveredFiles.put(testName, mainFileUuid, dbCoveredFile); + } else { + List<Integer> remainingBatchCoveredLines = new ArrayList<>(batchCoveredLines); + remainingBatchCoveredLines.removeAll(existingDbCoveredFile.getCoveredLineList()); + existingDbCoveredFile.addAllCoveredLine(batchCoveredLines); + } + } + private String getUuid(int fileRef) { return treeRootHolder.getComponentByRef(fileRef).getUuid(); } diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java b/sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java index ed78b2d9fb7..02c09597396 100644 --- a/sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java +++ b/sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java @@ -19,11 +19,11 @@ */ package org.sonar.duplications.statement; +import java.util.List; +import javax.annotation.Nullable; import org.sonar.duplications.CodeFragment; import org.sonar.duplications.token.Token; -import java.util.List; - public class Statement implements CodeFragment { private final int startLine; @@ -41,7 +41,7 @@ public class Statement implements CodeFragment { this.value = value; } - public Statement(List<Token> tokens) { + public Statement(@Nullable List<Token> tokens) { if (tokens == null || tokens.isEmpty()) { throw new IllegalArgumentException("A statement can't be initialized with an empty list of tokens"); } diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChannel.java b/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChannel.java index af89c8dc483..67646bcc323 100644 --- a/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChannel.java +++ b/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChannel.java @@ -21,7 +21,7 @@ package org.sonar.duplications.statement; import java.util.ArrayList; import java.util.List; - +import javax.annotation.Nullable; import org.sonar.duplications.statement.matcher.TokenMatcher; import org.sonar.duplications.token.Token; import org.sonar.duplications.token.TokenQueue; @@ -31,6 +31,14 @@ public final class StatementChannel { private final TokenMatcher[] tokenMatchers; private final boolean blackHole; + private StatementChannel(boolean blackHole, @Nullable TokenMatcher... tokenMatchers) { + if (tokenMatchers == null || tokenMatchers.length == 0) { + throw new IllegalArgumentException(); + } + this.blackHole = blackHole; + this.tokenMatchers = tokenMatchers; + } + public static StatementChannel create(TokenMatcher... tokenMatchers) { return new StatementChannel(false, tokenMatchers); } @@ -39,14 +47,6 @@ public final class StatementChannel { return new StatementChannel(true, tokenMatchers); } - private StatementChannel(boolean blackHole, TokenMatcher... tokenMatchers) { - if (tokenMatchers == null || tokenMatchers.length == 0) { - throw new IllegalArgumentException(); - } - this.blackHole = blackHole; - this.tokenMatchers = tokenMatchers; - } - public boolean consume(TokenQueue tokenQueue, List<Statement> output) { List<Token> matchedTokenList = new ArrayList<>(); for (TokenMatcher tokenMatcher : tokenMatchers) { diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChunker.java b/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChunker.java index f0ac6f28777..00757ec3c9b 100644 --- a/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChunker.java +++ b/sonar-duplications/src/main/java/org/sonar/duplications/statement/StatementChunker.java @@ -21,7 +21,7 @@ package org.sonar.duplications.statement; import java.util.ArrayList; import java.util.List; - +import javax.annotation.Nullable; import org.sonar.duplications.DuplicationsException; import org.sonar.duplications.statement.matcher.TokenMatcher; import org.sonar.duplications.token.TokenQueue; @@ -30,15 +30,15 @@ public final class StatementChunker { private final StatementChannelDisptacher channelDispatcher; - public static Builder builder() { - return new Builder(); - } - private StatementChunker(Builder builder) { this.channelDispatcher = builder.getChannelDispatcher(); } - public List<Statement> chunk(TokenQueue tokenQueue) { + public static Builder builder() { + return new Builder(); + } + + public List<Statement> chunk(@Nullable TokenQueue tokenQueue) { if (tokenQueue == null) { throw new IllegalArgumentException(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java index 6f734e84c59..01ab0eedb08 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; import java.util.List; +import java.util.function.Function; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.annotation.Nullable; @@ -165,12 +166,12 @@ public final class PropertyDefinition { return Result.SUCCESS; } - EnumMap<PropertyType, Validation> validations = createValidations(options); - return validations.getOrDefault(type, aValue -> Result.SUCCESS).validate(value); + EnumMap<PropertyType, Function<String, Result>> validations = createValidations(options); + return validations.getOrDefault(type, aValue -> Result.SUCCESS).apply(value); } - private static EnumMap<PropertyType, Validation> createValidations(List<String> options) { - return new EnumMap<>(ImmutableMap.<PropertyType, Validation>builder() + private static EnumMap<PropertyType, Function<String, Result>> createValidations(List<String> options) { + return new EnumMap<>(ImmutableMap.<PropertyType, Function<String, Result>>builder() .put(BOOLEAN, validateBoolean()) .put(INTEGER, validateInteger()) .put(LONG, validateInteger()) @@ -181,7 +182,7 @@ public final class PropertyDefinition { .build()); } - private static Validation validateBoolean() { + private static Function<String, Result> validateBoolean() { return value -> { if (!StringUtils.equalsIgnoreCase(value, "true") && !StringUtils.equalsIgnoreCase(value, "false")) { return Result.newError("notBoolean"); @@ -190,7 +191,7 @@ public final class PropertyDefinition { }; } - private static Validation validateInteger() { + private static Function<String, Result> validateInteger() { return value -> { if (!NumberUtils.isDigits(value)) { return Result.newError("notInteger"); @@ -199,7 +200,7 @@ public final class PropertyDefinition { }; } - private static Validation validateFloat() { + private static Function<String, Result> validateFloat() { return value -> { try { Double.parseDouble(value); @@ -210,7 +211,7 @@ public final class PropertyDefinition { }; } - private static Validation validateRegexp() { + private static Function<String, Result> validateRegexp() { return value -> { try { Pattern.compile(value); @@ -575,9 +576,4 @@ public final class PropertyDefinition { } } } - - @FunctionalInterface - private interface Validation { - Result validate(String value); - } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java index 2fdfbff01f2..30430453b4b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java @@ -19,13 +19,11 @@ */ package org.sonar.api.measures; -import com.google.common.base.Function; -import com.google.common.collect.Lists; import java.io.Serializable; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; @@ -40,7 +38,7 @@ import static org.apache.commons.lang.StringUtils.isNotBlank; /** * Used to define a metric in a plugin. Should be used with {@link Metrics} extension point. - * Should no more be used on scanner side. Use {@link org.sonar.api.batch.measure.Metric} instead. + * Should no more be used on scanner side. Use {@link org.sonar.api.batch.measure.Metric} instead. */ @ScannerSide @InstantiationStrategy(InstantiationStrategy.PER_BATCH) @@ -55,6 +53,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a /** * The maximum supported value of scale for decimal metrics + * * @since 5.3 */ public static final int MAX_DECIMAL_SCALE = 5; @@ -109,13 +108,9 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a public enum Level { OK("Green"), WARN("Orange"), ERROR("Red"); - private static final List<String> NAMES = Lists.transform(Arrays.asList(values()), new Function<Level, String>() { - @Nonnull - @Override - public String apply(@Nonnull Level level) { - return level.name(); - } - }); + private static final List<String> NAMES = Arrays.stream(values()) + .map(Level::name) + .collect(Collectors.toList()); private String colorName; @@ -521,6 +516,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a /** * Return the number scale if metric type is {@link ValueType#FLOAT}, else {@code null} + * * @since 5.3 */ @CheckForNull @@ -631,12 +627,11 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a * </ul> * Metric.DIRECTION_NONE is the default value. * + * @param d the direction + * @return the builder * @see Metric#DIRECTION_WORST * @see Metric#DIRECTION_BETTER * @see Metric#DIRECTION_NONE - * - * @param d the direction - * @return the builder */ public Builder setDirection(Integer d) { this.direction = d; @@ -680,7 +675,6 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a * * @param f the formula * @return the builder - * * @deprecated since 5.2, it's no more possible to define a formula on a metric, please use {@link org.sonar.api.ce.measure.MeasureComputer} instead */ @Deprecated @@ -741,10 +735,9 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a /** * Specifies whether this metric can be edited online in the "Manual measures" page. Default is false. * - * @since 2.10 - * * @param b true if the metric can be edited online. * @return the builder + * @since 2.10 */ public Builder setUserManaged(boolean b) { this.userManaged = b; @@ -756,10 +749,9 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a * <br> * By default, historical data are kept. * - * @since 2.14 - * * @param b true if measures from the past can be deleted automatically. * @return the builder + * @since 2.14 */ public Builder setDeleteHistoricalData(boolean b) { this.deleteHistoricalData = b; @@ -769,6 +761,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a /** * Scale to be used if the metric has decimal type ({@link ValueType#FLOAT} or {@link ValueType#PERCENT}). * Default is 1. It is not set (({@code null}) on non-decimal metrics. + * * @since 5.3 */ public Builder setDecimalScale(int scale) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/ZipUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/ZipUtils.java index e1dd34718c5..0cd98837689 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/ZipUtils.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/ZipUtils.java @@ -54,11 +54,11 @@ public final class ZipUtils { * @return the target directory */ public static File unzip(File zip, File toDir) throws IOException { - return unzip(zip, toDir, (Predicate<ZipEntry>)ze -> true); + return unzip(zip, toDir, (Predicate<ZipEntry>) ze -> true); } public static File unzip(InputStream zip, File toDir) throws IOException { - return unzip(zip, toDir, (Predicate<ZipEntry>)ze -> true); + return unzip(zip, toDir, (Predicate<ZipEntry>) ze -> true); } /** @@ -71,8 +71,9 @@ public final class ZipUtils { /** * Unzip a file to a directory. + * * @param stream the zip input file - * @param toDir the target directory. It is created if needed. + * @param toDir the target directory. It is created if needed. * @param filter filter zip entries so that only a subset of directories/files can be * extracted to target directory. * @return the parameter {@code toDir} @@ -88,14 +89,7 @@ public final class ZipUtils { ZipEntry entry; while ((entry = zipStream.getNextEntry()) != null) { if (filter.test(entry)) { - File to = new File(toDir, entry.getName()); - if (entry.isDirectory()) { - throwExceptionIfDirectoryIsNotCreatable(to); - } else { - File parent = to.getParentFile(); - throwExceptionIfDirectoryIsNotCreatable(parent); - copy(zipStream, to); - } + unzipEntry(entry, zipStream, toDir); } } return toDir; @@ -105,6 +99,17 @@ public final class ZipUtils { } } + private static void unzipEntry(ZipEntry entry, ZipInputStream zipStream, File toDir) throws IOException { + File to = new File(toDir, entry.getName()); + if (entry.isDirectory()) { + throwExceptionIfDirectoryIsNotCreatable(to); + } else { + File parent = to.getParentFile(); + throwExceptionIfDirectoryIsNotCreatable(parent); + copy(zipStream, to); + } + } + private static void throwExceptionIfDirectoryIsNotCreatable(File to) throws IOException { if (!to.exists() && !to.mkdirs()) { throw new IOException(ERROR_CREATING_DIRECTORY + to); @@ -121,8 +126,9 @@ public final class ZipUtils { /** * Unzip a file to a directory. - * @param zip the zip file. It must exist. - * @param toDir the target directory. It is created if needed. + * + * @param zip the zip file. It must exist. + * @param toDir the target directory. It is created if needed. * @param filter filter zip entries so that only a subset of directories/files can be * extracted to target directory. * @return the parameter {@code toDir} @@ -233,8 +239,8 @@ public final class ZipUtils { } /** - * @deprecated replaced by {@link Predicate<ZipEntry>} in 6.2. * @see #unzip(File, File, Predicate) + * @deprecated replaced by {@link Predicate<ZipEntry>} in 6.2. */ @Deprecated @FunctionalInterface diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/internal/SimpleGetRequestTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/internal/SimpleGetRequestTest.java index 08f69177262..650b9ace11e 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/internal/SimpleGetRequestTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/internal/SimpleGetRequestTest.java @@ -19,13 +19,14 @@ */ package org.sonar.api.server.ws.internal; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - import java.io.InputStream; import org.junit.Test; import org.sonar.api.server.ws.Request; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.mock; + public class SimpleGetRequestTest { SimpleGetRequest underTest = new SimpleGetRequest(); @@ -59,4 +60,32 @@ public class SimpleGetRequestTest { assertThat(underTest.paramAsPart("unknown")).isNull(); } + + @Test + public void getMediaType() { + underTest.setMediaType("JSON"); + + assertThat(underTest.getMediaType()).isEqualTo("JSON"); + } + + @Test + public void multiParam_with_one_element() { + underTest.setParam("foo", "bar"); + + assertThat(underTest.multiParam("foo")).containsExactly("bar"); + } + + @Test + public void multiParam_without_any_element() { + assertThat(underTest.multiParam("42")).isEmpty(); + } + + @Test + public void getParams() { + underTest + .setParam("foo", "bar") + .setParam("fee", "beer"); + + assertThat(underTest.getParams()).containsOnly(entry("foo", "bar"), entry("fee", "beer")); + } } |