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 }