001package org.maltparser.core.syntaxgraph.node; 002 003import java.util.Iterator; 004import java.util.SortedSet; 005import java.util.TreeSet; 006 007import org.maltparser.core.exception.MaltChainedException; 008import org.maltparser.core.syntaxgraph.GraphElement; 009import org.maltparser.core.syntaxgraph.SyntaxGraphException; 010import org.maltparser.core.syntaxgraph.edge.Edge; 011 012 013 014/** 015 * 016 * 017 * @author Johan Hall 018 * 019 */ 020public abstract class GraphNode extends GraphElement implements Node { 021 protected SortedSet<Edge> incomingEdges; 022 protected SortedSet<Edge> outgoingEdges; 023 024 public GraphNode() throws MaltChainedException { 025 super(); 026 incomingEdges = new TreeSet<Edge>(); 027 outgoingEdges = new TreeSet<Edge>(); 028 } 029 030 public void addIncomingEdge(Edge in) throws MaltChainedException { 031 if (in.getTarget() != this) { 032 throw new SyntaxGraphException("The incoming edge's 'to' reference is not correct."); 033 } 034 incomingEdges.add(in); 035 } 036 037 public void addOutgoingEdge(Edge out) throws MaltChainedException { 038 if (out.getSource() != this) { 039 throw new SyntaxGraphException("The outgoing edge's 'from' reference is not correct"); 040 } 041 outgoingEdges.add(out); 042 } 043 044 public void removeIncomingEdge(Edge in) throws MaltChainedException { 045 if (in.getTarget() != this) { 046 throw new SyntaxGraphException("The incoming edge's 'to' reference is not correct"); 047 } 048 incomingEdges.remove(in); 049 } 050 051 public void removeOutgoingEdge(Edge out) throws MaltChainedException { 052 if (out.getSource() != this) { 053 throw new SyntaxGraphException("The outgoing edge's 'from' reference is not correct"); 054 } 055 outgoingEdges.remove(out); 056 } 057 058 public int getLeftmostProperDescendantIndex() throws MaltChainedException { 059 ComparableNode node = getLeftmostProperDescendant(); 060 return (node != null)?node.getIndex():-1; 061 } 062 063 public int getRightmostProperDescendantIndex() throws MaltChainedException { 064 ComparableNode node = getRightmostProperDescendant(); 065 return (node != null)?node.getIndex():-1; 066 } 067 068 public int getLeftmostDescendantIndex() throws MaltChainedException { 069 ComparableNode node = getLeftmostProperDescendant(); 070 return (node != null)?node.getIndex():this.getIndex(); 071 } 072 073 public int getRightmostDescendantIndex() throws MaltChainedException { 074 ComparableNode node = getRightmostProperDescendant(); 075 return (node != null)?node.getIndex():this.getIndex(); 076 } 077 078 public Iterator<Edge> getIncomingEdgeIterator() { 079 return incomingEdges.iterator(); 080 } 081 082 public Iterator<Edge> getOutgoingEdgeIterator() { 083 return outgoingEdges.iterator(); 084 } 085 086 public void clear() throws MaltChainedException { 087 super.clear(); 088 incomingEdges.clear(); 089 outgoingEdges.clear(); 090 } 091 092 public int getInDegree() { 093 return incomingEdges.size(); 094 } 095 096 public int getOutDegree() { 097 return outgoingEdges.size(); 098 } 099 100 public SortedSet<Edge> getIncomingSecondaryEdges() { 101 SortedSet<Edge> inSecEdges = new TreeSet<Edge>(); 102 for (Edge e : incomingEdges) { 103 if (e.getType() == Edge.SECONDARY_EDGE) { 104 inSecEdges.add(e); 105 } 106 } 107 return inSecEdges; 108 } 109 110 public SortedSet<Edge> getOutgoingSecondaryEdges() { 111 SortedSet<Edge> outSecEdges = new TreeSet<Edge>(); 112 for (Edge e : outgoingEdges) { 113 if (e.getType() == Edge.SECONDARY_EDGE) { 114 outSecEdges.add(e); 115 } 116 } 117 return outSecEdges; 118 } 119 120 public int compareTo(ComparableNode o) { 121 return super.compareTo((GraphElement)o); 122 } 123 124 public abstract int getIndex(); 125 public abstract void setIndex(int index) throws MaltChainedException; 126 public abstract boolean isRoot(); 127 128 public boolean equals(Object obj) { 129 GraphNode v = (GraphNode)obj; 130 return super.equals(obj) && incomingEdges.equals(v.incomingEdges) 131 && outgoingEdges.equals(v.outgoingEdges); 132 } 133 134 public int hashCode() { 135 int hash = 7; 136 hash = 31 * hash + super.hashCode(); 137 hash = 31 * hash + (null == incomingEdges ? 0 : incomingEdges.hashCode()); 138 hash = 31 * hash + (null == outgoingEdges ? 0 : outgoingEdges.hashCode()); 139 return hash; 140 } 141 142 public String toString() { 143 final StringBuilder sb = new StringBuilder(); 144 sb.append(getIndex()); 145 sb.append(" [I:"); 146 for (Edge e : incomingEdges) { 147 sb.append(e.getSource().getIndex()); 148 sb.append("("); 149 sb.append(e.toString()); 150 sb.append(")"); 151 if (incomingEdges.last() != e) { 152 sb.append(","); 153 } 154 } 155 sb.append("][O:"); 156 for (Edge e : outgoingEdges) { 157 sb.append(e.getTarget().getIndex()); 158 if (outgoingEdges.last() != e) { 159 sb.append(","); 160 } 161 } 162 sb.append("]"); 163 sb.append(super.toString()); 164 return sb.toString(); 165 } 166}