001    package org.maltparser.core.syntaxgraph.feature;
002    
003    import org.maltparser.core.exception.MaltChainedException;
004    import org.maltparser.core.feature.function.AddressFunction;
005    import org.maltparser.core.feature.function.FeatureFunction;
006    import org.maltparser.core.feature.value.FeatureValue;
007    import org.maltparser.core.feature.value.SingleFeatureValue;
008    import org.maltparser.core.io.dataformat.ColumnDescription;
009    import org.maltparser.core.symbol.SymbolTable;
010    import org.maltparser.core.symbol.SymbolTableHandler;
011    import org.maltparser.core.symbol.nullvalue.NullValues.NullValueId;
012    import org.maltparser.core.syntaxgraph.SyntaxGraphException;
013    import org.maltparser.core.syntaxgraph.node.DependencyNode;
014    
015    public class ArcDirFeature implements FeatureFunction {
016            protected AddressFunction addressFunction;
017            protected SymbolTableHandler tableHandler;
018            protected SymbolTable table;
019            protected SingleFeatureValue featureValue;
020            
021            public ArcDirFeature(SymbolTableHandler tableHandler) throws MaltChainedException {
022                    super();
023                    featureValue = new SingleFeatureValue(this);
024                    setTableHandler(tableHandler);
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                    Class<?>[] paramTypes = { org.maltparser.core.feature.function.AddressFunction.class };
059                    return paramTypes; 
060            }
061            /**
062             * Returns the string representation of the integer <code>code</code> according to the exists feature function. 
063             * 
064             * @param code the integer representation of the symbol
065             * @return the string representation of the integer <code>code</code> according to the exists feature function.
066             * @throws MaltChainedException
067             */
068            public String getSymbol(int code) throws MaltChainedException {
069                    return table.getSymbolCodeToString(code);
070            }
071            
072            /**
073             * Returns the integer representation of the string <code>symbol</code> according to the exists feature function.
074             * 
075             * @param symbol the string representation of the symbol
076             * @return the integer representation of the string <code>symbol</code> according to the exists feature function.
077             * @throws MaltChainedException
078             */
079            public int getCode(String symbol) throws MaltChainedException {
080                    return table.getSymbolStringToCode(symbol);
081            }
082            
083            /**
084             * Cause the exists feature function to update the cardinality of the feature value.
085             * 
086             * @throws MaltChainedException
087             */
088            public void updateCardinality() {
089                    featureValue.setCardinality(table.getValueCounter()); 
090            }
091            
092            /**
093             * Cause the feature function to update the feature value.
094             * 
095             * @throws MaltChainedException
096             */
097            public void update() throws MaltChainedException {
098                    if (addressFunction.getAddressValue().getAddress() != null) {
099                            final DependencyNode node = (DependencyNode)addressFunction.getAddressValue().getAddress();
100                            if (!node.isRoot()) { 
101                                    if (node.getHead().getIndex() < node.getIndex()) {
102                                            featureValue.setCode(table.getSymbolStringToCode("LEFT"));
103                                            featureValue.setSymbol("LEFT");
104                                            featureValue.setKnown(true);
105                                            featureValue.setNullValue(false);
106                                    } else {
107                                            featureValue.setCode(table.getSymbolStringToCode("RIGHT"));
108                                            featureValue.setSymbol("RIGHT");
109                                            featureValue.setKnown(true);
110                                            featureValue.setNullValue(false);
111                                    }
112                            } else { 
113                                    featureValue.setCode(table.getNullValueCode(NullValueId.ROOT_NODE));
114                                    featureValue.setSymbol(table.getNullValueSymbol(NullValueId.ROOT_NODE));
115                                    featureValue.setKnown(true);
116                                    featureValue.setNullValue(true);
117                            }
118                    } else {
119                            featureValue.setCode(table.getNullValueCode(NullValueId.NO_NODE));
120                            featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
121                            featureValue.setKnown(true);
122                            featureValue.setNullValue(true);
123                    }
124            }
125            
126            /**
127             * Returns the feature value
128             * 
129             * @return the feature value
130             */
131            public FeatureValue getFeatureValue() {
132                    return featureValue;
133            }
134            
135            /**
136             * Returns the symbol table used by the exists feature function
137             * 
138             * @return the symbol table used by the exists feature function
139             */
140            public SymbolTable getSymbolTable() {
141                    return table;
142            }
143            
144            /**
145             * Returns the address function 
146             * 
147             * @return the address function 
148             */
149            public AddressFunction getAddressFunction() {
150                    return addressFunction;
151            }
152    
153    
154            /**
155             * Sets the address function 
156             * 
157             * @param addressFunction a address function 
158             */
159            public void setAddressFunction(AddressFunction addressFunction) {
160                    this.addressFunction = addressFunction;
161            }
162            
163            /**
164             * Returns symbol table handler
165             * 
166             * @return a symbol table handler
167             */
168            public SymbolTableHandler getTableHandler() {
169                    return tableHandler;
170            }
171            /**
172             * Sets the symbol table handler
173             * 
174             * @param tableHandler a symbol table handler
175             */
176            public void setTableHandler(SymbolTableHandler tableHandler) {
177                    this.tableHandler = tableHandler;
178            }
179    
180            /**
181             * Sets the symbol table used by the exists feature function
182             * 
183             * @param table
184             */
185            public void setSymbolTable(SymbolTable table) {
186                    this.table = table;
187            }
188            
189            public boolean equals(Object obj) {
190                    if (this == obj)
191                            return true;
192                    if (obj == null)
193                            return false;
194                    if (getClass() != obj.getClass())
195                            return false;
196                    return obj.toString().equals(this.toString());
197            }
198            
199            public int hashCode() {
200                    return 217 + (null == toString() ? 0 : toString().hashCode());
201            }
202            
203            public String toString() {
204                    final StringBuilder sb = new StringBuilder();
205                    sb.append("ArcDir(");
206                    sb.append(addressFunction.toString());
207                    sb.append(')');
208                    return sb.toString();
209            }
210    }