Skip to content

Commit

Permalink
Add/Improve Javadoc for annotatedWith
Browse files Browse the repository at this point in the history
This commit also incorporates the changes from #540, that meta-annotated-with predicates and conditions also consider direct annotations.

Signed-off-by: Roland Weisleder <roland.weisleder@googlemail.com>
  • Loading branch information
rweisleder authored and codecholeric committed Mar 29, 2022
1 parent 5a2d1e2 commit 693b187
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,72 @@
import static com.tngtech.archunit.core.domain.properties.HasType.Functions.GET_RAW_TYPE;

public interface CanBeAnnotated {

/**
* Returns {@code true}, if this element is annotated with the given annotation type.
*
* @param annotationType The type of the annotation to check for
*/
@PublicAPI(usage = ACCESS)
boolean isAnnotatedWith(Class<? extends Annotation> annotationType);

/**
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @see #isAnnotatedWith(Class)
*/
@PublicAPI(usage = ACCESS)
boolean isAnnotatedWith(String annotationTypeName);

/**
* Returns {@code true}, if this element is annotated with an annotation matching the given predicate.
*
* @param predicate Qualifies matching annotations
*/
@PublicAPI(usage = ACCESS)
boolean isAnnotatedWith(DescribedPredicate<? super JavaAnnotation<?>> predicate);

/**
* Returns {@code true}, if this element is meta-annotated with the given annotation type.
* A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* This method also returns {@code true} if this element is directly annotated with the given annotation type.
* </p>
*
* @param annotationType The type of the annotation to check for
*/
@PublicAPI(usage = ACCESS)
boolean isMetaAnnotatedWith(Class<? extends Annotation> annotationType);

/**
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @see #isMetaAnnotatedWith(Class)
*/
@PublicAPI(usage = ACCESS)
boolean isMetaAnnotatedWith(String annotationTypeName);

/**
* Returns {@code true}, if this element is meta-annotated with an annotation matching the given predicate.
* A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* This method also returns {@code true} if this element is directly annotated with an annotation matching the given predicate.
* </p>
*
* @param predicate Qualifies matching annotations
*/
@PublicAPI(usage = ACCESS)
boolean isMetaAnnotatedWith(DescribedPredicate<? super JavaAnnotation<?>> predicate);

final class Predicates {
private Predicates() {
}

/**
* Returns a predicate that matches elements that are annotated with the given annotation type.
*
* @param annotationType The type of the annotation to check for
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> annotatedWith(final Class<? extends Annotation> annotationType) {
checkAnnotationHasReasonableRetention(annotationType);
Expand All @@ -78,12 +122,21 @@ private static boolean isRetentionSource(Class<? extends Annotation> annotationT
&& (annotationType.getAnnotation(Retention.class).value() == RetentionPolicy.SOURCE);
}

/**
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @see #annotatedWith(Class)
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> annotatedWith(final String annotationTypeName) {
DescribedPredicate<HasType> typeNameMatches = GET_RAW_TYPE.then(GET_NAME).is(equalTo(annotationTypeName));
return annotatedWith(typeNameMatches.as("@" + ensureSimpleName(annotationTypeName)));
}

/**
* Returns a predicate that matches elements that are annotated with an annotation matching the given predicate.
*
* @param predicate Qualifies matching annotations
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> annotatedWith(final DescribedPredicate<? super JavaAnnotation<?>> predicate) {
return new AnnotatedPredicate(predicate);
Expand All @@ -103,19 +156,42 @@ public boolean apply(CanBeAnnotated input) {
}
}

/**
* Returns a predicate that matches elements that are meta-annotated with the given annotation type.
* A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* The returned predicate also matches elements that are directly annotated with the given annotation type.
* </p>
*
* @param annotationType The type of the annotation to check for
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> metaAnnotatedWith(final Class<? extends Annotation> annotationType) {
checkAnnotationHasReasonableRetention(annotationType);

return metaAnnotatedWith(annotationType.getName());
}

/**
* @see #metaAnnotatedWith(Class)
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> metaAnnotatedWith(final String annotationTypeName) {
DescribedPredicate<HasType> typeNameMatches = GET_RAW_TYPE.then(GET_NAME).is(equalTo(annotationTypeName));
return metaAnnotatedWith(typeNameMatches.as("@" + ensureSimpleName(annotationTypeName)));
}

/**
* Returns a predicate that matches elements that are meta-annotated with an annotation matching the given predicate.
* A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* The returned predicate also matches elements that are directly annotated with the given annotation type.
* </p>
*
* @param predicate Qualifies matching annotations
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<CanBeAnnotated> metaAnnotatedWith(final DescribedPredicate<? super JavaAnnotation<?>> predicate) {
return new MetaAnnotatedPredicate(predicate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaMethodCall;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.core.domain.properties.CanBeAnnotated;
import com.tngtech.archunit.core.domain.properties.HasAnnotations;
import com.tngtech.archunit.core.domain.properties.HasModifiers;
import com.tngtech.archunit.core.domain.properties.HasName;
Expand Down Expand Up @@ -715,72 +716,108 @@ public static ArchCondition<JavaClass> haveOnlyPrivateConstructors() {
return new HaveOnlyModifiersCondition<>("private constructors", PRIVATE, GET_CONSTRUCTORS);
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#annotatedWith(Class)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beAnnotatedWith(
Class<? extends Annotation> type) {
return new IsConditionByPredicate<>(annotatedWith(type));
}

/**
* @return negation of {@link #beAnnotatedWith(Class)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeAnnotatedWith(
Class<? extends Annotation> type) {
return not(ArchConditions.<HAS_ANNOTATIONS>beAnnotatedWith(type));
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#annotatedWith(String)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beAnnotatedWith(
String typeName) {
return new IsConditionByPredicate<>(annotatedWith(typeName));
}

/**
* @return negation of {@link #beAnnotatedWith(String)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeAnnotatedWith(
String typeName) {
return not(ArchConditions.<HAS_ANNOTATIONS>beAnnotatedWith(typeName));
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#annotatedWith(DescribedPredicate)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beAnnotatedWith(
final DescribedPredicate<? super JavaAnnotation<?>> predicate) {
return new IsConditionByPredicate<>(annotatedWith(predicate));
}

/**
* @return negation of {@link #beAnnotatedWith(DescribedPredicate)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeAnnotatedWith(
DescribedPredicate<? super JavaAnnotation<?>> predicate) {
return not(ArchConditions.<HAS_ANNOTATIONS>beAnnotatedWith(predicate));
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#metaAnnotatedWith(Class)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beMetaAnnotatedWith(
Class<? extends Annotation> type) {
return new IsConditionByPredicate<>(metaAnnotatedWith(type));
}

/**
* @return negation of {@link #beMetaAnnotatedWith(Class)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeMetaAnnotatedWith(
Class<? extends Annotation> type) {
return not(ArchConditions.<HAS_ANNOTATIONS>beMetaAnnotatedWith(type));
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#metaAnnotatedWith(String)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beMetaAnnotatedWith(
String typeName) {
return new IsConditionByPredicate<>(metaAnnotatedWith(typeName));
}

/**
* @return negation of {@link #beMetaAnnotatedWith(String)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeMetaAnnotatedWith(
String typeName) {
return not(ArchConditions.<HAS_ANNOTATIONS>beMetaAnnotatedWith(typeName));
}

/**
* @return a condition matching elements analogously to {@link CanBeAnnotated.Predicates#metaAnnotatedWith(DescribedPredicate)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> beMetaAnnotatedWith(
final DescribedPredicate<? super JavaAnnotation<?>> predicate) {
return new IsConditionByPredicate<>(metaAnnotatedWith(predicate));
}

/**
* @return negation of {@link #beMetaAnnotatedWith(DescribedPredicate)}
*/
@PublicAPI(usage = ACCESS)
public static <HAS_ANNOTATIONS extends HasAnnotations<?> & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_ANNOTATIONS> notBeMetaAnnotatedWith(
DescribedPredicate<? super JavaAnnotation<?>> predicate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ public interface ClassesShould {
* Asserts that classes are meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* The assertion is also successful if classes are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand All @@ -352,6 +356,10 @@ public interface ClassesShould {
* Asserts that classes are not meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* The assertion also fails if classes are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand All @@ -362,6 +370,10 @@ public interface ClassesShould {
* Asserts that classes are meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* The assertion is also successful if classes are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand All @@ -372,6 +384,10 @@ public interface ClassesShould {
* Asserts that classes are not meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* The assertion also fails if classes are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand All @@ -382,6 +398,10 @@ public interface ClassesShould {
* Asserts that classes are meta-annotated with a certain annotation, where matching meta-annotations are
* determined by the supplied predicate. A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* The assertion is also successful if classes are directly annotated with an annotation matching the supplied predicate.
* </p>
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand All @@ -392,6 +412,10 @@ public interface ClassesShould {
* Asserts that classes are not meta-annotated with a certain annotation, where matching meta-annotations are
* determined by the supplied predicate. A meta-annotation is an annotation that is declared on another annotation.
*
* <p>
* The assertion also fails if classes are directly annotated with an annotation matching the supplied predicate.
* </p>
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ public interface ClassesThat<CONJUNCTION> {
* Matches classes meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* This also matches classes that are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand All @@ -328,6 +332,10 @@ public interface ClassesThat<CONJUNCTION> {
* Matches classes not meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* Matching classes may also not directly be annotated with the supplied annotation type.
* </p>
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand All @@ -338,6 +346,10 @@ public interface ClassesThat<CONJUNCTION> {
* Matches classes meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* This also matches classes that are directly annotated with the supplied annotation type.
* </p>
*
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand All @@ -348,6 +360,10 @@ public interface ClassesThat<CONJUNCTION> {
* Matches classes not meta-annotated with a certain type of annotation. A meta-annotation is
* an annotation that is declared on another annotation.
*
* <p>
* Matching classes may also not directly be annotated with the supplied annotation type.
* </p>
*
* @param annotationTypeName Fully qualified class name of a specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand All @@ -359,6 +375,10 @@ public interface ClassesThat<CONJUNCTION> {
* determined by the supplied predicate. A meta-annotation is an annotation that is declared on
* another annotation.
*
* <p>
* This also matches classes where a direct annotation matches the supplied predicate.
* </p>
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand All @@ -370,6 +390,10 @@ public interface ClassesThat<CONJUNCTION> {
* determined by the supplied predicate. A meta-annotation is an annotation that is declared on
* another annotation.
*
* <p>
* Matching classes may also not be annotated with a direct annotation matching the supplied predicate.
* </p>
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
Expand Down
Loading

0 comments on commit 693b187

Please sign in to comment.