/*
 * Copyright 2014 - 2020 Rafael Winterhalter
 *
 * 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 net.bytebuddy.description.annotation;

import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.build.CachedReturnPlugin;
import net.bytebuddy.description.enumeration.EnumerationDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;

import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationTypeMismatchException;
import java.lang.annotation.IncompleteAnnotationException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.*;

Representation of an unloaded annotation value where all values represent either: The represented values are not necessarily resolvable, i.e. can contain non-available types, unknown enumeration constants or inconsistent annotations.
Type parameters:
  • <T> – The represented value's unloaded type.
  • <S> – The represented value's loaded type.
/** * Representation of an unloaded annotation value where all values represent either: * <ul> * <li>Primitive values (as their wrappers), {@link String}s or arrays of primitive types or strings.</li> * <li>A {@link TypeDescription} or an array of such a descriptions.</li> * <li>An {@link EnumerationDescription} or an array of such a description.</li> * <li>An {@link AnnotationDescription} or an array of such a description.</li> * </ul> * The represented values are not necessarily resolvable, i.e. can contain non-available types, unknown enumeration * constants or inconsistent annotations. * * @param <T> The represented value's unloaded type. * @param <S> The represented value's loaded type. */
public interface AnnotationValue<T, S> {
An undefined annotation value.
/** * An undefined annotation value. */
AnnotationValue<?, ?> UNDEFINED = null;
Returns the state of the represented annotation value.
Returns:The state represented by this instance.
/** * Returns the state of the represented annotation value. * * @return The state represented by this instance. */
State getState();
Filters this annotation value as a valid value of the provided property.
Params:
  • property – The property to filter against.
Returns:This annotation value or a new annotation value that describes why this value is not a valid value for the supplied property.
/** * Filters this annotation value as a valid value of the provided property. * * @param property The property to filter against. * @return This annotation value or a new annotation value that describes why this value is not a valid value for the supplied property. */
AnnotationValue<T, S> filter(MethodDescription.InDefinedShape property);
Filters this annotation value as a valid value of the provided property.
Params:
  • property – The property to filter against.
  • typeDefinition – The expected type.
Returns:This annotation value or a new annotation value that describes why this value is not a valid value for the supplied property.
/** * Filters this annotation value as a valid value of the provided property. * * @param property The property to filter against. * @param typeDefinition The expected type. * @return This annotation value or a new annotation value that describes why this value is not a valid value for the supplied property. */
AnnotationValue<T, S> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition);
Resolves the unloaded value of this annotation. The return value of this method is not defined if this annotation value is invalid.
Returns:The unloaded value of this annotation.
/** * Resolves the unloaded value of this annotation. The return value of this method is not defined if this annotation value is invalid. * * @return The unloaded value of this annotation. */
T resolve();
Resolves the unloaded value of this annotation. The return value of this method is not defined if this annotation value is invalid.
Params:
  • type – The annotation value's unloaded type.
Type parameters:
  • <W> – The annotation value's unloaded type.
Returns:The unloaded value of this annotation.
/** * Resolves the unloaded value of this annotation. The return value of this method is not defined if this annotation value is invalid. * * @param type The annotation value's unloaded type. * @param <W> The annotation value's unloaded type. * @return The unloaded value of this annotation. */
<W> W resolve(Class<? extends W> type);
Returns the loaded value of this annotation.
Params:
  • classLoader – The class loader for loading this value.
Returns:The loaded value of this annotation.
/** * Returns the loaded value of this annotation. * * @param classLoader The class loader for loading this value. * @return The loaded value of this annotation. */
Loaded<S> load(ClassLoader classLoader);
A rendering dispatcher is responsible for resolving annotation values to String representations.
/** * A rendering dispatcher is responsible for resolving annotation values to {@link String} representations. */
enum RenderingDispatcher {
A rendering dispatcher for any VM previous to Java 9.
/** * A rendering dispatcher for any VM previous to Java 9. */
LEGACY_VM('[', ']') { @Override public String toSourceString(char value) { return Character.toString(value); } @Override public String toSourceString(long value) { return Long.toString(value); } @Override public String toSourceString(float value) { return Float.toString(value); } @Override public String toSourceString(double value) { return Double.toString(value); } @Override public String toSourceString(String value) { return value; } @Override public String toSourceString(TypeDescription value) { return value.toString(); } },
A rendering dispatcher for Java 9 onward.
/** * A rendering dispatcher for Java 9 onward. */
JAVA_9_CAPABLE_VM('{', '}') { @Override public String toSourceString(char value) { StringBuilder stringBuilder = new StringBuilder().append('\''); if (value == '\'') { stringBuilder.append("\\\'"); } else { stringBuilder.append(value); } return stringBuilder.append('\'').toString(); } @Override public String toSourceString(long value) { return Math.abs(value) <= Integer.MAX_VALUE ? String.valueOf(value) : value + "L"; } @Override public String toSourceString(float value) { return Math.abs(value) <= Float.MAX_VALUE // Float.isFinite(value) ? value + "f" : (Float.isInfinite(value) ? (value < 0.0f ? "-1.0f/0.0f" : "1.0f/0.0f") : "0.0f/0.0f"); } @Override public String toSourceString(double value) { return Math.abs(value) <= Double.MAX_VALUE // Double.isFinite(value) ? Double.toString(value) : (Double.isInfinite(value) ? (value < 0.0d ? "-1.0/0.0" : "1.0/0.0") : "0.0/0.0"); } @Override public String toSourceString(String value) { return "\"" + (value.indexOf('"') == -1 ? value : value.replace("\"", "\\\"")) + "\""; } @Override public String toSourceString(TypeDescription value) { return value.getActualName() + ".class"; } },
A rendering dispatcher for Java 14 onward.
/** * A rendering dispatcher for Java 14 onward. */
JAVA_14_CAPABLE_VM('{', '}') { @Override public String toSourceString(byte value) { return "(byte)0x" + Integer.toHexString(value); } @Override public String toSourceString(char value) { StringBuilder stringBuilder = new StringBuilder().append('\''); if (value == '\'') { stringBuilder.append("\\\'"); } else { stringBuilder.append(value); } return stringBuilder.append('\'').toString(); } @Override public String toSourceString(long value) { return value + "L"; } @Override public String toSourceString(float value) { return Math.abs(value) <= Float.MAX_VALUE // Float.isFinite(value) ? value + "f" : (Float.isInfinite(value) ? (value < 0.0f ? "-1.0f/0.0f" : "1.0f/0.0f") : "0.0f/0.0f"); } @Override public String toSourceString(double value) { return Math.abs(value) <= Double.MAX_VALUE // Double.isFinite(value) ? Double.toString(value) : (Double.isInfinite(value) ? (value < 0.0d ? "-1.0/0.0" : "1.0/0.0") : "0.0/0.0"); } @Override public String toSourceString(String value) { return "\"" + (value.indexOf('"') == -1 ? value : value.replace("\"", "\\\"")) + "\""; } @Override public String toSourceString(TypeDescription value) { return value.getActualName() + ".class"; } };
The rendering dispatcher for the current VM.
/** * The rendering dispatcher for the current VM. */
public static final RenderingDispatcher CURRENT; static { ClassFileVersion classFileVersion = ClassFileVersion.ofThisVm(ClassFileVersion.JAVA_V6); if (classFileVersion.isAtLeast(ClassFileVersion.JAVA_V14)) { CURRENT = RenderingDispatcher.JAVA_14_CAPABLE_VM; } else if (classFileVersion.isAtLeast(ClassFileVersion.JAVA_V9)) { CURRENT = RenderingDispatcher.JAVA_9_CAPABLE_VM; } else { CURRENT = RenderingDispatcher.LEGACY_VM; } }
The opening brace of an array String representation.
/** * The opening brace of an array {@link String} representation. */
private final char openingBrace;
The closing brace of an array String representation.
/** * The closing brace of an array {@link String} representation. */
private final char closingBrace;
Creates a new rendering dispatcher.
Params:
  • openingBrace – The opening brace of an array String representation.
  • closingBrace – The closing brace of an array String representation.
/** * Creates a new rendering dispatcher. * * @param openingBrace The opening brace of an array {@link String} representation. * @param closingBrace The closing brace of an array {@link String} representation. */
RenderingDispatcher(char openingBrace, char closingBrace) { this.openingBrace = openingBrace; this.closingBrace = closingBrace; }
Represents the supplied boolean value as a String.
Params:
  • value – The boolean value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code boolean} value as a {@link String}. * * @param value The {@code boolean} value to render. * @return An appropriate {@link String} representation. */
public String toSourceString(boolean value) { return Boolean.toString(value); }
Represents the supplied boolean value as a String.
Params:
  • value – The boolean value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code boolean} value as a {@link String}. * * @param value The {@code boolean} value to render. * @return An appropriate {@link String} representation. */
public String toSourceString(byte value) { return Byte.toString(value); }
Represents the supplied short value as a String.
Params:
  • value – The short value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code short} value as a {@link String}. * * @param value The {@code short} value to render. * @return An appropriate {@link String} representation. */
public String toSourceString(short value) { return Short.toString(value); }
Represents the supplied char value as a String.
Params:
  • value – The char value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code char} value as a {@link String}. * * @param value The {@code char} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(char value);
Represents the supplied int value as a String.
Params:
  • value – The int value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code int} value as a {@link String}. * * @param value The {@code int} value to render. * @return An appropriate {@link String} representation. */
public String toSourceString(int value) { return Integer.toString(value); }
Represents the supplied long value as a String.
Params:
  • value – The long value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code long} value as a {@link String}. * * @param value The {@code long} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(long value);
Represents the supplied float value as a String.
Params:
  • value – The float value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code float} value as a {@link String}. * * @param value The {@code float} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(float value);
Represents the supplied double value as a String.
Params:
  • value – The double value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@code double} value as a {@link String}. * * @param value The {@code double} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(double value);
Represents the supplied String value as a String.
Params:
  • value – The String value to render.
Returns:An appropriate String representation.
/** * Represents the supplied {@link String} value as a {@link String}. * * @param value The {@link String} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(String value);
Represents the supplied TypeDescription value as a String.
Params:
Returns:An appropriate String representation.
/** * Represents the supplied {@link TypeDescription} value as a {@link String}. * * @param value The {@link TypeDescription} value to render. * @return An appropriate {@link String} representation. */
public abstract String toSourceString(TypeDescription value);
Represents the supplied list elements as a String.
Params:
  • values – The elements to render where each element is represented by its Object.toString() representation.
Returns:An appropriate String representation.
/** * Represents the supplied list elements as a {@link String}. * * @param values The elements to render where each element is represented by its {@link Object#toString()} representation. * @return An appropriate {@link String} representation. */
public String toSourceString(List<?> values) { StringBuilder stringBuilder = new StringBuilder().append(openingBrace); boolean first = true; for (Object value : values) { if (first) { first = false; } else { stringBuilder.append(", "); } stringBuilder.append(value); } return stringBuilder.append(closingBrace).toString(); }
Resolves the supplied type description's component tag.
Params:
  • typeDescription – The type to resolve.
Returns:The character that describes the component tag as an int to ease concatenation.
/** * Resolves the supplied type description's component tag. * * @param typeDescription The type to resolve. * @return The character that describes the component tag as an {@code int} to ease concatenation. */
public int toComponentTag(TypeDescription typeDescription) { if (typeDescription.represents(boolean.class)) { return 'Z'; } else if (typeDescription.represents(byte.class)) { return 'B'; } else if (typeDescription.represents(short.class)) { return 'S'; } else if (typeDescription.represents(char.class)) { return 'C'; } else if (typeDescription.represents(int.class)) { return 'I'; } else if (typeDescription.represents(long.class)) { return 'J'; } else if (typeDescription.represents(float.class)) { return 'F'; } else if (typeDescription.represents(double.class)) { return 'D'; } else if (typeDescription.represents(String.class)) { return 's'; } else if (typeDescription.represents(Class.class)) { return 'c'; } else if (typeDescription.isEnum()) { return 'e'; } else if (typeDescription.isAnnotation()) { return '@'; } else if (typeDescription.isArray()) { return '['; } else { throw new IllegalArgumentException("Not an annotation component: " + typeDescription); } } }
A loaded variant of an AnnotationValue. While implementations of this value are required to be processed successfully by a ClassLoader they might still be unresolved. Typical errors on loading an annotation value are: Implementations of this interface must implement methods for Object.hashCode() and Object.toString() that resemble those used for the annotation values of an actual Annotation implementation. Also, instances must implement Object.equals(Object) to return true for other instances of this interface that represent the same annotation value.
Type parameters:
  • <U> – The represented value's type.
/** * A loaded variant of an {@link AnnotationValue}. While * implementations of this value are required to be processed successfully by a * {@link java.lang.ClassLoader} they might still be unresolved. Typical errors on loading an annotation * value are: * <ul> * <li>{@link java.lang.annotation.IncompleteAnnotationException}: An annotation does not define a value * even though no default value for a property is provided.</li> * <li>{@link java.lang.EnumConstantNotPresentException}: An annotation defines an unknown value for * a known enumeration.</li> * <li>{@link java.lang.annotation.AnnotationTypeMismatchException}: An annotation property is not * of the expected type.</li> * </ul> * Implementations of this interface must implement methods for {@link Object#hashCode()} and * {@link Object#toString()} that resemble those used for the annotation values of an actual * {@link java.lang.annotation.Annotation} implementation. Also, instances must implement * {@link java.lang.Object#equals(Object)} to return {@code true} for other instances of * this interface that represent the same annotation value. * * @param <U> The represented value's type. */
interface Loaded<U> {
Returns the state of the represented loaded annotation value.
Returns:The state represented by this instance.
/** * Returns the state of the represented loaded annotation value. * * @return The state represented by this instance. */
State getState();
Resolves the value to the actual value of an annotation. Calling this method might throw a runtime exception if this value is either not defined or not resolved.
Returns:The actual annotation value represented by this instance.
/** * Resolves the value to the actual value of an annotation. Calling this method might throw a runtime * exception if this value is either not defined or not resolved. * * @return The actual annotation value represented by this instance. */
U resolve();
Resolves the value to the actual value of an annotation. Calling this method might throw a runtime exception if this value is either not defined or not resolved.
Params:
  • type – The value's loaded type.
Type parameters:
  • <V> – The value's loaded type.
Returns:The actual annotation value represented by this instance.
/** * Resolves the value to the actual value of an annotation. Calling this method might throw a runtime * exception if this value is either not defined or not resolved. * * @param type The value's loaded type. * @param <V> The value's loaded type. * @return The actual annotation value represented by this instance. */
<V> V resolve(Class<? extends V> type);
Verifies if this loaded value represents the supplied loaded value.
Params:
  • value – A loaded annotation value.
Returns:true if the supplied annotation value is represented by this annotation value.
/** * Verifies if this loaded value represents the supplied loaded value. * * @param value A loaded annotation value. * @return {@code true} if the supplied annotation value is represented by this annotation value. */
boolean represents(Object value);
An abstract base implementation of a loaded annotation value.
Type parameters:
  • <W> – The represented loaded type.
/** * An abstract base implementation of a loaded annotation value. * * @param <W> The represented loaded type. */
abstract class AbstractBase<W> implements Loaded<W> {
{@inheritDoc}
/** * {@inheritDoc} */
public <X> X resolve(Class<? extends X> type) { return type.cast(resolve()); }
A base implementation for an unresolved property.
Type parameters:
  • <Z> – The represented loaded type.
/** * A base implementation for an unresolved property. * * @param <Z> The represented loaded type. */
public abstract static class ForUnresolvedProperty<Z> extends AbstractBase<Z> {
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return false; } } } }
Represents the state of a Loaded annotation property.
/** * Represents the state of a {@link Loaded} annotation property. */
enum State {
An undefined annotation value describes an annotation property which is missing such that an IncompleteAnnotationException would be thrown.
/** * An undefined annotation value describes an annotation property which is missing such that * an {@link java.lang.annotation.IncompleteAnnotationException} would be thrown. */
UNDEFINED,
An unresolved annotation value describes an annotation property which does not represent a valid value but an exceptional state.
/** * An unresolved annotation value describes an annotation property which does not represent a * valid value but an exceptional state. */
UNRESOLVED,
A resolved annotation value describes an annotation property with an actual value.
/** * A resolved annotation value describes an annotation property with an actual value. */
RESOLVED;
Returns true if the related annotation value is defined, i.e. either represents an actual value or an exceptional state.
Returns:true if the related annotation value is defined.
/** * Returns {@code true} if the related annotation value is defined, i.e. either represents * an actual value or an exceptional state. * * @return {@code true} if the related annotation value is defined. */
public boolean isDefined() { return this != UNDEFINED; }
Returns true if the related annotation value is resolved, i.e. represents an actual value.
Returns:true if the related annotation value is resolved.
/** * Returns {@code true} if the related annotation value is resolved, i.e. represents an actual * value. * * @return {@code true} if the related annotation value is resolved. */
public boolean isResolved() { return this == RESOLVED; } }
An abstract base implementation of an unloaded annotation value.
Type parameters:
  • <U> – The represented unloaded type.
  • <V> – The represented loaded type.
/** * An abstract base implementation of an unloaded annotation value. * * @param <U> The represented unloaded type. * @param <V> The represented loaded type. */
abstract class AbstractBase<U, V> implements AnnotationValue<U, V> {
{@inheritDoc}
/** * {@inheritDoc} */
public <W> W resolve(Class<? extends W> type) { return type.cast(resolve()); } @Override public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property) { return filter(property, property.getReturnType()); } }
Represents a primitive value, a String or an array of the latter types.
Type parameters:
  • <U> – The type where primitive values are represented by their boxed type.
/** * Represents a primitive value, a {@link java.lang.String} or an array of the latter types. * * @param <U> The type where primitive values are represented by their boxed type. */
class ForConstant<U> extends AbstractBase<U, U> {
The represented value.
/** * The represented value. */
private final U value;
The property delegate for the value's type.
/** * The property delegate for the value's type. */
private final PropertyDelegate propertyDelegate;
Creates a new constant annotation value.
Params:
  • value – The represented value.
  • propertyDelegate – The property delegate for the value's type.
/** * Creates a new constant annotation value. * * @param value The represented value. * @param propertyDelegate The property delegate for the value's type. */
protected ForConstant(U value, PropertyDelegate propertyDelegate) { this.value = value; this.propertyDelegate = propertyDelegate; }
Creates an annotation value for a boolean value.
Params:
  • value – The boolean value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code boolean} value. * * @param value The {@code boolean} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Boolean, Boolean> of(boolean value) { return new ForConstant<Boolean>(value, PropertyDelegate.ForNonArrayType.BOOLEAN); }
Creates an annotation value for a byte value.
Params:
  • value – The byte value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code byte} value. * * @param value The {@code byte} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Byte, Byte> of(byte value) { return new ForConstant<Byte>(value, PropertyDelegate.ForNonArrayType.BYTE); }
Creates an annotation value for a short value.
Params:
  • value – The short value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code short} value. * * @param value The {@code short} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Short, Short> of(short value) { return new ForConstant<Short>(value, PropertyDelegate.ForNonArrayType.SHORT); }
Creates an annotation value for a char value.
Params:
  • value – The char value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code char} value. * * @param value The {@code char} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Character, Character> of(char value) { return new ForConstant<Character>(value, PropertyDelegate.ForNonArrayType.CHARACTER); }
Creates an annotation value for a int value.
Params:
  • value – The int value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code int} value. * * @param value The {@code int} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Integer, Integer> of(int value) { return new ForConstant<Integer>(value, PropertyDelegate.ForNonArrayType.INTEGER); }
Creates an annotation value for a long value.
Params:
  • value – The long value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code long} value. * * @param value The {@code long} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Long, Long> of(long value) { return new ForConstant<Long>(value, PropertyDelegate.ForNonArrayType.LONG); }
Creates an annotation value for a float value.
Params:
  • value – The float value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code float} value. * * @param value The {@code float} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Float, Float> of(float value) { return new ForConstant<Float>(value, PropertyDelegate.ForNonArrayType.FLOAT); }
Creates an annotation value for a double value.
Params:
  • value – The double value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code double} value. * * @param value The {@code double} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<Double, Double> of(double value) { return new ForConstant<Double>(value, PropertyDelegate.ForNonArrayType.DOUBLE); }
Creates an annotation value for a String value.
Params:
  • value – The String value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@link String} value. * * @param value The {@link String} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<String, String> of(String value) { return new ForConstant<String>(value, PropertyDelegate.ForNonArrayType.STRING); }
Creates an annotation value for a boolean[] value.
Params:
  • value – The boolean[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code boolean[]} value. * * @param value The {@code boolean[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<boolean[], boolean[]> of(boolean... value) { return new ForConstant<boolean[]>(value, PropertyDelegate.ForArrayType.BOOLEAN); }
Creates an annotation value for a byte[] value.
Params:
  • value – The byte[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code byte[]} value. * * @param value The {@code byte[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<byte[], byte[]> of(byte... value) { return new ForConstant<byte[]>(value, PropertyDelegate.ForArrayType.BYTE); }
Creates an annotation value for a short[] value.
Params:
  • value – The short[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code short[]} value. * * @param value The {@code short[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<short[], short[]> of(short... value) { return new ForConstant<short[]>(value, PropertyDelegate.ForArrayType.SHORT); }
Creates an annotation value for a char[] value.
Params:
  • value – The char[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code char[]} value. * * @param value The {@code char[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<char[], char[]> of(char... value) { return new ForConstant<char[]>(value, PropertyDelegate.ForArrayType.CHARACTER); }
Creates an annotation value for a int[] value.
Params:
  • value – The int[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code int[]} value. * * @param value The {@code int[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<int[], int[]> of(int... value) { return new ForConstant<int[]>(value, PropertyDelegate.ForArrayType.INTEGER); }
Creates an annotation value for a long[] value.
Params:
  • value – The long[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code long[]} value. * * @param value The {@code long[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<long[], long[]> of(long... value) { return new ForConstant<long[]>(value, PropertyDelegate.ForArrayType.LONG); }
Creates an annotation value for a float[] value.
Params:
  • value – The float[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code float[]} value. * * @param value The {@code float[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<float[], float[]> of(float... value) { return new ForConstant<float[]>(value, PropertyDelegate.ForArrayType.FLOAT); }
Creates an annotation value for a double[] value.
Params:
  • value – The double[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code double[]} value. * * @param value The {@code double[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<double[], double[]> of(double... value) { return new ForConstant<double[]>(value, PropertyDelegate.ForArrayType.DOUBLE); }
Creates an annotation value for a String[] value.
Params:
  • value – The String[] value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for a {@code String[]} value. * * @param value The {@code String[]} value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<String[], String[]> of(String... value) { return new ForConstant<String[]>(value, PropertyDelegate.ForArrayType.STRING); }
Creates an annotation value for any constant value, i.e any primitive (wrapper) type, any primitive array type or any String value or array. If no constant annotation type is provided, a runtime exception is thrown.
Params:
  • value – The value to represent.
Returns:An appropriate annotation value.
/** * Creates an annotation value for any constant value, i.e any primitive (wrapper) type, * any primitive array type or any {@link String} value or array. If no constant annotation * type is provided, a runtime exception is thrown. * * @param value The value to represent. * @return An appropriate annotation value. */
public static AnnotationValue<?, ?> of(Object value) { if (value instanceof Boolean) { return of(((Boolean) value).booleanValue()); } else if (value instanceof Byte) { return of(((Byte) value).byteValue()); } else if (value instanceof Short) { return of(((Short) value).shortValue()); } else if (value instanceof Character) { return of(((Character) value).charValue()); } else if (value instanceof Integer) { return of(((Integer) value).intValue()); } else if (value instanceof Long) { return of(((Long) value).longValue()); } else if (value instanceof Float) { return of(((Float) value).floatValue()); } else if (value instanceof Double) { return of(((Double) value).doubleValue()); } else if (value instanceof String) { return of((String) value); } else if (value instanceof boolean[]) { return of((boolean[]) value); } else if (value instanceof byte[]) { return of((byte[]) value); } else if (value instanceof short[]) { return of((short[]) value); } else if (value instanceof char[]) { return of((char[]) value); } else if (value instanceof int[]) { return of((int[]) value); } else if (value instanceof long[]) { return of((long[]) value); } else if (value instanceof float[]) { return of((float[]) value); } else if (value instanceof double[]) { return of((double[]) value); } else if (value instanceof String[]) { return of((String[]) value); } else { throw new IllegalArgumentException("Not a constant annotation value: " + value); } }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<U, U> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return typeDefinition.asErasure().asBoxed().represents(value.getClass()) ? this : new ForMismatchedType<U, U>(property, value.getClass().isArray() ? "Array with component tag: " + RenderingDispatcher.CURRENT.toComponentTag(TypeDescription.ForLoadedType.of(value.getClass().getComponentType())) : value.getClass().toString() + '[' + value + ']'); }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { return value; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { return new Loaded<U>(value, propertyDelegate); } @Override @CachedReturnPlugin.Enhance("hashCode") public int hashCode() { return propertyDelegate.hashCode(value); } @Override public boolean equals(Object other) { return this == other || other instanceof AnnotationValue<?, ?> && propertyDelegate.equals(value, ((AnnotationValue<?, ?>) other).resolve()); } @Override public String toString() { return propertyDelegate.toString(value); }
A property delegate for a constant annotation value.
/** * A property delegate for a constant annotation value. */
protected interface PropertyDelegate {
Copies the provided value, if it is not immutable.
Params:
  • value – The value to copy.
Type parameters:
  • <S> – The value's type.
Returns:A copy of the provided instance or the provided value, if it is immutable.
/** * Copies the provided value, if it is not immutable. * * @param value The value to copy. * @param <S> The value's type. * @return A copy of the provided instance or the provided value, if it is immutable. */
<S> S copy(S value);
Computes the value's hash code.
Params:
  • value – The value for which to compute the hash code.
Returns:The hash code of the provided value.
/** * Computes the value's hash code. * * @param value The value for which to compute the hash code. * @return The hash code of the provided value. */
int hashCode(Object value);
Determines if another value is equal to a constant annotation value.
Params:
  • self – The value that is represented as a constant annotation value.
  • other – Any other value for which to determine equality.
Returns:true if the provided value is equal to the represented value.
/** * Determines if another value is equal to a constant annotation value. * * @param self The value that is represented as a constant annotation value. * @param other Any other value for which to determine equality. * @return {@code true} if the provided value is equal to the represented value. */
boolean equals(Object self, Object other);
Renders the supplied value as a String.
Params:
  • value – The value to render.
Returns:An appropriate String representation of the provided value.
/** * Renders the supplied value as a {@link String}. * * @param value The value to render. * @return An appropriate {@link String} representation of the provided value. */
String toString(Object value);
A property delegate for a non-array type.
/** * A property delegate for a non-array type. */
enum ForNonArrayType implements PropertyDelegate {
A property delegate for a boolean value.
/** * A property delegate for a {@code boolean} value. */
BOOLEAN {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Boolean) value); } },
A property delegate for a byte value.
/** * A property delegate for a {@code byte} value. */
BYTE {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Byte) value); } },
A property delegate for a short value.
/** * A property delegate for a {@code short} value. */
SHORT {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Short) value); } },
A property delegate for a char value.
/** * A property delegate for a {@code char} value. */
CHARACTER {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Character) value); } },
A property delegate for a int value.
/** * A property delegate for a {@code int} value. */
INTEGER {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Integer) value); } },
A property delegate for a long value.
/** * A property delegate for a {@code long} value. */
LONG {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Long) value); } },
A property delegate for a float value.
/** * A property delegate for a {@code float} value. */
FLOAT {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Float) value); } },
A property delegate for a double value.
/** * A property delegate for a {@code double} value. */
DOUBLE {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((Double) value); } },
A property delegate for a String value.
/** * A property delegate for a {@link String} value. */
STRING {
{@inheritDoc}
/** {@inheritDoc} */
public String toString(Object value) { return RenderingDispatcher.CURRENT.toSourceString((String) value); } };
{@inheritDoc}
/** * {@inheritDoc} */
public <S> S copy(S value) { return value; }
{@inheritDoc}
/** * {@inheritDoc} */
public int hashCode(Object value) { return value.hashCode(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean equals(Object self, Object other) { return self.equals(other); } }
A property delegate for an array type of a constant value.
/** * A property delegate for an array type of a constant value. */
enum ForArrayType implements PropertyDelegate {
A property delegate for a boolean[] value.
/** * A property delegate for a {@code boolean[]} value. */
BOOLEAN { @Override protected Object doCopy(Object value) { return ((boolean[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((boolean[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof boolean[] && Arrays.equals((boolean[]) self, (boolean[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.BOOLEAN.toString(Array.getBoolean(array, index)); } },
A property delegate for a byte[] value.
/** * A property delegate for a {@code byte[]} value. */
BYTE { @Override protected Object doCopy(Object value) { return ((byte[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((byte[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof byte[] && Arrays.equals((byte[]) self, (byte[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.BYTE.toString(Array.getByte(array, index)); } },
A property delegate for a short[] value.
/** * A property delegate for a {@code short[]} value. */
SHORT { @Override protected Object doCopy(Object value) { return ((short[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((short[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof short[] && Arrays.equals((short[]) self, (short[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.SHORT.toString(Array.getShort(array, index)); } },
A property delegate for a char[] value.
/** * A property delegate for a {@code char[]} value. */
CHARACTER { @Override protected Object doCopy(Object value) { return ((char[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((char[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof char[] && Arrays.equals((char[]) self, (char[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.CHARACTER.toString(Array.getChar(array, index)); } },
A property delegate for a int[] value.
/** * A property delegate for a {@code int[]} value. */
INTEGER { @Override protected Object doCopy(Object value) { return ((int[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((int[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof int[] && Arrays.equals((int[]) self, (int[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.INTEGER.toString(Array.getInt(array, index)); } },
A property delegate for a long[] value.
/** * A property delegate for a {@code long[]} value. */
LONG { @Override protected Object doCopy(Object value) { return ((long[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((long[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof long[] && Arrays.equals((long[]) self, (long[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.LONG.toString(Array.getLong(array, index)); } },
A property delegate for a float[] value.
/** * A property delegate for a {@code float[]} value. */
FLOAT { @Override protected Object doCopy(Object value) { return ((float[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((float[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof float[] && Arrays.equals((float[]) self, (float[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.FLOAT.toString(Array.getFloat(array, index)); } },
A property delegate for a double[] value.
/** * A property delegate for a {@code double[]} value. */
DOUBLE { @Override protected Object doCopy(Object value) { return ((double[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((double[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof double[] && Arrays.equals((double[]) self, (double[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.DOUBLE.toString(Array.getDouble(array, index)); } },
A property delegate for a String[] value.
/** * A property delegate for a {@code String[]} value. */
STRING { @Override protected Object doCopy(Object value) { return ((String[]) value).clone(); }
{@inheritDoc}
/** {@inheritDoc} */
public int hashCode(Object value) { return Arrays.hashCode((String[]) value); }
{@inheritDoc}
/** {@inheritDoc} */
public boolean equals(Object self, Object other) { return other instanceof String[] && Arrays.equals((String[]) self, (String[]) other); } @Override protected String toString(Object array, int index) { return ForNonArrayType.STRING.toString(Array.get(array, index)); } };
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public <S> S copy(S value) { return (S) doCopy(value); }
Creates a copy of the provided array.
Params:
  • value – The array to copy.
Returns:A shallow copy of the provided array.
/** * Creates a copy of the provided array. * * @param value The array to copy. * @return A shallow copy of the provided array. */
protected abstract Object doCopy(Object value);
{@inheritDoc}
/** * {@inheritDoc} */
public String toString(Object value) { List<String> elements = new ArrayList<String>(Array.getLength(value)); for (int index = 0; index < Array.getLength(value); index++) { elements.add(toString(value, index)); } return RenderingDispatcher.CURRENT.toSourceString(elements); }
Renders the array element at the specified index.
Params:
  • array – The array for which an element should be rendered.
  • index – The index of the array element to render.
Returns:A String representation of the array element at the supplied index.
/** * Renders the array element at the specified index. * * @param array The array for which an element should be rendered. * @param index The index of the array element to render. * @return A {@link String} representation of the array element at the supplied index. */
protected abstract String toString(Object array, int index); } }
Represents a trivial loaded value.
Type parameters:
  • <V> – The annotation properties type.
/** * Represents a trivial loaded value. * * @param <V> The annotation properties type. */
protected static class Loaded<V> extends AnnotationValue.Loaded.AbstractBase<V> {
The represented value.
/** * The represented value. */
private final V value;
The property delegate for the value's type.
/** * The property delegate for the value's type. */
private final PropertyDelegate propertyDelegate;
Creates a new loaded representation of a constant value.
Params:
  • value – The represented value.
  • propertyDelegate – The property delegate for the value's type.
/** * Creates a new loaded representation of a constant value. * * @param value The represented value. * @param propertyDelegate The property delegate for the value's type. */
protected Loaded(V value, PropertyDelegate propertyDelegate) { this.value = value; this.propertyDelegate = propertyDelegate; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public V resolve() { return propertyDelegate.copy(value); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return propertyDelegate.equals(this.value, value); } @Override @CachedReturnPlugin.Enhance("hashCode") public int hashCode() { return propertyDelegate.hashCode(value); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue.Loaded<?>)) { return false; } AnnotationValue.Loaded<?> annotationValue = (AnnotationValue.Loaded<?>) other; return annotationValue.getState().isResolved() && propertyDelegate.equals(value, annotationValue.resolve()); } @Override public String toString() { return propertyDelegate.toString(value); } } }
A description of an Annotation as a value of another annotation.
Type parameters:
  • <U> – The type of the annotation.
/** * A description of an {@link java.lang.annotation.Annotation} as a value of another annotation. * * @param <U> The type of the annotation. */
class ForAnnotationDescription<U extends Annotation> extends AbstractBase<AnnotationDescription, U> {
The annotation description that this value represents.
/** * The annotation description that this value represents. */
private final AnnotationDescription annotationDescription;
Creates a new annotation value for a given annotation description.
Params:
  • annotationDescription – The annotation description that this value represents.
/** * Creates a new annotation value for a given annotation description. * * @param annotationDescription The annotation description that this value represents. */
public ForAnnotationDescription(AnnotationDescription annotationDescription) { this.annotationDescription = annotationDescription; }
Creates an annotation value instance for describing the given annotation type and values.
Params:
  • annotationType – The annotation type.
  • annotationValues – The values of the annotation.
Type parameters:
  • <V> – The type of the annotation.
Returns:An annotation value representing the given annotation.
/** * Creates an annotation value instance for describing the given annotation type and values. * * @param annotationType The annotation type. * @param annotationValues The values of the annotation. * @param <V> The type of the annotation. * @return An annotation value representing the given annotation. */
public static <V extends Annotation> AnnotationValue<AnnotationDescription, V> of(TypeDescription annotationType, Map<String, ? extends AnnotationValue<?, ?>> annotationValues) { return new ForAnnotationDescription<V>(new AnnotationDescription.Latent(annotationType, annotationValues)); }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<AnnotationDescription, U> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return typeDefinition.asErasure().equals(annotationDescription.getAnnotationType()) ? this : new ForMismatchedType<AnnotationDescription, U>(property, annotationDescription.getAnnotationType().toString() + '[' + annotationDescription + ']'); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationDescription resolve() { return annotationDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { try { return new Loaded<U>(annotationDescription .prepare((Class<U>) Class.forName(annotationDescription.getAnnotationType().getName(), false, classLoader)) .load()); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<U>(annotationDescription.getAnnotationType().getName(), exception); } } @Override public int hashCode() { return annotationDescription.hashCode(); } @Override public boolean equals(Object other) { return this == other || other instanceof AnnotationValue<?, ?> && annotationDescription.equals(((AnnotationValue<?, ?>) other).resolve()); } @Override public String toString() { return annotationDescription.toString(); }
A loaded version of the described annotation.
Type parameters:
  • <V> – The annotation type.
/** * A loaded version of the described annotation. * * @param <V> The annotation type. */
public static class Loaded<V extends Annotation> extends AnnotationValue.Loaded.AbstractBase<V> {
The loaded version of the represented annotation.
/** * The loaded version of the represented annotation. */
private final V annotation;
Creates a representation of a loaded annotation.
Params:
  • annotation – The represented annotation.
/** * Creates a representation of a loaded annotation. * * @param annotation The represented annotation. */
public Loaded(V annotation) { this.annotation = annotation; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public V resolve() { return annotation; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return annotation.equals(value); } @Override public int hashCode() { return annotation.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue.Loaded<?>)) { return false; } AnnotationValue.Loaded<?> annotationValue = (AnnotationValue.Loaded<?>) other; return annotationValue.getState().isResolved() && annotation.equals(annotationValue.resolve()); } @Override public String toString() { return annotation.toString(); } } }
A description of an Enum as a value of an annotation.
Type parameters:
  • <U> – The type of the enumeration.
/** * A description of an {@link java.lang.Enum} as a value of an annotation. * * @param <U> The type of the enumeration. */
class ForEnumerationDescription<U extends Enum<U>> extends AbstractBase<EnumerationDescription, U> {
The enumeration that is represented.
/** * The enumeration that is represented. */
private final EnumerationDescription enumerationDescription;
Creates a new description of an annotation value for a given enumeration.
Params:
  • enumerationDescription – The enumeration that is to be represented.
/** * Creates a new description of an annotation value for a given enumeration. * * @param enumerationDescription The enumeration that is to be represented. */
public ForEnumerationDescription(EnumerationDescription enumerationDescription) { this.enumerationDescription = enumerationDescription; }
Creates a new annotation value for the given enumeration description.
Params:
  • value – The value to represent.
Type parameters:
  • <V> – The type of the represented enumeration.
Returns:An annotation value that describes the given enumeration.
/** * Creates a new annotation value for the given enumeration description. * * @param value The value to represent. * @param <V> The type of the represented enumeration. * @return An annotation value that describes the given enumeration. */
public static <V extends Enum<V>> AnnotationValue<EnumerationDescription, V> of(EnumerationDescription value) { return new ForEnumerationDescription<V>(value); }
{@inheritDoc}
/** * {@inheritDoc} */
public EnumerationDescription resolve() { return enumerationDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<EnumerationDescription, U> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return typeDefinition.asErasure().equals(enumerationDescription.getEnumerationType()) ? this : new ForMismatchedType<EnumerationDescription, U>(property, enumerationDescription.getEnumerationType().toString() + '[' + enumerationDescription.getValue() + ']'); }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { try { return new Loaded<U>(enumerationDescription.load((Class<U>) Class.forName(enumerationDescription.getEnumerationType().getName(), false, classLoader))); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<U>(enumerationDescription.getEnumerationType().getName(), exception); } } @Override public int hashCode() { return enumerationDescription.hashCode(); } @Override public boolean equals(Object other) { return this == other || other instanceof AnnotationValue<?, ?> && enumerationDescription.equals(((AnnotationValue<?, ?>) other).resolve()); } @Override public String toString() { return enumerationDescription.toString(); }
A loaded representation of an enumeration value.
Type parameters:
  • <V> – The type of the represented enumeration.
/** * A loaded representation of an enumeration value. * * @param <V> The type of the represented enumeration. */
public static class Loaded<V extends Enum<V>> extends AnnotationValue.Loaded.AbstractBase<V> {
The represented enumeration.
/** * The represented enumeration. */
private final V enumeration;
Creates a loaded version of an enumeration description.
Params:
  • enumeration – The represented enumeration.
/** * Creates a loaded version of an enumeration description. * * @param enumeration The represented enumeration. */
public Loaded(V enumeration) { this.enumeration = enumeration; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public V resolve() { return enumeration; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return enumeration.equals(value); } @Override public int hashCode() { return enumeration.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue.Loaded<?>)) { return false; } AnnotationValue.Loaded<?> annotationValue = (AnnotationValue.Loaded<?>) other; return annotationValue.getState().isResolved() && enumeration.equals(annotationValue.resolve()); } @Override public String toString() { return enumeration.toString(); }

Represents an annotation's enumeration value for a runtime type that is not an enumeration type.

Note: Neither of Object.hashCode(), Object.toString() and Object.equals(Object) are implemented specifically what resembles the way such exceptional states are represented in the Open JDK's annotation implementations.

/** * <p> * Represents an annotation's enumeration value for a runtime type that is not an enumeration type. * </p> * <p> * <b>Note</b>: Neither of {@link Object#hashCode()}, {@link Object#toString()} and * {@link java.lang.Object#equals(Object)} are implemented specifically what resembles the way * such exceptional states are represented in the Open JDK's annotation implementations. * </p> */
public static class WithIncompatibleRuntimeType extends AnnotationValue.Loaded.AbstractBase<Enum<?>> {
The runtime type which is not an enumeration type.
/** * The runtime type which is not an enumeration type. */
private final Class<?> type;
Creates a new representation for an incompatible runtime type.
Params:
  • type – The runtime type which is not an enumeration type.
/** * Creates a new representation for an incompatible runtime type. * * @param type The runtime type which is not an enumeration type. */
public WithIncompatibleRuntimeType(Class<?> type) { this.type = type; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public Enum<?> resolve() { throw new IncompatibleClassChangeError("Not an enumeration type: " + type.toString()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return false; } /* hashCode, equals and toString are intentionally not implemented */ } }
Represents a property with an enumeration constant that is not defined by an enumeration type.
Type parameters:
  • <U> – The enumerationl type.
/** * Represents a property with an enumeration constant that is not defined by an enumeration type. * * @param <U> The enumerationl type. */
public static class WithUnknownConstant<U extends Enum<U>> extends AbstractBase<EnumerationDescription, U> {
A description of the enumeration type.
/** * A description of the enumeration type. */
private final TypeDescription typeDescription;
The enumeration constant value.
/** * The enumeration constant value. */
private final String value;
Creates a property description for an enumeration value that does not exist for the enumeration type.
Params:
  • typeDescription – A description of the enumeration type.
  • value – The enumeration constant value.
/** * Creates a property description for an enumeration value that does not exist for the enumeration type. * * @param typeDescription A description of the enumeration type. * @param value The enumeration constant value. */
public WithUnknownConstant(TypeDescription typeDescription, String value) { this.typeDescription = typeDescription; this.value = value; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<EnumerationDescription, U> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public EnumerationDescription resolve() { throw new IllegalStateException(typeDescription + " does not declare enumeration constant " + value); }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { try { // Type casting to Object is required for Java 6 compilability. return (AnnotationValue.Loaded<U>) (Object) new Loaded((Class<Enum<?>>) Class.forName(typeDescription.getName(), false, classLoader), value); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<U>(typeDescription.getName(), exception); } } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return value + " /* Warning: constant not present! */"; }
Represents a property with an enumeration constant that is not defined by an enumeration type.
/** * Represents a property with an enumeration constant that is not defined by an enumeration type. */
public static class Loaded extends AnnotationValue.Loaded.AbstractBase.ForUnresolvedProperty<Enum<?>> {
The loaded enumeration type.
/** * The loaded enumeration type. */
private final Class<? extends Enum<?>> enumType;
The value for which no enumeration constant exists at runtime.
/** * The value for which no enumeration constant exists at runtime. */
private final String value;
Creates a new representation for an unknown enumeration constant of an annotation.
Params:
  • enumType – The loaded enumeration type.
  • value – The value for which no enumeration constant exists at runtime.
/** * Creates a new representation for an unknown enumeration constant of an annotation. * * @param enumType The loaded enumeration type. * @param value The value for which no enumeration constant exists at runtime. */
public Loaded(Class<? extends Enum<?>> enumType, String value) { this.enumType = enumType; this.value = value; }
{@inheritDoc}
/** * {@inheritDoc} */
public Enum<?> resolve() { throw new EnumConstantNotPresentException(enumType, value); } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return value + " /* Warning: constant not present! */"; } } } }
A description of a Class as a value of an annotation.
Type parameters:
  • <U> – The type of the Class that is described.
/** * A description of a {@link java.lang.Class} as a value of an annotation. * * @param <U> The type of the {@link java.lang.Class} that is described. */
class ForTypeDescription<U extends Class<U>> extends AbstractBase<TypeDescription, U> {
Indicates to a class loading process that class initializers are not required to be executed when loading a type.
/** * Indicates to a class loading process that class initializers are not required to be executed when loading a type. */
private static final boolean NO_INITIALIZATION = false;
A description of the represented type.
/** * A description of the represented type. */
private final TypeDescription typeDescription;
Creates a new annotation value that represents a type.
Params:
  • typeDescription – The represented type.
/** * Creates a new annotation value that represents a type. * * @param typeDescription The represented type. */
public ForTypeDescription(TypeDescription typeDescription) { this.typeDescription = typeDescription; }
Creates an annotation value for representing the given type.
Params:
  • typeDescription – The type to represent.
Type parameters:
  • <V> – The represented type.
Returns:An annotation value that represents the given type.
/** * Creates an annotation value for representing the given type. * * @param typeDescription The type to represent. * @param <V> The represented type. * @return An annotation value that represents the given type. */
public static <V extends Class<V>> AnnotationValue<TypeDescription, V> of(TypeDescription typeDescription) { return new ForTypeDescription<V>(typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<TypeDescription, U> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return typeDefinition.asErasure().represents(Class.class) ? this : new ForMismatchedType<TypeDescription, U>(property, Class.class.getName() + '[' + typeDescription.getName() + ']'); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription resolve() { return typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { try { return new Loaded<U>((U) Class.forName(typeDescription.getName(), NO_INITIALIZATION, classLoader)); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<U>(typeDescription.getName(), exception); } } @Override public int hashCode() { return typeDescription.hashCode(); } @Override public boolean equals(Object other) { return this == other || other instanceof AnnotationValue<?, ?> && typeDescription.equals(((AnnotationValue<?, ?>) other).resolve()); } @Override public String toString() { return RenderingDispatcher.CURRENT.toSourceString(typeDescription); }
A loaded annotation value for a given type.
Type parameters:
  • <U> – The represented type.
/** * A loaded annotation value for a given type. * * @param <U> The represented type. */
protected static class Loaded<U extends Class<U>> extends AnnotationValue.Loaded.AbstractBase<U> {
The represented type.
/** * The represented type. */
private final U type;
Creates a new loaded annotation value for a given type.
Params:
  • type – The represented type.
/** * Creates a new loaded annotation value for a given type. * * @param type The represented type. */
public Loaded(U type) { this.type = type; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { return type; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return type.equals(value); } @Override public int hashCode() { return type.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue.Loaded<?>)) { return false; } AnnotationValue.Loaded<?> annotationValue = (AnnotationValue.Loaded<?>) other; return annotationValue.getState().isResolved() && type.equals(annotationValue.resolve()); } @Override public String toString() { return RenderingDispatcher.CURRENT.toSourceString(TypeDescription.ForLoadedType.of(type)); } } }
Describes a complex array that is the value of an annotation. Complex arrays are arrays that might trigger the loading of user-defined types, i.e. Class, Annotation and Enum instances.
Type parameters:
  • <U> – The array type of the annotation's value when it is not loaded.
  • <V> – The array type of the annotation's value when it is loaded.
/** * Describes a complex array that is the value of an annotation. Complex arrays are arrays that might trigger the loading * of user-defined types, i.e. {@link java.lang.Class}, {@link java.lang.annotation.Annotation} and {@link java.lang.Enum} * instances. * * @param <U> The array type of the annotation's value when it is not loaded. * @param <V> The array type of the annotation's value when it is loaded. */
class ForDescriptionArray<U, V> extends AbstractBase<U, V> {
The component type for arrays containing unloaded versions of the annotation array's values.
/** * The component type for arrays containing unloaded versions of the annotation array's values. */
private final Class<?> unloadedComponentType;
A description of the component type when it is loaded.
/** * A description of the component type when it is loaded. */
private final TypeDescription componentType;
A list of values of the array elements.
/** * A list of values of the array elements. */
private final List<? extends AnnotationValue<?, ?>> values;
Creates a new complex array.
Params:
  • unloadedComponentType – The component type for arrays containing unloaded versions of the annotation array's values.
  • componentType – A description of the component type when it is loaded.
  • values – A list of values of the array elements.
/** * Creates a new complex array. * * @param unloadedComponentType The component type for arrays containing unloaded versions of the annotation array's values. * @param componentType A description of the component type when it is loaded. * @param values A list of values of the array elements. */
public ForDescriptionArray(Class<?> unloadedComponentType, TypeDescription componentType, List<? extends AnnotationValue<?, ?>> values) { this.unloadedComponentType = unloadedComponentType; this.componentType = componentType; this.values = values; }
Creates a new complex array of enumeration descriptions.
Params:
  • enumerationType – A description of the type of the enumeration.
  • enumerationDescription – An array of enumeration descriptions.
Type parameters:
  • <W> – The type of the enumeration.
Returns:A description of the array of enumeration values.
/** * Creates a new complex array of enumeration descriptions. * * @param enumerationType A description of the type of the enumeration. * @param enumerationDescription An array of enumeration descriptions. * @param <W> The type of the enumeration. * @return A description of the array of enumeration values. */
public static <W extends Enum<W>> AnnotationValue<EnumerationDescription[], W[]> of(TypeDescription enumerationType, EnumerationDescription[] enumerationDescription) { List<AnnotationValue<EnumerationDescription, W>> values = new ArrayList<AnnotationValue<EnumerationDescription, W>>(enumerationDescription.length); for (EnumerationDescription value : enumerationDescription) { if (!value.getEnumerationType().equals(enumerationType)) { throw new IllegalArgumentException(value + " is not of " + enumerationType); } values.add(ForEnumerationDescription.<W>of(value)); } return new ForDescriptionArray<EnumerationDescription[], W[]>(EnumerationDescription.class, enumerationType, values); }
Creates a new complex array of annotation descriptions.
Params:
  • annotationType – A description of the type of the annotation.
  • annotationDescription – An array of annotation descriptions.
Type parameters:
  • <W> – The type of the annotation.
Returns:A description of the array of enumeration values.
/** * Creates a new complex array of annotation descriptions. * * @param annotationType A description of the type of the annotation. * @param annotationDescription An array of annotation descriptions. * @param <W> The type of the annotation. * @return A description of the array of enumeration values. */
public static <W extends Annotation> AnnotationValue<AnnotationDescription[], W[]> of(TypeDescription annotationType, AnnotationDescription[] annotationDescription) { List<AnnotationValue<AnnotationDescription, W>> values = new ArrayList<AnnotationValue<AnnotationDescription, W>>(annotationDescription.length); for (AnnotationDescription value : annotationDescription) { if (!value.getAnnotationType().equals(annotationType)) { throw new IllegalArgumentException(value + " is not of " + annotationType); } values.add(new ForAnnotationDescription<W>(value)); } return new ForDescriptionArray<AnnotationDescription[], W[]>(AnnotationDescription.class, annotationType, values); }
Creates a new complex array of annotation descriptions.
Params:
  • typeDescription – A description of the types contained in the array.
Returns:A description of the array of enumeration values.
/** * Creates a new complex array of annotation descriptions. * * @param typeDescription A description of the types contained in the array. * @return A description of the array of enumeration values. */
@SuppressWarnings("unchecked") public static AnnotationValue<TypeDescription[], Class<?>[]> of(TypeDescription[] typeDescription) { List<AnnotationValue<TypeDescription, Class<?>>> values = new ArrayList<AnnotationValue<TypeDescription, Class<?>>>(typeDescription.length); for (TypeDescription value : typeDescription) { values.add((AnnotationValue) ForTypeDescription.<Class>of(value)); } return new ForDescriptionArray<TypeDescription[], Class<?>[]>(TypeDescription.class, TypeDescription.CLASS, values); }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { if (typeDefinition.isArray() && typeDefinition.getComponentType().asErasure().equals(componentType)) { for (AnnotationValue<?, ?> value : values) { value = value.filter(property, typeDefinition.getComponentType()); if (value.getState() != State.RESOLVED) { return (AnnotationValue<U, V>) value; } } return this; } else { return new ForMismatchedType<U, V>(property, "Array with component tag: " + RenderingDispatcher.CURRENT.toComponentTag(componentType)); } }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { @SuppressWarnings("unchecked") U resolved = (U) Array.newInstance(unloadedComponentType, values.size()); int index = 0; for (AnnotationValue<?, ?> value : values) { Array.set(resolved, index++, value.resolve()); } return resolved; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<V> load(ClassLoader classLoader) { List<AnnotationValue.Loaded<?>> values = new ArrayList<AnnotationValue.Loaded<?>>(this.values.size()); for (AnnotationValue<?, ?> value : this.values) { values.add(value.load(classLoader)); } try { return new Loaded<V>((Class<V>) Class.forName(componentType.getName(), false, classLoader), values); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<V>(componentType.getName(), exception); } } @Override @CachedReturnPlugin.Enhance("hashCode") public int hashCode() { int result = 1; for (AnnotationValue<?, ?> value : values) { result = 31 * result + value.hashCode(); } return result; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue<?, ?>)) { return false; } AnnotationValue<?, ?> annotationValue = (AnnotationValue<?, ?>) other; Object value = annotationValue.resolve(); if (value == null || !value.getClass().isArray()) { return false; } if (values.size() != Array.getLength(value)) { return false; } Iterator<? extends AnnotationValue<?, ?>> iterator = values.iterator(); for (int index = 0; index < values.size(); index++) { AnnotationValue<?, ?> self = iterator.next(); if (!self.resolve().equals(Array.get(value, index))) { return false; } } return true; } @Override public String toString() { return RenderingDispatcher.CURRENT.toSourceString(values); }
Represents a loaded complex array.
Type parameters:
  • <W> – The type of the loaded array.
/** * Represents a loaded complex array. * * @param <W> The type of the loaded array. */
protected static class Loaded<W> extends AnnotationValue.Loaded.AbstractBase<W> {
The loaded component type of the array.
/** * The loaded component type of the array. */
private final Class<W> componentType;
A list of loaded values that the represented array contains.
/** * A list of loaded values that the represented array contains. */
private final List<AnnotationValue.Loaded<?>> values;
Creates a new loaded value representing a complex array.
Params:
  • componentType – The loaded component type of the array.
  • values – A list of loaded values that the represented array contains.
/** * Creates a new loaded value representing a complex array. * * @param componentType The loaded component type of the array. * @param values A list of loaded values that the represented array contains. */
protected Loaded(Class<W> componentType, List<AnnotationValue.Loaded<?>> values) { this.componentType = componentType; this.values = values; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { for (AnnotationValue.Loaded<?> value : values) { if (!value.getState().isResolved()) { return State.UNRESOLVED; } } return State.RESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public W resolve() { @SuppressWarnings("unchecked") W array = (W) Array.newInstance(componentType, values.size()); int index = 0; for (AnnotationValue.Loaded<?> annotationValue : values) { Array.set(array, index++, annotationValue.resolve()); } return array; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { if (!(value instanceof Object[])) return false; if (value.getClass().getComponentType() != componentType) return false; Object[] array = (Object[]) value; if (values.size() != array.length) return false; Iterator<AnnotationValue.Loaded<?>> iterator = values.iterator(); for (Object aValue : array) { AnnotationValue.Loaded<?> self = iterator.next(); if (!self.represents(aValue)) { return false; } } return true; } @Override @CachedReturnPlugin.Enhance("hashCode") public int hashCode() { int result = 1; for (AnnotationValue.Loaded<?> value : values) { result = 31 * result + value.hashCode(); } return result; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof AnnotationValue.Loaded<?>)) { return false; } AnnotationValue.Loaded<?> annotationValue = (AnnotationValue.Loaded<?>) other; if (!annotationValue.getState().isResolved()) { return false; } Object value = annotationValue.resolve(); if (!(value instanceof Object[])) { return false; } Object[] arrayValue = (Object[]) value; if (values.size() != arrayValue.length) { return false; } Iterator<AnnotationValue.Loaded<?>> iterator = values.iterator(); for (Object aValue : arrayValue) { AnnotationValue.Loaded<?> self = iterator.next(); if (!self.getState().isResolved() || !self.resolve().equals(aValue)) { return false; } } return true; } @Override public String toString() { return RenderingDispatcher.CURRENT.toSourceString(values); } } }
An annotation value for a type that could not be loaded.
Type parameters:
  • <U> – The type of the annotation's value when it is not loaded.
  • <V> – The type of the annotation's value when it is loaded.
/** * An annotation value for a type that could not be loaded. * * @param <U> The type of the annotation's value when it is not loaded. * @param <V> The type of the annotation's value when it is loaded. */
class ForMissingType<U, V> extends AbstractBase<U, V> {
The type's binary name.
/** * The type's binary name. */
private final String typeName;
Creates a new annotation value for a type that cannot be loaded.
Params:
  • typeName – The type's binary name.
/** * Creates a new annotation value for a type that cannot be loaded. * * @param typeName The type's binary name. */
public ForMissingType(String typeName) { this.typeName = typeName; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { throw new IllegalStateException("Type not found: " + typeName); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<V> load(ClassLoader classLoader) { return new Loaded<V>(typeName, new ClassNotFoundException(typeName)); } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return typeName + ".class /* Warning: type not present! */"; }
Represents a missing type during an annotation's resolution.
Type parameters:
  • <U> – The represented type.
/** * Represents a missing type during an annotation's resolution. * * @param <U> The represented type. */
public static class Loaded<U> extends AnnotationValue.Loaded.AbstractBase.ForUnresolvedProperty<U> {
The type's binary name.
/** * The type's binary name. */
private final String typeName;
The exception describing the missing type.
/** * The exception describing the missing type. */
private final ClassNotFoundException exception;
The type's binary name.
Params:
  • typeName – The type's binary name.
  • exception – The exception describing the missing type.
/** * The type's binary name. * * @param typeName The type's binary name. * @param exception The exception describing the missing type. */
public Loaded(String typeName, ClassNotFoundException exception) { this.typeName = typeName; this.exception = exception; }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { throw new TypeNotPresentException(typeName, exception); } @Override public String toString() { return typeName + ".class /* Warning: type not present! */"; } } }
Describes an annotation value that does not match the annotation' type for a property.
Type parameters:
  • <U> – The type of the annotation's value when it is not loaded.
  • <V> – The type of the annotation's value when it is loaded.
/** * Describes an annotation value that does not match the annotation' type for a property. * * @param <U> The type of the annotation's value when it is not loaded. * @param <V> The type of the annotation's value when it is loaded. */
class ForMismatchedType<U, V> extends AbstractBase<U, V> {
The property that does not defines a non-matching value.
/** * The property that does not defines a non-matching value. */
private final MethodDescription.InDefinedShape property;
A value description of the property.
/** * A value description of the property. */
private final String value;
Creates an annotation description for a mismatched typeName.
Params:
  • property – The property that does not defines a non-matching value.
  • value – A value description of the property.
/** * Creates an annotation description for a mismatched typeName. * * @param property The property that does not defines a non-matching value. * @param value A value description of the property. */
public ForMismatchedType(MethodDescription.InDefinedShape property, String value) { this.property = property; this.value = value; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { throw new IllegalStateException(property + " cannot define " + value); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<V> load(ClassLoader classLoader) { try { Class<?> type = Class.forName(property.getDeclaringType().getName(), false, classLoader); try { return new Loaded<V>(type.getMethod(property.getName()), value); } catch (NoSuchMethodException exception) { return new ForIncompatibleType.Loaded<V>(type); } } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<V>(property.getDeclaringType().getName(), exception); } } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return "/* Warning type mismatch! \"" + value + "\" */"; }
Describes an annotation value for a property that is not assignable to it.
Type parameters:
  • <W> – The type of the annotation's expected value.
/** * Describes an annotation value for a property that is not assignable to it. * * @param <W> The type of the annotation's expected value. */
public static class Loaded<W> extends AnnotationValue.Loaded.AbstractBase.ForUnresolvedProperty<W> {
The annotation property that is not well-defined.
/** * The annotation property that is not well-defined. */
private final Method property;
A value description of the incompatible property or null.
/** * A value description of the incompatible property or {@code null}. */
private final String value;
Creates a new loaded version of a property with an incompatible type.
Params:
  • property – The annotation property that is not well-defined.
  • value – A value description of the incompatible property or null.
/** * Creates a new loaded version of a property with an incompatible type. * * @param property The annotation property that is not well-defined. * @param value A value description of the incompatible property or {@code null}. */
public Loaded(Method property, String value) { this.property = property; this.value = value; }
{@inheritDoc}
/** * {@inheritDoc} */
public W resolve() { throw new AnnotationTypeMismatchException(property, value); } } }
Represents a missing annotation property which is not represented by a default value.
Type parameters:
  • <U> – The type of the annotation's value when it is not loaded.
  • <V> – The type of the annotation's value when it is loaded.
/** * Represents a missing annotation property which is not represented by a default value. * * @param <U> The type of the annotation's value when it is not loaded. * @param <V> The type of the annotation's value when it is loaded. */
class ForMissingValue<U, V> extends AnnotationValue.AbstractBase<U, V> {
The annotation type for which a property is not defined.
/** * The annotation type for which a property is not defined. */
private final TypeDescription typeDescription;
The name of the property without an annotation value.
/** * The name of the property without an annotation value. */
private final String property;
Creates a new missing annotation value.
Params:
  • typeDescription – The annotation type for which a property is not defined.
  • property – The name of the property without an annotation value.
/** * Creates a new missing annotation value. * * @param typeDescription The annotation type for which a property is not defined. * @param property The name of the property without an annotation value. */
public ForMissingValue(TypeDescription typeDescription, String property) { this.typeDescription = typeDescription; this.property = property; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNDEFINED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<V> load(ClassLoader classLoader) { try { Class<? extends Annotation> type = (Class<? extends Annotation>) Class.forName(typeDescription.getName(), false, classLoader); return type.isAnnotation() ? new Loaded<V>(type, property) : new ForIncompatibleType.Loaded<V>(type); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<V>(typeDescription.getName(), exception); } }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { throw new IllegalStateException(typeDescription + " does not define " + property); } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */
Describes an annotation value for a property that is not assignable to it.
Type parameters:
  • <W> – The type of the annotation's expected value.
/** * Describes an annotation value for a property that is not assignable to it. * * @param <W> The type of the annotation's expected value. */
public static class Loaded<W> extends AnnotationValue.Loaded.AbstractBase<W> {
The annotation type.
/** * The annotation type. */
private final Class<? extends Annotation> type;
The name of the property for which the annotation value is missing.
/** * The name of the property for which the annotation value is missing. */
private final String property;
Creates a new loaded representation for an unresolved property.
Params:
  • type – The annotation type.
  • property – The name of the property for which the annotation value is missing.
/** * Creates a new loaded representation for an unresolved property. * * @param type The annotation type. * @param property The name of the property for which the annotation value is missing. */
public Loaded(Class<? extends Annotation> type, String property) { this.type = type; this.property = property; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNDEFINED; }
{@inheritDoc}
/** * {@inheritDoc} */
public W resolve() { throw new IncompleteAnnotationException(type, property); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return false; } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ } }
Represents an annotation value where its declared type does not fulfil an expectation.
Type parameters:
  • <U> – The type of the annotation's value when it is not loaded.
  • <V> – The type of the annotation's value when it is loaded.
/** * Represents an annotation value where its declared type does not fulfil an expectation. * * @param <U> The type of the annotation's value when it is not loaded. * @param <V> The type of the annotation's value when it is loaded. */
class ForIncompatibleType<U, V> extends AnnotationValue.AbstractBase<U, V> {
A description of the type that does not fulfil an expectation.
/** * A description of the type that does not fulfil an expectation. */
private final TypeDescription typeDescription;
Creates a new description for an annotation value that does not fulfil expectations.
Params:
  • typeDescription – A description of the type that does not fulfil the expectations.
/** * Creates a new description for an annotation value that does not fulfil expectations. * * @param typeDescription A description of the type that does not fulfil the expectations. */
public ForIncompatibleType(TypeDescription typeDescription) { this.typeDescription = typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<U, V> filter(MethodDescription.InDefinedShape property, TypeDefinition typeDefinition) { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public U resolve() { throw new IllegalStateException("Property is defined with an incompatible runtime type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<V> load(ClassLoader classLoader) { try { return new Loaded<V>(Class.forName(typeDescription.getName(), false, classLoader)); } catch (ClassNotFoundException exception) { return new ForMissingType.Loaded<V>(typeDescription.getName(), exception); } } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return "/* Warning type incompatibility! \"" + typeDescription.getName() + "\" */"; }
A description of annotation value for a type that does not fulfil an expectation.
Type parameters:
  • <W> – The type of the annotation's expected value.
/** * A description of annotation value for a type that does not fulfil an expectation. * * @param <W> The type of the annotation's expected value. */
public static class Loaded<W> extends AnnotationValue.Loaded.AbstractBase.ForUnresolvedProperty<W> {
The type that does not fulfil an expectation.
/** * The type that does not fulfil an expectation. */
private final Class<?> type;
Creates a new description of an annotation.
Params:
  • type – The type that does not fulfil an expectation.
/** * Creates a new description of an annotation. * * @param type The type that does not fulfil an expectation. */
public Loaded(Class<?> type) { this.type = type; }
{@inheritDoc}
/** * {@inheritDoc} */
public W resolve() { throw new IncompatibleClassChangeError(type.toString()); } /* does not implement hashCode and equals method to mimic OpenJDK behavior. */ @Override public String toString() { return "/* Warning type incompatibility! \"" + type.getName() + "\" */"; } } } }