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