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

JAXB in ICE

What is JAXB?

Java's API for XML Binding (JAXB) is a library within the current JDK standard that binds data from XML directly to an annotated data structure and vice versa. The types of annotations that are added to data structure classes (also known as java beans), can be distinct in order to identify differences between an element and an attribute, element order, certain restrictions, and even enumerations. Yet JAXB's biggest benefit is it can take an XML file or stream and convert it to a java bean without the hassles of an intermediary classes, similar with Java's API for XML Parsing (JAXP), can have with manipulating a separate data structure, like the Document Object Model (DOM). Also, this method preserves existing data architecture by allowing the user to annotate classes to perform the conversions, which helps maintain code integrity. In turn, this helps cut down extensive amounts of code and debugging for diverse and proliferated amounts of data structures within a particular application or program.

Types of Annotations

There are several types of annotations used within JAXB to specify specific distinctions when manipulating a java bean with XML. In particular, a few of the more common annotations are listed below with descriptions of each:

  • @XmlRootElement()- specifies a root element of a particular xml file. Usually contains other elements, attributes, but can have just a value.
  • @XmlElement()- identifies a specific element of an XML file. Can contain other elements, attributes, or values.
  • @XmlAttribute()- identifies specific attributes on a particular element.
  • @XmlEnum()- identifies if an element is an enumeration or not.
  • @XmlType()- a generic type of assignment. Usually used for identifying order (ex. propOrder{}).

Some of the elements above can use the following arguments:

  • name - Specify a specific name.
  • nameSpace - specify a specific NameSpace to follow.
  • propOrder{} - specify an order to elements.

Example Annotated Class

Here is an example class written in Java:


   @XmlRootElement()
   public Class Person {
       @XmlAttribute()
       String firstName;
   
       @XmlAttribute()
       String lastName;
       @XmlElement()
       ArrayList<Person> children;
   
       public Person() {
           this.firstName="Bob";
           this.lastName="Jones";
           this.children = new ArrayList();
       }
           
   //getters and setters below
   
   } 

So the class above gives a very simple example of a Java class using annotations to represent an XML file. If a program were create a new instance of this class and use JAXB to print this to an XML file (or marshal it to a stream), the result will be as follows:

    <Person firstName="Bob" lastName="Jones"> 

The firstName and lastName are attributes whereas the Person is an element. In this particular example, there are no children and therefore it will not annotate a list of children underneath Person. If the program were to add a child to the list, the following XML can be created

    <Person firstName="Bob" lastName="Jones">
           <children firstName="Bill" lastName="Jones"> 

Sample source code for JAXBManipulator read/write

Here is some sample source code for read and write operations within ICE. This typical piece of source code is essentially universal for most known situations. Although streams are passed to the operations, the arguments can be changed to XML file types.


   //Code for setting up the class
   
   public void write(Object dataObject, OutputStream outputStream) throws NullPointerException, JAXBException, IOException {
       JAXBContext jaxbContext = JAXBContext.newInstance(dataObject.getClass());
       Marshaller marshaller = jaxbContext.createMarshaller();
       marshaller.setProperty(Marshaller.JAXB_Formatted_Output, Boolean.TRUE);
       marshaller.marshal(dataObject, outputStream);
   }
   
   public Object read(Class objectClass, InputStream inputStream) throws NullPointerException, JAXBException, IOException {
       JAXBContext context = JAXBContext.newInstance(objectClass);
       Unmarshaller unmarshaller = context.createUnmarshaller();
       return unmarshaller.unmarshall(inputStream);
   }
   
   //possibly more code 

In essence, the context creates the grounds for which the data can be marshaled and the marshaller/unmarshaller manipulates the data for a "xml file" stream. The only current known problem is if a person tries to override a particular class and then tries to pass it to the marhsaller. This can be avoided by adding a class argument to the write, or the write operation can be overridden during compile time. The cool part is that this code can be used for many different types of data structures and situations, therefore keeping code simple and efficient.

JAXB Quirks

This section pertains to the issues, or quirks, that JAXB has to follow before it can work properly on particular sets of a Java bean. This will be, hopefully, a simplified list. If there are errors in the code or certain items are not being marshaled correctly, check here.

  • In order for annotations on methods to work correctly, make sure that they are matched with the proper getter and setter pair. If an XML type does not have a getter and setter match, then it will need to be put on the property in the class.
  • Each getter and setter pair with annotations must match equivalently to their respective property for data to be marshaled correctly. For example, if a property on a class is a boolean variable named ready, then the method to get the information should be isReady():boolean and the setter should be titled setReady(boolean value). If it is anything else, it will not work. For non-boolean properties, a person should use the "get" method instead of "is".
  • The get/set methods with annotations cannot be private.
  • Always put the annotation on a getter if the method's value needs to be put into XML.
  • Naturally, annotations are read from both methods and properties. If the annotations are only read by methods, please specify with @XmlAccessorType(XmlAccessType.PROPERTY). Otherwise, replace PROPERTY with FIELDS. Remember the proper usage of getters and setters for methods!
  • When using booleans, make sure to stick to the same specified type on the getter and setter. A common mistake is to use a boolean primitive on a getter, and then using the Boolean class on a setter argument. This confuses JAXB and inhibits data from being read back in correctly when marshaled. Stick with a type.
  • With propOrder, a code can arrange the elements any way it wishes. Nevertheless, attributes do not have a way to be ordered. By default, they are read in reverse.
  • For JAXB to fully parse and work, there must be a nullary constructor for the data structure.
  • If there is an interface that is implemented on an XmlElement, the higher level class needs to use @XmlElementRef or @XmlElementRefs to specify the class type.
  • Using generics on a JAXB list will automatically generate namespaces to the specified generic elements (a lot more XML junk to deal with).
  • Unless appended with the required=true clause in the @Xml****** call, a property on a class does not have to exist in XML to be read in. It will default to the value of the constructor (if any). Nevertheless, for this to be checked there has to be a generated XSD schema followed by the use of the XMLValidator.

General Overview of JAXB in ICE

This is just a general overview of the implementation and testing architecture for adding JAXB into ICE.

Class: JAXBManipulator

Functions in JAXBManipulator:

Operation: write() * ARGS: Object dataObject, OutputStream outputStream * Description: Takes an object and converts it to an OutputStream.

Operation: read():Object * ARGS: Class dataClass, InputStream inputStream * Description: Takes an inputStream and converts it to a given class. Returns a newly created object.

List of data structures that have annotations:

  1. DataComponent
  2. Entry
  3. Form
  4. OutputComponent
  5. Section
  6. Table
  7. Location
  8. ICEObject
  9. ICEResource
  10. TableComponent
  11. GeometryComponent
  12. MatrixComponent

TDD

  1. Valid read()
  2. Valid write()
  3. Error catch: Sequences
  • Invalid order
  • Unknown attribute addition
  • Missing attribute
  1. Error catch: Passing bad values on XML document to program.
  2. Testing bad parameters on toXML creation.
  3. Testing bad parameters on fromXML read-in.

Design Overview (TDD and Implementation)

  1. Bottom–up approach (start with Entity, then Component, …)
  2. Class properties are XMLAttributes.
  3. References to other classes within a bean are elements.
  4. Order might not matter, but hierarchical structure does.
  5. Some elements are required, others are not.

List of References

Annotations "jaxb annotations for soa/ioc" "http://www.caucho.com/resin-3.1/doc/jaxb-annotations.xtp#XmlAccessorType%22

Eclipse Link "MOXy/JAXB" http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JAXB

JAXB and JPA usage on the same POJO. "It can be done, but this is a poor example" http://www.objectpartners.com/2010/01/25/using-jpa-and-jaxb-annotations-in-the-same-object/

Marshalling "XML data marshalling" http://static.springsource.org/spring-ws/site/reference/html/oxm.html

Numeric-Types "Setting up datatypes for a java class from Schema" http://jaxb.java.net/tutorial/section_2_2_2-Numeric-Types.html

Schema Marshalling "It will not generate restrictions from schema transformations" http://www.java.net/external?url=http://www.nabble.com/Does-jaxb-2.1-enforce-xs:restriction-td21348458.html

Using a schema with MOXY "Use a JAXB MOXy-like SCHEMA to write a java bean to xml without annotations." http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/ExternalizedMetadata

Vogella, "JAXB class" http://www.vogella.de/articles/JAXB/article.html#jaxb_usage

Vogella "Reading and Writing using JAXB" http://www.vogella.de/articles/JAXB/article.html#jaxb_usage

WebSphere "Generating a Javaclass from SCHEMA" http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_jaxbbind.html WebSphere "Generating a XML Schema from Java Class" http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_jaxbbind.html

XPath "Using XPath to simplify XML" http://www.ibm.com/developerworks/library/x-javaxpathapi/index.html

Copyright © Eclipse Foundation, Inc. All Rights Reserved.