1 | |
package org.jbehave.core.model; |
2 | |
|
3 | |
import static java.lang.Boolean.parseBoolean; |
4 | |
|
5 | |
import java.util.ArrayList; |
6 | |
import java.util.HashMap; |
7 | |
import java.util.LinkedHashMap; |
8 | |
import java.util.List; |
9 | |
import java.util.Map; |
10 | |
import java.util.Properties; |
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
|
29 | |
public class TableTransformers { |
30 | |
|
31 | |
public static final String FROM_LANDSCAPE = "FROM_LANDSCAPE"; |
32 | |
public static final String FORMATTING = "FORMATTING"; |
33 | |
public static final String REPLACING = "REPLACING"; |
34 | |
|
35 | 1639 | private final Map<String, TableTransformer> transformers = new HashMap<String, TableTransformer>(); |
36 | |
|
37 | 1639 | public TableTransformers() { |
38 | 1639 | useTransformer(FROM_LANDSCAPE, new FromLandscape()); |
39 | 1639 | useTransformer(FORMATTING, new Formatting()); |
40 | 1639 | useTransformer(REPLACING, new Replacing()); |
41 | 1639 | } |
42 | |
|
43 | |
public String transform(String transformerName, String tableAsString, |
44 | |
Properties properties) { |
45 | 8 | TableTransformer transformer = transformers.get(transformerName); |
46 | 8 | if (transformer != null) { |
47 | 7 | return transformer.transform(tableAsString, properties); |
48 | |
} |
49 | 1 | return tableAsString; |
50 | |
} |
51 | |
|
52 | |
public void useTransformer(String name, TableTransformer transformer) { |
53 | 4919 | transformers.put(name, transformer); |
54 | 4919 | } |
55 | |
|
56 | |
public interface TableTransformer { |
57 | |
String transform(String tableAsString, Properties properties); |
58 | |
} |
59 | |
|
60 | 1639 | public static class FromLandscape implements TableTransformer { |
61 | |
|
62 | |
private static final String ROW_SEPARATOR = "\n"; |
63 | |
|
64 | |
public String transform(String tableAsString, Properties properties) { |
65 | 2 | boolean trim = parseBoolean(properties.getProperty("trim", "true")); |
66 | 2 | String ignorableSeparator = properties.getProperty( |
67 | |
"ignorableSeparator", "|--"); |
68 | 2 | String headerSeparator = properties.getProperty("headerSeparator", |
69 | |
"|"); |
70 | 2 | String valueSeparator = properties.getProperty("valueSeparator", |
71 | |
"|"); |
72 | 2 | Map<String, List<String>> data = new LinkedHashMap<String, List<String>>(); |
73 | 6 | for (String rowAsString : tableAsString.split(ROW_SEPARATOR)) { |
74 | 4 | if (ignoreRow(rowAsString, ignorableSeparator)) { |
75 | 0 | continue; |
76 | |
} else { |
77 | 4 | List<String> values = TableUtils.parseRow(rowAsString, |
78 | |
valueSeparator, trim); |
79 | 4 | String header = values.get(0); |
80 | 4 | List<String> rowValues = new ArrayList<String>(values); |
81 | 4 | rowValues.remove(0); |
82 | 4 | data.put(header, rowValues); |
83 | |
} |
84 | |
} |
85 | 2 | StringBuilder builder = new StringBuilder(); |
86 | 2 | int numberOfRows = 1; |
87 | 2 | builder.append(headerSeparator); |
88 | 2 | for (String header : data.keySet()) { |
89 | 4 | builder.append(header).append(headerSeparator); |
90 | 4 | numberOfRows = data.get(header).size(); |
91 | 4 | } |
92 | 2 | builder.append(ROW_SEPARATOR); |
93 | 6 | for (int r = 0; r < numberOfRows; r++) { |
94 | 4 | builder.append(valueSeparator); |
95 | 4 | for (List<String> rows : data.values()) { |
96 | 8 | builder.append(rows.get(r)).append(valueSeparator); |
97 | 8 | } |
98 | 4 | builder.append(ROW_SEPARATOR); |
99 | |
} |
100 | 2 | return builder.toString(); |
101 | |
} |
102 | |
|
103 | |
private boolean ignoreRow(String rowAsString, String ignorableSeparator) { |
104 | 4 | return rowAsString.startsWith(ignorableSeparator) |
105 | |
|| rowAsString.length() == 0; |
106 | |
} |
107 | |
|
108 | |
} |
109 | |
|
110 | 1639 | public static class Formatting implements TableTransformer { |
111 | |
|
112 | |
private static final String ROW_SEPARATOR = "\n"; |
113 | |
|
114 | |
public String transform(String tableAsString, Properties properties) { |
115 | 1 | boolean trim = parseBoolean(properties.getProperty("trim", "true")); |
116 | 1 | String ignorableSeparator = properties.getProperty( |
117 | |
"ignorableSeparator", "|--"); |
118 | 1 | String headerSeparator = properties.getProperty("headerSeparator", |
119 | |
"|"); |
120 | 1 | String valueSeparator = properties.getProperty("valueSeparator", |
121 | |
"|"); |
122 | 1 | List<List<String>> data = new ArrayList<List<String>>(); |
123 | 4 | for (String rowAsString : tableAsString.split(ROW_SEPARATOR)) { |
124 | 3 | if (ignoreRow(rowAsString, ignorableSeparator)) { |
125 | 0 | continue; |
126 | 3 | } else if (rowAsString.contains(headerSeparator)) { |
127 | 3 | data.add(TableUtils.parseRow(rowAsString, headerSeparator, |
128 | |
trim)); |
129 | |
} else { |
130 | 0 | data.add(TableUtils.parseRow(rowAsString, valueSeparator, |
131 | |
trim)); |
132 | |
} |
133 | |
|
134 | |
} |
135 | |
|
136 | 1 | StringBuilder builder = new StringBuilder(); |
137 | 1 | Map<Integer, Integer> maxWidths = maxWidth(data); |
138 | 4 | for (int r = 0; r < data.size(); r++) { |
139 | 3 | String formattedRow = formatRow(data.get(r), maxWidths, |
140 | |
(r == 0 ? headerSeparator : valueSeparator)); |
141 | 3 | builder.append(formattedRow).append(ROW_SEPARATOR); |
142 | |
} |
143 | 1 | return builder.toString(); |
144 | |
} |
145 | |
|
146 | |
private boolean ignoreRow(String rowAsString, String ignorableSeparator) { |
147 | 3 | return rowAsString.startsWith(ignorableSeparator) |
148 | |
|| rowAsString.length() == 0; |
149 | |
} |
150 | |
|
151 | |
private Map<Integer, Integer> maxWidth(List<List<String>> data) { |
152 | 1 | Map<Integer, Integer> maxWidths = new HashMap<Integer, Integer>(); |
153 | 1 | for (List<String> row : data) { |
154 | 12 | for (int c = 0; c < row.size(); c++) { |
155 | 9 | String cell = row.get(c).trim(); |
156 | 9 | Integer width = maxWidths.get(c); |
157 | 9 | int length = cell.length(); |
158 | 9 | if (width == null || length > width) { |
159 | 3 | width = length; |
160 | 3 | maxWidths.put(c, width); |
161 | |
} |
162 | |
} |
163 | 3 | } |
164 | |
|
165 | 1 | return maxWidths; |
166 | |
|
167 | |
} |
168 | |
|
169 | |
private String formatRow(List<String> row, |
170 | |
Map<Integer, Integer> maxWidths, String separator) { |
171 | 3 | StringBuilder builder = new StringBuilder(); |
172 | 3 | builder.append(separator); |
173 | 12 | for (int c = 0; c < row.size(); c++) { |
174 | 9 | builder.append(formatValue(row.get(c).trim(), maxWidths.get(c))) |
175 | |
.append(separator); |
176 | |
} |
177 | 3 | return builder.toString(); |
178 | |
} |
179 | |
|
180 | |
private String formatValue(String value, int width) { |
181 | 9 | if (value.length() < width) { |
182 | 6 | return value + padding(width - value.length()); |
183 | |
} |
184 | 3 | return value; |
185 | |
} |
186 | |
|
187 | |
private String padding(int size) { |
188 | 6 | StringBuilder builder = new StringBuilder(); |
189 | 12 | for (int i = 0; i < size; i++) { |
190 | 6 | builder.append(' '); |
191 | |
} |
192 | 6 | return builder.toString(); |
193 | |
} |
194 | |
|
195 | |
} |
196 | |
|
197 | 1639 | public static class Replacing implements TableTransformer { |
198 | |
|
199 | |
public String transform(String tableAsString, Properties properties) { |
200 | 2 | String replacing = properties.getProperty("replacing"); |
201 | 2 | String replacement = properties.getProperty("replacement"); |
202 | 2 | if ( replacing == null || replacement == null ) { |
203 | 1 | return tableAsString; |
204 | |
} |
205 | 1 | return tableAsString.replace(replacing, replacement); |
206 | |
} |
207 | |
} |
208 | |
} |