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 }