    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                            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                            if (incomingEdges.last() != e) {
    149                                    sb.append(",");
    150                            }
    151                    }
    152                    sb.append("][O:");
    153                    for (Edge e : outgoingEdges) {
    154                            sb.append(e.getTarget().getIndex());
    155                            if (outgoingEdges.last() != e) {
    156                                    sb.append(",");
    157                            }
    158                    }
    159                    sb.append("]");
    160                    sb.append(super.toString());
    161                    return sb.toString();
    162            }
    163    }