Types - NibiruOS/model GitHub Wiki

Types

API

The basic building block is the Type interface. Any defined data type must implement it. The ComplexType interface add the ability to define a set of properties (Property) belonging to the type.

The separation between complex and simple types is more related to platforms issues than to design aspect. Some platforms, such as GWT, does not provide reflection capabilities. So, implementing a reflection based complex type would not be possible. However, simple types are still helpful. Keeping the interfaces separated helps to implement just what is needed.

Implementations

Java class

JavaType provides a wrapper for building types over an standard Java class. JavaComplexType does the same for complex types, using reflection to wrap class fields into properties.

Dynamic types

The DynamicType allows defining complex types in runtime. Its properties are backed in a Map, so no Java class is needed to reflect its structure.

Subclassing

You could extend any type implementation to add metadata. For example, you could use it for building a CRUD engine, adding metadata for validation, labels, etc.

Examples

You can also look at unit tests for more detailed examples.

Java

Simple type

Using JavaType.of():

Type<String> stringType = JavaType.of(String.class);
assertEquals("java.lang.String", stringType.getName());
assertEquals("java.lang", stringType.getNamespace());
assertEquals(String.class, stringType.cast());

Or using constants:

assertEquals("java.lang.String", JavaType.STRING.getName());
assertEquals("java.lang", JavaType.STRING.getNamespace());
assertEquals(String.class, JavaType.STRING.cast());

There are helper methods for Iterable and List :

Type<Iterable<String>> type = JavaType.ofIterable(String.class);
assertEquals("java.lang.Iterable", type.getName());
assertEquals("java.lang", type.getNamespace());
assertEquals(Iterable.class, type.cast());
Type<List<String>> type = JavaType.ofList(String.class);
assertEquals("java.util.List", type.getName());
assertEquals("java.util", type.getNamespace());
assertEquals(List.class, type.cast());

To avoid Java generic types limitations, you can create unchecked types:

Type<List<Iterable<Set<Reference<Date>>>>> type
    = JavaType.ofUnchecked(List.class);
assertEquals("java.util.List", type.getName());
assertEquals("java.util", type.getNamespace());
assertEquals(List.class, type.cast());

but this should be handled carefully, since you could create an inconsistent type:

Type<List<Iterable<Set<Reference<Date>>>>> type
    = JavaType.ofUnchecked(Integer.class);
assertEquals(List.class, type.cast()); // ERROR! the casted type is Integer!

Complex type

ComplexType<Person> type = JavaComplexType.of(Person.class);

assertEquals("org.nibiru.model.core.impl.java.Person", type.getName());
assertEquals("org.nibiru.model.core.impl.java", type.getNamespace());
assertEquals(Person.class, type.cast());

Property<Person, String> nameProperty = type.getProperty("name");
assertEquals("java.lang.String", nameProperty.getType().getName());
assertEquals("java.lang", nameProperty.getType().getNamespace());
⚠️ **GitHub.com Fallback** ⚠️