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 }