Use Odin Types

Odin offers an API to get objects and fields types. As seen above, all of the adapters give a ObjectType. It contains every class and fields information for the object to process.


Outside of an adapter you can also get the type with odin.getType(Foo.class)


All of the Odin types implement AnyType ( primitives, arrays, objects ) and every objects that are not a primitive or an array implements ObjectType

Get type information

From any type you can get the type name. This is the type alias added before the object on the serialization

type.getName();

You can also get the Class and the Type of the object

Class<?> type = type.getType();
Type genericType = type.getGenericType();

The generic type is different from the type only for objects coming from fields or superclasses with a type parameter ( ParameterizedType, WildcardType, TypeVariable and GenericArrayType ).

Browse through superclass

With object type, you can get the Odin type associated to the superclass.

ObjectType<AbstractList<Foo>> listType = odin.getType(new TypeBuilder<List<Foo>>() {}.type).getSuperClass();

The getSuperclass method can also take a Class as a parameter. This method returns the Odin type associated to the given Class if it is found in a superclass or an interface.

ObjectType<List<Foo>> listType = odin.getType(new TypeBuilder<List<Foo>>() {}.type).getSuperClass(List.class);

Get object type arguments

There are two ways of getting the type arguments if the generic type contains them: using object arguments or adapter type arguments.


To get the arguments of your object, use the generic getter

listType.getGenericArguments();

To get the arguments known by your adapter, use the adapter getter

listType.getAdapterArguments();

These two getters differ in the case of an adapter receiving a sub object that changes any generic parameters.


Consider the following case:

public class AbstractFoo<K, V> {
    private K key;
    private V value;
}
 
public class Foo<E> extends AbstractFoo<String, E> {
}
 
odin.toOdn(new Foo(), new TypeBuilder<Foo<UUID>>() {}.type);

With this adapter:

public class FooAdapter implements OdinObjectAdapter<AbstractFoo> {
    
    @Override
    public void read(OdinReader reader, ObjectType<? extends AbstractFoo> type, AbstractFoo o) throws IOException {
        AnyType[] generics = type.getGenericArguments();
        AnyType[] adapters = type.getAdapterArguments();
    }
    
    @Override
    public void write(OdinWriter writer, ObjectType<? extends AbstractFoo> type, AbstractFoo o) throws IOException {
        AnyType[] generics = type.getGenericArguments();
        AnyType[] adapters = type.getAdapterArguments();
    }
}

In this case, generics contains [ObjectType<UUID>] and adapters contains [AnyType<String>, ObjectType<UUID>]


As you can see, the adapter argument is the best choice because if the object you want to serialise contains 2 arguments, you still have these 2 arguments.

Get object fields

You also have methods to get your object fields. Each field uses a FieldType that contains the AnyType associated to the field generic type, the field name and the field comments.


If the field contains a @OdinField annotation, the name is the name given by this annotation.

You can get every the class fields, but you have to do this for each superclass. A ObjectType contains the fields declared by the Class, not by the super class.

FieldType[] fields = fooType.getFields();
FieldType aField = fooType.getField("key");

You also have a method to recursively search a field in the ObjectType and superclass

FieldType aField = fooType.findField("key");