001package org.maltparser.core.syntaxgraph.feature;
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.Modifiable;
007import org.maltparser.core.feature.value.FeatureValue;
008import org.maltparser.core.feature.value.SingleFeatureValue;
009import org.maltparser.core.io.dataformat.ColumnDescription;
010import org.maltparser.core.symbol.SymbolTable;
011import org.maltparser.core.symbol.nullvalue.NullValues.NullValueId;
012
013/**
014*
015*
016* @author Johan Hall
017*/
018public abstract class ColumnFeature implements FeatureFunction, Modifiable {
019        protected ColumnDescription column;
020        protected SymbolTable symbolTable;
021        protected final SingleFeatureValue featureValue;
022        
023        public ColumnFeature() throws MaltChainedException {
024                this.featureValue = new SingleFeatureValue(this);
025        }
026        
027        public abstract void update() throws MaltChainedException;
028        public abstract void initialize(Object[] arguments) throws MaltChainedException;
029        public abstract Class<?>[] getParameterTypes();
030        
031        public String getSymbol(int value) throws MaltChainedException {
032                return symbolTable.getSymbolCodeToString(value);
033        }
034        
035        public int getCode(String value) throws MaltChainedException {
036                return symbolTable.getSymbolStringToCode(value);
037        }
038        
039        public ColumnDescription getColumn() {
040                return column;
041        }
042        
043        protected void setColumn(ColumnDescription column) {
044                this.column = column;
045        }
046        
047        public SymbolTable getSymbolTable() {
048                return symbolTable;
049        }
050        
051        protected void setSymbolTable(SymbolTable symbolTable) {
052                this.symbolTable = symbolTable;
053        }
054        
055        public void setFeatureValue(int indexCode) throws MaltChainedException {
056                final String symbol = symbolTable.getSymbolCodeToString(indexCode);
057                
058                if (symbol == null) {
059                        featureValue.update(indexCode, symbolTable.getNullValueSymbol(NullValueId.NO_NODE), true, 1);
060                } else {
061                        boolean nullValue = symbolTable.isNullValue(indexCode);
062                        if (column.getType() == ColumnDescription.STRING || nullValue) {
063                                featureValue.update(indexCode, symbol, nullValue, 1);
064                        } else {
065                                castFeatureValue(symbol);
066                        }
067                }
068        }
069        
070        public void setFeatureValue(String symbol) throws MaltChainedException {
071                final int indexCode = symbolTable.getSymbolStringToCode(symbol);
072                if (indexCode < 0) {
073                        featureValue.update(symbolTable.getNullValueCode(NullValueId.NO_NODE), symbol, true, 1);
074                } else {
075                        boolean nullValue = symbolTable.isNullValue(symbol);
076                        if (column.getType() == ColumnDescription.STRING || nullValue) {
077                                featureValue.update(indexCode, symbol, nullValue, 1);
078                        } else {
079                                castFeatureValue(symbol);
080                        }
081                }
082        }
083        
084        protected void castFeatureValue(String symbol) throws MaltChainedException {
085                if (column.getType() == ColumnDescription.INTEGER) {
086                        try {
087                                final int dotIndex = symbol.indexOf('.');
088                                if (dotIndex == -1) {
089                                        featureValue.setValue(Integer.parseInt(symbol));
090                                        featureValue.setSymbol(symbol);
091                                } else {
092                                        featureValue.setValue(Integer.parseInt(symbol.substring(0,dotIndex)));
093                                        featureValue.setSymbol(symbol.substring(0,dotIndex));
094                                }
095                                featureValue.setNullValue(false);
096                                featureValue.setIndexCode(1);
097                        } catch (NumberFormatException e) {
098                                throw new FeatureException("Could not cast the feature value '"+symbol+"' to integer value.", e);
099                        }
100                } else if (column.getType() == ColumnDescription.BOOLEAN) {
101                        final int dotIndex = symbol.indexOf('.');
102                        if (symbol.equals("1") || symbol.equals("true") ||  symbol.equals("#true#") || (dotIndex != -1 && symbol.substring(0,dotIndex).equals("1"))) {
103                                featureValue.setValue(1);
104                                featureValue.setSymbol("true");
105                        } else if (symbol.equals("false") || symbol.equals("0") || (dotIndex != -1 && symbol.substring(0,dotIndex).equals("0"))) {
106                                featureValue.setValue(0);
107                                featureValue.setSymbol("false");
108                        } else {
109                                throw new FeatureException("Could not cast the feature value '"+symbol+"' to boolean value.");
110                        }
111                        featureValue.setNullValue(false);
112                        featureValue.setIndexCode(1);
113                } else if (column.getType() == ColumnDescription.REAL) {
114                        try {
115                                featureValue.setValue(Double.parseDouble(symbol));
116//                              featureValue.setValue(symbolTable.getSymbolStringToValue(symbol));
117                                featureValue.setSymbol(symbol);
118                        } catch (NumberFormatException e) {
119                                throw new FeatureException("Could not cast the feature value '"+symbol+"' to real value.", e);
120                        }
121                        featureValue.setNullValue(false);
122                        featureValue.setIndexCode(1);
123                }
124        }
125        
126        public FeatureValue getFeatureValue() {
127                return featureValue;
128        }
129        
130        public boolean equals(Object obj) {
131                if (this == obj)
132                        return true;
133                if (obj == null)
134                        return false;
135                if (getClass() != obj.getClass())
136                        return false;
137                return obj.toString().equals(this.toString());
138        }
139
140        public String getColumnName() {
141                return column.getName();
142        }
143        
144        public  int getType() {
145                return column.getType();
146        }
147        
148        public String getMapIdentifier() {
149                return getSymbolTable().getName();
150        }
151        
152        public String toString() {
153                return column.getName();
154        }
155}