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 * 020 * @author Carlos Gomez Rodriguez 021 * 022 */ 023public final class OutputArcFeature implements FeatureFunction { 024 public final static Class<?>[] paramTypes = { java.lang.String.class , org.maltparser.core.feature.function.AddressFunction.class , org.maltparser.core.feature.function.AddressFunction.class }; 025 private AddressFunction addressFunction1; 026 private AddressFunction addressFunction2; 027 private ColumnDescription column; 028 private final DataFormatInstance dataFormatInstance; 029 private final SymbolTableHandler tableHandler; 030 private SymbolTable table; 031 private final SingleFeatureValue featureValue; 032 033 034 public OutputArcFeature(DataFormatInstance dataFormatInstance, SymbolTableHandler tableHandler) throws MaltChainedException { 035 this.dataFormatInstance = dataFormatInstance; 036 this.tableHandler = tableHandler; 037 this.featureValue = 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 return paramTypes; 066 } 067 068 public int getCode(String symbol) throws MaltChainedException { 069 return table.getSymbolStringToCode(symbol); 070 } 071 072 073 public FeatureValue getFeatureValue() { 074 return featureValue; 075 } 076 077 078 public String getSymbol(int code) throws MaltChainedException { 079 return table.getSymbolCodeToString(code); 080 } 081 082 public void update() throws MaltChainedException { 083 // Retrieve the address value 084 final AddressValue arg1 = addressFunction1.getAddressValue(); 085 final AddressValue arg2 = addressFunction2.getAddressValue(); 086 try { 087 088 if (arg1.getAddress() == null || arg2.getAddress() == null) { 089 featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE)); 090 featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE)); 091 featureValue.setNullValue(true); 092 } else { 093 final DependencyNode node1 = (DependencyNode)arg1.getAddress(); 094 final DependencyNode node2 = (DependencyNode)arg2.getAddress(); 095 096 int head1 = -1; 097 int head2 = -1; 098 099 if ( node1.hasHead() ) 100 { 101 head1 = node1.getHead().getIndex(); //lines below don't seem to work 102 //head1 = Integer.parseInt(node1.getHeadEdgeLabelSymbol(column.getSymbolTable())); 103 //if ( node1.hasHeadEdgeLabel(column.getSymbolTable()) ) 104 // head1 = Integer.parseInt(node1.getHeadEdgeLabelSymbol(column.getSymbolTable())); 105 } 106 if ( node2.hasHead() ) 107 { 108 head2 = node2.getHead().getIndex(); //lines below don't seem to work 109 //head2 = Integer.parseInt(node2.getHeadEdgeLabelSymbol(column.getSymbolTable())); 110 //if ( node2.hasHeadEdgeLabel(column.getSymbolTable()) ) 111 // head2 = Integer.parseInt(node2.getHeadEdgeLabelSymbol(column.getSymbolTable())); 112 } 113 if (!node1.isRoot() && head1 == node2.getIndex()) { 114 featureValue.setIndexCode(table.getSymbolStringToCode("LEFT")); 115 featureValue.setSymbol("LEFT"); 116 featureValue.setNullValue(false); 117 } else if (!node2.isRoot() && head2 == node1.getIndex()) { 118 featureValue.setIndexCode(table.getSymbolStringToCode("RIGHT")); 119 featureValue.setSymbol("RIGHT"); 120 featureValue.setNullValue(false); 121 } else { 122 featureValue.setIndexCode(table.getNullValueCode(NullValueId.NO_NODE)); 123 featureValue.setSymbol(table.getNullValueSymbol(NullValueId.NO_NODE)); 124 featureValue.setNullValue(true); 125 } 126 } 127 } catch (NumberFormatException e) { 128 throw new FeatureException("The index of the feature must be an integer value. ", e); 129 } 130// featureValue.setKnown(true); 131 featureValue.setValue(1); 132 } 133 134 public ColumnDescription getColumn() { 135 return column; 136 } 137 138 public void setColumn(ColumnDescription column) throws MaltChainedException { 139 if (column.getType() != ColumnDescription.INTEGER) { 140 throw new FeatureException("OutputArc feature column must be of type integer. "); 141 } 142 this.column = column; 143 } 144 145 /** 146 * Returns the address function 1 (argument 1) 147 * 148 * @return the address function 1 (argument 1) 149 */ 150 public AddressFunction getAddressFunction1() { 151 return addressFunction1; 152 } 153 154 155 /** 156 * Sets the address function 1 (argument 1) 157 * 158 * @param addressFunction1 a address function 1 (argument 1) 159 */ 160 public void setAddressFunction1(AddressFunction addressFunction1) { 161 this.addressFunction1 = addressFunction1; 162 } 163 164 /** 165 * Returns the address function 2 (argument 2) 166 * 167 * @return the address function 1 (argument 2) 168 */ 169 public AddressFunction getAddressFunction2() { 170 return addressFunction2; 171 } 172 173 /** 174 * Sets the address function 2 (argument 2) 175 * 176 * @param addressFunction2 a address function 2 (argument 2) 177 */ 178 public void setAddressFunction2(AddressFunction addressFunction2) { 179 this.addressFunction2 = addressFunction2; 180 } 181 182 public DataFormatInstance getDataFormatInstance() { 183 return dataFormatInstance; 184 } 185 186 public SymbolTable getSymbolTable() { 187 return table; 188 } 189 190 public void setSymbolTable(SymbolTable table) { 191 this.table = table; 192 } 193 194 public SymbolTableHandler getTableHandler() { 195 return tableHandler; 196 } 197 198 public int getType() { 199 return ColumnDescription.STRING; 200 } 201 202 public String getMapIdentifier() { 203 return getSymbolTable().getName(); 204 } 205 206 public boolean equals(Object obj) { 207 if (!(obj instanceof InputArcFeature)) { 208 return false; 209 } 210 if (!obj.toString().equals(this.toString())) { 211 return false; 212 } 213 return true; 214 } 215 216 public String toString() { 217 return "OutputArc(" + column.getName() + ")"; 218 } 219}