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