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.graph;
021    
022    import java.util.Arrays;
023    import java.util.List;
024    
025    public class Cycle {
026    
027      private List<Node> nodes;
028      private int        hashCode;
029    
030      public Cycle(List<Node> nodes) {
031        this.nodes = nodes;
032        hashCode = 0;
033        for (Node node : nodes) {
034          hashCode += node.hashCode();
035        }
036      }
037    
038      public Cycle(Node... nodes) {
039        this(Arrays.asList(nodes));
040      }
041    
042      public int getCycleLength() {
043        return nodes.size();
044      }
045    
046      public boolean contains(Node resource) {
047        return nodes.contains(resource);
048      }
049    
050      public List<Node> getNodes() {
051        return nodes;
052      }
053    
054      @Override
055      public String toString() {
056        StringBuilder builder = new StringBuilder();
057        Edge weaker = getWeakerEdge();
058        builder.append("Cycle between " + getCycleLength() + " resources : \n");
059        for (Node from : nodes) {
060          Edge relation = getEdgeFrom(from);
061          String weakerFlag = "   ";
062          if (weaker.equals(relation)) {
063            weakerFlag = " * ";
064          }
065          builder.append(weakerFlag + relation.getFrom().getKey() + " --" + relation.getWeight() + "--> " + "\n");
066        }
067        return builder.toString();
068      }
069    
070      @Override
071      public boolean equals(Object object) {
072        if (!(object instanceof Cycle)) {
073          return false;
074        }
075        return hashCode == object.hashCode();
076      }
077      
078      @Override
079      public int hashCode(){
080        return hashCode;
081      }
082    
083      public Edge getWeakerEdge() {
084        Edge weaker = null;
085        for (Node from : nodes) {
086          Edge relation = getEdgeFrom(from);
087          if (weaker == null || weaker.getWeight() > relation.getWeight()) {
088            weaker = relation;
089          }
090        }
091        return weaker;
092      }
093    
094      private Edge getEdgeFrom(Node from) {
095        int index = nodes.indexOf(from);
096        Node to = nodes.get((index + 1 < nodes.size() ? index + 1 : 0));
097        return from.getEdgeTo(to);
098      }
099    }