About Blaise Doughan

Team lead for the TopLink/EclipseLink JAXB & SDO implementations, and the Oracle representative on those specifications.

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>

 

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


6 + = fifteen



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close