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}