001package org.maltparser.parser.history.container; 002 003import java.util.List; 004 005import org.maltparser.core.exception.MaltChainedException; 006import org.maltparser.core.symbol.Table; 007import org.maltparser.core.symbol.TableHandler; 008/** 009* 010* @author Johan Hall 011**/ 012public class CombinedTableContainer extends TableContainer implements Table { 013 private final TableHandler tableHandler; 014 private final char separator; 015 private final TableContainer[] containers; 016 private final StringBuilder[] cachedSymbols; 017 private final int[] cachedCodes; 018 019 public CombinedTableContainer(TableHandler _tableHandler, String _separator, List<TableContainer> _containers, char decisionSeparator) throws MaltChainedException { 020 super(null, null, decisionSeparator); 021 this.tableHandler = _tableHandler; 022 if (_separator.length() > 0) { 023 this.separator = _separator.charAt(0); 024 } else { 025 this.separator = '~'; 026 }; 027 this.containers = new TableContainer[_containers.size()]; 028 for (int i = 0; i < _containers.size(); i++) { 029 this.containers[i] = _containers.get(i); 030 } 031 032 final StringBuilder sb = new StringBuilder(); 033 for (int i = 0; i < this.containers.length; i++) { 034 sb.append(this.containers[i].getTableContainerName()); 035 sb.append('+'); 036 } 037 sb.setLength(sb.length()-1); 038 setTable((Table)tableHandler.addSymbolTable(sb.toString())); 039 setName(sb.toString()); 040 041 cachedSymbols = new StringBuilder[containers.length]; 042 cachedCodes = new int[containers.length]; 043 for (int i = 0; i < containers.length; i++) { 044 cachedCodes[i] = -1; 045 cachedSymbols[i] = new StringBuilder(); 046 }; 047 } 048 049 public void clearCache() { 050 super.clearCache(); 051 for (int i = 0; i < cachedCodes.length; i++) { 052 cachedCodes[i] = -1; 053 } 054 for (int i = 0; i < cachedSymbols.length; i++) { 055 cachedSymbols[i].setLength(0); 056 } 057 } 058 059 public int addSymbol(String value) throws MaltChainedException { 060 return table.addSymbol(value); 061 } 062 063 public String getName() { 064 return table.getName(); 065 } 066 067 public String getSymbolCodeToString(int code) 068 throws MaltChainedException { 069 return table.getSymbolCodeToString(code); 070 } 071 072 public int getSymbolStringToCode(String symbol) throws MaltChainedException { 073 return table.getSymbolStringToCode(symbol); 074 } 075 076 public double getSymbolStringToValue(String symbol) throws MaltChainedException { 077 return table.getSymbolStringToCode(symbol); 078 } 079 080 public int getNumberContainers() { 081 return containers.length; 082 } 083 084 085 /* override TableContainer */ 086 public String getSymbol(int code) throws MaltChainedException { 087 if (code < 0 && !containCode(code)) { 088 clearCache(); 089 return null; 090 } 091 if (cachedCode != code) { 092 clearCache(); 093 cachedCode = code; 094 cachedSymbol.append(table.getSymbolCodeToString(cachedCode)); 095 split(); 096 } 097 return cachedSymbol.toString(); 098 } 099 100 public int getCode(String symbol) throws MaltChainedException { 101 if (cachedSymbol == null || !cachedSymbol.equals(symbol)) { 102 clearCache(); 103 cachedSymbol.append(symbol); 104 cachedCode = table.getSymbolStringToCode(symbol); 105 split(); 106 } 107 return cachedCode; 108 } 109 110 public boolean containCode(int code) throws MaltChainedException { 111 if (cachedCode != code) { 112 clearCache(); 113 cachedSymbol.append(table.getSymbolCodeToString(code)); 114 if (cachedSymbol == null && cachedSymbol.length() == 0) { 115 return false; 116 } 117 cachedCode = code; 118 split(); 119 } 120 return true; 121 } 122 123 public boolean containSymbol(String symbol) throws MaltChainedException { 124 if (cachedSymbol == null || !cachedSymbol.equals(symbol)) { 125 clearCache(); 126 cachedCode = table.getSymbolStringToCode(symbol); 127 if (cachedCode < 0) { 128 return false; 129 } 130 cachedSymbol.append(symbol); 131 split(); 132 } 133 return true; 134 } 135 136 public int getCombinedCode(List<ActionContainer> codesToCombine) throws MaltChainedException { 137 boolean cachedUsed = true; 138 if (containers.length != codesToCombine.size()) { 139 clearCache(); 140 return -1; 141 } 142 143 for (int i = 0; i < containers.length; i++) { 144 if (codesToCombine.get(i).getActionCode() != cachedCodes[i]) { 145 cachedUsed = false; 146 if (codesToCombine.get(i).getActionCode() >= 0 && containers[i].containCode(codesToCombine.get(i).getActionCode())) { 147 cachedSymbols[i].setLength(0); 148 cachedSymbols[i].append(containers[i].getSymbol(codesToCombine.get(i).getActionCode())); 149 cachedCodes[i] = codesToCombine.get(i).getActionCode(); 150 } else { 151 cachedSymbols[i].setLength(0); 152 cachedCodes[i] = -1; 153 } 154 } 155 } 156 157 if (!cachedUsed) { 158 cachedSymbol.setLength(0); 159 for (int i = 0; i < containers.length; i++) { 160 if (cachedSymbols[i].length() != 0) { 161 cachedSymbol.append(cachedSymbols[i]); 162 cachedSymbol.append(separator); 163 } 164 } 165 if (cachedSymbol.length() > 0) { 166 cachedSymbol.setLength(cachedSymbol.length()-1); 167 } 168 if (cachedSymbol.length() > 0) { 169 cachedCode = table.addSymbol(cachedSymbol.toString()); 170 } else { 171 cachedCode = -1; 172 } 173 } 174 return cachedCode; 175 } 176 177 public int getCombinedCode(ActionContainer[] codesToCombine, int start) throws MaltChainedException { 178 boolean cachedUsed = true; 179 if (start < 0 || containers.length > (codesToCombine.length - start)) { 180 clearCache(); 181 return -1; 182 } 183 184 for (int i = 0; i < containers.length; i++) { 185 int code = codesToCombine[i+start].getActionCode(); 186 if (code != cachedCodes[i]) { 187 cachedUsed = false; 188 if (code >= 0 && containers[i].containCode(code)) { 189 cachedSymbols[i].setLength(0); 190 cachedSymbols[i].append(containers[i].getSymbol(code)); 191 cachedCodes[i] = code; 192 } else { 193 cachedSymbols[i].setLength(0); 194 cachedCodes[i] = -1; 195 } 196 } 197 } 198 199 if (!cachedUsed) { 200 cachedSymbol.setLength(0); 201 for (int i = 0; i < containers.length; i++) { 202 if (cachedSymbols[i].length() != 0) { 203 cachedSymbol.append(cachedSymbols[i]); 204 cachedSymbol.append(separator); 205 } 206 } 207 if (cachedSymbol.length() > 0) { 208 cachedSymbol.setLength(cachedSymbol.length()-1); 209 } 210 if (cachedSymbol.length() > 0) { 211 cachedCode = table.addSymbol(cachedSymbol.toString()); 212 } else { 213 cachedCode = -1; 214 } 215 } 216 return cachedCode; 217 } 218 219 220 public void setActionContainer(List<ActionContainer> actionContainers, int decision) throws MaltChainedException { 221 if (decision != cachedCode) { 222 clearCache(); 223 if (decision != -1) { 224 cachedSymbol.append(table.getSymbolCodeToString(decision)); 225 cachedCode = decision; 226 } 227 split(); 228 } 229 230 for (int i = 0; i < containers.length; i++) { 231 if (cachedSymbols[i].length() != 0) { 232 cachedCodes[i] = actionContainers.get(i).setAction(cachedSymbols[i].toString()); 233 } else { 234 cachedCodes[i] = actionContainers.get(i).setAction(null); 235 } 236 } 237 } 238 239 public void setActionContainer(ActionContainer[] actionContainers, int start, int decision) throws MaltChainedException { 240 if (decision != cachedCode) { 241 clearCache(); 242 if (decision != -1) { 243 cachedSymbol.append(table.getSymbolCodeToString(decision)); 244 cachedCode = decision; 245 } 246 split(); 247 } 248 249 for (int i = 0; i < containers.length; i++) { 250 if (cachedSymbols[i].length() != 0) { 251 cachedCodes[i] = actionContainers[i+start].setAction(cachedSymbols[i].toString()); 252 } else { 253 cachedCodes[i] = actionContainers[i+start].setAction(null); 254 } 255 } 256 } 257 258 protected void split() throws MaltChainedException { 259 int j = 0; 260 for (int i = 0; i < containers.length; i++) { 261 cachedSymbols[i].setLength(0); 262 } 263 for (int i = 0; i < cachedSymbol.length(); i++) { 264 if (cachedSymbol.charAt(i) == separator) { 265 j++; 266 } else { 267 cachedSymbols[j].append(cachedSymbol.charAt(i)); 268 } 269 } 270 for (int i = j+1; i < containers.length; i++) { 271 cachedSymbols[i].setLength(0); 272 } 273 for (int i = 0; i < containers.length; i++) { 274 if (cachedSymbols[i].length() != 0) { 275 cachedCodes[i] = containers[i].getCode(cachedSymbols[i].toString()); 276 } else { 277 cachedCodes[i] = -1; 278 } 279 } 280 } 281 282 public char getSeparator() { 283 return separator; 284 } 285 286 protected void initSymbolTable() throws MaltChainedException { 287 288 } 289}