TableParsers.java
- package org.jbehave.core.model;
- import java.util.ArrayList;
- import java.util.Deque;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import java.util.function.UnaryOperator;
- import java.util.regex.Matcher;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.text.translate.CharSequenceTranslator;
- import org.apache.commons.text.translate.LookupTranslator;
- import org.jbehave.core.configuration.Keywords;
- import org.jbehave.core.i18n.LocalizedKeywords;
- import org.jbehave.core.model.ExamplesTable.TableProperties;
- import org.jbehave.core.model.ExamplesTable.TablePropertiesQueue;
- import org.jbehave.core.model.ExamplesTable.TableRows;
- import org.jbehave.core.steps.ParameterConverters;
- public class TableParsers {
- private static final String ROW_SEPARATOR_PATTERN = "\r?\n";
- private static final CharSequenceTranslator UNESCAPE_TRANSLATOR;
- static {
- final Map<CharSequence, CharSequence> unescapeMapping = new HashMap<>();
- unescapeMapping.put("\\\\", "\\");
- unescapeMapping.put("\\", StringUtils.EMPTY);
- unescapeMapping.put("\\n", "\n");
- unescapeMapping.put("\\r", "\r");
- UNESCAPE_TRANSLATOR = new LookupTranslator(unescapeMapping);
- }
- private final Keywords keywords;
- private final ParameterConverters parameterConverters;
- private final Optional<String> defaultNullPlaceholder;
- public TableParsers(ParameterConverters parameterConverters) {
- this(new LocalizedKeywords(), parameterConverters);
- }
- public TableParsers(Keywords keywords, ParameterConverters parameterConverters) {
- this(keywords, parameterConverters, Optional.empty());
- }
- public TableParsers(Keywords keywords, ParameterConverters parameterConverters,
- Optional<String> defaultNullPlaceholder) {
- this.keywords = keywords;
- this.parameterConverters = parameterConverters;
- this.defaultNullPlaceholder = defaultNullPlaceholder;
- }
- public TablePropertiesQueue parseProperties(String tableAsString) {
- Deque<TableProperties> properties = new LinkedList<>();
- String tableWithoutProperties = tableAsString.trim();
- Matcher matcher = ExamplesTable.INLINED_PROPERTIES_PATTERN.matcher(tableWithoutProperties);
- while (matcher.matches()) {
- String propertiesAsString = matcher.group(1);
- propertiesAsString = StringUtils.replace(propertiesAsString, "\\{", "{");
- propertiesAsString = StringUtils.replace(propertiesAsString, "\\}", "}");
- properties.add(new TableProperties(propertiesAsString, keywords, parameterConverters));
- tableWithoutProperties = matcher.group(2).trim();
- matcher = ExamplesTable.INLINED_PROPERTIES_PATTERN.matcher(tableWithoutProperties);
- }
- if (properties.isEmpty()) {
- properties.add(new TableProperties("", keywords, parameterConverters));
- }
- return new TablePropertiesQueue(tableWithoutProperties, properties);
- }
- public TableRows parseRows(String tableAsString, TableProperties properties) {
- List<String> headers = new ArrayList<>();
- List<List<String>> rows = new ArrayList<>();
- for (String rowLine : tableAsString.split(ROW_SEPARATOR_PATTERN)) {
- String trimmedRowLine = rowLine.trim();
- // skip ignorable or empty lines
- if (!trimmedRowLine.startsWith(properties.getIgnorableSeparator()) && !trimmedRowLine.isEmpty()) {
- if (headers.isEmpty()) {
- headers.addAll(parseRow(trimmedRowLine, true, properties));
- } else {
- List<String> cells = parseRow(trimmedRowLine, false, properties);
- if (cells.size() > headers.size()) {
- cells = cells.subList(0, headers.size());
- }
- rows.add(cells);
- }
- }
- }
- return new TableRows(headers, rows);
- }
- public List<String> parseRow(String rowAsString, boolean header, TableProperties properties) {
- String separator = header ? properties.getHeaderSeparator() : properties.getValueSeparator();
- String commentSeparator = properties.getCommentSeparator();
- Optional<String> nullPlaceholder = properties.getNullPlaceholder().map(Optional::of).orElse(
- defaultNullPlaceholder);
- UnaryOperator<String> trimmer = properties.isTrim() ? String::trim : UnaryOperator.identity();
- boolean processEscapeSequences = properties.isProcessEscapeSequences();
- String[] cells = StringUtils.splitByWholeSeparatorPreserveAllTokens(rowAsString.trim(), separator);
- List<String> row = new ArrayList<>(cells.length);
- for (int i = 0; i < cells.length; i++) {
- String cell = cells[i];
- cell = StringUtils.substringBefore(cell, commentSeparator);
- if ((i == 0 || i == cells.length - 1) && cell.isEmpty()) {
- continue;
- }
- String trimmedCell = trimmer.apply(cell);
- if (processEscapeSequences) {
- trimmedCell = UNESCAPE_TRANSLATOR.translate(trimmedCell);
- }
- row.add(nullPlaceholder.filter(trimmedCell::equals).isPresent() ? null : trimmedCell);
- }
- return row;
- }
- }