package org.simantics.district.network.ui.techtype.table; import java.io.IOException; import java.io.StringReader; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.csv.CSVRecord; import org.eclipse.nebula.widgets.nattable.data.IDataProvider; import org.simantics.district.imports.DistrictImportUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TechTypeTableDataProvider implements IDataProvider { @SuppressWarnings("unused") private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTableDataProvider.class); private List records = new ArrayList<>(); private List filteredRecords = new ArrayList<>(); private String filter = ""; private List variables = null; private List headers = null; public TechTypeTableDataProvider(String data) { // load csv setData(data); } public String getVariableName(int columnIndex) { return variables != null && columnIndex < variables.size() ? variables.get(columnIndex) : null; } public int getVariableIndex(String variableName) { return variables != null ? variables.indexOf(variableName) : -1; } public String getHeaderValue(int columnIndex) { if (headers == null) { return ""; } return headers.get(columnIndex); } @Override public Object getDataValue(int columnIndex, int rowIndex) { return filteredRecords.get(rowIndex).get(columnIndex); } @Override public void setDataValue(int columnIndex, int rowIndex, Object newValue) { } @Override public int getColumnCount() { if (records.isEmpty()) { return 0; } return records.get(0).size(); } @Override public int getRowCount() { return filteredRecords.size(); } public boolean isEditable(int columnIndex, int rowIndex) { return false; } public void setFilter(String text) { this.filter = text.toLowerCase(); filteredRecords = records.stream().filter(record -> { for (int i = 0; i < record.size(); i++) { String columnContent = record.get(i); if (columnContent.toLowerCase().contains(filter)) { return true; } } return false; }).collect(Collectors.toList()); } /** * Read a CSV file into table contents. * * Set path to null to create an empty table. * * @param path The path of the CSV file to be read. */ public void setPath(String path) { records.clear(); filteredRecords.clear(); if (path != null) { Path techTypeCsv = Paths.get(path); try { DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> { records.add(record); return true; }); } catch (IOException e) { e.printStackTrace(); } } setFilter(""); } /** * Set table data contents to a given string of CSV data. * * Set 'data' to null to create an empty table. * * @param data The CSV data to be shown in the table. */ public void setData(String data) { records.clear(); filteredRecords.clear(); if (data != null) { long ncommas = data.chars().filter(c -> c == ',').count(); long nsemis = data.chars().filter(c -> c == ';').count(); char delim = nsemis > ncommas ? ';' : ','; StringReader reader = new StringReader(data); try { DistrictImportUtils.consumeCSV(reader, delim, false, record -> { records.add(record); return true; }); } catch (IOException e) { LOGGER.error("Error reading CSV file", e); return; } CSVRecord header = records.remove(0); CSVRecord units = records.remove(0); variables = new ArrayList<>(); headers = new ArrayList<>(); Iterator it = header.iterator(); Iterator uit = units.iterator(); while (it.hasNext()) { String variable = it.next().trim(); String unit = uit.hasNext() ? uit.next().trim() : null; variables.add(variable); headers.add(variable + (unit != null && !unit.isEmpty() && !(unit.startsWith("(") && unit.endsWith(")")) ? " [" + unit + "]" : "")); } } setFilter(""); } }