-
Notifications
You must be signed in to change notification settings - Fork 1
Bio Objects Annotations
Bio Objects Dictionary is built throughout annotations by default. In this section we will analyze annotation details.
@BioObj
is used to indicate that the current class is a Bio Object and dictionary should store definitions about it. Any class which extends BioObject
can be annotated with this annotation otherwise dictionary will throw an exception.
@BioObj
public class Car extends BioObject {
...
}
It also contains additional optional attributes.
-
code()
codes are auto-generated if not provided. code is used in serialization to indicate which Bio Object's data is serialized. -
name()
names are auto-generated as snake case based on class name. name is used as a reference to Bio Object inside Bio Expressions. -
type()
types are auto-generated as class name. type is used to define composition between Bio Objects. -
dictionary()
is used to define dictionary id. Bio Objects can have multiple dictionaries with their own objects. code must be unique within one dictionary. But if more projects are using Bio Objects it will be hard to maintain the uniqueness of these codes. By having a separate dictionary this problem can be managed. -
isLarge()
by default all arrays/lists/objects lengths are encoded as short which may create problem when you try to serialize a byte array with length more than Short.MAX_VALUE (32767). Once this property is set all lengths are encoded as int which solves this problem but increases encoded bytes.
@BioObj(code=1, dictionary=1, name="car", type="Car", isLarge=true)
public class Car extends BioObject {
...
}
Tags are fields inside Bio Objects which are serialized or parsed from XML or JSON. Using this annotation we define all necessary information to perform these operations.
-
code()
codes are auto-generated if not provided. code is used in serialization to indicate which tag's data is serialized. -
type()
indicates types can be used in Bio Objects. This information is used in lots of places such as serialization, XML parsing, JSON parsing, formatting etc. Here are supported types. -
isArray()
indicates this field contains array oftype()
. -
isList()
indicates this field contains list oftype()
. -
isEncodable()
by default all tags are encodable or serializable. If you want a tag not to be serialized then this property must befalse
. -
isExportable()
by default all tags are exportable to XML/JSON. If you want a tag (for example password) not to be exported then this property must befalse
. -
isMandatory()
by default is false and indicates that this tag must exist otherwise the system will throw an exception during validation. -
isInheritable()
by default is true and indicates that this tag can be accessed and inherited in subclasses. -
initial()
indicates initial value to be added while creating Bio Object instance. -
expression()
indicates initial expression to evaluate and put into the Bio Object. -
trimKeys()
indicates keys to be trimmed while callingtrim(String key)
method. -
inverseTrimKeys()
indicates keys not to be trimmed while callinginverseTrim(String key)
method.
Here is an example with usage of above properties.
@BioObj(code=1, name="car", type="Car")
public class Car extends BioObject {
@BioTag(type="String")
public static final String PRODUCER = "producer" ;
@BioTag(type="String")
public static final String MODEL = "model" ;
@BioTag(type="Integer", initial="2019")
public static final String YEAR_OF_PRODUCTION = "year_of_production" ;
@BioTag(type="Boolean", expression="year_of_production > 2016")
public static final String IS_NEW_CAR = "is_new_car" ;
@BioTag(type="String", isExportable=false)
public static final String KEY_PASSWORD = "key_password" ;
@BioTag(type="Long", isEncodable=false)
public static final String MILEAGE = "mileage" ;
@BioTag(type="Integer", isArray=true, initial="1,2,3,4,5")
public static final String GEARS = "gears" ;
}
As discussed above each tag must belong to a Bio Object. Inside dictionary all tags a grouped under Bio Objs excluding super tags. Super tags are tags which doesn't belong to any Bio Object yet can be serialized inside it. Super tags are very useful in encoding system related information which we don't want to add to each Bio Object class such as queue_time or processed_time etc.
In order to use it, we need to define super tags inside any kind of class by @BioSuperObj
annotations. For example:
@BioSuperObj
public class MySuperTags {
@BioSuperTag(type="Time")
public static final String QUEUE_TIME = "queue_time" ;
@BioSuperTag(type="Time")
public static final String PROCESSED_TIME = "processed_time" ;
}
Now we can use above tags in any Bio Object.
Order order = new Order() ;
order.set(MySuperTags.QUEUE_TIME, System.currentTimeMillis()) ;
order.set(MySuperTags.PROCESSED_TIME, System.currentTimeMillis() + 5) ;
Notification notification = new Notification() ;
notification.set(MySuperTags.QUEUE_TIME, System.currentTimeMillis()) ;
notification.set(MySuperTags.PROCESSED_TIME, System.currentTimeMillis() + 5) ;
Super tags are unique within dictionary. Again in order not to mess with them you can differentiate super tags by dictionary by adding dictionary
property to @BioSuperObj
annotation.
@BioSuperObj(dictionary=1)
public class MySuperTags {
...
}
For better understanding it is practical to assign minus codes to super tags and add "_" before their tag name. Minus tag codes will make easy not to mix with actual Bio Object tags and tag names starting with "_" are considered as system hence they are not exported to XML or JSON.
@BioSuperObj
public class MySuperTags {
@BioSuperTag(code=-1, type="Time")
public static final String QUEUE_TIME = "_queue_time" ;
@BioSuperTag(code=-2, type="Time")
public static final String PROCESSED_TIME = "_processed_time" ;
}
Let's assume we have a compiled and packaged Car class which extends Bio Object. And in our current project we need to add more tags to Car. There are two ways of doing it.
- by extending Car using Inheritance
- by adding remote tags
Here we will show how to use @BioRemoteTag
to achieve above. Inheritance example will be discussed later.
@BioRemoteObj
public class NewCar {
@BioRemoteTag(obj="Car", type="String")
public static final String MULTI_MEDIA_SYSTEM = "multi_media_system" ;
@BioRemoteTag(obj="Car", type="Integer", initial="6")
public static final String SPEAKERS = "speakers" ;
}
Here we annotate that NewCar class will modify the dictionary. Be careful we are not extending Car here we just add new tag definition to the dictionary. In order to indicate which Bio Object is on target, we need to specify obj
property in @BioRemoteTag
annotation. Here we must provide type()
of Bio Object.
Remote tags can be applied to multiple Bio Objects as following:
@BioRemoteObj
public class NewCar {
@BioRemoteTag(obj="Car", code=100, type="String")
@BioRemoteTag(obj="Truck", code=100, type="String")
@BioRemoteTag(obj="Ship", code=100, type="String")
public static final String MULTI_MEDIA_SYSTEM = "multi_media_system" ;
@BioRemoteTag(obj="Car", code=101, type="Integer", initial="6")
@BioRemoteTag(obj="Truck", code=201, type="String")
public static final String SPEAKERS = "speakers" ;
}
Here multiple Bio Object definitions are impacted each will receive a tag definition. Other tag properties are also available for Remote and Super tags.
When Bio Objects are used extensively throughout the projects sometimes unnecessary objects are added to the dictionary because they are inside JAR files with necessary annotations. But in some cases, not all these Bio Objects are needed to be added to the dictionary. Developers can use @BioProfile
annotations to mark Bio Objects for each project. Bio Object having custom profiles will be checked and added to the dictionary only if bio profile exists in configuration.
@BioObj
public class Car extends BioObject {
...
}
@BioObj
@BioProfile(profile="marine")
public class Ship extends BioObject {
...
}
@BioObj
public class Truck extends BioObject {
...
}
By default Car
and Truck
will be added to the dictionary but Ship
will be checked against profiles. If not profile is set then Ship
will be loaded to the dictionary.
In order to set profiles we need to modify BioDictionaryBuilder instance as following:
new BioDictionaryBuilder().addProfile("marine").addProfile("air").build();
Now all Bio Objects having profiles equal to "marine" or "air" will also be added to the dictionary. By the way a Bio Object can have more than one profile.
@BioObj
@BioProfile(profile="marine")
@BioProfile(profile="air")
public class Plane extends BioObject {
...
}
This section is not ready yet. Here it will be discussed how to handle different versions of same Bio Object where existing tag definitions are changed such as Integer became Double or String[] became Integer[] etc.
Byte
Short
Integer
Long
Float
Double
Boolean
String
UtfString
-
Time
(is stored as Long but during XML/JSON processing exported as date String) -
BioObject
(is composition of other Bio Objects) BioEnum