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