001package jmri.jmrit.logixng.implementation; 002 003import java.io.File; 004import java.io.BufferedWriter; 005import java.io.FileNotFoundException; 006import java.io.OutputStreamWriter; 007import java.io.FileOutputStream; 008import java.io.PrintWriter; 009import java.nio.charset.StandardCharsets; 010import java.util.HashMap; 011import java.util.Map; 012import javax.annotation.CheckForNull; 013import javax.annotation.Nonnull; 014import jmri.jmrit.logixng.AnonymousTable; 015 016/** 017 * Default implementation for anonymous tables 018 */ 019public class DefaultAnonymousTable implements AnonymousTable { 020 021 private final int _numRows; 022 private final int _numColumns; 023 private final Object[][] _data; 024 private final Map<String,Integer> rowNames = new HashMap<>(); 025 private final Map<String,Integer> columnNames = new HashMap<>(); 026 027 public DefaultAnonymousTable(int numRows, int numColumns) { 028 _numRows = numRows; 029 _numColumns = numColumns; 030 _data = new Object[numRows+1][numColumns+1]; 031 setupTable(); 032 } 033 034 /** 035 * Create a new anonymous table with an existing array of cells. 036 * Row 0 has the column names and column 0 has the row names. 037 * @param data the data in the table. Note that this data is not copied to 038 * an new array but used by the table as is. 039 */ 040 public DefaultAnonymousTable(@Nonnull Object[][] data) { 041 // Row 0 has column names 042 _numRows = data.length-1; 043 // Column 0 has row names 044 _numColumns = data[0].length-1; 045 _data = data; 046 047 for (int row=0; row < _data.length; row++) { 048 if (_numColumns+1 != _data[row].length) { 049 throw new IllegalArgumentException("All rows in table must have same number of columns"); 050 } 051 } 052 053 setupTable(); 054/* 055 int i[][] = new int[15][]; 056 i[5] = new int[3]; 057 i[7] = new int[10]; 058 i[5][2] = 3; 059// i[5][8] = 4; 060 i[7][2] = 5; 061 i[7][8] = 6; 062// i[2][2] = 7; 063// i[2][8] = 8; 064 065 i = new int[15][20]; 066// i[5] = new int[3]; 067 i[7] = new int[10]; 068 i[5][2] = 3; 069 i[5][8] = 4; 070 i[7][2] = 5; 071 i[7][8] = 6; 072 i[2][2] = 7; 073 i[2][8] = 8; 074*/ 075 } 076 077 private void setupTable() { 078 for (int i=0; i <= _numRows; i++) { 079 Object cell = _data[i][0]; 080 if (cell != null && cell instanceof String) { 081 rowNames.put(cell.toString(), i); 082 } 083 } 084 085 for (int i=0; i <= _numColumns; i++) { 086 Object cell = _data[0][i]; 087 if (cell != null && cell instanceof String) { 088 columnNames.put(cell.toString(), i); 089 } 090 } 091 } 092 093 /** 094 * {@inheritDoc} 095 */ 096 @Override 097 public void storeTableAsCSV() throws FileNotFoundException { 098 throw new UnsupportedOperationException("Not supported"); 099 } 100 101 /** 102 * {@inheritDoc} 103 */ 104 @Override 105 public void storeTableAsCSV(@Nonnull File file) 106 throws FileNotFoundException { 107 storeTableAsCSV(file, null, null); 108 } 109 110 /** 111 * {@inheritDoc} 112 */ 113 @Override 114 public void storeTableAsCSV(@Nonnull File file, boolean storeSystemUserName) 115 throws FileNotFoundException { 116 storeTableAsCSV(file, null, null); 117 } 118 119 /** 120 * {@inheritDoc} 121 */ 122 @Override 123 public void storeTableAsCSV( 124 @Nonnull File file, 125 @CheckForNull String systemName, @CheckForNull String userName) 126 throws FileNotFoundException { 127 128 storeTableAsCSV(file, systemName, userName, true); 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public void storeTableAsCSV( 136 @Nonnull File file, 137 @CheckForNull String systemName, @CheckForNull String userName, 138 boolean storeSystemUserName) 139 throws FileNotFoundException { 140 141 try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)))) { 142 if (storeSystemUserName) { 143 writer.format("%s\t%s%n", systemName, userName); 144 } 145 for (int row=0; row <= _numRows; row++) { 146 for (int column=0; column <= _numColumns; column++) { 147 if (column > 0) writer.print("\t"); 148// System.out.format("%d, %d: %s%n", row, column, _data[row][column].toString()); 149 if (_data[row][column] != null) writer.print(_data[row][column].toString()); 150 } 151 writer.println(); 152 } 153 } 154 } 155 156 /** 157 * {@inheritDoc} 158 */ 159 @Override 160 public Object getCell(int row, int column) { 161 return _data[row][column]; 162 } 163 164 /** 165 * {@inheritDoc} 166 */ 167 @Override 168 public void setCell(Object value, int row, int column) { 169 _data[row][column] = value; 170 } 171 172 /** 173 * {@inheritDoc} 174 */ 175 @Override 176 public int numRows() { 177 return _numRows; 178 } 179 180 /** 181 * {@inheritDoc} 182 */ 183 @Override 184 public int numColumns() { 185 return _numColumns; 186 } 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override 192 public int getRowNumber(String rowName) { 193 Integer rowNumber = rowNames.get(rowName); 194 if (rowNumber == null) { 195 try { 196 int row = Integer.parseInt(rowName); 197 if (row >= 0 && row <= _numRows) return row; 198 } catch (NumberFormatException e) { 199 // Do nothing 200 } 201 } else { 202 return rowNumber; 203 } 204 // If here, the row is not found 205 throw new RowNotFoundException(rowName); 206 } 207 208 /** 209 * {@inheritDoc} 210 */ 211 @Override 212 public int getColumnNumber(String columnName) { 213 Integer columnNumber = columnNames.get(columnName); 214 if (columnNumber == null) { 215 try { 216 int column = Integer.parseInt(columnName); 217 if (column >= 0 && column <= _numColumns) return column; 218 } catch (NumberFormatException e) { 219 // Do nothing 220 } 221 } else { 222 return columnNumber; 223 } 224 // If here, the column is not found 225 throw new ColumnNotFoundException(columnName); 226 } 227 228 @Override 229 public void insertColumn(int col) { 230 throw new UnsupportedOperationException("Not supported"); 231 } 232 233 @Override 234 public void deleteColumn(int col) { 235 throw new UnsupportedOperationException("Not supported"); 236 } 237 238 @Override 239 public void insertRow(int row) { 240 throw new UnsupportedOperationException("Not supported"); 241 } 242 243 @Override 244 public void deleteRow(int row) { 245 throw new UnsupportedOperationException("Not supported"); 246 } 247 248}