001package org.maltparser.core.feature.map;
002
003import org.maltparser.core.exception.MaltChainedException;
004import org.maltparser.core.feature.FeatureException;
005import org.maltparser.core.feature.function.FeatureFunction;
006import org.maltparser.core.feature.function.FeatureMapFunction;
007import org.maltparser.core.feature.value.FeatureValue;
008import org.maltparser.core.feature.value.FunctionValue;
009import org.maltparser.core.feature.value.MultipleFeatureValue;
010import org.maltparser.core.feature.value.SingleFeatureValue;
011import org.maltparser.core.io.dataformat.ColumnDescription;
012import org.maltparser.core.io.dataformat.DataFormatInstance;
013import org.maltparser.core.symbol.SymbolTable;
014import org.maltparser.core.symbol.SymbolTableHandler;
015/**
016*
017*
018* @author Johan Hall
019*/
020public final class SuffixFeature implements FeatureMapFunction {
021        public final static Class<?>[] paramTypes = { org.maltparser.core.syntaxgraph.feature.InputColumnFeature.class, java.lang.Integer.class };
022        private FeatureFunction parentFeature;
023        private final MultipleFeatureValue multipleFeatureValue;
024        private final SymbolTableHandler tableHandler;
025        private SymbolTable table;
026        private final DataFormatInstance dataFormatInstance;
027        private ColumnDescription column;
028        private int suffixLength;
029
030        public SuffixFeature(DataFormatInstance dataFormatInstance, SymbolTableHandler tableHandler) throws MaltChainedException {
031                this.dataFormatInstance = dataFormatInstance;
032                this.tableHandler = tableHandler;
033                this.multipleFeatureValue = new MultipleFeatureValue(this);
034        }
035        
036        public void initialize(Object[] arguments) throws MaltChainedException {
037                if (arguments.length != 2) {
038                        throw new FeatureException("Could not initialize SuffixFeature: number of arguments are not correct. ");
039                }
040                if (!(arguments[0] instanceof FeatureFunction)) {
041                        throw new FeatureException("Could not initialize SuffixFeature: the first argument is not a feature. ");
042                }
043                if (!(arguments[1] instanceof Integer)) {
044                        throw new FeatureException("Could not initialize SuffixFeature: the second argument is not a string. ");
045                }
046                setParentFeature((FeatureFunction)arguments[0]);
047                setSuffixLength(((Integer)arguments[1]).intValue());
048                ColumnDescription parentColumn = dataFormatInstance.getColumnDescriptionByName(parentFeature.getSymbolTable().getName());
049                if (parentColumn.getType() != ColumnDescription.STRING) {
050                        throw new FeatureException("Could not initialize SuffixFeature: the first argument must be a string. ");
051                }
052                setColumn(dataFormatInstance.addInternalColumnDescription(tableHandler,"SUFFIX_"+suffixLength+"_"+parentFeature.getSymbolTable().getName(), parentColumn));
053                setSymbolTable(tableHandler.getSymbolTable(column.getName()));
054//              setSymbolTable(tableHandler.addSymbolTable("SUFFIX_"+suffixLength+"_"+parentFeature.getSymbolTable().getName(), parentFeature.getSymbolTable()));
055        }
056        
057        public Class<?>[] getParameterTypes() {
058                return paramTypes; 
059        }
060        
061        public FeatureValue getFeatureValue() {
062                return multipleFeatureValue;
063        }
064        
065        public int getCode(String symbol) throws MaltChainedException {
066                return table.getSymbolStringToCode(symbol);
067        }
068
069        public String getSymbol(int code) throws MaltChainedException {
070                return table.getSymbolCodeToString(code);
071        }
072
073        public void update() throws MaltChainedException {
074                parentFeature.update();
075                FunctionValue value = parentFeature.getFeatureValue();
076                if (value instanceof SingleFeatureValue) {
077                        String symbol = ((SingleFeatureValue)value).getSymbol();
078                        if (((FeatureValue)value).isNullValue()) {
079                                multipleFeatureValue.addFeatureValue(parentFeature.getSymbolTable().getSymbolStringToCode(symbol), symbol);
080                                multipleFeatureValue.setNullValue(true);
081                        } else {
082                                String suffixStr;
083                                if (symbol.length()-suffixLength > 0) {
084                                        suffixStr = symbol.substring(symbol.length()-suffixLength);
085                                } else {
086                                        suffixStr = symbol;
087                                }
088                                int code = table.addSymbol(suffixStr);
089                                multipleFeatureValue.addFeatureValue(code, suffixStr);
090                                multipleFeatureValue.setNullValue(false);
091                        }
092                } else if (value instanceof MultipleFeatureValue) {
093                        multipleFeatureValue.reset();
094                        if (((MultipleFeatureValue)value).isNullValue()) {
095                                multipleFeatureValue.addFeatureValue(parentFeature.getSymbolTable().getSymbolStringToCode(((MultipleFeatureValue)value).getFirstSymbol()), ((MultipleFeatureValue)value).getFirstSymbol());
096                                multipleFeatureValue.setNullValue(true);
097                        } else {
098                                for (String symbol : ((MultipleFeatureValue)value).getSymbols()) {
099                                        String suffixStr;
100                                        if (symbol.length()-suffixLength > 0) {
101                                                suffixStr = symbol.substring(symbol.length()-suffixLength);
102                                        } else {
103                                                suffixStr = symbol;
104                                        }
105                                        int code = table.addSymbol(suffixStr);
106                                        multipleFeatureValue.addFeatureValue(code, suffixStr);
107                                        multipleFeatureValue.setNullValue(true);
108                                }
109                        }
110                }
111        }
112
113        public FeatureFunction getParentFeature() {
114                return parentFeature;
115        } 
116        
117        public void setParentFeature(FeatureFunction feature) {
118                this.parentFeature = feature;
119        }
120        
121        public int getSuffixLength() {
122                return suffixLength;
123        }
124
125        public void setSuffixLength(int suffixLength) {
126                this.suffixLength = suffixLength;
127        }
128
129        public SymbolTableHandler getTableHandler() {
130                return tableHandler;
131        }
132        
133        public SymbolTable getSymbolTable() {
134                return table;
135        }
136
137        public void setSymbolTable(SymbolTable table) {
138                this.table = table;
139        }
140        
141        public DataFormatInstance getDataFormatInstance() {
142                return dataFormatInstance;
143        }
144        
145        public ColumnDescription getColumn() {
146                return column;
147        }
148        
149        protected void setColumn(ColumnDescription column) {
150                this.column = column;
151        }
152        
153        public  int getType() {
154                return column.getType();
155        }
156        
157        public String getMapIdentifier() {
158                return getSymbolTable().getName();
159        }
160        
161        public boolean equals(Object obj) {
162                if (this == obj)
163                        return true;
164                if (obj == null)
165                        return false;
166                if (getClass() != obj.getClass())
167                        return false;
168                return obj.toString().equals(this.toString());
169        }
170        
171        public String toString() {
172                final StringBuilder sb = new StringBuilder();
173                sb.append("Suffix(");
174                sb.append(parentFeature.toString());
175                sb.append(", ");
176                sb.append(suffixLength);
177                sb.append(')');
178                return sb.toString();
179        }
180}