is the oneOf key word supported by jsonschema2pojo?

1,336 views
Skip to first unread message

Marco Manca

unread,
Feb 5, 2013, 10:34:01 AM2/5/13
to jsonschema...@googlegroups.com
Hello everybody!
I'm trying to convert an xml schema (xsd) in JSON schema; I have a problem transforming  the following xsd element:

<xs:complexType name="RuleType">             
         <xs:sequence>
                <xs:element name="event" type="EventType" minOccurs="1" maxOccurs="1"/>
                <xs:element name="condition" type="ConditionType" minOccurs="0"/>
                <xs:choice minOccurs="1" maxOccurs="1">
                    <xs:element name="action" type="ActionType"/>        
                    <xs:element name="rule" type="RuleType"/>
                </xs:choice>    
            </xs:sequence>            
    </xs:complexType>

This is the correspondent json schema definition

"RuleType" : {
"type" : "object",
"properties" : {
"event" : { "$ref" : "#/definitions/EventType" },
"condition" : { "$ref" : "#/definitions/ConditionType" },
"actionOrRule" : {
"type" : "object",
"oneOf": [
{ "$ref": "#/definitions/ActionType" },
{ "$ref": "#" }
]
}
}

"ActionType" : {
"type" : "object",
"properties" : {
"create" : { 
"type" : "array",
"items" : { "$ref" : "#/definitions/CreateActionType" }
},
"read"   : { 
"type" : "array",
"items" : { "$ref" : "#/definitions/ReadActionType" }
}
                        }
                }

This is the code generated through jsonschema2pojo:

...
public class Rule {

    @JsonProperty("event")
    private Event event;
    @JsonProperty("condition")
    private Condition condition;
    @JsonProperty("actionOrRule")
    private ActionOrRule actionOrRule; 

    //getter and setter
}

The rule class is ok, but the ActionOrRule class is not well generated:

public class ActionOrRule {

    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperties(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}
There are no references to action or tule class, it seems a problem with the oneOf key word, does anyone knows if jsonschema2pojo support the oneOf construct?
If can help I can attach the draft of my json schema.

Kind regards.


Marco

Joe Littlejohn

unread,
Feb 5, 2013, 10:54:20 AM2/5/13
to jsonschema...@googlegroups.com
Hi Marco,

No, unfortunately the 'oneOf' keyword is not supported, this tool is built on with the draft03 feature set and the new jsonschema validation spec (associated with jsonschema draft04) was published just 4 days ago. You can get a full list of the supported keywords here:


I'm interested to know, how would you like this to be supported? What Java construct would you like to be generated here?






Marco

--
You received this message because you are subscribed to the Google Groups "jsonschema2pojo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsonschema2pojo-...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Marco Manca

unread,
Feb 5, 2013, 11:19:34 AM2/5/13
to jsonschema...@googlegroups.com
Hi Joe!
Thanks for the quick answer...
Actually I don't know how oneOf can be supported.. The xjc tool (which generate POJO class from xsd definition) generate the following java code for xs:choice construct which is the xsd construct corresponding to oneOf:

<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="action" type="BlockType"/>        
<xs:element name="rule" type="RuleType"/>
</xs:choice> 


@XmlElements({
        @XmlElement(name = "action", type = BlockType.class),
        @XmlElement(name = "rule", type = RuleType.class)
    })
    protected List<Object> actionOrRule;

I'm searching for a json annotation similar to @XmlElements; do you know if exist something like this?

many thanks.

M

Joe Littlejohn

unread,
Feb 5, 2013, 11:37:57 AM2/5/13
to jsonschema...@googlegroups.com
The problem here is that xml documents include type information, the elements themselves are a combination of data and metadata that allows a parser/binding tool to choose the correct type. In JSON, no such metadata exists, so we're stuck with proprietary extensions to do this kind of thing. When using jaxb, it's easy to notice an 'action' element in the xml and choose the BlockType, or see a 'rule' element and choose the RuleType. With JSON you have to inspect the object itself, and try to make some guess based on the properties present.

If you read up on the 'polymorphic type' support in Jackson you'll see how this is achieved. You effectively add an extra property into your object (e.g. "type") that will contain a value that tells Jackson which type to use. You then use the JsonTypeInfo annotation to define which Java classes the "type" values refer to. The JavaDoc contains an example:


So this is the closest equivalent to XmlElements.

This approach has some serious limitations. It's specific to Jackson and also relies on having a useful common supertype shared by the given Java classes. Generally for a nice Java API, you need to craft this manually. Also, if you imagine a simple example where a value can be either Integer or String, you can see that you'll have to declare that property as Object, and at this point we're beginning to lose the benefits of data-binding.



Reply all
Reply to author
Forward
0 new messages