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 FeatureValue firstValue = firstFeature.getFeatureValue();
072 FeatureValue secondValue = secondFeature.getFeatureValue();
073 FeatureValue thirdValue = thirdFeature.getFeatureValue();
074
075 if (firstValue instanceof SingleFeatureValue && secondValue instanceof SingleFeatureValue && thirdValue instanceof SingleFeatureValue) {
076 String firstSymbol = ((SingleFeatureValue)firstValue).getSymbol();
077 if (firstValue.isNullValue() && secondValue.isNullValue() && 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 (firstValue.isNullValue() || secondValue.isNullValue() || 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 }