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