001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.api.utils.dag;
021
022 import org.sonar.api.utils.SonarException;
023
024 import java.util.ArrayList;
025 import java.util.List;
026
027 /**
028 * @since 1.10
029 */
030 public class Node implements Comparable<Node> {
031
032 private final Object object;
033 private int order = 0;
034 private boolean seen = false;
035 private final List<Node> dependencies = new ArrayList<Node>();
036
037 public Node(final Object object) {
038 if (object == null) {
039 throw new SonarException("object can not be null");
040 }
041 this.object = object;
042 }
043
044 public void reset() {
045 order = 0;
046 seen = false;
047 }
048
049 public Object getObject() {
050 return object;
051 }
052
053 public void addDependency(Node v) {
054 if (!equals(v) && !dependencies.contains(v)) {
055 dependencies.add(v);
056 }
057 }
058
059 public void resolveOrder() {
060 resolveOrder(toString());
061 }
062
063 private int resolveOrder(String path) {
064 seen = true;
065 try {
066 int highOrder = -1;
067 for (Node dep : dependencies) {
068 if (dep.seen) {
069 throw new CyclicDependenciesException(path + " -> " + dep.toString());
070 }
071 highOrder = Math.max(highOrder, dep.resolveOrder(path + " -> " + dep.toString()));
072
073 }
074
075 order = highOrder + 1;
076 return order;
077
078 } finally {
079 seen = false;
080 }
081 }
082
083 public List<Node> getDependencies() {
084 return dependencies;
085 }
086
087 public int compareTo(final Node other) {
088 int orderInd = 0;
089
090 if (order < other.order) {
091 orderInd = -1;
092 } else if (order > other.order) {
093 orderInd = 1;
094 }
095
096 return orderInd;
097 }
098
099 @Override
100 public String toString() {
101 return object.toString();
102 }
103
104 @Override
105 public boolean equals(Object o) {
106 if (this == o) {
107 return true;
108 }
109 if (!(o instanceof Node)) {
110 return false;
111 }
112 return object.equals(((Node) o).getObject());
113 }
114
115 @Override
116 public int hashCode() {
117 return object.hashCode();
118 }
119 }
120