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 int getNumberContainers() { 077 return containers.length; 078 } 079 080 081 /* override TableContainer */ 082 public String getSymbol(int code) throws MaltChainedException { 083 if (code < 0 && !containCode(code)) { 084 clearCache(); 085 return null; 086 } 087 if (cachedCode != code) { 088 clearCache(); 089 cachedCode = code; 090 cachedSymbol.append(table.getSymbolCodeToString(cachedCode)); 091 split(); 092 } 093 return cachedSymbol.toString(); 094 } 095 096 public int getCode(String symbol) throws MaltChainedException { 097 if (cachedSymbol == null || !cachedSymbol.equals(symbol)) { 098 clearCache(); 099 cachedSymbol.append(symbol); 100 cachedCode = table.getSymbolStringToCode(symbol); 101 split(); 102 } 103 return cachedCode; 104 } 105 106 public boolean containCode(int code) throws MaltChainedException { 107 if (cachedCode != code) { 108 clearCache(); 109 cachedSymbol.append(table.getSymbolCodeToString(code)); 110 if (cachedSymbol == null && cachedSymbol.length() == 0) { 111 return false; 112 } 113 cachedCode = code; 114 split(); 115 } 116 return true; 117 } 118 119 public boolean containSymbol(String symbol) throws MaltChainedException { 120 if (cachedSymbol == null || !cachedSymbol.equals(symbol)) { 121 clearCache(); 122 cachedCode = table.getSymbolStringToCode(symbol); 123 if (cachedCode < 0) { 124 return false; 125 } 126 cachedSymbol.append(symbol); 127 split(); 128 } 129 return true; 130 } 131 132 public int getCombinedCode(List<ActionContainer> codesToCombine) throws MaltChainedException { 133 boolean cachedUsed = true; 134 if (containers.length != codesToCombine.size()) { 135 clearCache(); 136 return -1; 137 } 138 139 for (int i = 0; i < containers.length; i++) { 140 if (codesToCombine.get(i).getActionCode() != cachedCodes[i]) { 141 cachedUsed = false; 142 if (codesToCombine.get(i).getActionCode() >= 0 && containers[i].containCode(codesToCombine.get(i).getActionCode())) { 143 cachedSymbols[i].setLength(0); 144 cachedSymbols[i].append(containers[i].getSymbol(codesToCombine.get(i).getActionCode())); 145 cachedCodes[i] = codesToCombine.get(i).getActionCode(); 146 } else { 147 cachedSymbols[i].setLength(0); 148 cachedCodes[i] = -1; 149 } 150 } 151 } 152 153 if (!cachedUsed) { 154 cachedSymbol.setLength(0); 155 for (int i = 0; i < containers.length; i++) { 156 if (cachedSymbols[i].length() != 0) { 157 cachedSymbol.append(cachedSymbols[i]); 158 cachedSymbol.append(separator); 159 } 160 } 161 if (cachedSymbol.length() > 0) { 162 cachedSymbol.setLength(cachedSymbol.length()-1); 163 } 164 if (cachedSymbol.length() > 0) { 165 cachedCode = table.addSymbol(cachedSymbol.toString()); 166 } else { 167 cachedCode = -1; 168 } 169 } 170 return cachedCode; 171 } 172 173 public int getCombinedCode(ActionContainer[] codesToCombine, int start) throws MaltChainedException { 174 boolean cachedUsed = true; 175 if (start < 0 || containers.length > (codesToCombine.length - start)) { 176 clearCache(); 177 return -1; 178 } 179 180 for (int i = 0; i < containers.length; i++) { 181 int code = codesToCombine[i+start].getActionCode(); 182 if (code != cachedCodes[i]) { 183 cachedUsed = false; 184 if (code >= 0 && containers[i].containCode(code)) { 185 cachedSymbols[i].setLength(0); 186 cachedSymbols[i].append(containers[i].getSymbol(code)); 187 cachedCodes[i] = code; 188 } else { 189 cachedSymbols[i].setLength(0); 190 cachedCodes[i] = -1; 191 } 192 } 193 } 194 195 if (!cachedUsed) { 196 cachedSymbol.setLength(0); 197 for (int i = 0; i < containers.length; i++) { 198 if (cachedSymbols[i].length() != 0) { 199 cachedSymbol.append(cachedSymbols[i]); 200 cachedSymbol.append(separator); 201 } 202 } 203 if (cachedSymbol.length() > 0) { 204 cachedSymbol.setLength(cachedSymbol.length()-1); 205 } 206 if (cachedSymbol.length() > 0) { 207 cachedCode = table.addSymbol(cachedSymbol.toString()); 208 } else { 209 cachedCode = -1; 210 } 211 } 212 return cachedCode; 213 } 214 215 216 public void setActionContainer(List<ActionContainer> actionContainers, int decision) throws MaltChainedException { 217 if (decision != cachedCode) { 218 clearCache(); 219 if (decision != -1) { 220 cachedSymbol.append(table.getSymbolCodeToString(decision)); 221 cachedCode = decision; 222 } 223 split(); 224 } 225 226 for (int i = 0; i < containers.length; i++) { 227 if (cachedSymbols[i].length() != 0) { 228 cachedCodes[i] = actionContainers.get(i).setAction(cachedSymbols[i].toString()); 229 } else { 230 cachedCodes[i] = actionContainers.get(i).setAction(null); 231 } 232 } 233 } 234 235 public void setActionContainer(ActionContainer[] actionContainers, int start, int decision) throws MaltChainedException { 236 if (decision != cachedCode) { 237 clearCache(); 238 if (decision != -1) { 239 cachedSymbol.append(table.getSymbolCodeToString(decision)); 240 cachedCode = decision; 241 } 242 split(); 243 } 244 245 for (int i = 0; i < containers.length; i++) { 246 if (cachedSymbols[i].length() != 0) { 247 cachedCodes[i] = actionContainers[i+start].setAction(cachedSymbols[i].toString()); 248 } else { 249 cachedCodes[i] = actionContainers[i+start].setAction(null); 250 } 251 } 252 } 253 254 protected void split() throws MaltChainedException { 255 int j = 0; 256 for (int i = 0; i < containers.length; i++) { 257 cachedSymbols[i].setLength(0); 258 } 259 for (int i = 0; i < cachedSymbol.length(); i++) { 260 if (cachedSymbol.charAt(i) == separator) { 261 j++; 262 } else { 263 cachedSymbols[j].append(cachedSymbol.charAt(i)); 264 } 265 } 266 for (int i = j+1; i < containers.length; i++) { 267 cachedSymbols[i].setLength(0); 268 } 269 for (int i = 0; i < containers.length; i++) { 270 if (cachedSymbols[i].length() != 0) { 271 cachedCodes[i] = containers[i].getCode(cachedSymbols[i].toString()); 272 } else { 273 cachedCodes[i] = -1; 274 } 275 } 276 } 277 278 public char getSeparator() { 279 return separator; 280 } 281 282 protected void initSymbolTable() throws MaltChainedException { 283 284 } 285}