Types - NibiruOS/model GitHub Wiki
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.
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.
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.
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.
You can also look at unit tests for more detailed examples.
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!
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());