aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2018-01-16 11:33:04 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2018-01-25 17:23:10 +0100
commitcaf4144f98ff834c8fd19ab5d0c5379fa05e32f7 (patch)
treedf50917d48c064b03cd275bd1f23f83d8964446e
parent972e426b9739983fa56b24b428ab400082951452 (diff)
downloadsonarqube-caf4144f98ff834c8fd19ab5d0c5379fa05e32f7.tar.gz
sonarqube-caf4144f98ff834c8fd19ab5d0c5379fa05e32f7.zip
SONAR-10288 move multivalue property parsing to sonar-core
-rw-r--r--sonar-core/pom.xml4
-rw-r--r--sonar-core/src/main/java/org/sonar/core/config/MultivalueProperty.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/scanner/config/MultivaluePropertyCleaner.java)85
-rw-r--r--sonar-core/src/test/java/org/sonar/core/config/MultivaluePropertyTest.java (renamed from sonar-scanner-engine/src/test/java/org/sonar/scanner/config/MultivaluePropertyCleanerTest.java)6
-rw-r--r--sonar-scanner-engine/pom.xml4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java69
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleFileSystemInitializer.java2
7 files changed, 93 insertions, 82 deletions
diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml
index be0e9836a67..a0e5e0af6ac 100644
--- a/sonar-core/pom.xml
+++ b/sonar-core/pom.xml
@@ -28,6 +28,10 @@
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-csv</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.picocontainer</groupId>
<artifactId>picocontainer</artifactId>
</dependency>
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/MultivaluePropertyCleaner.java b/sonar-core/src/main/java/org/sonar/core/config/MultivalueProperty.java
index a5ae8d807e6..17451ee0cb6 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/MultivaluePropertyCleaner.java
+++ b/sonar-core/src/main/java/org/sonar/core/config/MultivalueProperty.java
@@ -17,13 +17,89 @@
* 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.scanner.config;
+package org.sonar.core.config;
-class MultivaluePropertyCleaner {
- private MultivaluePropertyCleaner() {
+import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.apache.commons.lang.ArrayUtils;
+
+public class MultivalueProperty {
+ private MultivalueProperty() {
// prevents instantiation
}
+ public static String[] parseAsCsv(String key, String value) {
+ return parseAsCsv(key, value, Function.identity());
+ }
+
+ public static String[] parseAsCsv(String key, String value, Function<String, String> valueProcessor) {
+ String cleanValue = MultivalueProperty.trimFieldsAndRemoveEmptyFields(value);
+ List<String> result = new ArrayList<>();
+ try (CSVParser csvParser = CSVFormat.RFC4180
+ .withHeader((String) null)
+ .withIgnoreEmptyLines()
+ .withIgnoreSurroundingSpaces()
+ .parse(new StringReader(cleanValue))) {
+ List<CSVRecord> records = csvParser.getRecords();
+ if (records.isEmpty()) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ processRecords(result, records, valueProcessor);
+ return result.toArray(new String[result.size()]);
+ } catch (IOException e) {
+ throw new IllegalStateException("Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'", e);
+ }
+ }
+
+ /**
+ * In most cases we expect a single record. <br>Having multiple records means the input value was splitted over multiple lines (this is common in Maven).
+ * For example:
+ * <pre>
+ * &lt;sonar.exclusions&gt;
+ * src/foo,
+ * src/bar,
+ * src/biz
+ * &lt;sonar.exclusions&gt;
+ * </pre>
+ * In this case records will be merged to form a single list of items. Last item of a record is appended to first item of next record.
+ * <p>
+ * This is a very curious case, but we try to preserve line break in the middle of an item:
+ * <pre>
+ * &lt;sonar.exclusions&gt;
+ * a
+ * b,
+ * c
+ * &lt;sonar.exclusions&gt;
+ * </pre>
+ * will produce ['a\nb', 'c']
+ */
+ private static void processRecords(List<String> result, List<CSVRecord> records, Function<String, String> valueProcessor) {
+ for (CSVRecord csvRecord : records) {
+ Iterator<String> it = csvRecord.iterator();
+ if (!result.isEmpty()) {
+ String next = it.next();
+ if (!next.isEmpty()) {
+ int lastItemIdx = result.size() - 1;
+ String previous = result.get(lastItemIdx);
+ if (previous.isEmpty()) {
+ result.set(lastItemIdx, valueProcessor.apply(next));
+ } else {
+ result.set(lastItemIdx, valueProcessor.apply(previous + "\n" + next));
+ }
+ }
+ }
+ it.forEachRemaining(s -> result.add(valueProcessor.apply(s)));
+ }
+ }
+
/**
* Removes the empty fields from the value of a multi-value property from empty fields, including trimming each field.
* <p>
@@ -48,7 +124,8 @@ class MultivaluePropertyCleaner {
* <li>{@code "a,\" \",b" => "ab"]}</li>
* </ul>
*/
- public static String trimFieldsAndRemoveEmptyFields(String str) {
+ @VisibleForTesting
+ static String trimFieldsAndRemoveEmptyFields(String str) {
char[] chars = str.toCharArray();
char[] res = new char[chars.length];
/*
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/config/MultivaluePropertyCleanerTest.java b/sonar-core/src/test/java/org/sonar/core/config/MultivaluePropertyTest.java
index 70be5c59b90..d9daba88c54 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/config/MultivaluePropertyCleanerTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/config/MultivaluePropertyTest.java
@@ -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.scanner.config;
+package org.sonar.core.config;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
@@ -30,10 +30,10 @@ import org.junit.runner.RunWith;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.scanner.config.MultivaluePropertyCleaner.trimFieldsAndRemoveEmptyFields;
+import static org.sonar.core.config.MultivalueProperty.trimFieldsAndRemoveEmptyFields;
@RunWith(DataProviderRunner.class)
-public class MultivaluePropertyCleanerTest {
+public class MultivaluePropertyTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
diff --git a/sonar-scanner-engine/pom.xml b/sonar-scanner-engine/pom.xml
index 5b2147d285f..622c760e457 100644
--- a/sonar-scanner-engine/pom.xml
+++ b/sonar-scanner-engine/pom.xml
@@ -76,10 +76,6 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-csv</artifactId>
- </dependency>
<!-- For HTML Report -->
<dependency>
<groupId>org.freemarker</groupId>
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java
index 0b32c98a1d5..dfdfa2f9f1d 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java
@@ -19,19 +19,11 @@
*/
package org.sonar.scanner.config;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.concurrent.Immutable;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
import org.apache.commons.lang.ArrayUtils;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.Encryption;
@@ -44,6 +36,7 @@ import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.trim;
+import static org.sonar.core.config.MultivalueProperty.parseAsCsv;
@Immutable
public abstract class DefaultConfiguration implements Configuration {
@@ -119,66 +112,6 @@ public abstract class DefaultConfiguration implements Configuration {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
- public static String[] parseAsCsv(String key, String value) {
- String cleanValue = MultivaluePropertyCleaner.trimFieldsAndRemoveEmptyFields(value);
- List<String> result = new ArrayList<>();
- try (CSVParser csvParser = CSVFormat.RFC4180
- .withHeader((String) null)
- .withIgnoreEmptyLines()
- .withIgnoreSurroundingSpaces()
- .parse(new StringReader(cleanValue))) {
- List<CSVRecord> records = csvParser.getRecords();
- if (records.isEmpty()) {
- return ArrayUtils.EMPTY_STRING_ARRAY;
- }
- processRecords(result, records);
- return result.toArray(new String[result.size()]);
- } catch (IOException e) {
- throw new IllegalStateException("Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'", e);
- }
- }
-
- /**
- * In most cases we expect a single record. <br>Having multiple records means the input value was splitted over multiple lines (this is common in Maven).
- * For example:
- * <pre>
- * &lt;sonar.exclusions&gt;
- * src/foo,
- * src/bar,
- * src/biz
- * &lt;sonar.exclusions&gt;
- * </pre>
- * In this case records will be merged to form a single list of items. Last item of a record is appended to first item of next record.
- * <p>
- * This is a very curious case, but we try to preserve line break in the middle of an item:
- * <pre>
- * &lt;sonar.exclusions&gt;
- * a
- * b,
- * c
- * &lt;sonar.exclusions&gt;
- * </pre>
- * will produce ['a\nb', 'c']
- */
- private static void processRecords(List<String> result, List<CSVRecord> records) {
- for (CSVRecord csvRecord : records) {
- Iterator<String> it = csvRecord.iterator();
- if (!result.isEmpty()) {
- String next = it.next();
- if (!next.isEmpty()) {
- int lastItemIdx = result.size() - 1;
- String previous = result.get(lastItemIdx);
- if (previous.isEmpty()) {
- result.set(lastItemIdx, next);
- } else {
- result.set(lastItemIdx, previous + "\n" + next);
- }
- }
- }
- it.forEachRemaining(result::add);
- }
- }
-
private Optional<String> getInternal(String key) {
if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) {
throw MessageException.of("Access to the secured property '" + key
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java
index ac49740357b..9f5716c1a05 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java
@@ -45,9 +45,10 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.scanner.analysis.AnalysisProperties;
import org.sonar.scanner.bootstrap.DroppedPropertyChecker;
-import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.util.ScannerUtils;
+import static org.sonar.core.config.MultivalueProperty.parseAsCsv;
+
/**
* Class that creates a project definition based on a set of properties.
*/
@@ -408,7 +409,7 @@ public class ProjectReactorBuilder {
static String[] getListFromProperty(Map<String, String> properties, String key) {
String propValue = properties.get(key);
if (propValue != null) {
- return DefaultConfiguration.parseAsCsv(key, propValue);
+ return parseAsCsv(key, propValue);
}
return new String[0];
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleFileSystemInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleFileSystemInitializer.java
index 57dde312c17..12872bb2e49 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleFileSystemInitializer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleFileSystemInitializer.java
@@ -38,7 +38,7 @@ import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import static org.sonar.scanner.config.DefaultConfiguration.parseAsCsv;
+import static org.sonar.core.config.MultivalueProperty.parseAsCsv;
@ScannerSide
@Immutable