diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2016-03-16 17:15:30 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2016-03-16 17:25:16 +0100 |
commit | 1b09113d16a93c516b03c896202c71205d46134a (patch) | |
tree | 7695ebbcbc01a5ed1ff9e4cd32bfe0523837242e | |
parent | 887cda2d00ba7b62ee311bc78a4ea611696e9761 (diff) | |
download | sonarqube-1b09113d16a93c516b03c896202c71205d46134a.tar.gz sonarqube-1b09113d16a93c516b03c896202c71205d46134a.zip |
Fix some quality flaws
19 files changed, 202 insertions, 78 deletions
diff --git a/plugins/sonar-xoo-plugin/pom.xml b/plugins/sonar-xoo-plugin/pom.xml index 9b163554fad..6b48224d77d 100644 --- a/plugins/sonar-xoo-plugin/pom.xml +++ b/plugins/sonar-xoo-plugin/pom.xml @@ -20,22 +20,18 @@ <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> - <version>18.0</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.4</version> </dependency> <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.3.2</version> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> </dependency> <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> - <version>3.0.0</version> <scope>provided</scope> </dependency> <dependency> diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/coverage/AbstractCoverageSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/coverage/AbstractCoverageSensor.java index f3b663c2b04..2683e054b53 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/coverage/AbstractCoverageSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/coverage/AbstractCoverageSensor.java @@ -20,8 +20,12 @@ package org.sonar.xoo.coverage; import com.google.common.base.Splitter; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; @@ -32,11 +36,6 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.xoo.Xoo; -import java.io.File; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - public abstract class AbstractCoverageSensor implements Sensor { private static final Logger LOG = Loggers.get(AbstractCoverageSensor.class); diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java index c740b876960..9562f300fb1 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java @@ -24,7 +24,7 @@ import java.io.IOException; import java.io.Serializable; import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.Sensor; diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java index 760d865d6cf..7eb71225771 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java index e75ec0ecfe0..e0d28328382 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java index e4c04397d68..4f5d0e6b169 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java @@ -20,18 +20,17 @@ package org.sonar.xoo.scm; import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.scm.BlameCommand; -import org.sonar.api.batch.scm.BlameLine; -import org.sonar.api.utils.DateUtils; - import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.scm.BlameCommand; +import org.sonar.api.batch.scm.BlameLine; +import org.sonar.api.utils.DateUtils; public class XooBlameCommand extends BlameCommand { diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java index ef533827b28..f7853cb0717 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/CoveragePerTestSensor.java @@ -20,8 +20,13 @@ package org.sonar.xoo.test; import com.google.common.base.Splitter; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; @@ -38,12 +43,6 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.xoo.Xoo; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - /** * Parse files *.xoo.testcoverage */ diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java index 7e3db1977b0..be19c052fbb 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/test/TestExecutionSensor.java @@ -20,8 +20,12 @@ package org.sonar.xoo.test; import com.google.common.base.Splitter; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; @@ -38,11 +42,6 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.xoo.Xoo; -import java.io.File; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - /** * Parse files *.xoo.test */ diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java index 91f0fd59be4..5bf3879210d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java @@ -93,8 +93,7 @@ public class ProjectDataLoader { } private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, ComponentDto module) { - return module.isRootProject() ? - dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid()) + return module.isRootProject() ? dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid()) : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid()); } @@ -129,7 +128,7 @@ public class ProjectDataLoader { } } - private void addSettingsToChildrenModules(ProjectRepositories ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings, + private static void addSettingsToChildrenModules(ProjectRepositories ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings, boolean hasScanPerm) { Map<String, String> currentParentProperties = newHashMap(); currentParentProperties.putAll(parentProperties); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index e2f074bc085..cfebad6cbb5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -202,7 +202,7 @@ public class BatchExtensionDictionnary { return results; } - private void evaluateClass(Class extensionClass, Class annotationClass, List<Object> results) { + private static void evaluateClass(Class extensionClass, Class annotationClass, List<Object> results) { Annotation annotation = extensionClass.getAnnotation(annotationClass); if (annotation != null) { if (annotation.annotationType().isAssignableFrom(DependsUpon.class)) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/profiling/PhaseProfiling.java b/sonar-batch/src/main/java/org/sonar/batch/profiling/PhaseProfiling.java index 330750e5411..5b13f1d4ee1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/profiling/PhaseProfiling.java +++ b/sonar-batch/src/main/java/org/sonar/batch/profiling/PhaseProfiling.java @@ -87,7 +87,7 @@ public class PhaseProfiling extends AbstractTimeProfiling { * @param o * @return */ - private String toStringOrSimpleName(Object o) { + private static String toStringOrSimpleName(Object o) { String toString = o.toString(); if (toString == null || toString.startsWith(o.getClass().getName())) { return o.getClass().getSimpleName(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java index eb8e31f18bc..7e37b789c71 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.scan.report; -import org.sonar.batch.issue.tracking.TrackedIssue; - import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang.StringUtils; import org.sonar.api.Properties; @@ -31,11 +29,12 @@ import org.sonar.api.rule.Severity; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.batch.issue.IssueCache; +import org.sonar.batch.issue.tracking.TrackedIssue; import org.sonar.batch.scan.filesystem.InputPathCache; @Properties({ - @Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, name = "Enable console report", description = "Set this to true to generate a report in console output", - type = PropertyType.BOOLEAN, defaultValue = "false")}) + @Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, defaultValue = "false", name = "Enable console report", + description = "Set this to true to generate a report in console output", type = PropertyType.BOOLEAN)}) public class ConsoleReport implements Reporter { @VisibleForTesting @@ -122,7 +121,7 @@ public class ConsoleReport implements Reporter { LOG.info(sb.toString()); } - private void printNewIssues(Report r, StringBuilder sb) { + private static void printNewIssues(Report r, StringBuilder sb) { int newIssues = r.totalNewIssues; if (newIssues > 0) { sb.append(StringUtils.leftPad("+" + newIssues, LEFT_PAD)).append(" issue" + (newIssues > 1 ? "s" : "")).append("\n\n"); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/HtmlReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/HtmlReport.java index 369ba2b5e91..8111abd467e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/HtmlReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/HtmlReport.java @@ -21,16 +21,6 @@ package org.sonar.batch.scan.report; import com.google.common.collect.Maps; import freemarker.template.Template; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.Properties; -import org.sonar.api.Property; -import org.sonar.api.PropertyType; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.config.Settings; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -40,19 +30,26 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URISyntaxException; import java.util.Map; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.Properties; +import org.sonar.api.Property; +import org.sonar.api.PropertyType; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.config.Settings; @Properties({ - @Property(key = HtmlReport.HTML_REPORT_ENABLED_KEY, name = "Enable HTML report", description = "Set this to true to generate an HTML report", - type = PropertyType.BOOLEAN, defaultValue = "false"), - @Property(key = HtmlReport.HTML_REPORT_LOCATION_KEY, name = "HTML Report location", - description = "Location of the generated report. Can be absolute or relative to working directory", - type = PropertyType.STRING, defaultValue = HtmlReport.HTML_REPORT_LOCATION_DEFAULT, global = false, project = false), - @Property(key = HtmlReport.HTML_REPORT_NAME_KEY, name = "HTML Report name", - description = "Name of the generated report. Will be suffixed by .html or -light.html", - type = PropertyType.STRING, defaultValue = HtmlReport.HTML_REPORT_NAME_DEFAULT, global = false, project = false), - @Property(key = HtmlReport.HTML_REPORT_LIGHTMODE_ONLY, name = "Html report in light mode only", project = true, - description = "Set this to true to only generate the new issues report (light report)", - type = PropertyType.BOOLEAN, defaultValue = "false")}) + @Property(key = HtmlReport.HTML_REPORT_ENABLED_KEY, defaultValue = "false", name = "Enable HTML report", description = "Set this to true to generate an HTML report", + type = PropertyType.BOOLEAN), + @Property(key = HtmlReport.HTML_REPORT_LOCATION_KEY, defaultValue = HtmlReport.HTML_REPORT_LOCATION_DEFAULT, name = "HTML Report location", + description = "Location of the generated report. Can be absolute or relative to working directory", project = false, global = false, type = PropertyType.STRING), + @Property(key = HtmlReport.HTML_REPORT_NAME_KEY, defaultValue = HtmlReport.HTML_REPORT_NAME_DEFAULT, name = "HTML Report name", + description = "Name of the generated report. Will be suffixed by .html or -light.html", project = false, global = false, type = PropertyType.STRING), + @Property(key = HtmlReport.HTML_REPORT_LIGHTMODE_ONLY, defaultValue = "false", name = "Html report in light mode only", + description = "Set this to true to only generate the new issues report (light report)", project = true, type = PropertyType.BOOLEAN)}) public class HtmlReport implements Reporter { private static final Logger LOG = LoggerFactory.getLogger(HtmlReport.class); @@ -111,7 +108,7 @@ public class HtmlReport implements Reporter { if (!reportFileDir.isAbsolute()) { reportFileDir = new File(fs.workDir(), reportFileDirStr); } - if (reportFileDirStr.endsWith(".html")) { + if (StringUtils.endsWith(reportFileDirStr, ".html")) { LOG.warn(HTML_REPORT_LOCATION_KEY + " should indicate a directory. Using parent folder."); reportFileDir = reportFileDir.getParentFile(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java index 20be830f8aa..f6a88bf4465 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java @@ -22,6 +22,7 @@ package org.sonar.batch.scm; import com.google.common.base.Joiner; import java.util.LinkedHashMap; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.picocontainer.Startable; import org.sonar.api.CoreProperties; import org.sonar.api.Properties; @@ -40,13 +41,13 @@ import org.sonar.batch.scan.ImmutableProjectReactor; @Property( key = ScmConfiguration.FORCE_RELOAD_KEY, defaultValue = "false", - type = PropertyType.BOOLEAN, name = "Force reloading of SCM information for all files", description = "By default only files modified since previous analysis are inspected. Set this parameter to true to force the reloading.", - module = false, + category = CoreProperties.CATEGORY_SCM, project = false, + module = false, global = false, - category = CoreProperties.CATEGORY_SCM) + type = PropertyType.BOOLEAN) }) @InstantiationStrategy(InstantiationStrategy.PER_BATCH) @BatchSide @@ -103,7 +104,7 @@ public final class ScmConfiguration implements Startable { if (providerPerKey.containsKey(forcedProviderKey)) { this.provider = providerPerKey.get(forcedProviderKey); } else { - String supportedProviders = providerPerKey.isEmpty() ? "No SCM provider installed" : "Supported SCM providers are " + Joiner.on(",").join(providerPerKey.keySet()); + String supportedProviders = providerPerKey.isEmpty() ? "No SCM provider installed" : ("Supported SCM providers are " + Joiner.on(",").join(providerPerKey.keySet())); throw new IllegalArgumentException("SCM provider was set to \"" + forcedProviderKey + "\" but no SCM provider found for this key. " + supportedProviders); } } @@ -111,7 +112,7 @@ public final class ScmConfiguration implements Startable { private void considerOldScmUrl() { if (settings.hasKey(CoreProperties.LINKS_SOURCES_DEV)) { String url = settings.getString(CoreProperties.LINKS_SOURCES_DEV); - if (url.startsWith("scm:")) { + if (StringUtils.startsWith(url, "scm:")) { String[] split = url.split(":"); if (split.length > 1) { setProviderIfSupported(split[1]); diff --git a/sonar-batch/src/main/java/org/sonar/batch/util/ProgressReport.java b/sonar-batch/src/main/java/org/sonar/batch/util/ProgressReport.java index f6fb4cf1752..f2ea0406a01 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/util/ProgressReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/util/ProgressReport.java @@ -69,7 +69,7 @@ public class ProgressReport implements Runnable { } } - private void log(String message) { + private static void log(String message) { synchronized (LOG) { LOG.info(message); LOG.notifyAll(); diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java index 6e7d1161bb4..5162e6a8d40 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java @@ -244,7 +244,7 @@ public class ComponentContainer implements ContainerPopulator.Container { return this; } - private String getName(Object extension) { + private static String getName(Object extension) { if (extension instanceof Class) { return ((Class<?>) extension).getName(); } diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java index d4135d069e6..e2a2d5640f8 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FileSourceDto.java @@ -139,7 +139,7 @@ class FileSourceDto { return result; } - private void addBlock(int blockId, Block block, Map<Integer, StringBuilder> dupPerLine) { + private static void addBlock(int blockId, Block block, Map<Integer, StringBuilder> dupPerLine) { int currentLine = block.start; for (int i = 0; i < block.length; i++) { if (dupPerLine.get(currentLine) == null) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java index 47a62b82399..a177a554fa1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java @@ -56,11 +56,12 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { } @Override - public NewCpdTokens addToken(TextRange range, String image) { + public DefaultCpdTokens addToken(TextRange range, String image) { Preconditions.checkNotNull(range, "Range should not be null"); + Preconditions.checkNotNull(image, "Image should not be null"); Preconditions.checkState(inputFile != null, "Call onFile() first"); - Preconditions.checkState(lastRange == null || lastRange.end().compareTo(range.start()) >= 0, - "Tokens of file %s should be provided in order. \nPrevious token: %s\nLast token: %s", inputFile, lastRange, range); + Preconditions.checkState(lastRange == null || lastRange.end().compareTo(range.start()) <= 0, + "Tokens of file %s should be provided in order.\nPrevious token: %s\nLast token: %s", inputFile, lastRange, range); String value = image; @@ -72,6 +73,7 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { } currentIndex++; sb.append(value); + lastRange = range; return this; } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java new file mode 100644 index 00000000000..5f09cf064d9 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java @@ -0,0 +1,134 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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. + */ +package org.sonar.api.batch.sensor.cpd.internal; + +import org.junit.Test; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.internal.SensorStorage; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultCpdTokensTest { + + private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java") + .setLines(2) + .setOriginalLineOffsets(new int[] {0, 50}) + .setLastValidOffset(100); + + @Test + public void save_no_tokens() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(INPUT_FILE); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.inputFile()).isEqualTo(INPUT_FILE); + } + + @Test + public void save_one_token() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(INPUT_FILE) + .addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo"); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.getTokenLines()).extracting("value", "startLine", "hashCode", "startUnit", "endUnit").containsExactly(tuple("foo", 1, "foo".hashCode(), 1, 1)); + } + + @Test + public void save_many_tokens() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(INPUT_FILE) + .addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo") + .addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar") + .addToken(INPUT_FILE.newRange(1, 20, 1, 25), "biz") + .addToken(INPUT_FILE.newRange(2, 1, 2, 10), "next"); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.getTokenLines()) + .extracting("value", "startLine", "hashCode", "startUnit", "endUnit") + .containsExactly( + tuple("foobarbiz", 1, "foobarbiz".hashCode(), 1, 3), + tuple("next", 2, "next".hashCode(), 4, 4)); + } + + @Test + public void basic_validation() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage); + try { + tokens.save(); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Call onFile() first"); + } + try { + tokens.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Call onFile() first"); + } + try { + tokens.addToken(null, "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Range should not be null"); + } + try { + tokens.addToken(INPUT_FILE.newRange(1, 2, 1, 5), null); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Image should not be null"); + } + } + + @Test + public void validate_tokens_order() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(INPUT_FILE) + .addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar"); + + try { + tokens.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Tokens of file [moduleKey=foo, relative=src/Foo.java, basedir=null] should be provided in order.\n" + + "Previous token: Range[from [line=1, lineOffset=6] to [line=1, lineOffset=10]]\n" + + "Last token: Range[from [line=1, lineOffset=2] to [line=1, lineOffset=5]]"); + } + } + +} |