]> gerrit.simantics Code Review - simantics/district.git/blob
c23a6079952a82eb6927c1cdc28ef5de1a7853f0
[simantics/district.git] /
1 package org.simantics.district.network.ui.techtype.table;
2
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;
9 import java.util.List;
10 import java.util.stream.IntStream;
11
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;
18
19 public class TechTypeTableDataProvider implements IDataProvider {
20
21     private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTableDataProvider.class);
22
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;
29
30     private ListenerList<EnableListener> enableListeners = new ListenerList<EnableListener>();
31
32     public TechTypeTableDataProvider(String data, int[] enabledList) {
33         setData(data);
34         setEnabledFlags(enabledList);
35     }
36     
37     public TechTypeTableDataProvider(String data) {
38         // load csv
39         setData(data);
40     }
41     
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)
47                     enabled[i] = true;
48             }
49         }
50     }
51
52     public String getVariableName(int columnIndex) {
53         return variables != null && columnIndex > 0 && columnIndex <= variables.size() ? variables.get(columnIndex - 1) : null;
54     }
55
56     public int getVariableIndex(String variableName) {
57         return variables != null ? variables.indexOf(variableName) + 1 : -1;
58     }
59     
60     public CSVRecord getRecord(int rowIndex) {
61         return records.get(filteredRows[rowIndex]);
62     }
63     
64     public boolean isEnabled(int rowIndex) {
65         return enabled[filteredRows[rowIndex]];
66     }
67
68     public String getHeaderValue(int columnIndex) {
69         if (headers == null) {
70             return "<empty>";
71         } else if (columnIndex == 0) {
72             return "Enabled";
73         } else {
74             return headers.get(columnIndex - 1);
75         }
76     }
77
78     @Override
79     public Object getDataValue(int columnIndex, int rowIndex) {
80         if (columnIndex == 0) {
81             return isEnabled(rowIndex);
82         }
83         return getRecord(rowIndex).get(columnIndex - 1);
84     }
85
86     @Override
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);
92         }
93     }
94     
95     public void addEnableListener(EnableListener listener) {
96         enableListeners.add(listener);
97     }
98
99     private void fireEnableEvent(int rowIndex, boolean newValue) {
100         enableListeners.forEach(l -> l.rowEnabled(rowIndex, newValue));
101     }
102
103     @Override
104     public int getColumnCount() {
105         if (records.isEmpty()) {
106             return 0;
107         }
108         return records.get(0).size() + 1;
109     }
110
111     @Override
112     public int getRowCount() {
113         return filteredRows.length;
114     }
115
116     public boolean isEditable(int columnIndex, int rowIndex) {
117         return columnIndex == 0;
118     }
119
120     public void setFilter(String text) {
121         this.filter = text != null ? text.toLowerCase() : null;
122
123         filteredRows = IntStream.range(0, records.size())
124                 .filter(k -> isMatch(records.get(k), filter))
125                 .toArray();
126     }
127
128     private static boolean isMatch(CSVRecord record, String filterString) {
129         if (filterString == null || filterString.isEmpty())
130             return true;
131         
132         for (int i = 0; i < record.size(); i++) {
133             String columnContent = record.get(i);
134             if (columnContent.toLowerCase().contains(filterString)) {
135                 return true;
136             }
137         }
138         
139         return false;
140     }
141
142     /**
143      * Read a CSV file into table contents.
144      * 
145      * Set path to null to create an empty table.
146      * 
147      * @param path  The path of the CSV file to be read.
148      */
149     public void setPath(String path) {
150         records.clear();
151
152         if (path != null) {
153             Path techTypeCsv = Paths.get(path);
154             try {
155                 DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> {
156                     records.add(record);
157                     return true;
158                 });
159             } catch (IOException e) {
160                 e.printStackTrace();
161             }
162         }
163
164         setFilter(null);
165     }
166
167     /**
168      * Set table data contents to a given string of CSV data.
169      * 
170      * Set 'data' to null to create an empty table.
171      * 
172      * @param data  The CSV data to be shown in the table.
173      */
174     public void setData(String data) {
175         records.clear();
176
177         if (data != null) {
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);
182             try {
183                 DistrictImportUtils.consumeCSV(reader, delim, false, record -> {
184                     records.add(record);
185                     return true;
186                 });
187             } catch (IOException e) {
188                 LOGGER.error("Error reading CSV file", e);
189                 return;
190             }
191
192             CSVRecord header = records.remove(0);
193             CSVRecord units = records.remove(0);
194
195             variables = new ArrayList<>();
196             headers = new ArrayList<>();
197
198             Iterator<String> it = header.iterator();
199             Iterator<String> uit = units.iterator();
200
201             while (it.hasNext()) {
202                 String variable = it.next().trim();
203                 String unit = uit.hasNext() ? uit.next().trim() : null;
204
205                 variables.add(variable);
206                 headers.add(variable + (unit != null && !unit.isEmpty() && !(unit.startsWith("(") && unit.endsWith(")")) ? " [" + unit + "]" : ""));
207             }
208         }
209         
210         enabled = new boolean[records.size()];
211
212         setFilter(null);
213     }
214
215 }