Used to mark a class as available for use as an "adaptation type",
a data structure which is able to store a representation of a protocol
data type in some structured form, and expose that structure of the type
to the tools used to generate scenario schema adaptations.
"Outer" types (those which are not simply being used as fields within a larger type), also need to provide:
- one
AdaptationDecoder
- one
AdaptationEncoder
A type may also support a number of
variants()
, e.g. "inap", or "cap".
Variants are inherited from
AdaptationType
annotations on interfaces and superclasses.
A type may also provide a number of
constraints()
, e.g.
AdaptationConstraint.CHOICE_TYPE
.
A type may define a
AdaptationDescription
, to be used as the human readable description
of the generated schema type.
Note: annotations marked in inherited methods take effect,
unless the method is over-ridden by a subclass.
An adaptation type may be either a 'record adaptation type', or a 'generic adaptation type'.
Record adaptation types
A record adaptation type explicitly defines its fields, and is used to represent either a
RECORD type, or a CHOICE type.
Record adaptation types may be nested: the fields of a an "outer" adaptation type can themselves
be "inner" adaptation classes. The outer types provide the means to convert between an
encoded form (usually a byte array) and the structured form by way of encode and decode methods.
The inner types only need to be able to store and expose the structure of the represented data type,
and do not need to provide codec methods.
All record adaptation types need to provide the following annotations in their methods,
or in methods inherited from a superclass:
- one
AdaptationGetter
for each adaptation field
- one
AdaptationConstructor
The adaptation class can choose one of 2 different ways to construct the object from individual fields:
either (1) the annotation constructor takes a parameter for each field, with no setters,
or (2) the constructor takes no arguments, and the type declares an
AdaptationSetter
for each adaptation field.
Fields which are optional (whose values may be null) mark their getter methods
with the @AdaptationNullable annotation.
Example usage for a record adaptation type:
@AdaptationType(variants = {"inap","cap"}) public class SomeDataType {...}
Generic adaptation types
All the types which are supported as fields within a record adaptation type
can also be used as top level generic adaptation types.
A generic adaptation type can optionally specify a different class to use
as the adaptation type, using the adaptationClass property.
This is used when our adaptation wraps a type which we aren't able to annotate directly,
such as primitive types and array types.
Example usage of a generic adaptation, when using the annotated class as the adaptation type:
@AdaptationType(variants = {"inap","cap"}) public class SomeDataType {...}
Example usage of a generic adaptation, when specifying another class to use as the adaptation type:
@AdaptationType(adaptationClass = int.class) public static class IntAdaptation {...}