/*
 * Copyright 2014 - 2019 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.description.enumeration.EnumerationDescription;
import net.bytebuddy.description.type.TypeDescription;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
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;
Resolves the unloaded value of this annotation.
Returns:The unloaded value of this annotation.
/** * Resolves the unloaded value of this annotation. * * @return The unloaded value of this annotation. */
T resolve();
Resolves the unloaded value of this annotation.
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. * * @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.
Throws:
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. * @throws ClassNotFoundException If a type that represents a loaded value cannot be found. */
Loaded<S> load(ClassLoader classLoader) throws ClassNotFoundException;
Returns the loaded value of this annotation without throwing a checked exception.
Params:
  • classLoader – The class loader for loading this value.
Returns:The loaded value of this annotation.
/** * Returns the loaded value of this annotation without throwing a checked exception. * * @param classLoader The class loader for loading this value. * @return The loaded value of this annotation. */
Loaded<S> loadSilent(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) ? Float.toString(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 = ClassFileVersion.ofThisVm(ClassFileVersion.JAVA_V6).isAtLeast(ClassFileVersion.JAVA_V9) ? JAVA_9_CAPABLE_VM : 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(); } }
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);
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 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()); } } }
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()); }
{@inheritDoc}
/** * {@inheritDoc} */
public Loaded<V> loadSilent(ClassLoader classLoader) { try { return load(classLoader); } catch (ClassNotFoundException exception) { throw new IllegalStateException("Cannot load " + this, exception); } } }
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 U resolve() { return value; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<U> load(ClassLoader classLoader) { return new Loaded<U>(value, propertyDelegate); } @Override 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 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 AnnotationDescription resolve() { return annotationDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue.Loaded<U> load(ClassLoader classLoader) throws ClassNotFoundException { @SuppressWarnings("unchecked") Class<U> annotationType = (Class<U>) Class.forName(annotationDescription.getAnnotationType().getName(), false, classLoader); return new Loaded<U>(annotationDescription.prepare(annotationType).load()); } @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(); } }

Represents an annotation value which was attempted to ba loaded by a type that does not represent an annotation value.

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 value which was attempted to ba loaded by a type that does not represent * an annotation value. * </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 IncompatibleRuntimeType extends AnnotationValue.Loaded.AbstractBase<Annotation> {
The incompatible runtime type which is not an annotation type.
/** * The incompatible runtime type which is not an annotation type. */
private final Class<?> incompatibleType;
Creates a new representation for an annotation with an incompatible runtime type.
Params:
  • incompatibleType – The incompatible runtime type which is not an annotation type.
/** * Creates a new representation for an annotation with an incompatible runtime type. * * @param incompatibleType The incompatible runtime type which is not an annotation type. */
public IncompatibleRuntimeType(Class<?> incompatibleType) { this.incompatibleType = incompatibleType; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public Annotation resolve() { throw new IncompatibleClassChangeError("Not an annotation type: " + incompatibleType.toString()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return false; } /* does intentionally not implement hashCode, equals and 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. */
protected 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 AnnotationValue.Loaded<U> load(ClassLoader classLoader) throws ClassNotFoundException { @SuppressWarnings("unchecked") Class<U> enumerationType = (Class<U>) Class.forName(enumerationDescription.getEnumerationType().getName(), false, classLoader); return new Loaded<U>(enumerationDescription.load(enumerationType)); } @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 constant that does not exist for the runtime 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 constant that does not exist for the runtime * 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 UnknownRuntimeEnumeration extends AnnotationValue.Loaded.AbstractBase<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 UnknownRuntimeEnumeration(Class<? extends Enum<?>> enumType, String value) { this.enumType = enumType; this.value = value; }
{@inheritDoc}
/** * {@inheritDoc} */
public State getState() { return State.UNRESOLVED; }
{@inheritDoc}
/** * {@inheritDoc} */
public Enum<?> resolve() { throw new EnumConstantNotPresentException(enumType, value); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Object value) { return false; } /* hashCode, equals and toString are intentionally not implemented */ }

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 IncompatibleRuntimeType 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 IncompatibleRuntimeType(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 */ } }
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. */
protected 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 TypeDescription resolve() { return typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressWarnings("unchecked") public AnnotationValue.Loaded<U> load(ClassLoader classLoader) throws ClassNotFoundException { return new Loaded<U>((U) Class.forName(typeDescription.getName(), NO_INITIALIZATION, classLoader)); } @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 component type of the annotation's value when it is not loaded.
  • <V> – The component 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 component type of the annotation's value when it is not loaded. * @param <V> The component 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. */
protected 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 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) throws ClassNotFoundException { List<AnnotationValue.Loaded<?>> values = new ArrayList<AnnotationValue.Loaded<?>>(this.values.size()); for (AnnotationValue<?, ?> value : this.values) { values.add(value.load(classLoader)); } return new Loaded<V>((Class<V>) Class.forName(componentType.getName(), false, classLoader), values); } @Override 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 instanceof Object[])) { return false; } Object[] arrayValue = (Object[]) value; if (values.size() != arrayValue.length) { return false; } Iterator<? extends AnnotationValue<?, ?>> iterator = values.iterator(); for (Object aValue : arrayValue) { AnnotationValue<?, ?> self = iterator.next(); if (!self.resolve().equals(aValue)) { return false; } } return true; } @Override public String toString() { return RenderingDispatcher.CURRENT.toSourceString(values); }
Represents a loaded complex array.
Type parameters:
  • <W> – The component type of the loaded array.
/** * Represents a loaded complex array. * * @param <W> The component 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 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); } } } }