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.AddressFunction;
006import org.maltparser.core.feature.function.FeatureFunction;
007import org.maltparser.core.feature.value.AddressValue;
008import org.maltparser.core.feature.value.FeatureValue;
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;
014import org.maltparser.core.symbol.nullvalue.NullValues.NullValueId;
015import org.maltparser.core.syntaxgraph.SyntaxGraphException;
016import org.maltparser.core.syntaxgraph.node.DependencyNode;
017/**
018*
019* @author Johan Hall
020**/
021public final class InputArcFeature implements FeatureFunction {
022        public final static Class<?>[] paramTypes = { java.lang.String.class, org.maltparser.core.feature.function.AddressFunction.class, org.maltparser.core.feature.function.AddressFunction.class };
023        private AddressFunction addressFunction1;
024        private AddressFunction addressFunction2;
025        private ColumnDescription column;
026        private final DataFormatInstance dataFormatInstance;
027        private final SymbolTableHandler tableHandler;
028        private SymbolTable table;
029        private final SingleFeatureValue featureValue;
030
031        
032        public InputArcFeature(DataFormatInstance dataFormatInstance, SymbolTableHandler tableHandler) throws MaltChainedException {
033                this.dataFormatInstance = dataFormatInstance;
034                this.tableHandler = tableHandler;
035                this.featureValue = new SingleFeatureValue(this);
036        }
037        
038        public void initialize(Object[] arguments) throws MaltChainedException {
039                if (arguments.length != 3) {
040                        throw new FeatureException("Could not initialize InputArcFeature: number of arguments are not correct. ");
041                }
042                // Checks that the two arguments are address functions
043
044                if (!(arguments[0] instanceof String)) {
045                        throw new FeatureException("Could not initialize InputArcFeature: the first argument is not a string. ");
046                }
047                if (!(arguments[1] instanceof AddressFunction)) {
048                        throw new SyntaxGraphException("Could not initialize InputArcFeature: the second argument is not an address function. ");
049                }
050                if (!(arguments[2] instanceof AddressFunction)) {
051                        throw new SyntaxGraphException("Could not initialize InputArcFeature: the third argument is not an address function. ");
052                }
053                setAddressFunction1((AddressFunction)arguments[1]);
054                setAddressFunction2((AddressFunction)arguments[2]);
055                
056                setColumn(dataFormatInstance.getColumnDescriptionByName((String)arguments[0]));
057                setSymbolTable(tableHandler.addSymbolTable("ARC_"+column.getName(),ColumnDescription.INPUT, "one"));
058                table.addSymbol("LEFT");
059                table.addSymbol("RIGHT");
060        }
061        
062        public Class<?>[] getParameterTypes() {
063                return paramTypes;
064        }
065        
066        public int getCode(String symbol) throws MaltChainedException {
067                return table.getSymbolStringToCode(symbol);
068        }
069
070
071        public FeatureValue getFeatureValue() {
072                return featureValue;
073        }
074
075
076        public String getSymbol(int code) throws MaltChainedException {
077                return table.getSymbolCodeToString(code);
078        }
079
080
081        public void updateCardinality() throws MaltChainedException {
082//              featureValue.setCardinality(table.getValueCounter());
083        }
084
085        public void update() throws MaltChainedException {
086                // Retrieve the address value 
087                final AddressValue arg1 = addressFunction1.getAddressValue();
088                final AddressValue arg2 = addressFunction2.getAddressValue();
089                if (arg1.getAddress() != null && arg1.getAddressClass() == org.maltparser.core.syntaxgraph.node.DependencyNode.class &&
090                    arg2.getAddress() != null && arg2.getAddressClass() == org.maltparser.core.syntaxgraph.node.DependencyNode.class) {
091                    DependencyNode node1 = (DependencyNode)arg1.getAddress();
092                    DependencyNode node2 = (DependencyNode)arg2.getAddress();
093                    try {
094                    SymbolTable symbolTable = tableHandler.getSymbolTable(column.getName());
095                        int head1 = Integer.parseInt(node1.getLabelSymbol(symbolTable));
096                        int head2 = Integer.parseInt(node2.getLabelSymbol(symbolTable));
097                        if (!node1.isRoot() && head1 == node2.getIndex()) {
098                            featureValue.setIndexCode(table.getSymbolStringToCode("LEFT"));
099                            featureValue.setSymbol("LEFT");
100                            featureValue.setNullValue(false);
101                        } else if (!node2.isRoot() && head2 == node1.getIndex()) {
102                            featureValue.setIndexCode(table.getSymbolStringToCode("RIGHT"));
103                            featureValue.setSymbol("RIGHT");
104                            featureValue.setNullValue(false);                   
105                        } else {
106                            featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE));
107                            featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
108                            featureValue.setNullValue(true);
109                        }
110                    } catch (NumberFormatException e) {
111                        throw new FeatureException("The index of the feature must be an integer value. ", e);
112                    }
113                } else {
114                    featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE));
115                    featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
116                    featureValue.setNullValue(true);
117                }
118//              featureValue.setKnown(true);
119                featureValue.setValue(1);
120        }
121
122        public ColumnDescription getColumn() {
123                return column;
124        }
125
126        public void setColumn(ColumnDescription column) throws MaltChainedException {
127                if (column.getType() != ColumnDescription.INTEGER) {
128                        throw new FeatureException("InputArc feature column must be of type integer. ");
129                }
130                this.column = column;
131        }
132
133        /**
134         * Returns the address function 1 (argument 1) 
135         * 
136         * @return the address function 1 (argument 1) 
137         */
138        public AddressFunction getAddressFunction1() {
139                return addressFunction1;
140        }
141
142
143        /**
144         * Sets the address function 1 (argument 1) 
145         * 
146         * @param addressFunction1 a address function 1 (argument 1) 
147         */
148        public void setAddressFunction1(AddressFunction addressFunction1) {
149                this.addressFunction1 = addressFunction1;
150        }
151        
152        /**
153         * Returns the address function 2 (argument 2) 
154         * 
155         * @return the address function 1 (argument 2) 
156         */
157        public AddressFunction getAddressFunction2() {
158                return addressFunction2;
159        }
160
161        /**
162         * Sets the address function 2 (argument 2) 
163         * 
164         * @param addressFunction2 a address function 2 (argument 2) 
165         */
166        public void setAddressFunction2(AddressFunction addressFunction2) {
167                this.addressFunction2 = addressFunction2;
168        }
169        
170        public DataFormatInstance getDataFormatInstance() {
171                return dataFormatInstance;
172        }
173        
174        public SymbolTable getSymbolTable() {
175                return table;
176        }
177
178        public void setSymbolTable(SymbolTable table) {
179                this.table = table;
180        }
181        
182        public SymbolTableHandler getTableHandler() {
183                return tableHandler;
184        }
185        
186        public  int getType() {
187                return ColumnDescription.STRING;
188        }
189        
190        public String getMapIdentifier() {
191                return getSymbolTable().getName();
192        }
193        
194        public boolean equals(Object obj) {
195                if (!(obj instanceof InputArcFeature)) {
196                        return false;
197                }
198                if (!obj.toString().equals(this.toString())) {
199                        return false;
200                }
201                return true;
202        }
203        
204        public String toString() {
205                return "InputArc(" + column.getName() + ")";
206        }
207}