001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 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 }