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(@Nonnull File file) 098 throws FileNotFoundException { 099 storeTableAsCSV(file, null, null); 100 } 101 102 /** 103 * {@inheritDoc} 104 */ 105 @Override 106 public void storeTableAsCSV( 107 @Nonnull File file, 108 @CheckForNull String systemName, @CheckForNull String userName) 109 throws FileNotFoundException { 110 111 try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)))) { 112 writer.format("%s\t%s%n", systemName, userName); 113 for (int row=0; row <= _numRows; row++) { 114 for (int column=0; column <= _numColumns; column++) { 115 if (column > 0) writer.print("\t"); 116// System.out.format("%d, %d: %s%n", row, column, _data[row][column].toString()); 117 if (_data[row][column] != null) writer.print(_data[row][column].toString()); 118 } 119 writer.println(); 120 } 121 } 122 } 123 124 /** 125 * {@inheritDoc} 126 */ 127 @Override 128 public Object getCell(int row, int column) { 129 return _data[row][column]; 130 } 131 132 /** 133 * {@inheritDoc} 134 */ 135 @Override 136 public void setCell(Object value, int row, int column) { 137 _data[row][column] = value; 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 @Override 144 public int numRows() { 145 return _numRows; 146 } 147 148 /** 149 * {@inheritDoc} 150 */ 151 @Override 152 public int numColumns() { 153 return _numColumns; 154 } 155 156 /** 157 * {@inheritDoc} 158 */ 159 @Override 160 public int getRowNumber(String rowName) { 161 Integer rowNumber = rowNames.get(rowName); 162 if (rowNumber == null) { 163 try { 164 int row = Integer.parseInt(rowName); 165 if (row >= 0 && row <= _numRows) return row; 166 } catch (NumberFormatException e) { 167 // Do nothing 168 } 169 } else { 170 return rowNumber; 171 } 172 // If here, the row is not found 173 throw new RowNotFoundException(rowName); 174 } 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override 180 public int getColumnNumber(String columnName) { 181 Integer columnNumber = columnNames.get(columnName); 182 if (columnNumber == null) { 183 try { 184 int column = Integer.parseInt(columnName); 185 if (column >= 0 && column <= _numColumns) return column; 186 } catch (NumberFormatException e) { 187 // Do nothing 188 } 189 } else { 190 return columnNumber; 191 } 192 // If here, the column is not found 193 throw new ColumnNotFoundException(columnName); 194 } 195 196 @Override 197 public void insertColumn(int col) { 198 throw new UnsupportedOperationException("Not supported"); 199 } 200 201 @Override 202 public void deleteColumn(int col) { 203 throw new UnsupportedOperationException("Not supported"); 204 } 205 206 @Override 207 public void insertRow(int row) { 208 throw new UnsupportedOperationException("Not supported"); 209 } 210 211 @Override 212 public void deleteRow(int row) { 213 throw new UnsupportedOperationException("Not supported"); 214 } 215 216}