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.MultipleFeatureValue;
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 PrefixFeature implements FeatureMapFunction {
018            protected FeatureFunction parentFeature;
019            protected MultipleFeatureValue multipleFeatureValue;
020            protected SymbolTableHandler tableHandler;
021            protected SymbolTable table;
022            protected int prefixLength;
023    
024            public PrefixFeature(SymbolTableHandler tableHandler) throws MaltChainedException {
025                    super();
026                    setTableHandler(tableHandler);
027                    multipleFeatureValue = new MultipleFeatureValue(this);
028            }
029            
030            public void initialize(Object[] arguments) throws MaltChainedException {
031                    if (arguments.length != 2) {
032                            throw new FeatureException("Could not initialize PrefixFeature: number of arguments are not correct. ");
033                    }
034                    if (!(arguments[0] instanceof FeatureFunction)) {
035                            throw new FeatureException("Could not initialize PrefixFeature: the first argument is not a feature. ");
036                    }
037                    if (!(arguments[1] instanceof Integer)) {
038                            throw new FeatureException("Could not initialize PrefixFeature: the second argument is not a string. ");
039                    }
040                    setParentFeature((FeatureFunction)arguments[0]);
041                    setPrefixLength(((Integer)arguments[1]).intValue());
042                    setSymbolTable(tableHandler.addSymbolTable("PREFIX_"+prefixLength+"_"+parentFeature.getSymbolTable().getName(), parentFeature.getSymbolTable()));
043            }
044            
045            public Class<?>[] getParameterTypes() {
046                    Class<?>[] paramTypes = { org.maltparser.core.syntaxgraph.feature.InputColumnFeature.class, java.lang.Integer.class };
047                    return paramTypes; 
048            }
049            
050            public FeatureValue getFeatureValue() {
051                    return multipleFeatureValue;
052            }
053            
054            public int getCode(String symbol) throws MaltChainedException {
055                    return table.getSymbolStringToCode(symbol);
056            }
057    
058            public String getSymbol(int code) throws MaltChainedException {
059                    return table.getSymbolCodeToString(code);
060            }
061    
062            public void update() throws MaltChainedException {
063                    parentFeature.update();
064                    FeatureValue value = parentFeature.getFeatureValue();
065                    if (value instanceof SingleFeatureValue) {
066                            String symbol = ((SingleFeatureValue)value).getSymbol();
067                            if (((FeatureValue)value).isNullValue()) {
068                                    multipleFeatureValue.addFeatureValue(parentFeature.getSymbolTable().getSymbolStringToCode(symbol), symbol, true);
069                                    multipleFeatureValue.setNullValue(true);
070                            } else {
071                                    String prefixStr;
072                                    if (symbol.length()-prefixLength > 0) {
073                                            prefixStr = symbol.substring(0, prefixLength);
074                                    } else {
075                                            prefixStr = symbol;
076                                    }
077                                    int code = table.addSymbol(prefixStr);
078                                    multipleFeatureValue.addFeatureValue(code, prefixStr, table.getKnown(prefixStr));
079                                    multipleFeatureValue.setNullValue(false);
080                            }
081                    } else if (value instanceof MultipleFeatureValue) {
082                            multipleFeatureValue.reset();
083                            if (((MultipleFeatureValue)value).isNullValue()) {
084                                    multipleFeatureValue.addFeatureValue(parentFeature.getSymbolTable().getSymbolStringToCode(((MultipleFeatureValue)value).getFirstSymbol()), ((MultipleFeatureValue)value).getFirstSymbol(), true);
085                                    multipleFeatureValue.setNullValue(true);
086                            } else {
087                                    for (String symbol : ((MultipleFeatureValue)value).getSymbols()) {
088                                            String prefixStr;
089                                            if (symbol.length()-prefixLength > 0) {
090                                                    prefixStr = symbol.substring(0, prefixLength);
091                                            } else {
092                                                    prefixStr = symbol;
093                                            }
094                                            int code = table.addSymbol(prefixStr);
095                                            multipleFeatureValue.addFeatureValue(code, prefixStr, table.getKnown(prefixStr));
096                                            multipleFeatureValue.setNullValue(true);
097                                    }
098                            }
099                    }
100            }
101            
102            public void updateCardinality() throws MaltChainedException {
103                    parentFeature.updateCardinality();
104                    multipleFeatureValue.setCardinality(table.getValueCounter()); 
105            }
106            
107            public FeatureFunction getParentFeature() {
108                    return parentFeature;
109            } 
110            
111            public void setParentFeature(FeatureFunction feature) {
112                    this.parentFeature = feature;
113            }
114            
115            public int getPrefixLength() {
116                    return prefixLength;
117            }
118    
119            public void setPrefixLength(int prefixLength) {
120                    this.prefixLength = prefixLength;
121            }
122    
123            public SymbolTableHandler getTableHandler() {
124                    return tableHandler;
125            }
126    
127            public void setTableHandler(SymbolTableHandler tableHandler) {
128                    this.tableHandler = tableHandler;
129            }
130    
131            public SymbolTable getSymbolTable() {
132                    return table;
133            }
134    
135            public void setSymbolTable(SymbolTable table) {
136                    this.table = table;
137            }
138    
139            public boolean equals(Object obj) {
140                    if (this == obj)
141                            return true;
142                    if (obj == null)
143                            return false;
144                    if (getClass() != obj.getClass())
145                            return false;
146                    return obj.toString().equals(this.toString());
147            }
148            
149            public String toString() {
150                    final StringBuilder sb = new StringBuilder();
151                    sb.append("Prefix(");
152                    sb.append(parentFeature.toString());
153                    sb.append(", ");
154                    sb.append(prefixLength);
155                    sb.append(')');
156                    return sb.toString();
157            }
158    }
159