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                    if (source != null) {
050                            this.source.removeOutgoingEdge(this);
051                    }
052                    if (target != null) {
053                            this.target.removeIncomingEdge(this);
054                    }
055                    this.source = null;
056                    this.target = null;
057                    this.type = -1;
058            }
059            
060            /**
061             * Returns the source node of the edge.
062             * 
063             * @return the source node of the edge.
064             */
065            public Node getSource() {
066                    return this.source;
067            }
068            
069            /**
070             * Returns the target node of the edge.
071             * 
072             * @return the target node of the edge.
073             */
074            public Node getTarget() {
075                    return this.target;
076            }
077            
078            /**
079             * Returns the edge type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE or SECONDARY_EDGE).
080             * 
081             * @return the edge type (DEPENDENCY_EDGE, PHRASE_STRUCTURE_EDGE or SECONDARY_EDGE).
082             */
083            public int getType() {
084                    return this.type;
085            }
086    
087            public int compareTo(GraphEdge that) {
088                    final int BEFORE = -1;
089                final int EQUAL = 0;
090                final int AFTER = 1;
091                
092                if (this == that) return EQUAL;
093                
094                if (this.target.getCompareToIndex() < that.target.getCompareToIndex()) return BEFORE;
095                if (this.target.getCompareToIndex() > that.target.getCompareToIndex()) return AFTER;
096                
097                if (this.source.getCompareToIndex() < that.source.getCompareToIndex()) return BEFORE;
098                if (this.source.getCompareToIndex() > that.source.getCompareToIndex()) return AFTER;
099                
100                if (this.type < that.type) return BEFORE;
101                if (this.type > that.type) return AFTER;
102                
103                    return super.compareTo(that);
104            }
105            
106            
107            public boolean equals(Object obj) {
108                    final GraphEdge e = (GraphEdge)obj;
109                    return this.type == e.getType() && this.source.equals(e.getSource()) && this.target.equals(e.getTarget()) && super.equals(obj); 
110            }
111            
112            public int hashCode() {
113                    int hash = 7;
114                    hash = 31 * hash + type;
115                    hash = 31 * hash + (null == source ? 0 : source.hashCode());
116                    hash = 31 * hash + (null == target ? 0 : target.hashCode());
117                    return 31 * hash + super.hashCode();
118            }
119            
120            public String toString() {
121                    final StringBuilder sb = new StringBuilder();
122                    sb.append(source.getIndex());
123                    sb.append("->");
124                    sb.append(target.getIndex());
125                    sb.append(' ');
126                    sb.append(super.toString());
127                    return sb.toString();
128            }
129    }