Skip to content

Commit

Permalink
Introduce reverse on ClassFilter and MethodFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
Jinhui-Z authored and snicoll committed Aug 28, 2023
1 parent c918418 commit 13e62d0
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 0 deletions.
Expand Up @@ -85,6 +85,17 @@ public static ClassFilter intersection(ClassFilter[] classFilters) {
return new IntersectionClassFilter(classFilters);
}

/**
* reverse the given ClassFilter match.
* @param cf the ClassFilter
* @return a distinct ClassFilter that not matches classes
* of the given ClassFilter match
*/
public static ClassFilter reversion(ClassFilter cf) {
Assert.notNull(cf, "ClassFilter must not be null");
return new ReversionClassFilter(cf);
}


/**
* ClassFilter implementation for a union of the given ClassFilters.
Expand Down Expand Up @@ -167,4 +178,40 @@ public String toString() {

}


/**
* ClassFilter implementation for an reversion of the given ClassFilter.
*/
@SuppressWarnings("serial")
private static class ReversionClassFilter implements ClassFilter, Serializable {

private final ClassFilter filter;

ReversionClassFilter(ClassFilter filter) {
this.filter = filter;
}

@Override
public boolean matches(Class<?> clazz) {
return !this.filter.matches(clazz);
}

@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof ReversionClassFilter &&
this.filter.equals(((ReversionClassFilter)other).filter)));
}

@Override
public int hashCode() {
return 37 * this.filter.hashCode();
}

@Override
public String toString() {
return getClass().getName() + ": " + this.filter;
}

}

}
Expand Up @@ -81,6 +81,16 @@ public static MethodMatcher intersection(MethodMatcher mm1, MethodMatcher mm2) {
new IntersectionIntroductionAwareMethodMatcher(mm1, mm2) : new IntersectionMethodMatcher(mm1, mm2));
}

/**
* reverse the given MethodMatcher match.
* @param mm the MethodMatcher
* @return a distinct MethodMatcher that not matches methods
* of the given MethodMatcher match
*/
public static MethodMatcher reversion(MethodMatcher mm) {
return new ReversionMethodMatcher(mm);
}

/**
* Apply the given MethodMatcher to the given Method, supporting an
* {@link org.springframework.aop.IntroductionAwareMethodMatcher}
Expand Down Expand Up @@ -338,4 +348,57 @@ public boolean matches(Method method, Class<?> targetClass, boolean hasIntroduct
}
}


/**
* MethodMatcher implementation for an reversion of the given MethodMatcher.
*/
@SuppressWarnings("serial")
private static class ReversionMethodMatcher implements MethodMatcher, Serializable {

protected final MethodMatcher mm;

public ReversionMethodMatcher(MethodMatcher mm) {
Assert.notNull(mm, "MethodMatcher must not be null");
this.mm = mm;
}

@Override
public boolean matches(Method method, Class<?> targetClass) {
return !this.mm.matches(method, targetClass);
}

@Override
public boolean isRuntime() {
return this.mm.isRuntime();
}

@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
return !this.mm.matches(method, targetClass, args);
}

@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ReversionMethodMatcher)) {
return false;
}
ReversionMethodMatcher that = (ReversionMethodMatcher) other;
return this.mm.equals(that.mm);
}

@Override
public int hashCode() {
return 37 * this.mm.hashCode();
}

@Override
public String toString() {
return getClass().getName() + ": " + this.mm;
}

}

}
Expand Up @@ -66,4 +66,13 @@ void intersection() {
.matches("^.+IntersectionClassFilter: \\[.+RootClassFilter: .+Exception, .+RootClassFilter: .+NestedRuntimeException\\]$");
}

@Test
void reversion() {
assertThat(exceptionFilter.matches(RuntimeException.class)).isTrue();
ClassFilter reversion = ClassFilters.reversion(exceptionFilter);
assertThat(reversion.matches(RuntimeException.class)).isFalse();
assertThat(reversion.toString())
.matches("^.+ReversionClassFilter: .+RootClassFilter: .+Exception$");
}

}
Expand Up @@ -111,6 +111,19 @@ public void testUnionEquals() {
assertThat(second.equals(first)).isTrue();
}

@Test
public void testDynamicAndStaticMethodMatcherReversion() throws Exception {
MethodMatcher getterMatcher = new StartsWithMatcher("get");
MethodMatcher reversion = MethodMatchers.reversion(getterMatcher);
assertThat(reversion.isRuntime()).as("Reversion is a static matcher").isFalse();
assertThat(reversion.matches(ITESTBEAN_GETAGE, TestBean.class)).as("Didn't matched getAge method").isFalse();
assertThat(reversion.matches(IOTHER_ABSQUATULATE, TestBean.class)).as("Matched absquatulate method").isTrue();
reversion = MethodMatchers.reversion(new TestDynamicMethodMatcherWhichDoesNotMatch());
assertThat(reversion.isRuntime()).as("Intersection is a dynamic matcher").isTrue();
assertThat(reversion.matches(ITESTBEAN_SETAGE, TestBean.class)).as("Didn't matched setAge method").isFalse();
assertThat(reversion.matches(ITESTBEAN_SETAGE, TestBean.class, 5)).as("Matched setAge method").isTrue();
}


public static class StartsWithMatcher extends StaticMethodMatcher {

Expand Down

0 comments on commit 13e62d0

Please sign in to comment.