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