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.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE));
096                                    featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
097                                    featureValue.setNullValue(true); 
098                            } else {
099                                    final DependencyNode node1 = (DependencyNode)arg1.getAddress();
100                                    final DependencyNode node2 = (DependencyNode)arg2.getAddress();
101                                    
102                                    int head1 = -1;
103                                    int head2 = -1;
104    
105                                    if ( node1.hasHead() )
106                                    {
107                                            head1 = node1.getHead().getIndex(); //lines below don't seem to work
108                                            //head1 = Integer.parseInt(node1.getHeadEdgeLabelSymbol(column.getSymbolTable()));
109                                            //if ( node1.hasHeadEdgeLabel(column.getSymbolTable()) )
110                                            //      head1 = Integer.parseInt(node1.getHeadEdgeLabelSymbol(column.getSymbolTable()));
111                                    }
112                                    if ( node2.hasHead() )
113                                    {
114                                            head2 = node2.getHead().getIndex(); //lines below don't seem to work
115                                            //head2 = Integer.parseInt(node2.getHeadEdgeLabelSymbol(column.getSymbolTable()));
116                                            //if ( node2.hasHeadEdgeLabel(column.getSymbolTable()) )
117                                            //      head2 = Integer.parseInt(node2.getHeadEdgeLabelSymbol(column.getSymbolTable()));
118                                    }
119                                    if (!node1.isRoot() && head1 == node2.getIndex()) {
120                                            featureValue.setIndexCode(table.getSymbolStringToCode("LEFT"));
121                                            featureValue.setSymbol("LEFT");
122                                            featureValue.setNullValue(false);
123                                    } else if (!node2.isRoot() && head2 == node1.getIndex()) {
124                                            featureValue.setIndexCode(table.getSymbolStringToCode("RIGHT"));
125                                            featureValue.setSymbol("RIGHT");
126                                            featureValue.setNullValue(false);                       
127                                    } else {
128                                            featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE));
129                                            featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE));
130                                            featureValue.setNullValue(true);
131                                    }
132                            }
133                    } catch (NumberFormatException e) {
134                            throw new FeatureException("The index of the feature must be an integer value. ", e);
135                    }
136    //              featureValue.setKnown(true);
137                    featureValue.setValue(1);
138            }
139    
140            public ColumnDescription getColumn() {
141                    return column;
142            }
143    
144            public void setColumn(ColumnDescription column) throws MaltChainedException {
145                    if (column.getType() != ColumnDescription.INTEGER) {
146                            throw new FeatureException("OutputArc feature column must be of type integer. ");
147                    }
148                    this.column = column;
149            }
150    
151            /**
152             * Returns the address function 1 (argument 1) 
153             * 
154             * @return the address function 1 (argument 1) 
155             */
156            public AddressFunction getAddressFunction1() {
157                    return addressFunction1;
158            }
159    
160    
161            /**
162             * Sets the address function 1 (argument 1) 
163             * 
164             * @param addressFunction1 a address function 1 (argument 1) 
165             */
166            public void setAddressFunction1(AddressFunction addressFunction1) {
167                    this.addressFunction1 = addressFunction1;
168            }
169            
170            /**
171             * Returns the address function 2 (argument 2) 
172             * 
173             * @return the address function 1 (argument 2) 
174             */
175            public AddressFunction getAddressFunction2() {
176                    return addressFunction2;
177            }
178    
179            /**
180             * Sets the address function 2 (argument 2) 
181             * 
182             * @param addressFunction2 a address function 2 (argument 2) 
183             */
184            public void setAddressFunction2(AddressFunction addressFunction2) {
185                    this.addressFunction2 = addressFunction2;
186            }
187            
188            public DataFormatInstance getDataFormatInstance() {
189                    return dataFormatInstance;
190            }
191    
192            public void setDataFormatInstance(DataFormatInstance dataFormatInstance) {
193                    this.dataFormatInstance = dataFormatInstance;
194            }
195    
196            public void setFeatureValue(SingleFeatureValue featureValue) {
197                    this.featureValue = featureValue;
198            }
199            
200            public SymbolTable getSymbolTable() {
201                    return table;
202            }
203    
204            public void setSymbolTable(SymbolTable table) {
205                    this.table = table;
206            }
207            
208            public SymbolTableHandler getTableHandler() {
209                    return tableHandler;
210            }
211    
212            public void setTableHandler(SymbolTableHandler tableHandler) {
213                    this.tableHandler = tableHandler;
214            }
215            
216            public boolean equals(Object obj) {
217                    if (!(obj instanceof InputArcFeature)) {
218                            return false;
219                    }
220                    if (!obj.toString().equals(this.toString())) {
221                            return false;
222                    }
223                    return true;
224            }
225            
226            public String toString() {
227                    return "OutputArc(" + column.getName() + ")";
228            }
229    }