给定一组不应禁止使用某些 API(无论出于何种原因)的类。
例如,禁止 Java 8 Streaming API,或调用Builder内部类,因为您想强制对特定类使用循环和构造函数。
ownerName
关键部分是您事先不知道,并且callMethod(methodName)
我无法粗粒度地禁止调用stream()
或build()
方法。
有任何想法吗?
ArchRule
您可以使用谓词而不是 fluent API来组合强大的 s;在你的情况下
.callMethodWhere(DescribedPredicate<? super JavaMethodCall> predicate)
。
为了防止使用someCollection.stream()
,您可以从 开始HasName.Predicates.
name
:
noClasses().should().callMethodWhere(name("stream"))
为了避免误报,该规则可能应该变得更加具体。
ArchUnit 提供了许多有用的预定义谓词;您只需要找到它们(并可能通过 处理它们的协变参数类型DescribedPredicate.forSubtype
):
noClasses().should().callMethodWhere(target(
name("stream").<CodeUnitCallTarget>forSubtype().and(
owner(assignableTo(Collection.class)).<CodeUnitCallTarget>forSubtype().and(
rawParameterTypes(new Class[0])
)
)
))
我个人觉得定义一个自定义谓词更简单(例如使用
DescribedPredicate.
describe
):
noClasses().should().callMethodWhere(target(describe("is Collection.stream()",
target -> "stream".equals(target.getName()) &&
target.getOwner().isAssignableTo(Collection.class) &&
target.getParameterTypes().isEmpty()
)))
仅供参考:我的解决方案使用以下导入:
import static com.tngtech.archunit.base.DescribedPredicate.describe;
import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;