JSON schema types

All components that contribute to the string output of the schema are called members and are nested under the schema. During generation, the system processes each member recursively (top down), appending each member’s result to a JSON writer. This creates the final JSON output string.

Three interfaces represent three structural types of the JSON payload:

  • Property (key/value pair)
  • Object
  • Array

A getJsonName() defines each schema member.

Figure 22.   Schema types
Image

Three interfaces represent the three structural types of a JSON payload: property (key and value pair), object and array. All schema members have a name defined by getJsonName().

All schema members inherit the default processChildJsonMembers() behaviour, which allows us to recursively call process() on each member down through the nested schema structure.

All schema member types extend BJsonSchemaMember and most implement one of the three interface types. The base class lets us define the parent-child legal checks. This restricts nested types to just other BJsonSchemaMembers. This is where the JSON passes global schema events, for example, unsubscribe.

Different types of JSON schema members may be nested under a schema. These are logically grouped by common behaviour.

Figure 23.   Json schema members
Image

When developing against the toolkit, most of these classes are open to extension.

Example 1

Consider a requirement for a new key and value pair to represent a device’s startup time as a string value. You might simply extend the BJsonSchemaProperty<T> as type <String> using your own date format or type <BAbsTime> allowing the schema to render the date automatically using the schema date config. Now, you just need to implement getJsonValue() to return the appropriate value.

 @NiagaraType
 public class BDeviceTimeProperty extends BJsonSchemaProperty<BAbsTime>
 {
 /*+ ------------ BEGIN BAJA AUTO GENERATED CODE ------------ +*/
 .....
 /*+ ------------ END BAJA AUTO GENERATED CODE -------------- +*/
 
  @Override
  public BAbsTime getJsonValue()
  {
    return (BAbsTime) ..... // this will use the schemas date format config
  }
 }

Example 2

This requirement is for an object that contains a key and value pair for each slot on the target component, but only those with a user defined 1 flag. You might extend BJsonSchemaBoundObject, hide the slotsToInclude slot, and override the method getPropertiesToIncludeInJson() to only return properties with the user defined flag.

 @NiagaraType
 @NiagaraProperty(name = "slotsToInclude", type = "jsonToolkit:SlotSelectionType", 
 defaultValue = "BSlotSelectionType.allVisibleSlots",flags = Flags.HIDDEN, 
 override = true) public class BUserDefinedFlags extends BJsonSchemaBoundObject
 {
 /*+ ------------ BEGIN BAJA AUTO GENERATED CODE ------------ +*/
 .....
 /*+ ------------ END BAJA AUTO GENERATED CODE -------------- +*/
  @Override
  public List <String>getPropertiesToIncludeInJson(BComplex resolvedTarget)
  {
   if (resolvedTarget == null)
   {
    return Collections.emptyList(); // or try to resolve it!
   }
    return Arrays.stream(resolvedTarget.getPropertiesArray())
     .filter(prop -> (resolvedTarget.getFlags(prop) & Flags.USER_DEFINED_1) != 0)
     .map(prop -> prop.getName())
     .collect(Collectors.toList());
 }
}