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, ColumnDescription.STRING, "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.setValue(1); 119 } 120 121 public ColumnDescription getColumn() { 122 return column; 123 } 124 125 public void setColumn(ColumnDescription column) throws MaltChainedException { 126 if (column.getType() != ColumnDescription.INTEGER) { 127 throw new FeatureException("InputArc feature column must be of type integer. "); 128 } 129 this.column = column; 130 } 131 132 /** 133 * Returns the address function 1 (argument 1) 134 * 135 * @return the address function 1 (argument 1) 136 */ 137 public AddressFunction getAddressFunction1() { 138 return addressFunction1; 139 } 140 141 142 /** 143 * Sets the address function 1 (argument 1) 144 * 145 * @param addressFunction1 a address function 1 (argument 1) 146 */ 147 public void setAddressFunction1(AddressFunction addressFunction1) { 148 this.addressFunction1 = addressFunction1; 149 } 150 151 /** 152 * Returns the address function 2 (argument 2) 153 * 154 * @return the address function 1 (argument 2) 155 */ 156 public AddressFunction getAddressFunction2() { 157 return addressFunction2; 158 } 159 160 /** 161 * Sets the address function 2 (argument 2) 162 * 163 * @param addressFunction2 a address function 2 (argument 2) 164 */ 165 public void setAddressFunction2(AddressFunction addressFunction2) { 166 this.addressFunction2 = addressFunction2; 167 } 168 169 public DataFormatInstance getDataFormatInstance() { 170 return dataFormatInstance; 171 } 172 173 public SymbolTable getSymbolTable() { 174 return table; 175 } 176 177 public void setSymbolTable(SymbolTable table) { 178 this.table = table; 179 } 180 181 public SymbolTableHandler getTableHandler() { 182 return tableHandler; 183 } 184 185 public int getType() { 186 return ColumnDescription.STRING; 187 } 188 189 public String getMapIdentifier() { 190 return getSymbolTable().getName(); 191 } 192 193 public boolean equals(Object obj) { 194 if (!(obj instanceof InputArcFeature)) { 195 return false; 196 } 197 if (!obj.toString().equals(this.toString())) { 198 return false; 199 } 200 return true; 201 } 202 203 public String toString() { 204 return "InputArc(" + column.getName() + ")"; 205 } 206}