1 package org.simantics.district.network.ui.techtype.table;
3 import java.io.IOException;
4 import java.io.StringReader;
5 import java.nio.file.Path;
6 import java.nio.file.Paths;
7 import java.util.ArrayList;
8 import java.util.Iterator;
10 import java.util.stream.IntStream;
12 import org.apache.commons.csv.CSVRecord;
13 import org.eclipse.core.runtime.ListenerList;
14 import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
15 import org.simantics.district.imports.DistrictImportUtils;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
19 public class TechTypeTableDataProvider implements IDataProvider {
21 private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTableDataProvider.class);
23 private List<CSVRecord> records = new ArrayList<>();
24 private boolean[] enabled;
25 private String filter = null;
26 private List<String> variables = null;
27 private List<String> headers = null;
28 private int[] filteredRows;
30 private ListenerList<EnableListener> enableListeners = new ListenerList<EnableListener>();
32 public TechTypeTableDataProvider(String data, int[] enabledList) {
34 setEnabledFlags(enabledList);
37 public TechTypeTableDataProvider(String data) {
42 public void setEnabledFlags(int[] enabledList) {
43 this.enabled = new boolean[records.size()];
44 if (enabledList != null) {
45 for (int i : enabledList) {
46 if (i >= 0 && i < enabled.length)
52 public String getVariableName(int columnIndex) {
53 return variables != null && columnIndex > 0 && columnIndex <= variables.size() ? variables.get(columnIndex - 1) : null;
56 public int getVariableIndex(String variableName) {
57 return variables != null ? variables.indexOf(variableName) + 1 : -1;
60 public CSVRecord getRecord(int rowIndex) {
61 return records.get(filteredRows[rowIndex]);
64 public boolean isEnabled(int rowIndex) {
65 return enabled[filteredRows[rowIndex]];
68 public String getHeaderValue(int columnIndex) {
69 if (headers == null) {
71 } else if (columnIndex == 0) {
74 return headers.get(columnIndex - 1);
79 public Object getDataValue(int columnIndex, int rowIndex) {
80 if (columnIndex == 0) {
81 return isEnabled(rowIndex);
83 return getRecord(rowIndex).get(columnIndex - 1);
87 public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
88 if (columnIndex == 0) {
89 boolean value = Boolean.parseBoolean((String) newValue);
90 enabled[filteredRows[rowIndex]] = value;
91 fireEnableEvent(rowIndex, value);
95 public void addEnableListener(EnableListener listener) {
96 enableListeners.add(listener);
99 private void fireEnableEvent(int rowIndex, boolean newValue) {
100 enableListeners.forEach(l -> l.rowEnabled(rowIndex, newValue));
104 public int getColumnCount() {
105 if (records.isEmpty()) {
108 return records.get(0).size() + 1;
112 public int getRowCount() {
113 return filteredRows.length;
116 public boolean isEditable(int columnIndex, int rowIndex) {
117 return columnIndex == 0;
120 public void setFilter(String text) {
121 this.filter = text != null ? text.toLowerCase() : null;
123 filteredRows = IntStream.range(0, records.size())
124 .filter(k -> isMatch(records.get(k), filter))
128 private static boolean isMatch(CSVRecord record, String filterString) {
129 if (filterString == null || filterString.isEmpty())
132 for (int i = 0; i < record.size(); i++) {
133 String columnContent = record.get(i);
134 if (columnContent.toLowerCase().contains(filterString)) {
143 * Read a CSV file into table contents.
145 * Set path to null to create an empty table.
147 * @param path The path of the CSV file to be read.
149 public void setPath(String path) {
153 Path techTypeCsv = Paths.get(path);
155 DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> {
159 } catch (IOException e) {
168 * Set table data contents to a given string of CSV data.
170 * Set 'data' to null to create an empty table.
172 * @param data The CSV data to be shown in the table.
174 public void setData(String data) {
178 long ncommas = data.chars().filter(c -> c == ',').count();
179 long nsemis = data.chars().filter(c -> c == ';').count();
180 char delim = nsemis > ncommas ? ';' : ',';
181 StringReader reader = new StringReader(data);
183 DistrictImportUtils.consumeCSV(reader, delim, false, record -> {
187 } catch (IOException e) {
188 LOGGER.error("Error reading CSV file", e);
192 CSVRecord header = records.remove(0);
193 CSVRecord units = records.remove(0);
195 variables = new ArrayList<>();
196 headers = new ArrayList<>();
198 Iterator<String> it = header.iterator();
199 Iterator<String> uit = units.iterator();
201 while (it.hasNext()) {
202 String variable = it.next().trim();
203 String unit = uit.hasNext() ? uit.next().trim() : null;
205 variables.add(variable);
206 headers.add(variable + (unit != null && !unit.isEmpty() && !(unit.startsWith("(") && unit.endsWith(")")) ? " [" + unit + "]" : ""));
210 enabled = new boolean[records.size()];