001package org.maltparser.core.syntaxgraph.feature;
002
003import org.maltparser.core.exception.MaltChainedException;
004import org.maltparser.core.feature.function.AddressFunction;
005import org.maltparser.core.feature.function.FeatureFunction;
006import org.maltparser.core.feature.value.FeatureValue;
007import org.maltparser.core.feature.value.SingleFeatureValue;
008import org.maltparser.core.io.dataformat.ColumnDescription;
009import org.maltparser.core.symbol.SymbolTable;
010import org.maltparser.core.symbol.SymbolTableHandler;
011import org.maltparser.core.symbol.nullvalue.NullValues.NullValueId;
012import org.maltparser.core.syntaxgraph.SyntaxGraphException;
013import org.maltparser.core.syntaxgraph.node.DependencyNode;
014
015public final class ArcDirFeature implements FeatureFunction {
016        public final static Class<?>[] paramTypes = { org.maltparser.core.feature.function.AddressFunction.class };
017        private AddressFunction addressFunction;
018        private final SymbolTableHandler tableHandler;
019        private SymbolTable table;
020        private final SingleFeatureValue featureValue;
021        
022        public ArcDirFeature(SymbolTableHandler tableHandler) throws MaltChainedException {
023                this.tableHandler = tableHandler;
024                this.featureValue = new SingleFeatureValue(this);
025        }
026        
027        /**
028         * Initialize the exists feature function
029         * 
030         * @param arguments an array of arguments with the type returned by getParameterTypes()
031         * @throws MaltChainedException
032         */
033        public void initialize(Object[] arguments) throws MaltChainedException {
034                if (arguments.length != 1) {
035                        throw new SyntaxGraphException("Could not initialize ArcDirFeature: number of arguments are not correct. ");
036                }
037                // Checks that the two arguments are address functions
038                if (!(arguments[0] instanceof AddressFunction)) {
039                        throw new SyntaxGraphException("Could not initialize ArcDirFeature: the first argument is not an address function. ");
040                }
041
042                setAddressFunction((AddressFunction)arguments[0]);
043                
044                // Creates a symbol table called "ARCDIR" using one null value
045                setSymbolTable(tableHandler.addSymbolTable("ARCDIR", ColumnDescription.INPUT, "one"));
046                
047                table.addSymbol("LEFT"); // The address exists
048                table.addSymbol("RIGHT"); // The address don't exists
049        }
050        
051        /**
052         * Returns an array of class types used by the feature extraction system to invoke initialize with
053         * correct arguments.
054         * 
055         * @return an array of class types
056         */
057        public Class<?>[] getParameterTypes() {
058                return paramTypes; 
059        }
060        /**
061         * Returns the string representation of the integer <code>code</code> according to the exists feature function. 
062         * 
063         * @param code the integer representation of the symbol
064         * @return the string representation of the integer <code>code</code> according to the exists feature function.
065         * @throws MaltChainedException
066         */
067        public String getSymbol(int code) throws MaltChainedException {
068                return table.getSymbolCodeToString(code);
069        }
070        
071        /**
072         * Returns the integer representation of the string <code>symbol</code> according to the exists feature function.
073         * 
074         * @param symbol the string representation of the symbol
075         * @return the integer representation of the string <code>symbol</code> according to the exists feature function.
076         * @throws MaltChainedException
077         */
078        public int getCode(String symbol) throws MaltChainedException {
079                return table.getSymbolStringToCode(symbol);
080        }
081        
082        /**
083         * Cause the feature function to update the feature value.
084         * 
085         * @throws MaltChainedException
086         */
087        public void update() throws MaltChainedException {
088                if (addressFunction.getAddressValue().getAddress() != null) {
089                        final DependencyNode node = (DependencyNode)addressFunction.getAddressValue().getAddress();
090                        if (!node.isRoot()) { 
091                                if (node.getHead().getIndex() < node.getIndex()) {
092                                        featureValue.setIndexCode(table.getSymbolStringToCode("LEFT"));
093                                        featureValue.setValue(1);
094                                        featureValue.setSymbol("LEFT");
095                                        featureValue.setNullValue(false);
096                                } else {
097                                        featureValue.setIndexCode(table.getSymbolStringToCode("RIGHT"));
098                                        featureValue.setValue(1);
099                                        featureValue.setSymbol("RIGHT");
100                                        featureValue.setNullValue(false);
101                                }
102                        } else { 
103                                featureValue.setIndexCode(table.getNullValueCode(NullValueId.ROOT_NODE));
104                                featureValue.setValue(1);
105                                featureValue.setSymbol(table.getNullValueSymbol(NullValueId.ROOT_NODE));
106                                featureValue.setNullValue(true);
107                        }
108                } else {
109                        featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE));
110                        featureValue.setValue(1);
111                        featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
112                        featureValue.setNullValue(true);
113                }
114//              featureValue.setKnown(true);
115        }
116        
117        /**
118         * Returns the feature value
119         * 
120         * @return the feature value
121         */
122        public FeatureValue getFeatureValue() {
123                return featureValue;
124        }
125        
126        /**
127         * Returns the symbol table used by the exists feature function
128         * 
129         * @return the symbol table used by the exists feature function
130         */
131        public SymbolTable getSymbolTable() {
132                return table;
133        }
134        
135        /**
136         * Returns the address function 
137         * 
138         * @return the address function 
139         */
140        public AddressFunction getAddressFunction() {
141                return addressFunction;
142        }
143
144
145        /**
146         * Sets the address function 
147         * 
148         * @param addressFunction a address function 
149         */
150        public void setAddressFunction(AddressFunction addressFunction) {
151                this.addressFunction = addressFunction;
152        }
153        
154        /**
155         * Returns symbol table handler
156         * 
157         * @return a symbol table handler
158         */
159        public SymbolTableHandler getTableHandler() {
160                return tableHandler;
161        }
162
163        public  int getType() {
164                return ColumnDescription.STRING;
165        }
166        
167        public String getMapIdentifier() {
168                return getSymbolTable().getName();
169        }
170        /**
171         * Sets the symbol table used by the exists feature function
172         * 
173         * @param table
174         */
175        public void setSymbolTable(SymbolTable table) {
176                this.table = table;
177        }
178        
179        public boolean equals(Object obj) {
180                if (this == obj)
181                        return true;
182                if (obj == null)
183                        return false;
184                if (getClass() != obj.getClass())
185                        return false;
186                return obj.toString().equals(this.toString());
187        }
188        
189        public int hashCode() {
190                return 217 + (null == toString() ? 0 : toString().hashCode());
191        }
192        
193        public String toString() {
194                final StringBuilder sb = new StringBuilder();
195                sb.append("ArcDir(");
196                sb.append(addressFunction.toString());
197                sb.append(')');
198                return sb.toString();
199        }
200}