Skip to content

Commit c2f3304

Browse files
author
Ben Romberg
committed
grouping output packages by cycle and name
1 parent 21e4380 commit c2f3304

File tree

3 files changed

+94
-39
lines changed

3 files changed

+94
-39
lines changed

src/main/java/de/andrena/tools/nopackagecycles/NoPackageCyclesRule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.File;
44
import java.io.IOException;
5+
import java.util.ArrayList;
56
import java.util.Collection;
67

78
import jdepend.framework.JDepend;
@@ -56,7 +57,7 @@ protected JDepend createJDepend() {
5657
private String getPackageCycles(JDepend jdepend) {
5758
@SuppressWarnings("unchecked")
5859
Collection<JavaPackage> packages = jdepend.getPackages();
59-
return new PackageCycleOutput(packages).getOutput();
60+
return new PackageCycleOutput(new ArrayList<JavaPackage>(packages)).getOutput();
6061
}
6162

6263
private boolean checkIsNecessary(MavenProject project, File classesDir) {

src/main/java/de/andrena/tools/nopackagecycles/PackageCycleOutput.java

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,35 @@
1616

1717
public class PackageCycleOutput {
1818

19-
private final Collection<JavaPackage> packages;
19+
private List<JavaPackage> packages;
2020
private StringBuilder output;
2121

22-
public PackageCycleOutput(Collection<JavaPackage> packages) {
22+
public PackageCycleOutput(List<JavaPackage> packages) {
2323
this.packages = packages;
2424
}
2525

2626
public String getOutput() {
2727
output = new StringBuilder();
28-
for (JavaPackage javaPackage : packages) {
28+
orderPackagesByName();
29+
while (!packages.isEmpty()) {
30+
JavaPackage javaPackage = packages.get(0);
31+
packages.remove(0);
2932
if (javaPackage.containsCycle()) {
3033
appendOutputForPackage(javaPackage);
3134
}
3235
}
3336
return output.toString();
3437
}
3538

39+
private void orderPackagesByName() {
40+
List<JavaPackage> packageList = new ArrayList<JavaPackage>(packages);
41+
orderByPackageName(packageList);
42+
packages = packageList;
43+
}
44+
3645
private void appendOutputForPackage(final JavaPackage javaPackage) {
3746
output.append("\n").append(javaPackage.getName()).append(" has cyclic dependency to: ");
38-
joinCollection(getCyclicPackages(javaPackage), output, new Appender<JavaPackage>() {
47+
joinCollection(getAndPrependCyclicPackages(javaPackage), output, new Appender<JavaPackage>() {
3948
public void append(JavaPackage cyclicPackage) {
4049
appendOutputForCyclicPackage(javaPackage, cyclicPackage);
4150
}
@@ -78,20 +87,37 @@ private List<JavaClass> getClassesDependentOnPackage(JavaPackage javaPackage, Ja
7887
return dependentClasses;
7988
}
8089

81-
private List<JavaPackage> getCyclicPackages(JavaPackage javaPackage) {
90+
private List<JavaPackage> getAndPrependCyclicPackages(JavaPackage javaPackage) {
8291
List<JavaPackage> cyclicPackages = new ArrayList<JavaPackage>();
8392
javaPackage.collectAllCycles(cyclicPackages);
8493
removeSelfAndDuplications(javaPackage, cyclicPackages);
85-
return orderByPackageName(cyclicPackages);
94+
orderByPackageName(cyclicPackages);
95+
prependPackages(cyclicPackages);
96+
return cyclicPackages;
97+
}
98+
99+
private void prependPackages(List<JavaPackage> cyclicPackages) {
100+
List<JavaPackage> pendingCyclicPackages = getPendingCyclicPackages(cyclicPackages);
101+
packages.removeAll(pendingCyclicPackages);
102+
packages.addAll(0, pendingCyclicPackages);
86103
}
87104

88-
private List<JavaPackage> orderByPackageName(List<JavaPackage> cyclicPackages) {
105+
private List<JavaPackage> getPendingCyclicPackages(List<JavaPackage> cyclicPackages) {
106+
List<JavaPackage> pendingCyclicPackages = new ArrayList<JavaPackage>();
107+
for (JavaPackage cyclicPackage : cyclicPackages) {
108+
if (packages.contains(cyclicPackage)) {
109+
pendingCyclicPackages.add(cyclicPackage);
110+
}
111+
}
112+
return pendingCyclicPackages;
113+
}
114+
115+
private void orderByPackageName(List<JavaPackage> cyclicPackages) {
89116
Collections.sort(cyclicPackages, new Comparator<JavaPackage>() {
90117
public int compare(JavaPackage package1, JavaPackage package2) {
91118
return package1.getName().compareTo(package2.getName());
92119
}
93120
});
94-
return cyclicPackages;
95121
}
96122

97123
private void removeSelfAndDuplications(JavaPackage javaPackage, List<JavaPackage> cyclicPackages) {

src/test/java/de/andrena/tools/nopackagecycles/PackageCycleOutputTest.java

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
import static de.andrena.tools.nopackagecycles.CollectionOutput.joinArray;
44
import static org.hamcrest.MatcherAssert.assertThat;
5-
import static org.hamcrest.Matchers.containsString;
5+
import static org.hamcrest.Matchers.is;
66

77
import java.util.ArrayList;
8-
import java.util.Collection;
98
import java.util.List;
109

1110
import jdepend.framework.JavaClass;
@@ -24,29 +23,21 @@ public class PackageCycleOutputTest {
2423
private static final String PACKAGE2_CLASS_NAME = "Package2Class";
2524
private static final String PACKAGE1_NAME = "sample.package1";
2625
private static final String PACKAGE2_NAME = "sample.package2";
27-
private Collection<JavaPackage> packages;
26+
private List<JavaPackage> packages;
2827
private JavaPackage package1;
2928
private JavaPackage package2;
3029

3130
@Before
3231
public void setUp() {
3332
packages = new ArrayList<JavaPackage>();
34-
package1 = createPackage(PACKAGE1_NAME);
35-
package2 = createPackage(PACKAGE2_NAME);
33+
initDefaultPackages();
3634
package1.dependsUpon(package2);
3735
package2.dependsUpon(package1);
3836
}
3937

40-
private JavaPackage createPackage(String package1Name) {
41-
JavaPackage newPackage = new JavaPackage(package1Name);
42-
packages.add(newPackage);
43-
return newPackage;
44-
}
45-
4638
@Test
4739
public void outputFor_TwoPackagesWithCycle() throws Exception {
48-
assertOutput(package1, package2);
49-
assertOutput(package2, package1);
40+
assertOutput(getPackageOutput(package1, package2) + getPackageOutput(package2, package1));
5041
}
5142

5243
@Test
@@ -55,16 +46,15 @@ public void outputFor_TwoPackagesWithCycleAndClasses() throws Exception {
5546
package1Class.addImportedPackage(package2);
5647
JavaClass package2Class = createClassInPackage(PACKAGE2_CLASS_NAME, package2);
5748
package2Class.addImportedPackage(package1);
58-
assertOutputWithClasses(package1, package2, PACKAGE2_CLASS_NAME);
59-
assertOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1);
49+
assertOutput(getPackageOutputWithClasses(package1, package2, PACKAGE2_CLASS_NAME)
50+
+ getPackageOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1));
6051
}
6152

6253
@Test
6354
public void outputFor_TwoPackagesWithCycle_AndOnePackageWithoutCycle() throws Exception {
6455
String packageWithoutCycleName = "sample.package.without.cycle";
6556
createPackage(packageWithoutCycleName);
66-
assertOutput(package1, package2);
67-
assertOutput(package2, package1);
57+
assertOutput(getPackageOutput(package1, package2) + getPackageOutput(package2, package1));
6858
}
6959

7060
@Test
@@ -73,9 +63,8 @@ public void outputFor_ThreePackagesWithCycle() throws Exception {
7363
JavaPackage package3 = createPackage(package3Name);
7464
package1.dependsUpon(package3);
7565
package3.dependsUpon(package1);
76-
assertOutput(package1, package2, package3);
77-
assertOutput(package2, package1, package3);
78-
assertOutput(package3, package1, package2);
66+
assertOutput(getPackageOutput(package1, package2, package3) + getPackageOutput(package2, package1, package3)
67+
+ getPackageOutput(package3, package1, package2));
7968
}
8069

8170
@Test
@@ -84,17 +73,52 @@ public void outputFor_PackageWithCycleAndMultipleClasses() throws Exception {
8473
package1Class1.addImportedPackage(package2);
8574
JavaClass package1Class2 = createClassInPackage(PACKAGE1_CLASS_NAME2, package1);
8675
package1Class2.addImportedPackage(package2);
87-
assertOutput(package1, package2);
88-
assertOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1, PACKAGE1_CLASS_NAME2);
76+
assertOutput(getPackageOutput(package1, package2)
77+
+ getPackageOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1, PACKAGE1_CLASS_NAME2));
8978
}
9079

9180
@Test
9281
public void outputFor_PackageWithCycleAndClassWithoutCycle() throws Exception {
9382
JavaClass package1Class1 = createClassInPackage(PACKAGE1_CLASS_NAME1, package1);
9483
package1Class1.addImportedPackage(package2);
9584
createClassInPackage(PACKAGE1_CLASS_NAME2, package1);
96-
assertOutput(package1, package2);
97-
assertOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1);
85+
assertOutput(getPackageOutput(package1, package2)
86+
+ getPackageOutputWithClasses(package2, package1, PACKAGE1_CLASS_NAME1));
87+
}
88+
89+
@Test
90+
public void outputFor_MultiplePackageCycles_IsOrderedByName() {
91+
JavaPackage otherPackage1 = createPackage("other.package1");
92+
JavaPackage otherPackage2 = createPackage("other.package2");
93+
otherPackage1.dependsUpon(otherPackage2);
94+
otherPackage2.dependsUpon(otherPackage1);
95+
assertOutput(getPackageOutput(otherPackage1, otherPackage2) + getPackageOutput(otherPackage2, otherPackage1)
96+
+ getPackageOutput(package1, package2) + getPackageOutput(package2, package1));
97+
}
98+
99+
@Test
100+
public void outputFor_MultiplePackageCycles_IsOrderedByCycle() {
101+
initDefaultPackages();
102+
JavaPackage otherPackage1 = createPackage("other.package1");
103+
JavaPackage otherPackage2 = createPackage("other.package2");
104+
package1.dependsUpon(otherPackage1);
105+
otherPackage1.dependsUpon(package1);
106+
package2.dependsUpon(otherPackage2);
107+
otherPackage2.dependsUpon(package2);
108+
assertOutput(getPackageOutput(otherPackage1, package1) + getPackageOutput(package1, otherPackage1)
109+
+ getPackageOutput(otherPackage2, package2) + getPackageOutput(package2, otherPackage2));
110+
}
111+
112+
private JavaPackage createPackage(String package1Name) {
113+
JavaPackage newPackage = new JavaPackage(package1Name);
114+
packages.add(newPackage);
115+
return newPackage;
116+
}
117+
118+
private void initDefaultPackages() {
119+
packages.clear();
120+
package1 = createPackage(PACKAGE1_NAME);
121+
package2 = createPackage(PACKAGE2_NAME);
98122
}
99123

100124
private JavaClass createClassInPackage(String className, JavaPackage classPackage) {
@@ -103,17 +127,18 @@ private JavaClass createClassInPackage(String className, JavaPackage classPackag
103127
return package1Class;
104128
}
105129

106-
private void assertOutputWithClasses(JavaPackage javaPackage, JavaPackage dependencyPackage, String... classNames) {
130+
private String getPackageOutputWithClasses(JavaPackage javaPackage, JavaPackage dependencyPackage,
131+
String... classNames) {
107132
String joinedClassNames = joinArray(classNames, new StringProvider<String>() {
108133
public String provide(String value) {
109134
return value;
110135
}
111136
});
112-
assertThat(new PackageCycleOutput(packages).getOutput(), containsString(getPackageOutput(javaPackage.getName())
113-
+ getDependencyPackageOutput(dependencyPackage.getName(), joinedClassNames)));
137+
return getPackageOutput(javaPackage.getName())
138+
+ getDependencyPackageOutput(dependencyPackage.getName(), joinedClassNames);
114139
}
115140

116-
private void assertOutput(JavaPackage javaPackage, JavaPackage... dependencyPackages) {
141+
private String getPackageOutput(JavaPackage javaPackage, JavaPackage... dependencyPackages) {
117142
@SuppressWarnings("unchecked")
118143
List<JavaPackage> dependencyPackageList = Arrays.asList(dependencyPackages);
119144
String dependencyOutput = CollectionOutput.joinCollection(dependencyPackageList,
@@ -122,8 +147,11 @@ public String provide(JavaPackage dependencyPackage) {
122147
return getDependencyPackageOutput(dependencyPackage.getName(), "");
123148
}
124149
});
125-
assertThat(new PackageCycleOutput(packages).getOutput(), containsString(getPackageOutput(javaPackage.getName())
126-
+ dependencyOutput));
150+
return getPackageOutput(javaPackage.getName()) + dependencyOutput;
151+
}
152+
153+
private void assertOutput(String output) {
154+
assertThat(new PackageCycleOutput(packages).getOutput(), is(output));
127155
}
128156

129157
private String getPackageOutput(String packageName) {

0 commit comments

Comments
 (0)