    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    }