001package org.maltparser.core.lw.graph; 002 003import java.util.HashSet; 004import java.util.Iterator; 005import java.util.Set; 006import java.util.SortedMap; 007import java.util.TreeMap; 008 009import org.maltparser.concurrent.graph.dataformat.ColumnDescription; 010import org.maltparser.core.exception.MaltChainedException; 011import org.maltparser.core.symbol.SymbolTable; 012import org.maltparser.core.symbol.SymbolTableHandler; 013import org.maltparser.core.syntaxgraph.LabelSet; 014import org.maltparser.core.syntaxgraph.LabeledStructure; 015import org.maltparser.core.syntaxgraph.edge.Edge; 016import org.maltparser.core.syntaxgraph.node.Node; 017 018/** 019* A lightweight version of org.maltparser.core.syntaxgraph.edge.GraphEdge. 020* 021* @author Johan Hall 022*/ 023public final class LWEdge implements Edge, Comparable<LWEdge> { 024 private final Node source; 025 private final Node target; 026 private final SortedMap<ColumnDescription, String> labels; 027 028 protected LWEdge(LWEdge edge) throws LWGraphException { 029 this.source = edge.source; 030 this.target = edge.target; 031 this.labels = new TreeMap<ColumnDescription, String>(edge.labels); 032 } 033 034 protected LWEdge(Node _source, Node _target, SortedMap<ColumnDescription, String> _labels) throws MaltChainedException { 035 if (_source.getBelongsToGraph() != _target.getBelongsToGraph()) { 036 throw new LWGraphException("The source node and target node must belong to the same dependency graph."); 037 } 038 this.source = _source; 039 this.target = _target; 040 this.labels = _labels; 041 SymbolTableHandler symbolTableHandler = getBelongsToGraph().getSymbolTables(); 042 for (ColumnDescription column : labels.keySet()) { 043 SymbolTable table = symbolTableHandler.addSymbolTable(column.getName()); 044 table.addSymbol(labels.get(column)); 045 } 046 } 047 048 protected LWEdge(Node _source, Node _target) throws MaltChainedException { 049 if (_source.getBelongsToGraph() != _target.getBelongsToGraph()) { 050 throw new LWGraphException("The source node and target node must belong to the same dependency graph."); 051 } 052 this.source = _source; 053 this.target = _target; 054 this.labels = new TreeMap<ColumnDescription, String>(); 055 } 056 057 public Node getSource() { 058 return source; 059 } 060 061 public Node getTarget() { 062 return target; 063 } 064 065 public String getLabel(ColumnDescription column) { 066 if (labels.containsKey(column)) { 067 return labels.get(column); 068 } else if (column.getCategory() == ColumnDescription.IGNORE) { 069 return column.getDefaultOutput(); 070 } 071 return ""; 072 } 073 074 public int nLabels() { 075 return labels.size(); 076 } 077 078 public boolean isLabeled() { 079 return labels.size() > 0; 080 } 081 082 083 @Override 084 public void setEdge(Node source, Node target, int type) 085 throws MaltChainedException { 086 throw new LWGraphException("Not implemented in light-weight dependency graph"); 087 } 088 089 @Override 090 public int getType() { 091 return DEPENDENCY_EDGE; 092 } 093 094 095 /** 096 * Adds a label (a string value) to the symbol table and to the graph element. 097 * 098 * @param table the symbol table 099 * @param symbol a label symbol 100 * @throws MaltChainedException 101 */ 102 public void addLabel(SymbolTable table, String symbol) throws MaltChainedException { 103 LWDependencyGraph graph = (LWDependencyGraph)getBelongsToGraph(); 104 ColumnDescription column = graph.getDataFormat().getColumnDescription(table.getName()); 105 table.addSymbol(symbol); 106 labels.put(column, symbol); 107 } 108 109 /** 110 * Adds a label (an integer value) to the symbol table and to the graph element. 111 * 112 * @param table the symbol table 113 * @param code a label code 114 * @throws MaltChainedException 115 */ 116 public void addLabel(SymbolTable table, int code) throws MaltChainedException { 117 addLabel(table, table.getSymbolCodeToString(code)); 118 } 119 120 /** 121 * Adds the labels of the label set to the label set of the graph element. 122 * 123 * @param labelSet a label set. 124 * @throws MaltChainedException 125 */ 126 public void addLabel(LabelSet labelSet) throws MaltChainedException { 127 for (SymbolTable table : labelSet.keySet()) { 128 addLabel(table, labelSet.get(table)); 129 } 130 } 131 132 /** 133 * Returns <i>true</i> if the graph element has a label for the symbol table, otherwise <i>false</i>. 134 * 135 * @param table the symbol table 136 * @return <i>true</i> if the graph element has a label for the symbol table, otherwise <i>false</i>. 137 * @throws MaltChainedException 138 */ 139 public boolean hasLabel(SymbolTable table) throws MaltChainedException { 140 if (table == null) { 141 return false; 142 } 143 LWDependencyGraph graph = (LWDependencyGraph)getBelongsToGraph(); 144 ColumnDescription column = graph.getDataFormat().getColumnDescription(table.getName()); 145 return labels.containsKey(column); 146 } 147 148 /** 149 * Returns the label symbol(a string representation) of the symbol table if it exists, otherwise 150 * an exception is thrown. 151 * 152 * @param table the symbol table 153 * @return the label (a string representation) of the symbol table if it exists. 154 * @throws MaltChainedException 155 */ 156 public String getLabelSymbol(SymbolTable table) throws MaltChainedException { 157 LWDependencyGraph graph = (LWDependencyGraph)getBelongsToGraph(); 158 ColumnDescription column = graph.getDataFormat().getColumnDescription(table.getName()); 159 return labels.get(column); 160 } 161 162 /** 163 * Returns the label code (an integer representation) of the symbol table if it exists, otherwise 164 * an exception is thrown. 165 * 166 * @param table the symbol table 167 * @return the label code (an integer representation) of the symbol table if it exists 168 * @throws MaltChainedException 169 */ 170 public int getLabelCode(SymbolTable table) throws MaltChainedException { 171 LWDependencyGraph graph = (LWDependencyGraph)getBelongsToGraph(); 172 ColumnDescription column = graph.getDataFormat().getColumnDescription(table.getName()); 173 return table.getSymbolStringToCode(labels.get(column)); 174 } 175 176 /** 177 * Returns a set of symbol tables (labeling functions or label types) that labels the graph element. 178 * 179 * @return a set of symbol tables (labeling functions or label types) 180 */ 181 public Set<SymbolTable> getLabelTypes() { 182 Set<SymbolTable> labelTypes = new HashSet<SymbolTable>(); 183 SymbolTableHandler symbolTableHandler = getBelongsToGraph().getSymbolTables(); 184 for (ColumnDescription column : labels.keySet()) { 185 try { 186 labelTypes.add(symbolTableHandler.getSymbolTable(column.getName())); 187 } catch (MaltChainedException e) { 188 e.printStackTrace(); 189 } 190 } 191 return labelTypes; 192 } 193 194 /** 195 * Returns the label set. 196 * 197 * @return the label set. 198 */ 199 public LabelSet getLabelSet() { 200 SymbolTableHandler symbolTableHandler = getBelongsToGraph().getSymbolTables(); 201 LabelSet labelSet = new LabelSet(); 202 203 for (ColumnDescription column : labels.keySet()) { 204 try { 205 SymbolTable table = symbolTableHandler.getSymbolTable(column.getName()); 206 int code = table.getSymbolStringToCode(labels.get(column)); 207 labelSet.put(table, code); 208 } catch (MaltChainedException e) { 209 e.printStackTrace(); 210 } 211 } 212 return labelSet; 213 } 214 215 public void removeLabel(SymbolTable table) throws MaltChainedException { 216 LWDependencyGraph graph = (LWDependencyGraph)getBelongsToGraph(); 217 ColumnDescription column = graph.getDataFormat().getColumnDescription(table.getName()); 218 labels.remove(column); 219 } 220 221 public void removeLabels() throws MaltChainedException { 222 labels.clear(); 223 } 224 225 /** 226 * Returns the graph (structure) in which the graph element belongs to. 227 * 228 * @return the graph (structure) in which the graph element belongs to. 229 */ 230 public LabeledStructure getBelongsToGraph() { 231 return target.getBelongsToGraph(); 232 } 233 234 public void setBelongsToGraph(LabeledStructure belongsToGraph) { } 235 236 237 /** 238 * Resets the graph element. 239 * 240 * @throws MaltChainedException 241 */ 242 public void clear() throws MaltChainedException { 243 labels.clear(); 244 } 245 246 public int compareTo(LWEdge that) { 247 final int BEFORE = -1; 248 final int EQUAL = 0; 249 final int AFTER = 1; 250 251 if (this == that) return EQUAL; 252 253 if (this.target.getIndex() < that.target.getIndex()) return BEFORE; 254 if (this.target.getIndex() > that.target.getIndex()) return AFTER; 255 256 if (this.source.getIndex() < that.source.getIndex()) return BEFORE; 257 if (this.source.getIndex() > that.source.getIndex()) return AFTER; 258 259 260 if (this.labels.equals(that.labels)) return EQUAL; 261 262 Iterator<ColumnDescription> itthis = this.labels.keySet().iterator(); 263 Iterator<ColumnDescription> itthat = that.labels.keySet().iterator(); 264 while (itthis.hasNext() && itthat.hasNext()) { 265 ColumnDescription keythis = itthis.next(); 266 ColumnDescription keythat = itthat.next(); 267 if (keythis.getPosition() < keythat.getPosition()) return BEFORE; 268 if (keythis.getPosition() > keythat.getPosition()) return AFTER; 269 if (this.labels.get(keythis).compareTo(that.labels.get(keythat)) != EQUAL) { 270 return this.labels.get(keythis).compareTo(that.labels.get(keythat)); 271 } 272 } 273 if (itthis.hasNext() == false && itthat.hasNext() == true) return BEFORE; 274 if (itthis.hasNext() == true && itthat.hasNext() == false) return AFTER; 275 276 277 return EQUAL; 278 } 279 280 @Override 281 public int hashCode() { 282 final int prime = 31; 283 int result = 1; 284 result = prime * result + source.getIndex(); 285 result = prime * result + target.getIndex(); 286 result = prime * result + ((labels == null) ? 0 : labels.hashCode()); 287 return result; 288 } 289 290 @Override 291 public boolean equals(Object obj) { 292 if (this == obj) 293 return true; 294 if (obj == null) 295 return false; 296 if (getClass() != obj.getClass()) 297 return false; 298 LWEdge other = (LWEdge) obj; 299 if (source.getIndex() != other.source.getIndex()) 300 return false; 301 if (target.getIndex() != other.target.getIndex()) 302 return false; 303 if (labels == null) { 304 if (other.labels != null) 305 return false; 306 } else if (!labels.equals(other.labels)) 307 return false; 308 return true; 309 } 310 311 public String toString() { 312 final StringBuilder sb = new StringBuilder(); 313 sb.append(source); 314 sb.append(" -> "); 315 sb.append(target); 316 if (labels.size() > 0) { 317 int i = 1; 318 sb.append(" {"); 319 for (ColumnDescription column : labels.keySet()) { 320 sb.append(column.getName()); 321 sb.append('='); 322 sb.append(labels.get(column)); 323 if (i < labels.size()) { 324 sb.append(','); 325 } 326 i++; 327 } 328 sb.append(" }"); 329 } 330 return sb.toString(); 331 } 332}