001    package org.maltparser.parser.history;
002    
003    import java.util.ArrayList;
004    import java.util.HashMap;
005    
006    import org.maltparser.core.exception.MaltChainedException;
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    }