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