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 }