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