...
Before we look at the definition of our Example.json let's first look at the definition of our new VertebrateOrganType.json. For this example we want to use the Basic Vertebrate Anatomy ontology to define the valid values for Organs:
VertebrateOrganType.json
Code Block |
---|
{ "type":"string", "format":"uri", "enum":[ "XQUERY":" doc(http://rest.bioontology.org/bioportal/concepts/4531?conceptid=tbio:Organ&light=1&apikey=2fb9306a-7f3f-477a-821e-e3ccd7356a18)/success/data/classBean/relations/entry[string=Subclass]/list/classBean/fullId" "] ] } |
In this example, the enumeration values are defined by an XQuery that is used to get the "fullId" (URIs) of all Sub-classes of the Term "Organ" using the XML returned from NCBO's BioPortal Term services. Here is the XML returned by the term service for this exampl: http://rest.bioontology.org/bioportal/concepts/4531?conceptid=tbio:Organ&light=1&apikey=2fb9306a-7f3f-477a-821e-e3ccd7356a18.
Now that we have defined an Annotation Type for Organ using the ontology we can use this type in the definition of the entity.
Here is our definition of our example Entity:
Example.json
...
Assuming the XQuery is setup correctly, the effective enum definition for this type would be"
Code Block |
---|
"enum":[
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Heart",
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Pericardium",
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Brain",
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Stomach",
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Lung",
"http://www.co-ode.org/ontologies/basic-bio/basic-vertebrate-gross-anatomy.owl#Liver",
]
|
Now that we have defined an Annotation Type for Organ using the ontology we can use this type in the definition of the entity.
Here is our definition of our example Entity:
Example.json
Code Block |
---|
{ "extends":"org/sagebionetworks/entity/type/Entity.json""name":"Product", "properties":{ }, "id":{ }, "additionalProperties":{ "tissue":{ "type":"objectnumber", "$ref":"org/sagebionetworks/annotation/types/BioOntologyTissueType.json" } "description":"Example identifier", } } |
The first thing to point out about our Example.json is that it extends Entity.json, which makes it a Synapse Entity. This implies it inherits all of its values from the base Entity. The second thing to point out is that it defines a type called "tissue" in its additional properties that is based on the annotation type we defined earlier.
Compile JPJOs (first time)
Since we still want Java POJOs to represent all entities, we will use the schema-to-pojo-maven-plugin to build these POJOs. This is done by simply added the following to the lib-auto-generated/pom.xml file:
Code Block |
---|
<!-- This plugin builds the POJOs from JSON schemas. -->
<plugins>
<plugin>
<groupId>org.sagebionetworks</groupId>
<artifactId>schema-to-pojo-maven-plugin</artifactId>
<version>${schema-to-pojo.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<sourceDirectory>src/main/resources</sourceDirectory>
<packageName>org.sagebionetworks</packageName>
<outputDirectory>target/auto-generated-pojos</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
|
The plugin will automatically create a POJOs class for each JSON schema found in the resource directory. These POJOs will be placed in the target/auto-generated-pojos directory.
Synapse Deploy (first time)
The first time Synapse is deployed after creating Entities, the org.sagebionetworks.repo.model.bootstrap.EntityBootstrapper will read all JSON schema files found in the lib-auto-generated.jar file and create a Synapse SchemaEntity (to be defined) for each using the directory structure create each path. All schema entities will be placed in the folder:
Code Block |
---|
root/schemas
|
The resulting SchemaEntity objects from the two examples above would have the following paths:
Code Block |
---|
root/schemas/org/sagebionetworks/entity/type/Example.json
root/schemas/org/sagebionetworks/annotation/types/BioOntologyTissueType.json
|
Folder entities will be created as need to create each path. By giving each SchemaEntity a unique path, we can use this path to reference a schema before we have an entity to represent it.
The API user will be able to get the SchemaEntity objects but they will be READ-ONLY copies. This is important, because the "truth" of each entity is the JSON text file from the auto-generated-pojos project. Hopefully, this will make more sense as the rest of the life-cycle is outlined.
Edit of an Schema
Imagine that we want to add a new primary field to our Example.json Entity. To do this we need to modify the original JSON file in the lib-auto-generated
Code Block |
---|
/lib-auto-generated/src/main/resource/ "required":true }, "name":{ "description":"Name of the Example", "type":"string", "required":true }, "organ":{ "$ref":"org/sagebionetworks/annotation/types/VertebrateOrganType.json" } } } |
The first thing to point out about our Example.json is that it extends Entity.json, which makes it a Synapse Entity. This implies it inherits all of its values from the base Entity. The second thing to point out is that the "organ" property is defined using the annotation type we created earlier.
Compile JPJOs (first time)
Since we still want Java POJOs to represent all entities, we will use the schema-to-pojo-maven-plugin to build these POJOs. This is done by simply added the following to the lib-auto-generated/pom.xml file:
Code Block |
---|
<plugin>
<groupId>org.sagebionetworks</groupId>
<artifactId>schema-to-pojo-maven-plugin</artifactId>
<version>${schema-to-pojo.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<sourceDirectory>src/main/resources</sourceDirectory>
<packageName>org.sagebionetworks</packageName>
<outputDirectory>target/auto-generated-pojos</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
|
The plugin will automatically create a POJOs class for each JSON schema found in the resource directory. These POJOs will be placed in the target/auto-generated-pojos directory.
Synapse Deploy (first time)
The first time Synapse is deployed after creating Entities, the org.sagebionetworks.repo.model.bootstrap.EntityBootstrapper will read all JSON schema files found in the lib-auto-generated.jar file and create a Synapse SchemaEntity (to be defined) for each using the directory structure create each path. All schema entities will be placed in the folder:
Code Block |
---|
root/schemas
|
The resulting SchemaEntity objects from the two examples above would have the following paths:
Code Block |
---|
root/schemas/org/sagebionetworks/entity/type/Example.json
|
We want to add a new required primary field called "status". Since "status" is required, we must provide a default value. This is a requirement because we already have instances of Example entities deployed to Synapse, and each of these must be given a default value. We will cover how these default values are applied shortly. Here is our new Example.json:
Example.json
Code Block |
---|
{root/schemas/org/sagebionetworks/annotation/types/VertebrateOrganType.json |
Folder entities will be created as need to create each path. By giving each SchemaEntity a unique path, we can use this path to reference a schema before we have an entity to represent it.
The API user will be able to get the SchemaEntity objects but they will be READ-ONLY copies. This is important, because the "truth" of each entity is the JSON text file from the auto-generated-pojos project. Hopefully, this will make more sense as the rest of the life-cycle is outlined.
Edit of an Schema
Imagine that we want to add a new primary field to our Example.json Entity. To do this we need to modify the original JSON file in the lib-auto-generated
Code Block |
---|
/lib-auto-generated/src/main/resource/org/sagebionetworks/entity/type/Example.json
|
We want to add a new required primary field called "status". Since "status" is required, we must provide a default value. This is a requirement because we already have instances of Example entities deployed to Synapse, and each of these must be given a default value. We will cover how these default values are applied shortly. Here is our new Example.json:
Example.json
Code Block |
---|
{ "extends":"org/sagebionetworks/entity/type/Entity.json""name":"Product", "properties":{ "id":{ "type":"number", "description":"Example identifier", "required":true }, "name":{ "description":"Name of the Example", "type":"string", "required":true }, "extends":"org/sagebionetworks/entity/type/Entity.json"organ":{ "name$ref":"Product", "properties":{org/sagebionetworks/annotation/types/VertebrateOrganType.json" "id":{ }, "typestatus":"number",{ "descriptiontype":"Example identifierstring", "required":true, }, "enum":[ "name":{ "description":"Name of the Example"PROTOTYPE", "type":"string", "requiredRELEASED":true , }, "status":{ "type":"stringRECALLED", "required":true, "enum":[ "PROTOTYPE", "RELEASED", "RECALLED", "DEPRECIATED"], "default":"PROTOTYPE" }], }, "additionalProperties":{ "tissue":{ "type"default":"objectPROTOTYPE", "$ref":"org/sagebionetworks/annotation/types/BioOntologyTissueType.json" } } } |
Compile POJOs (Nth Time)
...