001package org.maltparser.core.syntaxgraph; 002 003import java.util.LinkedHashSet; 004import java.util.Observable; 005import java.util.Set; 006 007import org.maltparser.core.exception.MaltChainedException; 008import org.maltparser.core.symbol.SymbolTable; 009 010/** 011* 012* 013* @author Johan Hall 014*/ 015public abstract class GraphElement extends Observable implements Element { 016 private LabeledStructure belongsToGraph; 017 private LabelSet labelSet; 018 019 public GraphElement() { 020 belongsToGraph = null; 021 labelSet = null; 022 } 023 024 /** 025 * Adds a label (a string value) to the symbol table and to the graph element. 026 * 027 * @param table the symbol table 028 * @param symbol a label symbol 029 * @throws MaltChainedException 030 */ 031 public void addLabel(SymbolTable table, String symbol) throws MaltChainedException { 032 table.addSymbol(symbol); 033 addLabel(table, table.getSymbolStringToCode(symbol)); 034 } 035 036 /** 037 * Adds a label (an integer value) to the symbol table and to the graph element. 038 * 039 * @param table the symbol table 040 * @param code a label code 041 * @throws MaltChainedException 042 */ 043 public void addLabel(SymbolTable table, int code) throws MaltChainedException { 044 if (table.getSymbolCodeToString(code) != null) { 045 if (labelSet == null) { 046 if (belongsToGraph == null) { 047 throw new SyntaxGraphException("The graph element doesn't belong to any graph. "); 048 } 049 labelSet = belongsToGraph.checkOutNewLabelSet(); 050 } 051 labelSet.put(table, code); 052 setChanged(); 053 notifyObservers(table); 054 } 055 } 056 057 /** 058 * Adds the labels of the label set to the label set of the graph element. 059 * 060 * @param labels a label set. 061 * @throws MaltChainedException 062 */ 063 public void addLabel(LabelSet labels) throws MaltChainedException { 064 if (labels != null) { 065 for (SymbolTable table : labels.keySet()) { 066 addLabel(table, labels.get(table)); 067 } 068 } 069 } 070 071 /** 072 * Returns <i>true</i> if the graph element has a label for the symbol table, otherwise <i>false</i>. 073 * 074 * @param table the symbol table 075 * @return <i>true</i> if the graph element has a label for the symbol table, otherwise <i>false</i>. 076 * @throws MaltChainedException 077 */ 078 public boolean hasLabel(SymbolTable table) throws MaltChainedException { 079 if (labelSet != null) { 080 return labelSet.containsKey(table); 081 } 082 return false; 083 } 084 085 /** 086 * Returns the label symbol(a string representation) of the symbol table if it exists, otherwise 087 * an exception is thrown. 088 * 089 * @param table the symbol table 090 * @return the label (a string representation) of the symbol table if it exists. 091 * @throws MaltChainedException 092 */ 093 public String getLabelSymbol(SymbolTable table) throws MaltChainedException { 094 Integer code = labelSet.get(table); 095 if (code == null) { 096 throw new SyntaxGraphException("No label symbol available for label '"+table.getName()+"'."); 097 } 098 return table.getSymbolCodeToString(code); 099 } 100 101 /** 102 * Returns the label code (an integer representation) of the symbol table if it exists, otherwise 103 * an exception is thrown. 104 * 105 * @param table the symbol table 106 * @return the label code (an integer representation) of the symbol table if it exists 107 * @throws MaltChainedException 108 */ 109 public int getLabelCode(SymbolTable table) throws MaltChainedException { 110 Integer code = labelSet.get(table); 111 if (code == null) { 112 throw new SyntaxGraphException("No label symbol available for label '"+table.getName()+"'."); 113 } 114// if (code != null) { 115// return -1; 116// } 117 return code.intValue(); 118 } 119 120 /** 121 * Returns <i>true</i> if the graph element has one or more labels, otherwise <i>false</i>. 122 * 123 * @return <i>true</i> if the graph element has one or more labels, otherwise <i>false</i>. 124 */ 125 public boolean isLabeled() { 126 if (labelSet == null) { 127 return false; 128 } 129 return labelSet.size() > 0; 130 } 131 132 /** 133 * Returns the number of labels of the graph element. 134 * 135 * @return the number of labels of the graph element. 136 */ 137 public int nLabels() { 138 if (labelSet == null) { 139 return 0; 140 } 141 return labelSet.size(); 142 } 143 144 /** 145 * Returns a set of symbol tables (labeling functions or label types) that labels the graph element. 146 * 147 * @return a set of symbol tables (labeling functions or label types) 148 */ 149 public Set<SymbolTable> getLabelTypes() { 150 if (labelSet == null) { 151 return new LinkedHashSet<SymbolTable>(); 152 } 153 return labelSet.keySet(); 154 } 155 156 /** 157 * Returns the label set. 158 * 159 * @return the label set. 160 */ 161 public LabelSet getLabelSet() { 162 return labelSet; 163 } 164 165 public void removeLabel(SymbolTable table) throws MaltChainedException { 166 if (labelSet != null) { 167 labelSet.remove(table); 168 } 169 } 170 171 public void removeLabels() throws MaltChainedException { 172 if (labelSet != null && belongsToGraph != null) { 173 belongsToGraph.checkInLabelSet(labelSet); 174 } 175 labelSet = null; 176 } 177 178 /** 179 * Returns the graph (structure) in which the graph element belongs to. 180 * 181 * @return the graph (structure) in which the graph element belongs to. 182 */ 183 public LabeledStructure getBelongsToGraph() { 184 return belongsToGraph; 185 } 186 187 /** 188 * Sets the graph (structure) in which the graph element belongs to. 189 * 190 * @param belongsToGraph a graph (structure). 191 */ 192 public void setBelongsToGraph(LabeledStructure belongsToGraph) { 193 this.belongsToGraph = belongsToGraph; 194 addObserver((SyntaxGraph)belongsToGraph); 195 } 196 197 198 /** 199 * Resets the graph element. 200 * 201 * @throws MaltChainedException 202 */ 203 public void clear() throws MaltChainedException { 204 if (labelSet != null && belongsToGraph != null) { 205 belongsToGraph.checkInLabelSet(labelSet); 206 } 207 labelSet = null; 208 deleteObserver((SyntaxGraph)belongsToGraph); 209 belongsToGraph = null; 210 } 211 212 public boolean equals(Object obj) { 213 GraphElement ge = (GraphElement)obj; 214 return belongsToGraph == ge.getBelongsToGraph() && labelSet == null ? ge.getLabelSet() == null : labelSet.equals(ge.getLabelSet()); 215 } 216 217 public int hashCode() { 218 int hash = 7; 219 hash = 31 * hash + (null == belongsToGraph ? 0 : belongsToGraph.hashCode()); 220 return 31 * hash + (null == labelSet ? 0 : labelSet.hashCode()); 221 } 222 223 public int compareTo(GraphElement o) { 224 final int BEFORE = -1; 225 final int EQUAL = 0; 226 final int AFTER = 1; 227 if ( this == o ) return EQUAL; 228 229 if (this.labelSet == null && o.labelSet != null) return BEFORE; 230 if (this.labelSet != null && o.labelSet == null) return AFTER; 231 if (this.labelSet == null && o.labelSet == null) return EQUAL; 232 233 int comparison = EQUAL; 234 for (SymbolTable table : labelSet.keySet()) { 235 Integer ocode = o.labelSet.get(table); 236 Integer tcode = labelSet.get(table); 237 if (ocode != null && tcode != null) { 238 if (!ocode.equals(tcode)) { 239 try { 240 comparison = table.getSymbolCodeToString(tcode).compareTo(table.getSymbolCodeToString(ocode)); 241 if ( comparison != EQUAL ) return comparison; 242 } catch (MaltChainedException e) { } 243 } 244 } 245 } 246 return EQUAL; 247 } 248 249 public String toString() { 250 final StringBuilder sb = new StringBuilder(); 251 if (labelSet != null) { 252 for (SymbolTable table : labelSet.keySet()) { 253 try { 254 sb.append(table.getName()); 255 sb.append(':'); 256 sb.append(getLabelSymbol(table)); 257 } catch (MaltChainedException e) { 258 System.err.println("Print error : "+e.getMessageChain()); 259 } 260 sb.append(' '); 261 } 262 } 263 return sb.toString(); 264 } 265}