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