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