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