    001    package org.maltparser.parser.history;
    002
    003    import java.util.ArrayList;
    004
    005    import org.maltparser.core.exception.MaltChainedException;
    006    import org.maltparser.core.helper.HashMap;
    007    import org.maltparser.core.pool.ObjectPoolList;
    008    import org.maltparser.core.symbol.TableHandler;
    009    import org.maltparser.parser.history.action.ActionDecision;
    010    import org.maltparser.parser.history.action.ComplexDecisionAction;
    011    import org.maltparser.parser.history.action.GuideDecision;
    012    import org.maltparser.parser.history.action.GuideUserAction;
    013    import org.maltparser.parser.history.container.ActionContainer;
    014    import org.maltparser.parser.history.container.CombinedTableContainer;
    015    import org.maltparser.parser.history.container.TableContainer;
    016    import org.maltparser.parser.history.kbest.KBestList;
    017
    018    /**
    019    *
    020    * @author Johan Hall
    021    * @since 1.1
    022    **/
    023    public class History implements GuideUserHistory, GuideHistory {
    024            protected final ObjectPoolList<ComplexDecisionAction> actionPool;
    025            protected Class<? extends KBestList> kBestListClass = null;
    026            protected int kBestSize;
    027            protected String separator = "~";
    028            protected String decisionSettings;
    029            protected ArrayList<TableContainer> decisionTables;
    030            protected ArrayList<TableContainer> actionTables;
    031            protected HashMap<String, TableHandler> tableHandlers;
    032
    033            public History(String decisionSettings, String separator, HashMap<String, TableHandler> tableHandlers) throws MaltChainedException {
    034                    setTableHandlers(tableHandlers);
    035                    setSeparator(separator);
    036                    initDecisionSettings(decisionSettings);
    037                    actionPool = new ObjectPoolList<ComplexDecisionAction>() {
    038                            protected ComplexDecisionAction create() throws MaltChainedException { return new ComplexDecisionAction(getThis()); }
    039                            public void resetObject(ComplexDecisionAction o) throws MaltChainedException { o.clear(); }
    040                    };
    041                    clear();
    042            }
    043
    044            private History getThis() {
    045                    return this;
    046            }
    047
    048            /* GuideUserHistory interface */
    049            public GuideUserAction getEmptyGuideUserAction() throws MaltChainedException {
    050                    return (GuideUserAction)getEmptyActionObject();
    051            }
    052
    053            public ArrayList<ActionContainer> getActionContainers() {
    054                    ArrayList<ActionContainer> actionContainers = new ArrayList<ActionContainer>();
    055                    for (int i=0; i<actionTables.size(); i++) {
    056                            actionContainers.add(new ActionContainer(actionTables.get(i)));
    057                    }
    058                    return actionContainers;
    059            }
    060
    061            public ActionContainer[] getActionContainerArray() {
    062                    ActionContainer[] actionContainers = new ActionContainer[actionTables.size()];
    063                    for (int i=0; i<actionTables.size(); i++) {
    064                            actionContainers[i] = new ActionContainer(actionTables.get(i));
    065                    }
    066                    return actionContainers;
    067            }
    068
    069
    070            public void clear() throws MaltChainedException {
    071                    actionPool.checkInAll();
    072            }
    073
    074    //      public void clear() {
    075    //              currentAction = -1;
    076    //      }
    077
    078            /* GuideHistory interface */
    079            public GuideDecision getEmptyGuideDecision() throws MaltChainedException {
    080                    return (GuideDecision)getEmptyActionObject();
    081            }
    082
    083            public int getNumberOfDecisions() {
    084                    return decisionTables.size();
    085            }
    086
    087            public TableHandler getTableHandler(String name) {
    088                    return tableHandlers.get(name);
    089            }
    090
    091            public Class<? extends KBestList> getKBestListClass() {
    092                    return kBestListClass;
    093            }
    094
    095            public void setKBestListClass(Class<?> kBestListClass) throws MaltChainedException {
    096                    try {
    097                            if (kBestListClass != null) {
    098                                    this.kBestListClass = kBestListClass.asSubclass(org.maltparser.parser.history.kbest.KBestList.class);
    099                            }
    100                    } catch (ClassCastException e) {
    101                            throw new HistoryException("The class '"+kBestListClass.getName()+"' is not a subclass of '"+org.maltparser.parser.history.kbest.KBestList.class.getName()+"'. ", e);
    102                    }
    103            }
    104
    105            public int getKBestSize() {
    106                    return kBestSize;
    107            }
    108
    109            public void setKBestSize(int kBestSize) {
    110                    this.kBestSize = kBestSize;
    111            }
    112
    113            public int getNumberOfActions() {
    114                    return actionTables.size();
    115            }
    116
    117            public ArrayList<TableContainer> getDecisionTables() {
    118                    return decisionTables;
    119            }
    120
    121            public ArrayList<TableContainer> getActionTables() {
    122                    return actionTables;
    123            }
    124
    125            public HashMap<String, TableHandler> getTableHandlers() {
    126                    return tableHandlers;
    127            }
    128
    129            public String getSeparator() {
    130                    return separator;
    131            }
    132
    133            public void setSeparator(String separator) throws MaltChainedException {
    134                    if (separator == null || separator.length() < 1) {
    135                            throw new HistoryException("The class item separator (--guide-classitem_separator) does not have correct value. ");
    136                    }
    137                    this.separator = separator;
    138            }
    139
    140            public String getDecisionSettings() {
    141                    return decisionSettings;
    142            }
    143
    144            public void setDecisionSettings(String decisionSettings) {
    145                    this.decisionSettings = decisionSettings;
    146            }
    147
    148            protected void setTableHandlers(HashMap<String, TableHandler> tableHandlers) {
    149                    this.tableHandlers = tableHandlers;
    150            }
    151
    152            protected ActionDecision getEmptyActionObject() throws MaltChainedException {
    153                    return actionPool.checkOut();
    154            }
    155
    156            protected void initDecisionSettings(String decisionSettings) throws MaltChainedException {
    157                    decisionTables = new ArrayList<TableContainer>();
    158                    actionTables = new ArrayList<TableContainer>();
    159                    this.decisionSettings = decisionSettings;
    160                    int start = 0;
    161                    int k = 0;
    162                    char prevDecisionSeparator = ' ';
    163                    TableContainer tmp = null;
    164                    final StringBuilder sbTableHandler = new StringBuilder();
    165                    final StringBuilder sbTable = new StringBuilder();
    166                    int state = 0;
    167                    for (int i = 0; i < decisionSettings.length(); i++) {
    168                            switch (decisionSettings.charAt(i)) {
    169                            case '.':
    170                                    if (state != 0) {
    171                                            //error
    172                                    }
    173                                    state = 1;
    174                                    break;
    175                            case '+':
    176                                    tmp = new TableContainer(tableHandlers.get(sbTableHandler.toString()).getSymbolTable(sbTable.toString()), sbTableHandler.toString()+"."+sbTable.toString(), '+');
    177                                    actionTables.add(tmp);
    178                                    k++;
    179                                    sbTableHandler.setLength(0);
    180                                    sbTable.setLength(0);
    181                                    state = 0;
    182                                    break;
    183                            case '#':
    184                                    state = 2;
    185                                    break;
    186                            case ';':
    187                                    state = 2;
    188                                    break;
    189                            case ',':
    190                                    state = 2;
    191                                    break;
    192                            default:
    193                                    if (state == 0) {
    194                                            sbTableHandler.append(decisionSettings.charAt(i));
    195                                    } else if (state == 1) {
    196                                            sbTable.append(decisionSettings.charAt(i));
    197                                    }
    198                            }
    199                            if (state == 2 || i == decisionSettings.length()-1) {
    200                                    char decisionSeparator = decisionSettings.charAt(i);
    201                                    if (i == decisionSettings.length()-1) {
    202                                            //decisionSeparator = ' ';
    203                                            decisionSeparator = prevDecisionSeparator;
    204                                    }
    205                                    tmp = new TableContainer(tableHandlers.get(sbTableHandler.toString()).getSymbolTable(sbTable.toString()), sbTableHandler.toString()+"."+sbTable.toString(), decisionSeparator);
    206                                    actionTables.add(tmp);
    207                                    k++;
    208                                    if (k-start > 1) {
    209                                            decisionTables.add(new CombinedTableContainer(getTableHandler("A"), separator, actionTables.subList(start, k), decisionSeparator));
    210                                    } else {
    211                                            decisionTables.add(tmp);
    212                                    }
    213                                    sbTableHandler.setLength(0);
    214                                    sbTable.setLength(0);
    215                                    state = 0;
    216                                    start = k;
    217                                    prevDecisionSeparator = decisionSeparator;
    218                            }
    219                    }
    220            }
    221
    222            public String toString() {
    223                    StringBuilder sb = new StringBuilder();
    224                    return sb.toString();
    225            }
    226    }