mirror of
https://github.com/valitydev/gambit.git
synced 2024-11-06 00:25:16 +00:00
fix result mapping with double quotes string (#22)
Co-authored-by: ggmaleva <ggmaleva@yandex.ru>
This commit is contained in:
parent
25f467e6f0
commit
8adf294551
@ -1,6 +1,6 @@
|
||||
package dev.vality.gambit.factory;
|
||||
|
||||
import dev.vality.gambit.util.Constants;
|
||||
import dev.vality.gambit.util.CsvUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -18,8 +18,8 @@ public class DataMapFactory {
|
||||
log.error("Headers or values cannot be empty. headers: {}, values {}", headers, values);
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
String[] splitHeaders = headers.split(Constants.SEPARATOR);
|
||||
String[] splitValues = values.split(Constants.SEPARATOR);
|
||||
String[] splitHeaders = headers.split(CsvUtils.SEPARATOR);
|
||||
String[] splitValues = CsvUtils.trimAndSplitValueLine(values).toArray(new String[0]);
|
||||
if (splitValues.length != splitHeaders.length) {
|
||||
log.error("Error during split. headers: {}, values {}", splitHeaders, splitValues);
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -3,7 +3,7 @@ package dev.vality.gambit.service.impl;
|
||||
import dev.vality.gambit.exception.FileProcessingException;
|
||||
import dev.vality.gambit.model.DataEntries;
|
||||
import dev.vality.gambit.service.FileService;
|
||||
import dev.vality.gambit.util.Constants;
|
||||
import dev.vality.gambit.util.CsvUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -12,8 +12,6 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -46,7 +44,7 @@ public class CsvFileServiceImpl implements FileService {
|
||||
log.error("Empty file");
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
List<String> inputHeaders = trimAndSplitLine(headerLine);
|
||||
List<String> inputHeaders = CsvUtils.trimAndSplitLine(headerLine);
|
||||
if (!CollectionUtils.isEmpty(existingHeaders)) {
|
||||
validateByExistingHeaders(inputHeaders, existingHeaders);
|
||||
}
|
||||
@ -65,12 +63,12 @@ public class CsvFileServiceImpl implements FileService {
|
||||
}
|
||||
|
||||
private String validateAndTrimValues(String line, int headersCount) {
|
||||
List<String> trimmedValues = trimAndSplitValueLine(line);
|
||||
List<String> trimmedValues = CsvUtils.trimAndSplitValueLine(line);
|
||||
if (headersCount != trimmedValues.size()) {
|
||||
log.error("Line '{}' doesn't match headers count {}", line, headersCount);
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return String.join(Constants.SEPARATOR, trimmedValues);
|
||||
return String.join(CsvUtils.SEPARATOR, trimmedValues);
|
||||
}
|
||||
|
||||
private void validateByExistingHeaders(List<String> inputHeaders, List<String> existingHeaders) {
|
||||
@ -86,31 +84,4 @@ public class CsvFileServiceImpl implements FileService {
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> trimAndSplitLine(String line) {
|
||||
return Arrays.stream(line.split(Constants.SEPARATOR))
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> trimAndSplitValueLine(String line) {
|
||||
List<String> values = new ArrayList<>();
|
||||
int startPosition = 0;
|
||||
boolean isInsideQuotes = false;
|
||||
for (int currentPosition = 0; currentPosition < line.length(); currentPosition++) {
|
||||
if (line.charAt(currentPosition) == Constants.DOUBLE_QUOTES) {
|
||||
isInsideQuotes = !isInsideQuotes;
|
||||
} else if (line.charAt(currentPosition) == Constants.SEPARATOR.charAt(0) && !isInsideQuotes) {
|
||||
values.add(line.substring(startPosition, currentPosition).trim());
|
||||
startPosition = currentPosition + 1;
|
||||
}
|
||||
}
|
||||
String lastValue = line.substring(startPosition).trim();
|
||||
if (lastValue.equals(Constants.SEPARATOR)) {
|
||||
values.add("");
|
||||
} else {
|
||||
values.add(lastValue);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ import dev.vality.gambit.domain.tables.pojos.DataSetInfo;
|
||||
import dev.vality.gambit.exception.DataSetInfoAlreadyExistException;
|
||||
import dev.vality.gambit.factory.DataFactory;
|
||||
import dev.vality.gambit.model.DataEntries;
|
||||
import dev.vality.gambit.service.FileService;
|
||||
import dev.vality.gambit.service.DataService;
|
||||
import dev.vality.gambit.service.DataSetInfoService;
|
||||
import dev.vality.gambit.service.DataSetService;
|
||||
import dev.vality.gambit.util.Constants;
|
||||
import dev.vality.gambit.service.FileService;
|
||||
import dev.vality.gambit.util.CsvUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -39,7 +39,7 @@ public class DataSetServiceImpl implements DataSetService {
|
||||
validateDataSetNameRequest(dataSetName);
|
||||
DataEntries dataEntries = fileService.process(bufferedReader);
|
||||
Integer dataSetInfoId = dataSetInfoService.createDataSetInfo(
|
||||
new DataSetInfo(null, dataSetName, String.join(Constants.SEPARATOR, dataEntries.getHeaders())));
|
||||
new DataSetInfo(null, dataSetName, String.join(CsvUtils.SEPARATOR, dataEntries.getHeaders())));
|
||||
dataService.saveDataBatch(dataEntries.getValues().stream()
|
||||
.map(value -> DataFactory.create(dataSetInfoId, value))
|
||||
.collect(Collectors.toList()));
|
||||
@ -50,7 +50,7 @@ public class DataSetServiceImpl implements DataSetService {
|
||||
public void updateDataSet(String dataSetName, BufferedReader bufferedReader) throws DataSetNotFound {
|
||||
DataSetInfo dataSetInfo = dataSetInfoService.getDataSetInfoByName(dataSetName)
|
||||
.orElseThrow(DataSetNotFound::new);
|
||||
List<String> existingHeaders = Arrays.asList(dataSetInfo.getHeaders().split(Constants.SEPARATOR));
|
||||
List<String> existingHeaders = Arrays.asList(dataSetInfo.getHeaders().split(CsvUtils.SEPARATOR));
|
||||
DataEntries dataEntries = fileService.process(bufferedReader, existingHeaders);
|
||||
dataService.saveDataBatch(dataEntries.getValues().stream()
|
||||
.map(value -> DataFactory.create(dataSetInfo.getId(), value))
|
||||
|
@ -1,13 +0,0 @@
|
||||
package dev.vality.gambit.util;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Constants {
|
||||
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
public static final char DOUBLE_QUOTES = '\"';
|
||||
|
||||
}
|
43
src/main/java/dev/vality/gambit/util/CsvUtils.java
Normal file
43
src/main/java/dev/vality/gambit/util/CsvUtils.java
Normal file
@ -0,0 +1,43 @@
|
||||
package dev.vality.gambit.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
public class CsvUtils {
|
||||
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
public static final char DOUBLE_QUOTES = '\"';
|
||||
|
||||
public static List<String> trimAndSplitLine(String line) {
|
||||
return Arrays.stream(line.split(SEPARATOR))
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<String> trimAndSplitValueLine(String line) {
|
||||
List<String> values = new ArrayList<>();
|
||||
int startPosition = 0;
|
||||
boolean isInsideQuotes = false;
|
||||
for (int currentPosition = 0; currentPosition < line.length(); currentPosition++) {
|
||||
if (line.charAt(currentPosition) == DOUBLE_QUOTES) {
|
||||
isInsideQuotes = !isInsideQuotes;
|
||||
} else if (line.charAt(currentPosition) == SEPARATOR.charAt(0) && !isInsideQuotes) {
|
||||
values.add(line.substring(startPosition, currentPosition).trim());
|
||||
startPosition = currentPosition + 1;
|
||||
}
|
||||
}
|
||||
String lastValue = line.substring(startPosition).trim();
|
||||
if (lastValue.equals(SEPARATOR)) {
|
||||
values.add("");
|
||||
} else {
|
||||
values.add(lastValue);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class DataMapFactoryTest {
|
||||
|
||||
@ -24,6 +25,18 @@ class DataMapFactoryTest {
|
||||
assertThrows(IllegalArgumentException.class, () -> DataMapFactory.createDataMap("one,two", "tres"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createDataMapWithDoubleQuotes() {
|
||||
String headers = "one,two";
|
||||
String values = "uno,\"dos,tres\"";
|
||||
Map<String, String> expected = Map.of(
|
||||
"one", "uno",
|
||||
"two", "\"dos,tres\""
|
||||
);
|
||||
Map<String, String> actual = DataMapFactory.createDataMap(headers, values);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createDataMap() {
|
||||
Map<String, String> expected = Map.of(
|
||||
|
Loading…
Reference in New Issue
Block a user