Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/DesignDocs/350483

Design Specification: Object-to-JSON Binding Layer

ER 350483

Document History

Date Author Version Description & Notes
 ? Denise Smith  ?
2011/08/11 Blaise Doughan  ?

Project overview

Overview of the project/feature. Why is it desired, what are its goals.

Goals:

  • goal 1
  • goal 2

Concepts

See http://www.json.org/ for more JSON reference

Requirements

The following sections will expand the goals of this project into more concrete requirements.

Design Constraints

Design / Functionality

Testing

API

PublicAPI

Standard JAXB API will be used to marshal and unmarshal. Users will need to set a property on the Marshaller and Unmarshaller to enable JSON mode.

Unmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(JAXBContext.MEDIA_TYPE, org.eclipse.persistence.oxm.MEDIA_TYPE.APPLICATION_JSON);
 
Marshaller jsonMarshaller = jaxbContext.createMarshaller();
jsonMarshaller.setProperty(JAXBContext.MEDIA_TYPE, org.eclipse.persistence.oxm.MEDIA_TYPE.APPLICATION_JSON);

New Enum class - org.eclipse.persistence.oxm.MEDIA_TYPE will be added with initial enum values (APPLICATION_XML, APPLICATION_JSON)

GUI

Config files

  • No changes are required to the current config files to support this feature.
  • With the introduction of this feature we could support exposing our config files in JSON format.

Documentation

Open Issues

This section lists the open issues that are still pending that must be decided prior to fully implementing this project's requirements.

Issue # Owner Description / Notes

Decisions

This section lists decisions made. These are intended to document the resolution of open issues or constraints added to the project that are important.

Issue # Description / Notes Decision
1 How should we parse JSON messages? We have decided to use ANTLR to implement a JSON parser: Bug 351113.

Future Considerations

During the research for this project the following items were identified as out of scope but are captured here as potential future enhancements. If agreed upon during the review process these should be logged in the bug system:

  •  ?

Bug 350483:Object to JSON Support

See http://www.json.org/ for more JSON reference

To support unmarshalling JSON antlr will be used. Bug 351113.

PublicAPI

Standard JAXB API will be used to marshal and unmarshal. Users will need to set a property on the Marshaller and Unmarshaller to enable JSON mode.

  Unmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
  jsonUnmarshaller.setProperty(JAXBContext.MEDIA_TYPE, org.eclipse.persistence.oxm.MEDIA_TYPE.APPLICATION_JSON);
 
  Marshaller jsonMarshaller = jaxbContext.createMarshaller();
  jsonMarshaller.setProperty(JAXBContext.MEDIA_TYPE, org.eclipse.persistence.oxm.MEDIA_TYPE.APPLICATION_JSON);

New Enum class - org.eclipse.persistence.oxm.MEDIA_TYPE will be added with initial enum values (APPLICATION_XML, APPLICATION_JSON)


String vs non-String values

Bug 351119 In JSON String values are in "" but not string values are not.

{"address":
    "id":1,
    "city":"Ottawa",
    "isMailingAddress":true
}

Namespaces

Bug 351588 By default namespaces/prefixes will be ignored during marshal and unmarshal operations. This default behavior is a problem if there are multiple mappings with the same local name in different namespaces as there would be no way to distinguish between those mappings. Users will be able to provide a Map of namespaces to customize the behavior.

 Map namespaces = new HashMap<String, String>();
 namespaces.put("ns1", "namespace1");
 namespaces.put("ns2", "namespace2");
 jsonUnmarshaller.setProperty(JAXBContext.JSON_NAMESPACES, namespaces);

If the namespace map is set on the marshaller it will be used to prefix elements during the marshal operation.

 jsonMarshaller.setProperty(JAXBContext.JSON_USE_NAMESPACES, true);

The namespaces will be give the prefix from the map separated with a `.` ie:

 {"ns0.employee:{
     "ns0.id":123
    }
 }

Design-To allow unmarshal to ignore namespaces XPathFragment will have an isNamespaceAware methods so that uris can be ignored during equals comparisons when in JSON unmarshal mode. Additionally a new class that represents a QName will also be introduced (org.eclipse.persistence.internal.oxm.XPathQName) and it was also have an isNamespaceAware boolean. XMLContext will store descriptors based on the new XPathQNames instead of the old QName.

Inheritance

XML - <prefix:vehicle xsi:type="prefix:car-type"> JSON-Can unmarshal "type":"prefix:car-type" or "type":"car-type", Should it marshal "type":"prefix:car-type" or "type":"car-type",


XSI type attribute

ie:CompositeObjectMapping to Object.class attributes of type java.lang.Object (or Collection of Objects).

    • Equivalent XML -
  <responsibilities>
     <responsibility xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xsi:type="xsd:string">Fix Bugs</responsibility>

no "root element" support

Bug 353938 JSON supports documents with no root element

{"area-code":"613",
 "number":"1234567"}

During marshal if there is no @XmlRootElement specified then the JSON document won't have a root element (as above). During an unmarshal operation if the document has more than one child element it will be treated as an object without a root element. The only unmarshal methods that will be supported for the non root element case will be those that take a Class argument that specifies the class to unmarshal to. If there is an object with no root element that only has 1 mapped field it will marshal fine but will not unmarshal correctly. This is because the check to determine if this is a root vs. non-root case is to check if there is more than one child element at the root level. To override this behavior users will be able to specify a property on the JAXBUnmarshaller to specify that it is a non-root element case.

 jaxbUnmarshaller.setProperty(JAXBContext.JSON_HAS_ROOT_ELEMENT, false);

Attributes

JSON doesn't have the concept as attributes so by default when marshaling anything mapped as an attribute will be marshalled as an element. During unmarshal elements will trigger both the attribute and element events to allow either the mapped attribute or element to handle the value. If there is an element and attribute with the same name this will cause problems. Additionally there would likely be issues if an AnyAttribute or Any existed as all items would probably be duplicated in the AnyAttribute mapping and the Any Mapping.

Users will be able to override the default behaviors by providing a prefix to marshal with attributes and to recognize during unmarshal. In the example below the number attribute is mapped as an attribute.

 jsonUnmarshaller.setProperty(JAXBContext.JSON_ATTRIBUTE_PREFIX, "@");
 jsonMarshaller.setProperty(JAXBContext.JSON_ATTRIBUTE_PREFIX, "@") ;
{"phone":{
  "area-code":"613",
  "@number":"1234567"
  }
}

Null support

Bug 351587 When marshaling if the getMarshalNullRepresentation setting on nullpolicy is ABSENT_NODE we don't write that pair to JSON. If the getMarshalNullRepresentation is NIL we should write "null" If the getMarshalNullRepresentation is EMPTY_NODE we should write "null"

Complex Object example employee.setAddress(null);

     {"emp":{
          "address":null
       }

Complex Object example employee.setAddress(new Address());

      {"emp":{
          "address":{}
       }

Simple example address.setCity(null);

       {"address":{
            "city":null
          }
       }

Date Types

JAXB Annotations

Annotation Applicable to JSON Tested
XmlAccessorOrder Yes No
XmlAccessorType Yes No
XmlAnyAttribute ? No
XmlAnyElement Yes No
XmlAttribute Yes Yes
XmlAttributeRef ? No
XmlElement Yes Yes
XmlElementWrapper Yes No
XmlID Yes No
XmlIDREF Yes No
XmlJavaTypeAdapter Yes No
XmlJavaTypeAdapters Yes No
XmlList Yes No
XmlMimeType ? No
XmlMixed ? No
XmlNs No No
XmlNsForm No No
XmlRootElement Yes Yes
XmlSchema No No
XmlSeeAlso Yes No
XmlTransient Yes No
XmlType Yes No
XmlValue Yes No
  • XmlValue

2 options for XmlValue behavior (ideally we will support both). If Phone.java has 1 field called number and it is marked with @XmlValue Option1- use a pair name called "value" (or something customizable)

   {"employee":{
      {"phone":{
          "value":"123-4567"
        }
   }}

Option2

   {"employee":{
      {"phone":"123-4567"
   }}

MOXy Annotations

Annotation Applicable to JSON Tested
XmlAccessMethods
XmlCDATA
XmlClassExtractor
XmlContainerPolicy
XmlCustomizer
XMLDiscriminatorNode
XMLDiscriminatorValue
XmlElementsJoinNodes
XmlInverseReference
XmlIsSetNullPolicy
XmlJoinNode
XmlJoinNodes
XmlKey
XmlMashalNullRepresentation
XmlNameTransformer
XmlNullPolicy
XmlParameter
XmlPath
XmlPaths
XmlProperties
XmlProperty
XmlReadOnly
XmlReadTransformer
XmlTransformation
XmlVirtualAccessMethods
XmlVirtualAccessMethodsSchema
XmlWriteOnly
XmlWriteTransformer
XmlWriteTransformers

Back to the top