    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    }