001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.squid.api;
021
022 import java.util.HashSet;
023 import java.util.Set;
024
025 import org.sonar.graph.Edge;
026
027 public class SourceCodeEdge implements Edge<SourceCode> {
028
029 private final SourceCode from;
030 private final SourceCode to;
031 private final SourceCodeEdgeUsage usage;
032 private Set<SourceCodeEdge> rootEdges;
033 private Set<SourceCode> rootFromNodes;
034 private Set<SourceCode> rootToNodes;
035 private final int hashcode;
036 private SourceCodeEdge parent;
037
038 public SourceCodeEdge(SourceCode from, SourceCode to, SourceCodeEdgeUsage link) {
039 this(from, to, link, null);
040 }
041
042 public SourceCodeEdge(SourceCode from, SourceCode to, SourceCodeEdgeUsage usage, SourceCodeEdge rootEdge) {
043 this.hashcode = from.hashCode() * 31 + to.hashCode() + usage.hashCode();
044 this.from = from;
045 this.to = to;
046 this.usage = usage;
047 addRootEdge(rootEdge);
048 }
049
050 public SourceCode getFrom() {
051 return from;
052 }
053
054 public SourceCode getTo() {
055 return to;
056 }
057
058 public SourceCodeEdgeUsage getUsage() {
059 return usage;
060 }
061
062 private boolean noRoots() {
063 return rootEdges == null;
064 }
065
066 public boolean hasAnEdgeFromRootNode(SourceCode rootFromNode) {
067 if (noRoots()) {
068 return false;
069 }
070 return rootFromNodes.contains(rootFromNode);
071 }
072
073 public boolean hasAnEdgeToRootNode(SourceCode rootToNode) {
074 if (noRoots()) {
075 return false;
076 }
077 return rootToNodes.contains(rootToNode);
078 }
079
080 public Set<SourceCodeEdge> getRootEdges() {
081 return rootEdges;
082 }
083
084 public int getNumberOfRootFromNodes() {
085 if (noRoots()) {
086 return 0;
087 }
088 return rootFromNodes.size();
089 }
090
091 public final void addRootEdge(SourceCodeEdge rootRelationShip) {
092 if (noRoots()) {
093 rootEdges = new HashSet<SourceCodeEdge>();
094 rootFromNodes = new HashSet<SourceCode>();
095 rootToNodes = new HashSet<SourceCode>();
096 }
097 if (rootRelationShip != null) {
098 rootEdges.add(rootRelationShip);
099 rootFromNodes.add(rootRelationShip.getFrom());
100 rootToNodes.add(rootRelationShip.getTo());
101 rootRelationShip.setParent(this);
102 }
103 }
104
105 public int getWeight() {
106 if (noRoots()) {
107 return 0;
108 }
109 return rootEdges.size();
110 }
111
112 public SourceCodeEdge getParent() {
113 return parent;
114 }
115
116 public SourceCodeEdge setParent(SourceCodeEdge parent) {
117 this.parent = parent;
118 return this;
119 }
120
121 @Override
122 public boolean equals(Object obj) {
123 if (!(obj instanceof SourceCodeEdge) || this.hashCode() != obj.hashCode()) {
124 return false;
125 }
126 SourceCodeEdge edge = (SourceCodeEdge) obj;
127 return from.equals(edge.from) && to.equals(edge.to);
128 }
129
130 @Override
131 public int hashCode() {
132 return hashcode;
133 }
134
135 @Override
136 public String toString() {
137 return "from : " + from + ", to : " + to;
138 }
139 }