/*
* Copyright 2017 TNG Technology Consulting GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.tngtech.archunit.lang.syntax.elements;
import java.lang.annotation.Annotation;
import com.tngtech.archunit.PublicAPI;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.base.PackageMatcher;
import com.tngtech.archunit.core.domain.JavaAnnotation;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.core.domain.properties.HasName.Predicates;
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
public interface ClassesThat<CONJUNCTION> {
/**
* Matches classes by their fully qualified class name.
*
* @param name The fully qualified class name
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveFullyQualifiedName(String name);
/**
* Matches classes that don't have a certain fully qualified class name.
*
* @param name The fully qualified class name
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontHaveFullyQualifiedName(String name);
/**
* Matches classes by their simple class name.
*
* @param name The simple class name
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveSimpleName(String name);
/**
* Matches classes that don't have a certain simple class name.
*
* @param name The simple class name
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontHaveSimpleName(String name);
/**
* Matches classes with a fully qualified class name matching a given regular expression.
*
* @param regex A regular expression
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameMatching(String regex);
/**
* Matches classes with a fully qualified class name not matching a given regular expression.
*
* @param regex A regular expression
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameNotMatching(String regex);
/**
* Matches classes residing in a package matching the supplied package identifier.
*
* @param packageIdentifier A string identifying packages, for details see {@link PackageMatcher}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION resideInAPackage(String packageIdentifier);
/**
* Matches classes residing in a package matching any of the supplied package identifiers.
*
* @param packageIdentifiers Strings identifying packages, for details see {@link PackageMatcher}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION resideInAnyPackage(String... packageIdentifiers);
/**
* Matches classes not residing in a package matching the supplied package identifier.
*
* @param packageIdentifier A string identifying packages, for details see {@link PackageMatcher}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION resideOutsideOfPackage(String packageIdentifier);
/**
* Matches classes not residing in a package matching any of the supplied package identifiers.
*
* @param packageIdentifiers Strings identifying packages, for details see {@link PackageMatcher}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION resideOutsideOfPackages(String... packageIdentifiers);
/**
* Matches public classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION arePublic();
/**
* Matches non-public classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotPublic();
/**
* Matches protected classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areProtected();
/**
* Matches non-protected classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotProtected();
/**
* Matches package private classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION arePackagePrivate();
/**
* Matches non-package private classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotPackagePrivate();
/**
* Matches private classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION arePrivate();
/**
* Matches non-private classes.
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotPrivate();
/**
* Matches classes having a certain {@link JavaModifier} (e.g. {@link JavaModifier#ABSTRACT}).
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveModifier(JavaModifier modifier);
/**
* Matches classes not having a certain {@link JavaModifier} (e.g. {@link JavaModifier#ABSTRACT}).
*
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontHaveModifier(JavaModifier modifier);
/**
* Matches classes annotated with a certain type of annotation.
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAnnotatedWith(Class<? extends Annotation> annotationType);
/**
* Matches classes not annotated with a certain type of annotation.
*
* @param annotationType Specific type of {@link Annotation}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAnnotatedWith(Class<? extends Annotation> annotationType);
/**
* Matches classes annotated with a certain type of annotation.
*
* @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
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAnnotatedWith(String annotationTypeName);
/**
* Matches classes not annotated with a certain type of annotation.
*
* @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
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAnnotatedWith(String annotationTypeName);
/**
* Matches classes annotated with a certain annotation, where matching annotations are
* determined by the supplied predicate.
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAnnotatedWith(DescribedPredicate<? super JavaAnnotation> predicate);
/**
* Matches classes not annotated with a certain annotation, where matching annotations are
* determined by the supplied predicate.
*
* @param predicate A predicate defining matching {@link JavaAnnotation JavaAnnotations}
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAnnotatedWith(DescribedPredicate<? super JavaAnnotation> predicate);
/**
* Matches classes that implement a certain interface.
*
* @param type An interface type matching classes must implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION implement(Class<?> type);
/**
* Matches classes that don't implement a certain interface. This is the negation of {@link #implement(Class)}.
*
* @param type An interface type matching classes must not implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontImplement(Class<?> type);
/**
* Matches classes that implement a certain interface with the given type name. This is equivalent to
* {@link #implement(Class)}, but doesn't depend on having a certain type on the classpath.
*
* @param typeName Name of an interface type matching classes must implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION implement(String typeName);
/**
* Matches classes that don't implement a certain interface with the given type name.
* This is equivalent to {@link #dontImplement(Class)}, but doesn't depend on having a certain
* type on the classpath.
*
* @param typeName Name of an interface type matching classes must not implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontImplement(String typeName);
/**
* Matches classes that implement a certain interface matching the given predicate. For example, a call with
* {@link Predicates#name(String)} would be equivalent to
* {@link #implement(String)}, but the approach is a lot more generic.
*
* @param predicate A predicate identifying interfaces matching classes must implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION implement(DescribedPredicate<? super JavaClass> predicate);
/**
* Matches classes that don't implement a certain interface matching the given predicate.
* This is the negation of {@link #implement(DescribedPredicate)}.
*
* @param predicate A predicate identifying interfaces matching classes must not implement
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION dontImplement(DescribedPredicate<? super JavaClass> predicate);
/**
* Matches classes assignable to a certain type (compare {@link Class#isAssignableFrom(Class)} to terminology).
* A simple example for this predicate would be
* <pre><code>
* assignableTo(Object.class).apply(importedStringClass); // --> returns true
* assignableTo(String.class).apply(importedStringClass); // --> returns true
* assignableTo(List.class).apply(importedStringClass); // --> returns false
* </code></pre>
*
* @param type An upper type bound to match imported classes against (imported subtypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableTo(Class<?> type);
/**
* Matches classes not assignable to a certain type. This is the negation of {@link #areAssignableTo(Class)}.
*
* @param type An upper type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableTo(Class<?> type);
/**
* Matches classes assignable to a certain type with the given type name. This is equivalent to
* {@link #areAssignableTo(Class)}, but doesn't depend on having a certain type on the classpath.
*
* @param typeName Name of an upper type bound to match imported classes against (imported subtypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableTo(String typeName);
/**
* Matches classes not assignable to a certain type with the given type name.
* This is equivalent to {@link #areNotAssignableTo(Class)}, but doesn't depend on having a certain
* type on the classpath.
*
* @param typeName Name of an upper type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableTo(String typeName);
/**
* Matches classes assignable to a certain type matching the given predicate. For example, a call with
* {@link Predicates#name(String)} would be equivalent to
* {@link #areAssignableTo(String)}, but the approach is a lot more generic.
*
* @param predicate A predicate identifying an upper type bound to match imported classes against
* (imported subtypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableTo(DescribedPredicate<? super JavaClass> predicate);
/**
* Matches classes not assignable to a certain type matching the given predicate.
* This is the negation of {@link #areAssignableTo(DescribedPredicate)}.
*
* @param predicate A predicate identifying an upper type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableTo(DescribedPredicate<? super JavaClass> predicate);
/**
* Matches classes assignable from a certain type (compare {@link Class#isAssignableFrom(Class)} to terminology).
* This is roughly equivalent to the use of reflection:
* <pre><code>
* someClass.class.isAssignableFrom(type);
* </code></pre>
* A simple example for this predicate would be
* <pre><code>
* assignableFrom(ArrayList.class).apply(importedArrayListClass); // --> returns true
* assignableFrom(ArrayList.class).apply(importedListClass); // --> returns true
* assignableFrom(ArrayList.class).apply(importedStringClass); // --> returns false
* </code></pre>
*
* @param type A lower type bound to match imported classes against (imported supertypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableFrom(Class<?> type);
/**
* Matches classes not assignable from a certain type. This is the negation of {@link #areAssignableFrom(Class)}.
*
* @param type A lower type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableFrom(Class<?> type);
/**
* Matches classes assignable from a certain type with the given type name. This is equivalent to
* {@link #areAssignableFrom(Class)}, but doesn't depend on having a certain type on the classpath.
*
* @param typeName Name of a lower type bound to match imported classes against (imported supertypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableFrom(String typeName);
/**
* Matches classes not assignable from a certain type with the given type name.
* This is equivalent to {@link #areNotAssignableFrom(Class)}, but doesn't depend on having a certain
* type on the classpath.
*
* @param typeName Name of a lower type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableFrom(String typeName);
/**
* Matches classes assignable from a certain type matching the given predicate. For example, a call with
* {@link Predicates#name(String)} would be equivalent to
* {@link #areAssignableFrom(String)}, but the approach is a lot more generic.
*
* @param predicate A predicate identifying a lower type bound to match imported classes against
* (imported supertypes will match)
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areAssignableFrom(DescribedPredicate<? super JavaClass> predicate);
/**
* Matches classes not assignable from a certain type matching the given predicate.
* This is the negation of {@link #areAssignableFrom(DescribedPredicate)}.
*
* @param predicate A predicate identifying a lower type bound imported classes should NOT have
* @return A syntax conjunction element, which can be completed to form a full rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION areNotAssignableFrom(DescribedPredicate<? super JavaClass> predicate);
}