001    package org.maltparser.core.syntaxgraph.edge;
002    
003    import org.maltparser.core.exception.MaltChainedException;
004    import org.maltparser.core.syntaxgraph.GraphElement;
005    import org.maltparser.core.syntaxgraph.node.Node;
006    
007    
008    /**
009    *
010    *
011    * @author Johan Hall
012    */
013    public class GraphEdge extends GraphElement implements Edge, Comparable<GraphEdge> {
014            private Node source = null;
015            private Node target = null;
016            private int type;
017            
018            public GraphEdge() { }
019            
020            public GraphEdge(Node source, Node target, int type) throws MaltChainedException {
021                    super();
022                    clear();
023                    setEdge(source, target, type);
024            }
025            
026            /**
027             * Sets the edge with a source node, a target node and a type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE
028             * or SECONDARY_EDGE). 
029             * 
030             * @param source a source node
031             * @param target a target node
032             * @param type a type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE or SECONDARY_EDGE)
033             * @throws MaltChainedException
034             */
035            public void setEdge(Node source, Node target, int type) throws MaltChainedException {
036                    this.source = source;
037                    this.target = target;
038                    if (type >= Edge.DEPENDENCY_EDGE && type <= Edge.SECONDARY_EDGE ) {
039                            this.type = type;
040                    }
041                    this.source.addOutgoingEdge(this);
042                    this.target.addIncomingEdge(this);
043                    setChanged(); 
044                    notifyObservers(this);
045            }
046            
047            public void clear() throws MaltChainedException {
048                    super.clear();
049                    this.source.removeOutgoingEdge(this);
050                    this.target.removeIncomingEdge(this);
051                    this.source = null;
052                    this.target = null;
053                    this.type = -1;
054            }
055            
056            /**
057             * Returns the source node of the edge.
058             * 
059             * @return the source node of the edge.
060             */
061            public Node getSource() {
062                    return this.source;
063            }
064            
065            /**
066             * Returns the target node of the edge.
067             * 
068             * @return the target node of the edge.
069             */
070            public Node getTarget() {
071                    return this.target;
072            }
073            
074            /**
075             * Returns the edge type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE or SECONDARY_EDGE).
076             * 
077             * @return the edge type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE or SECONDARY_EDGE).
078             */
079            public int getType() {
080                    return this.type;
081            }
082    
083            public int compareTo(GraphEdge that) {
084                    final int BEFORE = -1;
085                final int EQUAL = 0;
086                final int AFTER = 1;
087                
088                if (this == that) return EQUAL;
089                
090                if (this.target.getCompareToIndex() < that.target.getCompareToIndex()) return BEFORE;
091                if (this.target.getCompareToIndex() > that.target.getCompareToIndex()) return AFTER;
092                
093                if (this.source.getCompareToIndex() < that.source.getCompareToIndex()) return BEFORE;
094                if (this.source.getCompareToIndex() > that.source.getCompareToIndex()) return AFTER;
095                
096                if (this.type < that.type) return BEFORE;
097                if (this.type > that.type) return AFTER;
098                
099                    return super.compareTo(that);
100            }
101            
102            
103            public boolean equals(Object obj) {
104                    final GraphEdge e = (GraphEdge)obj;
105                    return this.type == e.getType() && this.source.equals(e.getSource()) && this.target.equals(e.getTarget()) && super.equals(obj); 
106            }
107            
108            public int hashCode() {
109                    int hash = 7;
110                    hash = 31 * hash + type;
111                    hash = 31 * hash + (null == source ? 0 : source.hashCode());
112                    hash = 31 * hash + (null == target ? 0 : target.hashCode());
113                    return 31 * hash + super.hashCode();
114            }
115            
116            public String toString() {
117                    final StringBuilder sb = new StringBuilder();
118                    sb.append(source.getIndex());
119                    sb.append("->");
120                    sb.append(target.getIndex());
121                    sb.append(' ');
122                    sb.append(super.toString());
123                    return sb.toString();
124            }
125    }