MOXy’s @XmlVariableNode – JSON Schema Example

We are in the process of adding the ability to generate a JSON Schema from your domain model to EclipseLink MOXy.  To accomplish this we have created a new Variable Node mapping. In this post I will demonstrate the new mapping by mapping a Java model to a JSON Schema.

You can try this out today using a nightly build of EclipseLink 2.6.0:

 
 

JSON Schema (input.json/Output) 

Below is the “Basic Example” taken from http://json-schema.org/examples.html.  Note how the type has many properties, but they don’t appear as a JSON array.  Instead they appear as separate JSON objects keyed on the property name.

{    "title": "Example Schema",    "type": "object",    "properties": {        "firstName": {            "type": "string"        },        "lastName": {            "type": "string"        },        "age": {            "description": "Age in years",            "type": "integer",            "minimum": 0        }    },    "required": ["firstName", "lastName"]}

Java Model

Below is the Java model we will use for this example.

JsonSchema (Properties Stored in a List)

In this Java representation of the JSON Schema we have a class that has a collection of Property objects.  Instead of the default representation of the collection (see:  Binding to JSON & XML – Handling Collections), we want each Property to be keyed by its name.  We can do this using the @XmlVariableNode annotation.  With it we specify the field/property from the target object that should be used as the key.

package blog.variablenode.jsonschema;import java.util.*;import javax.xml.bind.annotation.*;import org.eclipse.persistence.oxm.annotations.XmlVariableNode;@XmlAccessorType(XmlAccessType.FIELD)public class JsonSchema {    private String title;    private String type;    @XmlElementWrapper    @XmlVariableNode("name")    public List<Property> properties;    private List<String> required;}

JsonSchema (Properties Stored in a Map)

In this version of the JsonSchema class we have changed the type of properties property from List<Property> property to Map<String, Property>.  The annotation remains the same, the difference is that when @XmlVariableNode is used on a Map the variable node name is used as the map key.

package blog.variablenode.jsonschema;import java.util.*;import javax.xml.bind.annotation.*;import org.eclipse.persistence.oxm.annotations.XmlVariableNode;@XmlAccessorType(XmlAccessType.FIELD)public class JsonSchema {    private String title;    private String type;    @XmlElementWrapper    @XmlVariableNode("name")    public Map<String, Property> properties;    private List<String> required;}

Property

To prevent the name field from being marshalled we need to annotate it with @XmlTransient (see JAXB and Unmapped Properties).

package blog.variablenode.jsonschema;import javax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)public class Property {    @XmlTransient    private String name;    private String description;    private String type;    private Integer minimum;}

Demo Code

Below is some sample code that you can use to prove that everything works.

package blog.variablenode.jsonschema;import java.util.*;import javax.xml.bind.*;import javax.xml.transform.stream.StreamSource;import org.eclipse.persistence.jaxb.JAXBContextProperties;public class Demo {    public static void main(String[] args) throws Exception {        Map<String, Object> properties = new HashMap<String, Object>();        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);        JAXBContext jc = JAXBContext.newInstance(new Class[] {JsonSchema.class}, properties);        Unmarshaller unmarshaller = jc.createUnmarshaller();        StreamSource json = new StreamSource("src/blog/variablenode/jsonschema/input.json");        JsonSchema jsonSchema = unmarshaller.unmarshal(json, JsonSchema.class).getValue();        Marshaller marshaller = jc.createMarshaller();        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);        marshaller.marshal(jsonSchema, System.out);    }}

External Metadata

MOXy also offers an external mapping document which allows you to provide metadata for third party objects or apply alternate mappings for your model (see: Mapping Object to Multiple XML Schemas – Weather Example).  Below is the mapping document for this example.

<?xml version="1.0"?><xml-bindings    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"    package-name="blog.variablenode.jsonschema"    xml-accessor-type="FIELD">    <java-types>        <java-type name="JsonSchema">            <java-attributes>                <xml-variable-node                     java-attribute="properties" java-variable-attribute="name">                    <xml-element-wrapper/>                </xml-variable-node>            </java-attributes>        </java-type>        <java-type name="Property">            <java-attributes>                <xml-transient java-attribute="name"/>            </java-attributes>        </java-type>    </java-types></xml-bindings>



Source : http://www.javacodegeeks.com/2013/06/moxys-xmlvariablenode-json-schema-example.html

Back to Top