Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fffe312

Browse filesBrowse files
committed
Make apache commons restrictions more accurate and legible
1 parent ce17396 commit fffe312
Copy full SHA for fffe312

File tree

Expand file treeCollapse file tree

1 file changed

+96
-39
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+96
-39
lines changed

‎src/test/java/org/kohsuke/github/ArchTests.java

Copy file name to clipboardExpand all lines: src/test/java/org/kohsuke/github/ArchTests.java
+96-39Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
package org.kohsuke.github;
22

33
import com.tngtech.archunit.base.DescribedPredicate;
4-
import com.tngtech.archunit.core.domain.JavaAnnotation;
5-
import com.tngtech.archunit.core.domain.JavaCall;
6-
import com.tngtech.archunit.core.domain.JavaClass;
7-
import com.tngtech.archunit.core.domain.JavaClasses;
4+
import com.tngtech.archunit.core.domain.*;
85
import com.tngtech.archunit.core.domain.properties.HasName;
96
import com.tngtech.archunit.core.domain.properties.HasOwner;
107
import com.tngtech.archunit.core.importer.ClassFileImporter;
118
import com.tngtech.archunit.core.importer.ImportOption;
9+
import com.tngtech.archunit.lang.ArchCondition;
1210
import com.tngtech.archunit.lang.ArchRule;
11+
import org.apache.commons.io.IOUtils;
12+
import org.apache.commons.lang3.StringUtils;
13+
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
14+
import org.apache.commons.lang3.builder.ToStringBuilder;
15+
import org.apache.commons.lang3.builder.ToStringStyle;
1316
import org.junit.BeforeClass;
1417
import org.junit.Test;
1518

19+
import java.io.Closeable;
20+
import java.io.InputStream;
21+
import java.io.Reader;
22+
import java.lang.reflect.Field;
23+
import java.nio.charset.Charset;
24+
25+
import static com.google.common.base.Preconditions.checkNotNull;
1626
import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
1727
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
28+
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.type;
29+
import static com.tngtech.archunit.core.domain.JavaClass.namesOf;
1830
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
1931
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameContaining;
32+
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
33+
import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
2034
import static com.tngtech.archunit.lang.conditions.ArchConditions.*;
2135
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
2236
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
@@ -139,45 +153,88 @@ public void testRequireUseOfAssertThat() {
139153
@Test
140154
public void testRequireUseOfOnlySpecificApacheCommons() {
141155

142-
final DescribedPredicate<JavaCall<?>> approvedStringUtilsMethods = target(
143-
HasOwner.Predicates.With.<JavaClass>owner(name("org.apache.commons.lang3.StringUtils")))
144-
.and(target(name("prependIfMissing").or(name("isBlank"))
145-
.or(name("isEmpty"))
146-
.or(name("equals"))
147-
.or(name("capitalize"))
148-
.or(name("join"))
149-
.or(name("defaultString"))));
150-
final DescribedPredicate<JavaCall<?>> approvedToStringBuilderMethods = target(
151-
HasOwner.Predicates.With.<JavaClass>owner(name("org.apache.commons.lang3.builder.ToStringBuilder")))
152-
.and(target(name("toString").or(name("append"))
153-
.or(name("isEmpty"))
154-
.or(name("equals"))
155-
.or(name("capitalize"))));
156-
final DescribedPredicate<JavaCall<?>> approvedToStringStyleMethods = target(
157-
HasOwner.Predicates.With.<JavaClass>owner(name("org.apache.commons.lang3.builder.ToStringStyle")))
158-
.and(target(name("append")));
159-
final DescribedPredicate<JavaCall<?>> approvedReflectionStringBuilderMethods = target(HasOwner.Predicates.With
160-
.<JavaClass>owner(name("org.apache.commons.lang3.builder.ReflectionToStringBuilder")))
161-
.and(target(name("accept")));
162-
163-
final DescribedPredicate<JavaCall<?>> approvedIOUtilsMethods = target(
164-
HasOwner.Predicates.With.<JavaClass>owner(name("org.apache.commons.io.IOUtils")))
165-
.and(target(name("closeQuietly").or(name("toString")).or(name("toByteArray"))));
166-
167-
final DescribedPredicate<JavaCall<?>> approvedApacheCommonsMethods = approvedStringUtilsMethods
168-
.or(approvedToStringBuilderMethods)
169-
.or(approvedToStringStyleMethods)
170-
.or(approvedReflectionStringBuilderMethods)
171-
.or(approvedIOUtilsMethods);
172-
173156
final ArchRule onlyApprovedApacheCommonsLang3Methods = classes()
174-
.should(not(callMethodWhere(
175-
target(HasOwner.Predicates.With.<JavaClass>owner(resideInAPackage("org.apache.commons..")))
176-
.and(DescribedPredicate.not(approvedApacheCommonsMethods)))))
157+
.should(notCallMethodsInPackageUnless("org.apache.commons..",
158+
// unless it is one of these methods
159+
targetMethodIs(StringUtils.class, "capitalize", String.class),
160+
targetMethodIs(StringUtils.class, "defaultString", String.class, String.class),
161+
targetMethodIs(StringUtils.class, "equals", CharSequence.class, CharSequence.class),
162+
targetMethodIs(StringUtils.class, "isBlank", CharSequence.class),
163+
targetMethodIs(StringUtils.class, "isEmpty", CharSequence.class),
164+
targetMethodIs(StringUtils.class, "join", Iterable.class, String.class),
165+
targetMethodIs(StringUtils.class,
166+
"prependIfMissing",
167+
String.class,
168+
CharSequence.class,
169+
CharSequence[].class),
170+
targetMethodIs(ToStringBuilder.class, "toString"),
171+
targetMethodIs(ToStringBuilder.class, "append", String.class, Object.class),
172+
targetMethodIs(ToStringBuilder.class, "append", String.class, long.class),
173+
targetMethodIs(ToStringBuilder.class, "append", String.class, int.class),
174+
targetMethodIs(ToStringBuilder.class, "isEmpty"),
175+
targetMethodIs(ToStringBuilder.class, "equals"),
176+
targetMethodIs(ToStringBuilder.class, "capitalize"),
177+
targetMethodIs(ToStringStyle.class,
178+
"append",
179+
StringBuffer.class,
180+
String.class,
181+
Object.class,
182+
Boolean.class),
183+
targetMethodIs(ReflectionToStringBuilder.class, "accept", Field.class),
184+
targetMethodIs(IOUtils.class, "closeQuietly", InputStream.class),
185+
targetMethodIs(IOUtils.class, "closeQuietly", Closeable.class),
186+
targetMethodIs(IOUtils.class, "toString", InputStream.class, Charset.class),
187+
targetMethodIs(IOUtils.class, "toString", Reader.class),
188+
targetMethodIs(IOUtils.class, "toByteArray", InputStream.class)))
177189
.because(
178-
"Only commons methods that have been manually verified to be compatible with commons-io:2.4 or earlier and commons-lang3:3.9 or earlier should be used.");
190+
"Commons methods must be manually verified to be compatible with commons-io:2.4 or earlier and commons-lang3:3.9 or earlier should be used.");
179191

180192
onlyApprovedApacheCommonsLang3Methods.check(classFiles);
181193
}
182194

195+
public static ArchCondition<JavaClass> notCallMethodsInPackageUnless(final String packageIdentifier,
196+
final DescribedPredicate<JavaCall<?>>... unlessPredicates) {
197+
DescribedPredicate<JavaCall<?>> restrictedPackageCalls = target(
198+
HasOwner.Predicates.With.<JavaClass>owner(resideInAPackage(packageIdentifier)));
199+
200+
if (unlessPredicates.length > 0) {
201+
DescribedPredicate<JavaCall<?>> allowed = unlessPredicates[0];
202+
for (int x = 1; x < unlessPredicates.length; x++) {
203+
allowed = allowed.or(unlessPredicates[x]);
204+
}
205+
restrictedPackageCalls = unless(restrictedPackageCalls, allowed);
206+
}
207+
return not(callMethodWhere(restrictedPackageCalls));
208+
}
209+
210+
public static DescribedPredicate<JavaCall<?>> targetMethodIs(Class<?> owner,
211+
String methodName,
212+
Class<?>... parameterTypes) {
213+
return JavaCall.Predicates.target(owner(type(owner)))
214+
.and(JavaCall.Predicates.target(name(methodName)))
215+
.and(JavaCall.Predicates.target(rawParameterTypes(parameterTypes)))
216+
.as("method is %s",
217+
Formatters.formatMethodSimple(owner.getSimpleName(), methodName, namesOf(parameterTypes)));
218+
}
219+
220+
public static <T> DescribedPredicate<T> unless(DescribedPredicate<? super T> first,
221+
DescribedPredicate<? super T> second) {
222+
return new UnlessPredicate(first, second);
223+
}
224+
225+
private static class UnlessPredicate<T> extends DescribedPredicate<T> {
226+
private final DescribedPredicate<T> current;
227+
private final DescribedPredicate<? super T> other;
228+
229+
UnlessPredicate(DescribedPredicate<T> current, DescribedPredicate<? super T> other) {
230+
super(current.getDescription() + " unless " + other.getDescription());
231+
this.current = checkNotNull(current);
232+
this.other = checkNotNull(other);
233+
}
234+
235+
@Override
236+
public boolean apply(T input) {
237+
return current.apply(input) && !other.apply(input);
238+
}
239+
}
183240
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.