package tc.oc.api.document; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Member; import java.lang.reflect.Type; import javax.annotation.Nullable; import com.google.common.reflect.TypeToken; import tc.oc.api.docs.virtual.Document; /** * Metadata for an accessor of a {@link Document} property of type {@link T}. * This object wraps a particular field or method declared in a particular * class. A property can have multiple accessors e.g. if they override each other. */ public interface Accessor { /** * Metadata of the {@link Document} that declares this property */ DocumentMeta document(); /** * Serialized name of the property */ String name(); /** * Generic type of the property */ Type type(); boolean isPrimitive(); /** * Type of the property in the context of the given document type. * If this property type depends on type parameters declared on the * document, they will be resolved using the actual type arguments * of the given document type. * * For example, if a document is declared {@code Doc} and it has a * property {@code List things;}, then calling this method on the * things accessor with argument {@code Doc} would return * {@code List}. */ Type resolvedType(Type documentType); Type resolvedType(TypeToken documentType); /** * Raw type of the property */ Class rawType(); Class boxType(); /** * Java reflection API handle for the wrapped accessor */ M member(); /** * Accessor for the same property from an ancestor document that this accessor overrides. */ @Nullable Accessor override(); /** * Is the property allowed to be null? This is determined from @Nullable and @Nonnull * annotations on the wrapped member. Overrides inherit the nullability of their parent, * and can override it with their own annotation. Nulls are allowed by default if no * annotations are present in the property ancestry. */ boolean isNullable(); /** * Is this accessor implemented in the given class? This is true only if * the wrapped member exists on the given class, and is not an abstract method. */ boolean isImplemented(Class type); boolean hasDefault(); T validate(T value); }