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
021package org.sonar.squid.api;
022
023import java.util.HashSet;
024import java.util.Set;
025
026import org.sonar.graph.Edge;
027
028public 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}