diff options
Diffstat (limited to 'framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java')
-rw-r--r-- | framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java new file mode 100644 index 00000000..65e3cfbc --- /dev/null +++ b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java @@ -0,0 +1,118 @@ +package org.onlab.jdvue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Simple representation of a Java package dependency cycle. + */ +public class DependencyCycle { + + private final List<JavaPackage> cycle; + + /** + * Creates a normalized dependency cycle represented by the specified list + * of Java packages, which are expected to be given in order of dependency. + * List is assumed to be non-empty. + * + * @param cycle list of Java packages in the dependency cycle + * @param cause Java package that caused the cycle + */ + DependencyCycle(List<JavaPackage> cycle, JavaPackage cause) { + this.cycle = normalize(cycle, cause); + } + + /** + * Produces a normalized dependency cycle list. Normalization is performed + * by rotating the list so that the package with the least lexicographic + * name is at the start of the list. + * + * @param cycle list of Java packages in the dependency cycle + * @param cause Java package that caused the cycle + * @return normalized cycle + */ + private List<JavaPackage> normalize(List<JavaPackage> cycle, JavaPackage cause) { + int start = cycle.indexOf(cause); + List<JavaPackage> clone = new ArrayList<>(cycle.subList(start, cycle.size())); + int leastIndex = findIndexOfLeastName(clone); + Collections.rotate(clone, -leastIndex); + return Collections.unmodifiableList(clone); + } + + /** + * Returns the index of the Java package with the least name. + * + * @param cycle list of Java packages in the dependency cycle + * @return index of the least Java package name + */ + private int findIndexOfLeastName(List<JavaPackage> cycle) { + int leastIndex = 0; + String leastName = cycle.get(leastIndex).name(); + for (int i = 1, n = cycle.size(); i < n; i++) { + JavaPackage javaPackage = cycle.get(i); + if (leastName.compareTo(javaPackage.name()) > 0) { + leastIndex = i; + leastName = javaPackage.name(); + } + } + return leastIndex; + } + + /** + * Returns the normalized Java package dependency cycle + * + * @return list of packages in the dependency cycle + */ + public List<JavaPackage> getCycle() { + return cycle; + } + + /** + * Returns the dependency cycle in form of individual dependencies. + * + * @return list of dependencies forming the cycle + */ + public List<Dependency> getCycleSegments() { + List<Dependency> dependencies = new ArrayList<>(); + for (int i = 0, n = cycle.size(); i < n; i++) { + dependencies.add(new Dependency(cycle.get(i), cycle.get(i < n - 1 ? i + 1 : 0))); + } + return dependencies; + } + + @Override + public boolean equals(Object o) { + if (o instanceof DependencyCycle) { + DependencyCycle that = (DependencyCycle) o; + return Objects.equals(cycle, that.cycle); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(cycle); + } + + @Override + public String toString() { + return toStringHelper(this).add("cycle", cycle).toString(); + } + + public String toShortString() { + StringBuilder sb = new StringBuilder("["); + for (JavaPackage javaPackage : cycle) { + sb.append(javaPackage.name()).append(", "); + } + if (sb.length() > 1) { + sb.delete(sb.length() - 2, sb.length()); + } + sb.append("]"); + return sb.toString(); + } + +} |