All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ui4j.bytebuddy.matcher.ElementMatchers Maven / Gradle / Ivy

The newest version!
package com.ui4j.bytebuddy.matcher;

import com.ui4j.bytebuddy.instrumentation.ByteCodeElement;
import com.ui4j.bytebuddy.instrumentation.ModifierReviewable;
import com.ui4j.bytebuddy.instrumentation.NamedElement;
import com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotatedElement;
import com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationList;
import com.ui4j.bytebuddy.instrumentation.field.FieldDescription;
import com.ui4j.bytebuddy.instrumentation.method.MethodDescription;
import com.ui4j.bytebuddy.instrumentation.method.MethodList;
import com.ui4j.bytebuddy.instrumentation.method.ParameterDescription;
import com.ui4j.bytebuddy.instrumentation.method.ParameterList;
import com.ui4j.bytebuddy.instrumentation.type.TypeDescription;
import com.ui4j.bytebuddy.instrumentation.type.TypeList;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;

import static com.ui4j.bytebuddy.utility.ByteBuddyCommons.*;

/**
 * A utility class that contains a human-readable language for creating {@link com.ui4j.bytebuddy.matcher.ElementMatcher}s.
 */
public final class ElementMatchers {

    /**
     * A private constructor that must not be invoked.
     */
    private ElementMatchers() {
        throw new UnsupportedOperationException();
    }

    /**
     * Matches the given value which can also be {@code null} by the {@link java.lang.Object#equals(Object)} method or
     * by a null-check.
     *
     * @param value The value that is to be matched.
     * @param    The type of the matched object.
     * @return A matcher that matches an exact value.
     */
    public static  ElementMatcher.Junction is(Object value) {
        return value == null
                ? new NullMatcher()
                : new EqualityMatcher(value);
    }

    /**
     * Exactly matches a given method as a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}.
     *
     * @param method The method to match by its description
     * @param     The type of the matched object.
     * @return An element matcher that exactly matches the given method.
     */
    public static  ElementMatcher.Junction is(Method method) {
        return is(new MethodDescription.ForLoadedMethod(nonNull(method)));
    }

    /**
     * Exactly matches a given constructor as a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}.
     *
     * @param constructor The constructor to match by its description
     * @param          The type of the matched object.
     * @return An element matcher that exactly matches the given constructor.
     */
    public static  ElementMatcher.Junction is(Constructor constructor) {
        return is(new MethodDescription.ForLoadedConstructor(nonNull(constructor)));
    }

    /**
     * Exactly matches a given {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}.
     *
     * @param methodDescription The method description to match.
     * @param                The type of the matched object.
     * @return An element matcher that matches the given method description.
     */
    public static  ElementMatcher.Junction is(MethodDescription methodDescription) {
        return new EqualityMatcher(nonNull(methodDescription));
    }

    /**
     * Exactly matches a given type as a {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param type The type to match by its description
     * @param   The type of the matched object.
     * @return An element matcher that exactly matches the given type.
     */
    public static  ElementMatcher.Junction is(Class type) {
        return is(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Exactly matches a given {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param typeDescription The type to match by its description
     * @param              The type of the matched object.
     * @return An element matcher that exactly matches the given type.
     */
    public static  ElementMatcher.Junction is(TypeDescription typeDescription) {
        return new EqualityMatcher(nonNull(typeDescription));
    }

    /**
     * Exactly matches a given annotation as an {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription}.
     *
     * @param annotation The annotation to match by its description.
     * @param         The type of the matched object.
     * @return An element matcher that exactly matches the given annotation.
     */
    public static  ElementMatcher.Junction is(Annotation annotation) {
        return is(AnnotationDescription.ForLoadedAnnotation.of(nonNull(annotation)));
    }

    /**
     * Exactly matches a given {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription}.
     *
     * @param annotationDescription The annotation description to match.
     * @param                    The type of the matched object.
     * @return An element matcher that exactly matches the given annotation.
     */
    public static  ElementMatcher.Junction is(AnnotationDescription annotationDescription) {
        return new EqualityMatcher(nonNull(annotationDescription));
    }

    /**
     * Inverts another matcher.
     *
     * @param matcher The matcher to invert.
     * @param      The type of the matched object.
     * @return An inverted version of the given {@code matcher}.
     */
    public static  ElementMatcher.Junction not(ElementMatcher matcher) {
        return new NegatingMatcher(nonNull(matcher));
    }

    /**
     * Creates a matcher that always returns {@code true}.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches anything.
     */
    public static  ElementMatcher.Junction any() {
        return new BooleanMatcher(true);
    }

    /**
     * Creates a matcher that always returns {@code false}.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches nothing.
     */
    public static  ElementMatcher.Junction none() {
        return new BooleanMatcher(false);
    }

    /**
     * Creates a matcher that matches any of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Object... value) {
        return anyOf(Arrays.asList(nonNull(value)));
    }

    /**
     * Creates a matcher that matches any of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param values The input values to be compared against.
     * @param     The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Iterable values) {
        ElementMatcher.Junction matcher = none();
        for (Object value : values) {
            matcher = matcher.or(is(value));
        }
        return matcher;
    }

    /**
     * Creates a matcher that matches any of the given types as {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Class... value) {
        return anyOf(new TypeList.ForLoadedType(nonNull(value)));
    }

    /**
     * Creates a matcher that matches any of the given constructors as {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Constructor... value) {
        return anyOf(new MethodList.ForLoadedType(nonNull(value), new Method[0]));
    }

    /**
     * Creates a matcher that matches any of the given methods as {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Method... value) {
        return anyOf(new MethodList.ForLoadedType(new Constructor[0], nonNull(value)));
    }

    /**
     * Creates a matcher that matches any of the given annotations as {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Annotation... value) {
        return anyOf(new AnnotationList.ForLoadedAnnotation(nonNull(value)));
    }

    /**
     * Creates a matcher that matches none of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Object... value) {
        return noneOf(Arrays.asList(value));
    }

    /**
     * Creates a matcher that matches none of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param values The input values to be compared against.
     * @param     The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Iterable values) {
        ElementMatcher.Junction matcher = any();
        for (Object value : values) {
            matcher = matcher.and(not(is(value)));
        }
        return matcher;
    }

    /**
     * Creates a matcher that matches none of the given types as {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Class... value) {
        return noneOf(new TypeList.ForLoadedType(nonNull(value)));
    }

    /**
     * Creates a matcher that matches none of the given constructors as {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Constructor... value) {
        return noneOf(new MethodList.ForLoadedType(nonNull(value), new Method[0]));
    }

    /**
     * Creates a matcher that matches none of the given methods as {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Method... value) {
        return noneOf(new MethodList.ForLoadedType(new Constructor[0], nonNull(value)));
    }

    /**
     * Creates a matcher that matches none of the given annotations as {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Annotation... value) {
        return noneOf(new AnnotationList.ForLoadedAnnotation(nonNull(value)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its exact name.
     *
     * @param name The expected name.
     * @param   The type of the matched object.
     * @return An element matcher for a named element's exact name.
     */
    public static  ElementMatcher.Junction named(String name) {
        return new NameMatcher(new StringMatcher(nonNull(name), StringMatcher.Mode.EQUALS_FULLY));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its name. The name's
     * capitalization is ignored.
     *
     * @param name The expected name.
     * @param   The type of the matched object.
     * @return An element matcher for a named element's name.
     */
    public static  ElementMatcher.Junction namedIgnoreCase(String name) {
        return new NameMatcher(new StringMatcher(nonNull(name), StringMatcher.Mode.EQUALS_FULLY_IGNORE_CASE));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its name's prefix.
     *
     * @param prefix The expected name's prefix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's prefix.
     */
    public static  ElementMatcher.Junction nameStartsWith(String prefix) {
        return new NameMatcher(new StringMatcher(nonNull(prefix), StringMatcher.Mode.STARTS_WITH));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its name's prefix. The name's
     * capitalization is ignored.
     *
     * @param prefix The expected name's prefix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's prefix.
     */
    public static  ElementMatcher.Junction nameStartsWithIgnoreCase(String prefix) {
        return new NameMatcher(new StringMatcher(nonNull(prefix), StringMatcher.Mode.STARTS_WITH_IGNORE_CASE));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its name's suffix.
     *
     * @param suffix The expected name's suffix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's suffix.
     */
    public static  ElementMatcher.Junction nameEndsWith(String suffix) {
        return new NameMatcher(new StringMatcher(nonNull(suffix), StringMatcher.Mode.ENDS_WITH));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for its name's suffix. The name's
     * capitalization is ignored.
     *
     * @param suffix The expected name's suffix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's suffix.
     */
    public static  ElementMatcher.Junction nameEndsWithIgnoreCase(String suffix) {
        return new NameMatcher(new StringMatcher(nonNull(suffix), StringMatcher.Mode.ENDS_WITH_IGNORE_CASE));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for an infix of its name.
     *
     * @param infix The expected infix of the name.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's infix.
     */
    public static  ElementMatcher.Junction nameContains(String infix) {
        return new NameMatcher(new StringMatcher(nonNull(infix), StringMatcher.Mode.CONTAINS));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} for an infix of its name. The name's
     * capitalization is ignored.
     *
     * @param infix The expected infix of the name.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's infix.
     */
    public static  ElementMatcher.Junction nameContainsIgnoreCase(String infix) {
        return new NameMatcher(new StringMatcher(nonNull(infix), StringMatcher.Mode.CONTAINS_IGNORE_CASE));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.NamedElement} name against a regular expression.
     *
     * @param regex The regular expression to match the name against.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's against the given regular expression.
     */
    public static  ElementMatcher.Junction nameMatches(String regex) {
        return new NameMatcher(new StringMatcher(nonNull(regex), StringMatcher.Mode.MATCHES));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement}'s descriptor against a given value.
     *
     * @param descriptor The expected descriptor.
     * @param         The type of the matched object.
     * @return A matcher for the given {@code descriptor}.
     */
    public static  ElementMatcher.Junction hasDescriptor(String descriptor) {
        return new DescriptorMatcher(new StringMatcher(descriptor, StringMatcher.Mode.EQUALS_FULLY));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement} for being declared by a given
     * {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(TypeDescription type) {
        return isDeclaredBy(is(nonNull(type)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement} for being declared by a given
     * {@link java.lang.Class}.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(Class type) {
        return isDeclaredBy(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement} for being declared by a
     * {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription} that is matched by the given matcher.
     *
     * @param matcher A matcher for the declaring type of the matched byte code element as long as it
     *                is not {@code null}.
     * @param      The type of the matched object.
     * @return A matcher for byte code elements being declared by a type matched by the given {@code matcher}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(ElementMatcher matcher) {
        return new DeclaringTypeMatcher(nonNull(matcher));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement} that is visible to a given {@link java.lang.Class}.
     *
     * @param type The type that a matched byte code element is expected to be visible to.
     * @param   The type of the matched object.
     * @return A matcher for a byte code element to be visible to a given {@code type}.
     */
    public static  ElementMatcher.Junction isVisibleTo(Class type) {
        return isVisibleTo(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ByteCodeElement} that is visible to a given
     * {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param typeDescription The type that a matched byte code element is expected to be visible to.
     * @param              The type of the matched object.
     * @return A matcher for a byte code element to be visible to a given {@code typeDescription}.
     */
    public static  ElementMatcher.Junction isVisibleTo(TypeDescription typeDescription) {
        return new VisibilityMatcher(typeDescription);
    }

    /**
     * Matches an {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotatedElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.ui4j.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(Class)} for matching inherited annotations.
     *
     * @param type The annotation type to match against.
     * @param   The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of {@code type}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(Class type) {
        return isAnnotatedWith(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches an {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotatedElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.ui4j.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(com.ui4j.bytebuddy.instrumentation.type.TypeDescription)}
     * for matching inherited annotations.
     *
     * @param typeDescription The annotation type to match against.
     * @param              The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of {@code typeDescription}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(TypeDescription typeDescription) {
        return isAnnotatedWith(is(isAnnotation(typeDescription)));
    }

    /**
     * Matches an {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotatedElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.ui4j.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(com.ui4j.bytebuddy.matcher.ElementMatcher)}
     * for matching inherited annotations.
     *
     * @param matcher The matcher to apply to any annotation's type found on the matched annotated element.
     * @param      The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of a type
     * that matches the given {@code matcher}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(ElementMatcher matcher) {
        return declaresAnnotation(new AnnotationTypeMatcher(nonNull(matcher)));
    }

    /**
     * Matches an {@link com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotatedElement} to declare any annotation
     * that matches the given matcher. Note that this matcher does not match inherited annotations that only exist
     * for types. Use {@link com.ui4j.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(com.ui4j.bytebuddy.matcher.ElementMatcher)}
     * for matching inherited annotations.
     *
     * @param matcher A matcher to apply on any declared annotation of the matched annotated element.
     * @param      The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation that matches
     * the given {@code matcher}.
     */
    public static  ElementMatcher.Junction declaresAnnotation(ElementMatcher matcher) {
        return new DeclaringAnnotationMatcher(new CollectionItemMatcher(nonNull(matcher)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is {@code public}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code public} modifier reviewable.
     */
    public static  ElementMatcher.Junction isPublic() {
        return new ModifierMatcher(ModifierMatcher.Mode.PUBLIC);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is {@code protected}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code protected} modifier reviewable.
     */
    public static  ElementMatcher.Junction isProtected() {
        return new ModifierMatcher(ModifierMatcher.Mode.PROTECTED);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is package-private.
     *
     * @param  The type of the matched object.
     * @return A matcher for a package-private modifier reviewable.
     */
    public static  ElementMatcher.Junction isPackagePrivate() {
        return not(isPublic().or(isProtected()).or(isPrivate()));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is {@code private}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code private} modifier reviewable.
     */
    public static  ElementMatcher.Junction isPrivate() {
        return new ModifierMatcher(ModifierMatcher.Mode.PRIVATE);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is {@code final}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code final} modifier reviewable.
     */
    public static  ElementMatcher.Junction isFinal() {
        return new ModifierMatcher(ModifierMatcher.Mode.FINAL);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is {@code static}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code static} modifier reviewable.
     */
    public static  ElementMatcher.Junction isStatic() {
        return new ModifierMatcher(ModifierMatcher.Mode.STATIC);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.ModifierReviewable} that is synthetic.
     *
     * @param  The type of the matched object.
     * @return A matcher for a synthetic modifier reviewable.
     */
    public static  ElementMatcher.Junction isSynthetic() {
        return new ModifierMatcher(ModifierMatcher.Mode.SYNTHETIC);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} that is {@code synchronized}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code synchronized} method description.
     */
    public static  ElementMatcher.Junction isSynchronized() {
        return new ModifierMatcher(ModifierMatcher.Mode.SYNCHRONIZED);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} that is {@code native}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code native} method description.
     */
    public static  ElementMatcher.Junction isNative() {
        return new ModifierMatcher(ModifierMatcher.Mode.NATIVE);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} that is {@code strictfp}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code strictfp} method description.
     */
    public static  ElementMatcher.Junction isStrict() {
        return new ModifierMatcher(ModifierMatcher.Mode.STRICT);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} that is a var-args.
     *
     * @param  The type of the matched object.
     * @return A matcher for a var-args method description.
     */
    public static  ElementMatcher.Junction isVarArgs() {
        return new ModifierMatcher(ModifierMatcher.Mode.VAR_ARGS);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} that is a bridge.
     *
     * @param  The type of the matched object.
     * @return A matcher for a bridge method.
     */
    public static  ElementMatcher.Junction isBridge() {
        return new ModifierMatcher(ModifierMatcher.Mode.BRIDGE);
    }

    /**
     * Matches {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s that returns a given
     * {@link java.lang.Class}.
     *
     * @param type The type the matched method is expected to return.
     * @param   The type of the matched object.
     * @return An element matcher that matches a given return type for a method description.
     */
    public static  ElementMatcher.Junction returns(Class type) {
        return returns(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s that returns a given
     * {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param typeDescription The type the matched method is expected to return.
     * @param              The type of the matched object.
     * @return An element matcher that matches a given return type for a method description.
     */
    public static  ElementMatcher.Junction returns(TypeDescription typeDescription) {
        return returns(is(nonNull(typeDescription)));
    }

    /**
     * Matches {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription}s that matches a matched method's
     * return type.
     *
     * @param matcher A matcher to apply onto a matched method's return type.
     * @param      The type of the matched object.
     * @return An element matcher that matches a given return type against another {@code matcher}.
     */
    public static  ElementMatcher.Junction returns(ElementMatcher matcher) {
        return new MethodReturnTypeMatcher(nonNull(matcher));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its exact parameter types.
     *
     * @param type The parameter types of a method in their order.
     * @param   The type of the matched object.
     * @return An element matcher that matches a method by its exact argument types.
     */
    public static  ElementMatcher.Junction takesArguments(Class... type) {
        TypeDescription[] typeDescription = new TypeDescription[type.length];
        int index = 0;
        for (Class aType : type) {
            typeDescription[index++] = new TypeDescription.ForLoadedType(nonNull(aType));
        }
        return takesArguments(typeDescription);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its exact parameter types.
     *
     * @param typeDescription The parameter types of a method in their order.
     * @param              The type of the matched object.
     * @return An element matcher that matches a method by its exact argument types.
     */
    public static  ElementMatcher.Junction takesArguments(TypeDescription... typeDescription) {
        return takesArguments((Arrays.asList(typeDescription)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its exact parameter types.
     *
     * @param typeDescriptions The parameter types of a method in their order.
     * @param               The type of the matched object.
     * @return An element matcher that matches a method by its exact argument types.
     */
    public static  ElementMatcher.Junction takesArguments(Iterable typeDescriptions) {
        List> typeMatchers = new LinkedList>();
        for (TypeDescription typeDescription : typeDescriptions) {
            typeMatchers.add(is(nonVoid(typeDescription)));
        }
        return takesArguments(new CollectionOneToOneMatcher(typeMatchers));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by applying an iterable collection
     * of element matcher on any parameter's {@link com.ui4j.bytebuddy.instrumentation.type.TypeDescription}.
     *
     * @param matchers The matcher that are applied onto the parameter types of the matched method description.
     * @param       The type of the matched object.
     * @return A matcher that matches a method description by applying another element matcher onto each
     * parameter's type.
     */
    public static  ElementMatcher.Junction takesArguments(ElementMatcher> matchers) {
        return new MethodParameterMatcher(new MethodParameterTypeMatcher(nonNull(matchers)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by the number of its parameters.
     *
     * @param length The expected length.
     * @param     The type of the matched object.
     * @return A matcher that matches a method description by the number of its parameters.
     */
    public static  ElementMatcher.Junction takesArguments(int length) {
        return new MethodParameterMatcher(new CollectionSizeMatcher(length));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by validating that at least one
     * parameter fullfils a given constraint.
     *
     * @param matcher The constraint to check the parameters against.
     * @param      The type of the matched object.
     * @return A matcher that matches a method description's parameters against the given constraint.
     */
    public static  ElementMatcher.Junction hasParameter(ElementMatcher matcher) {
        return hasParameters(new CollectionItemMatcher(nonNull(matcher)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by validating that its parameters
     * fulfill a given constraint.
     *
     * @param matcher The matcher to apply for validating the parameters.
     * @param      The type of the matched object.
     * @return A matcher that matches a method description's parameters against the given constraint.
     */
    public static  ElementMatcher.Junction hasParameters(ElementMatcher> matcher) {
        return new MethodParameterMatcher(matcher);
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its capability to throw a given
     * checked exception. For specifying a non-checked exception, any method is matched.
     *
     * @param exceptionType The type of the exception that should be declared by the method to be matched.
     * @param            The type of the matched object.
     * @return A matcher that matches a method description by its declaration of throwing a checked exception.
     */
    public static  ElementMatcher.Junction canThrow(Class exceptionType) {
        return canThrow(new TypeDescription.ForLoadedType(nonNull(exceptionType)));
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its capability to throw a given
     * checked exception. For specifying a non-checked exception, any method is matched.
     *
     * @param exceptionType The type of the exception that should be declared by the method to be matched.
     * @param            The type of the matched object.
     * @return A matcher that matches a method description by its declaration of throwing a checked exception.
     */
    public static  ElementMatcher.Junction canThrow(TypeDescription exceptionType) {
        if (exceptionType.isAssignableTo(Throwable.class)) {
            return exceptionType.isAssignableTo(RuntimeException.class) || exceptionType.isAssignableTo(Error.class)
                    ?
                    new BooleanMatcher(true)
                    :
                    ElementMatchers.throwing(new CollectionItemMatcher(
                            new SubTypeMatcher(exceptionType)));
        } else {
            throw new IllegalArgumentException(exceptionType + " is not an exception type");
        }
    }

    /**
     * Matches a {@link com.ui4j.bytebuddy.instrumentation.method.MethodDescription} by its declared exceptions.
     *
     * @param exceptionMatcher A matcher that is applied by to the declared exceptions.
     * @param               The type of the matched object.
     * @return A matcher that matches a method description by its declared exceptions.
     */
    public static  ElementMatcher.Junction throwing(ElementMatcher> exceptionMatcher) {
        return new MethodExceptionTypeMatcher(exceptionMatcher);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.reflect.Method}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent a Java method.
     */
    public static  ElementMatcher.Junction isMethod() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.METHOD);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.reflect.Constructor}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent a Java constructor.
     */
    public static  ElementMatcher.Junction isConstructor() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.CONSTRUCTOR);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.Class} type initializer.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent the type initializer.
     */
    public static  ElementMatcher.Junction isTypeInitializer() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.TYPE_INITIALIZER);
    }

    /**
     * Only matches method descriptions that represent a visibility bridge. A visibility bridge is a Java bridge
     * method that was inserted by the compiler in order to increase the visibility of a method when inheriting
     * a {@code public} method from a package-private type. In this case, the package-private type's method
     * is declared to be package-private itself such that the bridge method needs to increase the visibility and
     * delegates the call to the original, package-private implementation.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches visibility bridge methods.
     */
    public static  ElementMatcher.Junction isVisibilityBridge() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.VISIBILITY_BRIDGE);
    }

    /**
     * Only matches methods that are overridable, i.e. non-final and dispatched virtually.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches overridable methods.
     */
    public static  ElementMatcher.Junction isOverridable() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.OVERRIDABLE);
    }

    /**
     * Only matches Java 8 default methods.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches Java 8 default methods.
     */
    public static  ElementMatcher.Junction isDefaultMethod() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.DEFAULT_METHOD);
    }

    /**
     * Matches a default constructor, i.e. a constructor without arguments.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches a default constructor.
     */
    public static  ElementMatcher.Junction isDefaultConstructor() {
        return isConstructor().and(takesArguments(0));
    }

    /**
     * Only matches the {@link Object#finalize()} method if it was not overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches a non-overridden {@link Object#finalize()} method.
     */
    public static  ElementMatcher.Junction isDefaultFinalizer() {
        return isFinalizer().and(isDeclaredBy(Object.class));
    }

    /**
     * Only matches the {@link Object#finalize()} method, even if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#finalize()} method.
     */
    public static  ElementMatcher.Junction isFinalizer() {
        return named("finalize").and(takesArguments(0)).and(returns(void.class));
    }

    /**
     * Only matches the {@link Object#toString()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#toString()} method.
     */
    public static  ElementMatcher.Junction isHashCode() {
        return named("hashCode").and(takesArguments(0)).and(returns(int.class));
    }

    /**
     * Only matches the {@link Object#equals(Object)} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#equals(Object)} method.
     */
    public static  ElementMatcher.Junction isEquals() {
        return named("equals").and(takesArguments(Object.class)).and(returns(boolean.class));
    }

    /**
     * Only matches the {@link Object#clone()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#clone()} method.
     */
    public static  ElementMatcher.Junction isClone() {
        return named("clone").and(takesArguments(0)).and(returns(Object.class));
    }

    /**
     * Only matches the {@link Object#toString()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#toString()} method.
     */
    public static  ElementMatcher.Junction isToString() {
        return named("toString").and(takesArguments(0)).and(returns(String.class));
    }

    /**
     * Matches any Java bean setter method.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches any setter method.
     */
    public static  ElementMatcher.Junction isSetter() {
        return nameStartsWith("set").and(takesArguments(1)).and(returns(void.class));
    }

    /**
     * Matches any Java bean setter method which takes an argument the given type.
     *
     * @param type The required setter type.
     * @param   The type of the matched object.
     * @return A matcher that matches any setter method.
     */
    public static  ElementMatcher.Junction isSetter(Class type) {
        return isSetter(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches any Java bean setter method which takes an argument the given type.
     *
     * @param typeDescription The required setter type.
     * @param              The type of the matched object.
     * @return A matcher that matches a setter method with the specified argument type.
     */
    public static  ElementMatcher.Junction isSetter(TypeDescription typeDescription) {
        return isSetter(is(nonVoid(typeDescription)));
    }

    /**
     * Matches any Java bean setter method which takes an argument that matches the supplied matcher.
     *
     * @param matcher A matcher to be allied to a setter method's argument type.
     * @param      The type of the matched object.
     * @return A matcher that matches a setter method with an argument type that matches the supplied matcher.
     */
    public static  ElementMatcher.Junction isSetter(ElementMatcher matcher) {
        return isSetter().and(takesArguments(
                new CollectionOneToOneMatcher(Collections.singletonList(nonNull(matcher)))));
    }

    /**
     * Matches any Java bean getter method.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches any getter method.
     */
    public static  ElementMatcher.Junction isGetter() {
        return takesArguments(0).and(not(returns(void.class))).and(nameStartsWith("get")
                .or(nameStartsWith("is").and(returns(anyOf(boolean.class, Boolean.class)))));
    }

    /**
     * Matches any Java bean getter method which returns the given type.
     *
     * @param type The required getter type.
     * @param   The type of the matched object.
     * @return A matcher that matches a getter method with the given type.
     */
    public static  ElementMatcher.Junction isGetter(Class type) {
        return isGetter(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches any Java bean getter method which returns the given type.
     *
     * @param typeDescription The required getter type.
     * @param              The type of the matched object.
     * @return A matcher that matches a getter method with the given type.
     */
    public static  ElementMatcher.Junction isGetter(TypeDescription typeDescription) {
        return isGetter(is(nonVoid(typeDescription)));
    }

    /**
     * Matches any Java bean getter method which returns an value with a type matches the supplied matcher.
     *
     * @param matcher A matcher to be allied to a getter method's argument type.
     * @param      The type of the matched object.
     * @return A matcher that matches a getter method with a return type that matches the supplied matcher.
     */
    public static  ElementMatcher.Junction isGetter(ElementMatcher matcher) {
        return isGetter().and(returns(nonNull(matcher)));
    }

    /**
     * Matches a specialized version of a given method. This method is characterized by an identical name and
     * by a return type that is a sub type of the given method's return type and by parameter types that are sub types
     * of the the given method's parameter types.
     *
     * @param methodDescription The method description to match.
     * @param                The type of the matched object.
     * @return A matcher that matches a specialized version of the given method.
     */
    public static  ElementMatcher.Junction isSpecializationOf(MethodDescription methodDescription) {
        TypeList parameterTypes = methodDescription.getParameters().asTypeList();
        List> matchers = new ArrayList>(
                parameterTypes.size());
        for (TypeDescription typeDescription : parameterTypes) {
            matchers.add(isSubTypeOf(typeDescription));
        }
        return (methodDescription.isStatic() ? ElementMatchers.isStatic() : ElementMatchers.not(isStatic()))
                .and(named(methodDescription.getSourceCodeName()))
                .and(returns(isSubTypeOf(methodDescription.getReturnType())))
                .and(takesArguments(new CollectionOneToOneMatcher(matchers)));
    }

    /**
     * Matches any type description that is a subtype of the given type.
     *
     * @param type The type to be checked being a super type of the matched type.
     * @param   The type of the matched object.
     * @return A matcher that matches any type description that represents a sub type of the given type.
     */
    public static  ElementMatcher.Junction isSubTypeOf(Class type) {
        return isSubTypeOf(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches any type description that is a subtype of the given type.
     *
     * @param typeDescription The type to be checked being a super type of the matched type.
     * @param              The type of the matched object.
     * @return A matcher that matches any type description that represents a sub type of the given type.
     */
    public static  ElementMatcher.Junction isSubTypeOf(TypeDescription typeDescription) {
        return new SubTypeMatcher(nonNull(typeDescription));
    }

    /**
     * Matches any type description that is a super type of the given type.
     *
     * @param type The type to be checked being a subtype of the matched type.
     * @param   The type of the matched object.
     * @return A matcher that matches any type description that represents a super type of the given type.
     */
    public static  ElementMatcher.Junction isSuperTypeOf(Class type) {
        return isSuperTypeOf(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches any type description that is a super type of the given type.
     *
     * @param typeDescription The type to be checked being a subtype of the matched type.
     * @param              The type of the matched object.
     * @return A matcher that matches any type description that represents a super type of the given type.
     */
    public static  ElementMatcher.Junction isSuperTypeOf(TypeDescription typeDescription) {
        return new SuperTypeMatcher(nonNull(typeDescription));
    }

    /**
     * Matches any annotations by their type on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param type The annotation type to be matched.
     * @param   The type of the matched object.
     * @return A matcher that matches any inherited annotation by their type.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(Class type) {
        return inheritsAnnotation(new TypeDescription.ForLoadedType(nonNull(type)));
    }

    /**
     * Matches any annotations by their type on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param typeDescription The annotation type to be matched.
     * @param              The type of the matched object.
     * @return A matcher that matches any inherited annotation by their type.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(TypeDescription typeDescription) {
        return inheritsAnnotation(is(typeDescription));
    }

    /**
     * Matches any annotations by a given matcher on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param matcher A matcher to apply onto the inherited annotations.
     * @param      The type of the matched object.
     * @return A matcher that matches any inherited annotation by a given matcher.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(ElementMatcher matcher) {
        return hasAnnotation(new AnnotationTypeMatcher(nonNull(matcher)));
    }

    /**
     * Matches a list of annotations by a given matcher on a type that declared these annotations or inherited them
     * from its super classes.
     *
     * @param matcher A matcher to apply onto a list of inherited annotations.
     * @param      The type of the matched object.
     * @return A matcher that matches a list of inherited annotation by a given matcher.
     */
    public static  ElementMatcher.Junction hasAnnotation(ElementMatcher matcher) {
        return new InheritedAnnotationMatcher(new CollectionItemMatcher(nonNull(matcher)));
    }

    /**
     * Matches a type by a another matcher that is applied on any of its declared fields.
     *
     * @param fieldMatcher The matcher that is applied onto each declared field.
     * @param           The type of the matched object.
     * @return A matcher that matches any type where another matcher is matched positively on at least on declared field.
     */
    public static  ElementMatcher.Junction declaresField(ElementMatcher fieldMatcher) {
        return new DeclaringFieldMatcher(new CollectionItemMatcher(nonNull(fieldMatcher)));
    }

    /**
     * Matches a type by a another matcher that is applied on any of its declared methods.
     *
     * @param methodMatcher The matcher that is applied onto each declared method.
     * @param            The type of the matched object.
     * @return A matcher that matches any type where another matcher is matched positively on at least on declared methods.
     */
    public static  ElementMatcher.Junction declaresMethod(ElementMatcher methodMatcher) {
        return new DeclaringMethodMatcher(new CollectionItemMatcher(nonNull(methodMatcher)));
    }

    /**
     * Matches exactly the bootstrap {@link java.lang.ClassLoader} . The returned matcher is a synonym to
     * a matcher matching {@code null}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the bootstrap class loader.
     */
    public static  ElementMatcher isBootstrapClassLoader() {
        return new NullMatcher();
    }

    /**
     * Matches exactly the system {@link java.lang.ClassLoader}. The returned matcher is a synonym to
     * a matcher matching {@code ClassLoader.gerSystemClassLoader()}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the system class loader.
     */
    public static  ElementMatcher isSystemClassLoader() {
        return new EqualityMatcher(ClassLoader.getSystemClassLoader());
    }

    /**
     * Matches exactly the extension {@link java.lang.ClassLoader}. The returned matcher is a synonym to
     * a matcher matching {@code ClassLoader.gerSystemClassLoader().getParent()}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the extension class loader.
     */
    public static  ElementMatcher isExtensionClassLoader() {
        return new EqualityMatcher(ClassLoader.getSystemClassLoader().getParent());
    }

    /**
     * Matches any class loader that is either the given class loader or a child of the given class loader.
     *
     * @param classLoader The class loader of which child class loaders are matched.
     * @param          The type of the matched object.
     * @return A matcher that matches the given class loader and any class loader that is a child of the given
     * class loader.
     */
    public static  ElementMatcher isChildOf(ClassLoader classLoader) {
        return classLoader == null
                ? new BooleanMatcher(true)
                : ElementMatchers.hasChild(is(classLoader));
    }

    /**
     * Matches all class loaders in the hierarchy of the matched class loader against a given matcher.
     *
     * @param matcher The matcher to apply to all class loaders in the hierarchy of the matched class loader.
     * @param      The type of the matched object.
     * @return A matcher that matches all class loaders in the hierarchy of the matched class loader.
     */
    public static  ElementMatcher hasChild(ElementMatcher matcher) {
        return new ClassLoaderHierarchyMatcher(nonNull(matcher));
    }

    /**
     * Matches any class loader that is either the given class loader or a parent of the given class loader.
     *
     * @param classLoader The class loader of which parent class loaders are matched.
     * @param          The type of the matched object.
     * @return A matcher that matches the given class loader and any class loader that is a parent of the given
     * class loader.
     */
    public static  ElementMatcher isParentOf(ClassLoader classLoader) {
        return classLoader == null
                ? ElementMatchers.isBootstrapClassLoader()
                : new ClassLoaderParentMatcher(classLoader);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy