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