001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
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
021 package org.sonar.squid.api;
022
023 import java.util.HashSet;
024 import java.util.Set;
025
026 import org.sonar.graph.Edge;
027
028 public class SourceCodeEdge implements Edge<SourceCode> {
029
030 private final SourceCode from;
031 private final SourceCode to;
032 private final SourceCodeEdgeUsage usage;
033 private Set<SourceCodeEdge> rootEdges;
034 private Set<SourceCode> rootFromNodes;
035 private Set<SourceCode> rootToNodes;
036 private final int hashcode;
037 private SourceCodeEdge parent;
038
039 public SourceCodeEdge(SourceCode from, SourceCode to, SourceCodeEdgeUsage link) {
040 this(from, to, link, null);
041 }
042
043 public SourceCodeEdge(SourceCode from, SourceCode to, SourceCodeEdgeUsage usage, SourceCodeEdge rootEdge) {
044 this.hashcode = from.hashCode() * 31 + to.hashCode() + usage.hashCode(); //NOSONAR even if this basic algorithm could be improved
045 this.from = from;
046 this.to = to;
047 this.usage = usage;
048 addRootEdge(rootEdge);
049 }
050
051 public SourceCode getFrom() {
052 return from;
053 }
054
055 public SourceCode getTo() {
056 return to;
057 }
058
059 public SourceCodeEdgeUsage getUsage() {
060 return usage;
061 }
062
063 private boolean noRoots() {
064 return rootEdges == null;
065 }
066
067 public boolean hasAnEdgeFromRootNode(SourceCode rootFromNode) {
068 if (noRoots()) {
069 return false;
070 }
071 return rootFromNodes.contains(rootFromNode);
072 }
073
074 public boolean hasAnEdgeToRootNode(SourceCode rootToNode) {
075 if (noRoots()) {
076 return false;
077 }
078 return rootToNodes.contains(rootToNode);
079 }
080
081 public Set<SourceCodeEdge> getRootEdges() {
082 return rootEdges;
083 }
084
085 public int getNumberOfRootFromNodes() {
086 if (noRoots()) {
087 return 0;
088 }
089 return rootFromNodes.size();
090 }
091
092 public final void addRootEdge(SourceCodeEdge rootRelationShip) {
093 if (noRoots()) {
094 rootEdges = new HashSet<SourceCodeEdge>();
095 rootFromNodes = new HashSet<SourceCode>();
096 rootToNodes = new HashSet<SourceCode>();
097 }
098 if (rootRelationShip != null) {
099 rootEdges.add(rootRelationShip);
100 rootFromNodes.add(rootRelationShip.getFrom());
101 rootToNodes.add(rootRelationShip.getTo());
102 rootRelationShip.setParent(this);
103 }
104 }
105
106 public int getWeight() {
107 if (noRoots()) {
108 return 0;
109 }
110 return rootEdges.size();
111 }
112
113 public SourceCodeEdge getParent() {
114 return parent;
115 }
116
117 public SourceCodeEdge setParent(SourceCodeEdge parent) {
118 this.parent = parent;
119 return this;
120 }
121
122 @Override
123 public boolean equals(Object obj) {
124 if ( !(obj instanceof SourceCodeEdge) || this.hashCode() != obj.hashCode()) {
125 return false;
126 }
127 SourceCodeEdge edge = (SourceCodeEdge) obj;
128 return from.equals(edge.from) && to.equals(edge.to);
129 }
130
131 @Override
132 public int hashCode() {
133 return hashcode;
134 }
135
136 @Override
137 public String toString() {
138 return "from : " + from + ", to : " + to;
139 }
140 }