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