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