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.symbol.SymbolTable;
011    import org.maltparser.core.symbol.SymbolTableHandler;
012    /**
013    *
014    *
015    * @author Johan Hall
016    */
017    public class Merge3Feature implements FeatureMapFunction {
018            protected FeatureFunction firstFeature;
019            protected FeatureFunction secondFeature;
020            protected FeatureFunction thirdFeature;
021            protected SymbolTableHandler tableHandler;
022            protected SymbolTable table;
023            protected SingleFeatureValue singleFeatureValue;
024            
025            public Merge3Feature(SymbolTableHandler tableHandler) throws MaltChainedException {
026                    super();
027                    setTableHandler(tableHandler);
028                    singleFeatureValue = new SingleFeatureValue(this);
029            }
030            
031            public void initialize(Object[] arguments) throws MaltChainedException {
032                    if (arguments.length != 3) {
033                            throw new FeatureException("Could not initialize Merge3Feature: number of arguments are not correct. ");
034                    }
035                    if (!(arguments[0] instanceof FeatureFunction)) {
036                            throw new FeatureException("Could not initialize Merge3Feature: the first argument is not a feature. ");
037                    }
038                    if (!(arguments[1] instanceof FeatureFunction)) {
039                            throw new FeatureException("Could not initialize Merge3Feature: the second argument is not a feature. ");
040                    }
041                    if (!(arguments[2] instanceof FeatureFunction)) {
042                            throw new FeatureException("Could not initialize Merge3Feature: the third argument is not a feature. ");
043                    }
044                    setFirstFeature((FeatureFunction)arguments[0]);
045                    setSecondFeature((FeatureFunction)arguments[1]);
046                    setThirdFeature((FeatureFunction)arguments[2]);
047                    setSymbolTable(tableHandler.addSymbolTable("MERGE3_"+firstFeature.getSymbolTable().getName()+"_"+secondFeature.getSymbolTable().getName()+"_"+thirdFeature.getSymbolTable().getName(), 
048                                    firstFeature.getSymbolTable()));
049            }
050            
051            public void update() throws MaltChainedException {
052                    singleFeatureValue.reset();
053                    firstFeature.update();
054                    secondFeature.update();
055                    thirdFeature.update();
056                    FunctionValue firstValue = firstFeature.getFeatureValue();
057                    FunctionValue secondValue = secondFeature.getFeatureValue();
058                    FunctionValue thirdValue = thirdFeature.getFeatureValue();
059                    if (firstValue instanceof SingleFeatureValue && secondValue instanceof SingleFeatureValue && thirdValue instanceof SingleFeatureValue) {
060                            String symbol = ((SingleFeatureValue)firstValue).getSymbol();
061                            if (((FeatureValue)firstValue).isNullValue() && ((FeatureValue)secondValue).isNullValue() && ((FeatureValue)thirdValue).isNullValue()) {
062                                    singleFeatureValue.setCode(firstFeature.getSymbolTable().getSymbolStringToCode(symbol));
063                                    singleFeatureValue.setKnown(firstFeature.getSymbolTable().getKnown(symbol));
064                                    singleFeatureValue.setSymbol(symbol);
065                                    singleFeatureValue.setNullValue(true);
066                            } else {
067                                    StringBuilder mergedValue = new StringBuilder();
068                                    mergedValue.append(((SingleFeatureValue)firstValue).getSymbol());
069                                    mergedValue.append('~');
070                                    mergedValue.append(((SingleFeatureValue)secondValue).getSymbol());
071                                    mergedValue.append('~');
072                                    mergedValue.append(((SingleFeatureValue)thirdValue).getSymbol());
073                                    singleFeatureValue.setCode(table.addSymbol(mergedValue.toString()));
074                                    singleFeatureValue.setKnown(table.getKnown(mergedValue.toString()));
075                                    singleFeatureValue.setSymbol(mergedValue.toString());
076                                    singleFeatureValue.setNullValue(false);
077                            }
078                    } else {
079                            throw new FeatureException("It is not possible to merge Split features. ");
080                    }
081            }
082            
083            public Class<?>[] getParameterTypes() {
084                    Class<?>[] paramTypes = {         org.maltparser.core.feature.function.FeatureFunction.class, 
085                                    org.maltparser.core.feature.function.FeatureFunction.class, 
086                                    org.maltparser.core.feature.function.FeatureFunction.class };
087                    return paramTypes; 
088            }
089    
090            public FeatureValue getFeatureValue() {
091                    return singleFeatureValue;
092            }
093    
094            public String getSymbol(int code) throws MaltChainedException {
095                    return table.getSymbolCodeToString(code);
096            }
097            
098            public int getCode(String symbol) throws MaltChainedException {
099                    return table.getSymbolStringToCode(symbol);
100            }
101            
102            public void updateCardinality() throws MaltChainedException {
103                    firstFeature.updateCardinality();
104                    secondFeature.updateCardinality();
105                    thirdFeature.updateCardinality();
106                    singleFeatureValue.setCardinality(table.getValueCounter()); 
107            }
108            
109            public FeatureFunction getFirstFeature() {
110                    return firstFeature;
111            }
112    
113            public void setFirstFeature(FeatureFunction firstFeature) {
114                    this.firstFeature = firstFeature;
115            }
116    
117            public FeatureFunction getSecondFeature() {
118                    return secondFeature;
119            }
120    
121            public void setSecondFeature(FeatureFunction secondFeature) {
122                    this.secondFeature = secondFeature;
123            }
124    
125            public FeatureFunction getThirdFeature() {
126                    return thirdFeature;
127            }
128    
129            public void setThirdFeature(FeatureFunction thirdFeature) {
130                    this.thirdFeature = thirdFeature;
131            }
132            
133            public SymbolTableHandler getTableHandler() {
134                    return tableHandler;
135            }
136    
137            public void setTableHandler(SymbolTableHandler tableHandler) {
138                    this.tableHandler = tableHandler;
139            }
140    
141            public SymbolTable getSymbolTable() {
142                    return table;
143            }
144    
145            public void setSymbolTable(SymbolTable table) {
146                    this.table = table;
147            }
148            
149            public boolean equals(Object obj) {
150                    if (this == obj)
151                            return true;
152                    if (obj == null)
153                            return false;
154                    if (getClass() != obj.getClass())
155                            return false;
156                    return obj.toString().equals(this.toString());
157            }
158            
159            public String toString() {
160                    final StringBuilder sb = new StringBuilder();
161                    sb.append("Merge3(");
162                    sb.append(firstFeature.toString());
163                    sb.append(", ");
164                    sb.append(secondFeature.toString());
165                    sb.append(", ");
166                    sb.append(thirdFeature.toString());
167                    sb.append(')');
168                    return sb.toString();
169            }
170    }