001 package org.maltparser.core.feature.map; 002 003 import org.maltparser.core.exception.MaltChainedException; 004 import org.maltparser.core.feature.FeatureException; 005 import org.maltparser.core.feature.function.FeatureFunction; 006 import org.maltparser.core.feature.function.FeatureMapFunction; 007 import org.maltparser.core.feature.value.FeatureValue; 008 import org.maltparser.core.feature.value.FunctionValue; 009 import org.maltparser.core.feature.value.SingleFeatureValue; 010 import org.maltparser.core.io.dataformat.ColumnDescription; 011 import org.maltparser.core.io.dataformat.DataFormatInstance; 012 import org.maltparser.core.symbol.SymbolTable; 013 import org.maltparser.core.symbol.SymbolTableHandler; 014 /** 015 * 016 * 017 * @author Johan Hall 018 */ 019 public class Merge3Feature implements FeatureMapFunction { 020 protected FeatureFunction firstFeature; 021 protected FeatureFunction secondFeature; 022 protected FeatureFunction thirdFeature; 023 protected DataFormatInstance dataFormatInstance; 024 protected SymbolTable table; 025 protected ColumnDescription column; 026 protected SingleFeatureValue singleFeatureValue; 027 028 public Merge3Feature(DataFormatInstance dataFormatInstance) throws MaltChainedException { 029 super(); 030 setDataFormatInstance(dataFormatInstance); 031 singleFeatureValue = new SingleFeatureValue(this); 032 } 033 034 public void initialize(Object[] arguments) throws MaltChainedException { 035 if (arguments.length != 3) { 036 throw new FeatureException("Could not initialize Merge3Feature: number of arguments are not correct. "); 037 } 038 if (!(arguments[0] instanceof FeatureFunction)) { 039 throw new FeatureException("Could not initialize Merge3Feature: the first argument is not a feature. "); 040 } 041 if (!(arguments[1] instanceof FeatureFunction)) { 042 throw new FeatureException("Could not initialize Merge3Feature: the second argument is not a feature. "); 043 } 044 if (!(arguments[2] instanceof FeatureFunction)) { 045 throw new FeatureException("Could not initialize Merge3Feature: the third argument is not a feature. "); 046 } 047 setFirstFeature((FeatureFunction)arguments[0]); 048 setSecondFeature((FeatureFunction)arguments[1]); 049 setThirdFeature((FeatureFunction)arguments[2]); 050 ColumnDescription firstColumn = dataFormatInstance.getColumnDescriptionByName(firstFeature.getSymbolTable().getName()); 051 ColumnDescription secondColumn = dataFormatInstance.getColumnDescriptionByName(secondFeature.getSymbolTable().getName()); 052 ColumnDescription thirdColumn = dataFormatInstance.getColumnDescriptionByName(thirdFeature.getSymbolTable().getName()); 053 if (firstColumn.getType() != secondColumn.getType() || firstColumn.getType() != thirdColumn.getType()) { 054 throw new FeatureException("Could not initialize MergeFeature: the arguments are not of the same type."); 055 } 056 // setSymbolTable(tableHandler.addSymbolTable("MERGE3_"+firstFeature.getSymbolTable().getName()+"_"+secondFeature.getSymbolTable().getName()+"_"+thirdFeature.getSymbolTable().getName(), 057 // firstFeature.getSymbolTable())); 058 059 setColumn(dataFormatInstance.addInternalColumnDescription("MERGE3_"+firstFeature.getSymbolTable().getName()+"_"+secondFeature.getSymbolTable().getName()+"_"+thirdFeature.getSymbolTable().getName(), firstColumn)); 060 setSymbolTable(column.getSymbolTable()); 061 } 062 063 public void update() throws MaltChainedException { 064 singleFeatureValue.reset(); 065 firstFeature.update(); 066 secondFeature.update(); 067 thirdFeature.update(); 068 FunctionValue firstValue = firstFeature.getFeatureValue(); 069 FunctionValue secondValue = secondFeature.getFeatureValue(); 070 FunctionValue thirdValue = thirdFeature.getFeatureValue(); 071 072 if (firstValue instanceof SingleFeatureValue && secondValue instanceof SingleFeatureValue && thirdValue instanceof SingleFeatureValue) { 073 String firstSymbol = ((SingleFeatureValue)firstValue).getSymbol(); 074 if (((FeatureValue)firstValue).isNullValue() && ((FeatureValue)secondValue).isNullValue() && ((FeatureValue)thirdValue).isNullValue()) { 075 singleFeatureValue.setIndexCode(firstFeature.getSymbolTable().getSymbolStringToCode(firstSymbol)); 076 singleFeatureValue.setSymbol(firstSymbol); 077 singleFeatureValue.setNullValue(true); 078 } else { 079 if (column.getType() == ColumnDescription.STRING) { 080 StringBuilder mergedValue = new StringBuilder(); 081 mergedValue.append(((SingleFeatureValue)firstValue).getSymbol()); 082 mergedValue.append('~'); 083 mergedValue.append(((SingleFeatureValue)secondValue).getSymbol()); 084 mergedValue.append('~'); 085 mergedValue.append(((SingleFeatureValue)thirdValue).getSymbol()); 086 singleFeatureValue.setIndexCode(table.addSymbol(mergedValue.toString())); 087 singleFeatureValue.setSymbol(mergedValue.toString()); 088 singleFeatureValue.setNullValue(false); 089 singleFeatureValue.setValue(1); 090 } else { 091 if (((FeatureValue)firstValue).isNullValue() || ((FeatureValue)secondValue).isNullValue() || ((FeatureValue)thirdValue).isNullValue()) { 092 singleFeatureValue.setValue(0); 093 table.addSymbol("#null#"); 094 singleFeatureValue.setSymbol("#null#"); 095 singleFeatureValue.setNullValue(true); 096 singleFeatureValue.setIndexCode(1); 097 } else { 098 if (column.getType() == ColumnDescription.BOOLEAN) { 099 boolean result = false; 100 int dotIndex = firstSymbol.indexOf('.'); 101 result = firstSymbol.equals("1") || firstSymbol.equals("true") || firstSymbol.equals("#true#") || (dotIndex != -1 && firstSymbol.substring(0,dotIndex).equals("1")); 102 if (result == true) { 103 String secondSymbol = ((SingleFeatureValue)secondValue).getSymbol(); 104 dotIndex = secondSymbol.indexOf('.'); 105 result = secondSymbol.equals("1") || secondSymbol.equals("true") || secondSymbol.equals("#true#") || (dotIndex != -1 && secondSymbol.substring(0,dotIndex).equals("1")); 106 } 107 if (result == true) { 108 String thirdSymbol = ((SingleFeatureValue)thirdValue).getSymbol(); 109 dotIndex = thirdSymbol.indexOf('.'); 110 result = thirdSymbol.equals("1") || thirdSymbol.equals("true") || thirdSymbol.equals("#true#") || (dotIndex != -1 && thirdSymbol.substring(0,dotIndex).equals("1")); 111 } 112 if (result) { 113 singleFeatureValue.setValue(1); 114 table.addSymbol("true"); 115 singleFeatureValue.setSymbol("true"); 116 } else { 117 singleFeatureValue.setValue(0); 118 table.addSymbol("false"); 119 singleFeatureValue.setSymbol("false"); 120 } 121 } else if (column.getType() == ColumnDescription.INTEGER) { 122 Integer firstInt = 0; 123 Integer secondInt = 0; 124 Integer thirdInt = 0; 125 126 try { 127 int dotIndex = firstSymbol.indexOf('.'); 128 if (dotIndex == -1) { 129 firstInt = Integer.parseInt(firstSymbol); 130 } else { 131 firstInt = Integer.parseInt(firstSymbol.substring(0,dotIndex)); 132 } 133 } catch (NumberFormatException e) { 134 throw new FeatureException("Could not cast the feature value '"+firstSymbol+"' to integer value.", e); 135 } 136 String secondSymbol = ((SingleFeatureValue)secondValue).getSymbol(); 137 try { 138 int dotIndex = secondSymbol.indexOf('.'); 139 if (dotIndex == -1) { 140 secondInt = Integer.parseInt(secondSymbol); 141 } else { 142 secondInt = Integer.parseInt(secondSymbol.substring(0,dotIndex)); 143 } 144 } catch (NumberFormatException e) { 145 throw new FeatureException("Could not cast the feature value '"+secondSymbol+"' to integer value.", e); 146 } 147 String thirdSymbol = ((SingleFeatureValue)thirdValue).getSymbol(); 148 try { 149 int dotIndex = thirdSymbol.indexOf('.'); 150 if (dotIndex == -1) { 151 secondInt = Integer.parseInt(thirdSymbol); 152 } else { 153 secondInt = Integer.parseInt(thirdSymbol.substring(0,dotIndex)); 154 } 155 } catch (NumberFormatException e) { 156 throw new FeatureException("Could not cast the feature value '"+thirdSymbol+"' to integer value.", e); 157 } 158 Integer result = firstInt*secondInt*thirdInt; 159 singleFeatureValue.setValue(result); 160 table.addSymbol(result.toString()); 161 singleFeatureValue.setSymbol(result.toString()); 162 } else if (column.getType() == ColumnDescription.REAL) { 163 Double firstReal = 0.0; 164 Double secondReal = 0.0; 165 Double thirdReal = 0.0; 166 try { 167 firstReal = Double.parseDouble(firstSymbol); 168 } catch (NumberFormatException e) { 169 throw new FeatureException("Could not cast the feature value '"+firstSymbol+"' to real value.", e); 170 } 171 String secondSymbol = ((SingleFeatureValue)secondValue).getSymbol(); 172 try { 173 secondReal = Double.parseDouble(secondSymbol); 174 } catch (NumberFormatException e) { 175 throw new FeatureException("Could not cast the feature value '"+secondSymbol+"' to real value.", e); 176 } 177 String thirdSymbol = ((SingleFeatureValue)thirdValue).getSymbol(); 178 try { 179 thirdReal = Double.parseDouble(thirdSymbol); 180 } catch (NumberFormatException e) { 181 throw new FeatureException("Could not cast the feature value '"+thirdSymbol+"' to real value.", e); 182 } 183 Double result = firstReal*secondReal*thirdReal; 184 singleFeatureValue.setValue(result); 185 table.addSymbol(result.toString()); 186 singleFeatureValue.setSymbol(result.toString()); 187 } 188 singleFeatureValue.setNullValue(false); 189 singleFeatureValue.setIndexCode(1); 190 } 191 } 192 } 193 } else { 194 throw new FeatureException("It is not possible to merge Split-features. "); 195 } 196 } 197 198 public Class<?>[] getParameterTypes() { 199 Class<?>[] paramTypes = { org.maltparser.core.feature.function.FeatureFunction.class, 200 org.maltparser.core.feature.function.FeatureFunction.class, 201 org.maltparser.core.feature.function.FeatureFunction.class }; 202 return paramTypes; 203 } 204 205 public FeatureValue getFeatureValue() { 206 return singleFeatureValue; 207 } 208 209 public String getSymbol(int code) throws MaltChainedException { 210 return table.getSymbolCodeToString(code); 211 } 212 213 public int getCode(String symbol) throws MaltChainedException { 214 return table.getSymbolStringToCode(symbol); 215 } 216 217 public void updateCardinality() throws MaltChainedException { 218 // firstFeature.updateCardinality(); 219 // secondFeature.updateCardinality(); 220 // thirdFeature.updateCardinality(); 221 // singleFeatureValue.setCardinality(table.getValueCounter()); 222 } 223 224 public FeatureFunction getFirstFeature() { 225 return firstFeature; 226 } 227 228 public void setFirstFeature(FeatureFunction firstFeature) { 229 this.firstFeature = firstFeature; 230 } 231 232 public FeatureFunction getSecondFeature() { 233 return secondFeature; 234 } 235 236 public void setSecondFeature(FeatureFunction secondFeature) { 237 this.secondFeature = secondFeature; 238 } 239 240 public FeatureFunction getThirdFeature() { 241 return thirdFeature; 242 } 243 244 public void setThirdFeature(FeatureFunction thirdFeature) { 245 this.thirdFeature = thirdFeature; 246 } 247 248 public SymbolTableHandler getTableHandler() { 249 return dataFormatInstance.getSymbolTables(); 250 } 251 252 public SymbolTable getSymbolTable() { 253 return table; 254 } 255 256 public void setSymbolTable(SymbolTable table) { 257 this.table = table; 258 } 259 260 public ColumnDescription getColumn() { 261 return column; 262 } 263 264 protected void setColumn(ColumnDescription column) { 265 this.column = column; 266 } 267 268 public DataFormatInstance getDataFormatInstance() { 269 return dataFormatInstance; 270 } 271 272 public void setDataFormatInstance(DataFormatInstance dataFormatInstance) { 273 this.dataFormatInstance = dataFormatInstance; 274 } 275 276 public boolean equals(Object obj) { 277 if (this == obj) 278 return true; 279 if (obj == null) 280 return false; 281 if (getClass() != obj.getClass()) 282 return false; 283 return obj.toString().equals(this.toString()); 284 } 285 286 public String toString() { 287 final StringBuilder sb = new StringBuilder(); 288 sb.append("Merge3("); 289 sb.append(firstFeature.toString()); 290 sb.append(", "); 291 sb.append(secondFeature.toString()); 292 sb.append(", "); 293 sb.append(thirdFeature.toString()); 294 sb.append(')'); 295 return sb.toString(); 296 } 297 }