Developer Guide

Preface

Skaringa is an API for Java, JSON and XML language binding. Its core component is an Object Transformer, which is able to transform Java objects into XML or JSON documents and vice versa.

Typical applications are:

Skaringa consists of the parts:

It is designed for simplicity, supporting a wide range of types, and speed:

Getting the software

The software is available as a binary package, a source code package, and via anonymous CVS access. The access to all kinds of distributions is provided via Sourceforge.net.

Binary package

The binary package is distributed as .zip and .tar.gz archive. It contains skaringa.jar and the full API documentation. This package should directly work as it is.

Source package

This package is distributed as well as .zip and .tar.gz archive. The source package contains the Java source files and the prerequisites listed below. An Ant build file is included.

This distribution includes software developed by the Apache Software Foundation.

Anonymous CVS access

This method provides access to the current developer source code. See Sourceforge.net for details how to work with the CVS repository.

The access to a former distribution via CVS is supported by using CVS tags. The tags have a name like rxpy , where x is the version number and y the patch level.

Prerequisites

Binary package

Source package

Installing

Binary package

Unpack the distribution into an arbitrary directory. The subdirectory skaringa/lib contains the library skaringa.jar. Documentation can be found by pointing an HTML browser to doc/index.html.

Source package

Testing

The Skaringa source package contains self-testing JUnit tests to ensure everything works well.

The JUnit tests may be run by

ant runtest

Logging

Skaringa may produce some output for logging and tracing using the Jakarta Commons Logging API.

Skaringa uses the log levels ERROR, INFO, and DEBUG. To configure the amount and destination of log messages, look at the documentation of Jakarta Commons Logging.

It is however not required to have the Commons Logging API present at runtime - if Skaringa fails to load Commons Logging it simply proceeds without logging.

Java 2 security issues

Skaringa uses reflection to get and set the state of an object. If Skaringa is running under a security manager (for example in a Web or EJB container) its security policies may prohibit the use of reflection. In this case, the following permissions have to be granted in the policy file of the Java run-time environment (e.g. server.policy):

permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

How to use XML serialization and deserialization - A simple example

Hint: The code shown in the following chapters is completely contained in the Skaringa source distribution (directory test/com/skaringa/javaxml/example).

Assume we have a simple Java class Person:

package com.skaringa.javaxml.example;

/**
 * An example class to demonstrate the usage of the object transformer.
 */
public class Person {
    
    /**
     * Private member fields.
     */
    private int id;
    private String firstName;
    private String lastName;
    private String email;

    /**
     * Default Constructor.
     * It is required for deserialization, but it doesn't need to be public!
     */
    private Person() {}

    /**
     * Public Constructor to initialize all member fields of a Person.
     */
    public Person(int id, String firstName, String lastName, String email) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
    
    /**
     * Public member function definitions, like getters and setters, 
     * toString(), equals(), business methods, ...
     * None of these functions are required for purposes of serialization
     * and deserialization!
     */

}

Note that the class needs a default constructor. But this is the only one that is necessary to meet Skaringa's requirements! No definition of public accessors to the fields, setting of special tags or following a distinct pattern is necessary to make a class ready for (de)serialization with the Skaringa framework!

So we can straight go on and use it. First we construct a Person object:

package com.skaringa.javaxml.example;

import java.io.File;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import com.skaringa.javaxml.DeserializerException;
import com.skaringa.javaxml.NoImplementationException;
import com.skaringa.javaxml.ObjectTransformer;
import com.skaringa.javaxml.ObjectTransformerFactory;
import com.skaringa.javaxml.SerializerException;

/**
 * Demonstrate the serialization and deserialization of a Person object.
 */
public class PersonExample {

    public static void main(String[] args) {

        // Construct a Person.
        Person fred = new Person(101, "Fred", "Feuerstein", "ff@email.com");

Next we need Skaringa's ObjectTransformer:

        
        try {
            // Get an ObjectTransformer.
            // The ObjectTransformer interface offers all needed methods.
            ObjectTransformer trans =
                ObjectTransformerFactory.getInstance().getImplementation();

            // The transformer should create extra line feeds in the output.
            trans.setProperty(javax.xml.transform.OutputKeys.INDENT, "yes");

            // Set the amount of indenting if Xalan is used as XSL transformer.
            trans.setProperty("{http://xml.apache.org/xalan}indent-amount", "2");

With the ObjectTransformer it is possible to serialize our Person...

            // Serialize the Person object into a file.
            FileOutputStream out = new FileOutputStream("fred.xml");
            trans.serialize(fred, new StreamResult(out));
            out.close();

... or to create an XML schema definition that describes the class Person:

            // Create an XML schema file that describes the Person class.
            out = new FileOutputStream("Person.xsd");
            trans.writeXMLSchema(Person.class, new StreamResult(out));
            out.close();

The XML file and the XSD file created above are the ticket to the world of XML processing. The XML document may be stored into a database, transformed with XSLT or transmitted to a remote application via SOAP. Let's have a look at the XML document:

<?xml version="1.0" encoding="UTF-8"?>
<com.skaringa.javaxml.example.Person id="i1769610132"
    xsi:type="com.skaringa.javaxml.example.Person" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
    <id xsi:type="xsd:int">101</id>
    <firstName xsi:type="xsd:string">Fred</firstName>
    <lastName xsi:type="xsd:string">Feuerstein</lastName>
    <email xsi:type="xsd:string">ff@email.com</email>
</com.skaringa.javaxml.example.Person>

And the schema:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="com.skaringa.javaxml.example.Person"
    type="com.skaringa.javaxml.example.Person" nillable="true" />
  <xsd:complexType name="java.lang.Object">
    <xsd:attribute name="id" type="xsd:ID" />
    <xsd:attribute name="reference" type="xsd:IDREF" />
  </xsd:complexType>
  <xsd:complexType name="com.skaringa.javaxml.example.Person">
    <xsd:complexContent>
      <xsd:extension base="java.lang.Object">
        <xsd:sequence>
          <xsd:element name="id" type="xsd:int" nillable="true"
            minOccurs="0" />
          <xsd:element name="firstName" type="xsd:string"
            nillable="true" minOccurs="0" />
          <xsd:element name="lastName" type="xsd:string" nillable="true"
            minOccurs="0" />
          <xsd:element name="email" type="xsd:string" nillable="true"
            minOccurs="0" />
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

We see here, that the Java type hierarchy »Person extends java.lang.Object« is converted to a similar XSD type hierarchy. This is useful because one could define a Java class member like:

private Object f1 = new Person();

During serialization, the field f1 is correctly serialized with its runtime type Person. But in the schema, the field f1 has of course its declared type Object! Therefore, the information, that a Person »is a« Object needs to be provided in the schema to allow a correct validation of the XML instance against the schema.

To complete our example, we want to read the XML document back and check if the resulting object is really a clone of our Person fred:

            // Read a Person's XML file and create a new Person object
            // from its content.
            FileInputStream in = new FileInputStream("fred.xml");
            Person freddy =
                (Person) trans.deserialize(new StreamSource(in));
            in.close();

            // Check the result.
            if (fred.equals(freddy)) {
                System.out.println("OK");
            }
            else {
                System.out.println("ERROR");
            }
        }
        // Handle the weird things...
        catch (NoImplementationException e) {
            System.err.println(e);
        }
        catch (SerializerException e) {
            System.err.println(e);
        }
        catch (DeserializerException e) {
            System.err.println(e);
        }
        catch (IOException e) {
            System.err.println(e);
        }
    }
}

How to use JSON serialization and deserialization - A similar example

Let's use the same class Person as above to demonstrate JSON serialization and deserialization. The steps to perform JSON serialization are mostly the same as with XML: At first we create the ObjectTransformer. It is used to call serializeToJson or serializeToJsonString:

      // Get an ObjectTransformer.
      // The ObjectTransformer interface offers all needed methods.
      ObjectTransformer trans = ObjectTransformerFactory.getInstance()
          .getImplementation();

      // Serialize the Person object into a JSON file.
      FileOutputStream out = new FileOutputStream("fred.js");
      trans.serializeToJson(fred, out);
      out.close();

This produces a JSON file with the content

{"id":101,"firstName":"Fred","lastName":"Feuerstein","email":"ff@email.com"}

Now we deserialize this file back into Java:

      // Read a Person's JSON file and create a new Person object
      // from its content.
      FileInputStream in = new FileInputStream("fred.js");
      Person freddy = (Person) trans.deserializeFromJson(in, Person.class);
      in.close();

The concrete class of the root object to deserialize must be provided as the second argument of deserializeFromJson. This is required in opposite to XML deserialization because the deserializer otherwise has no clue of the type of the object to instantiate - the JSON format doesn't provide something like xsi:type.

If the root object contains other nested objects, then Skaringa tries to figure out their type during deserialization by looking at the declared class of the member. If the actual type doesn't fit into the declared type, then deserialization fails.

There is however a second method deserializeFromJson without the type parameter. Using this method, the JSON string is deserialized into a Map of name - value parameters:

      // now deserialize the JSON file into a map instead of a person
      in = new FileInputStream("fred.js");
      Map fredMap = (Map) trans.deserializeFromJson(in);
      in.close();

This works for nested objects as well of course.

Serializable Java types

Beside the above simple examples, Skaringa is able to process complex Java objects, which may have the following types of member fields:

The components of arrays, collections and maps may be all types of the above list.

XML documents

Skaringa can process XML documents which exist as Files, Streams, Strings, DOM trees and SAX events. More exactly, all kinds of documents that can be passed into javax.xml.transform.Source or javax.xml.transform.Result respectively.

JSON documents

Skaringa can process JSON documents which exist as String or streams of bytes. The encoding used to read/write characters from/to the streams is always UTF-8.

Handling the state of an object

The state of an object is represented by its member variables. The values of these member variables are saved into the XML or JSON document during serialization and restored during deserialization.

Static and transient fields are not serialized, because they don't represent the persistent state of an object. Final variables are serialized, but can't be restored during deserialization. We assume that class definitions don't change between serialization and deserialization, therefore final variables get their correct value in this definition.

The developer of a class may define and implement two additional special functions to get more subtle control over Skaringa's serialization and deserialization:

public Object skaWriteReplace();

If this function exists, it is called before an object is serialized. It may be used to replace the object by another one, for example by one where secure data is encrypted or where non-transient fields that should not be persisted are set to null.

public Object skaReadResolve();

If this function exists, it is called after an object has been deserialized and all of its non-transient member variables have been restored. This function can be used to change the deserialized object, for example to compute transient fields from non-transient fields.

Because an object can be serialized more than once, be careful with modifying the state of the object in skaWriteReplace. It is guaranteed, that skaReadResolve is called only once during deserialization.

Using a certain class loader

Skaringa needs to load classes for new objects to be created during deserialization. By default, the class loader used to load these classes is the same class loader that has been loaded the Skaringa JAR file.

This can cause problems if different class loaders are used in an application. For example, web containers (like Tomcat) and EJB containers (like JBoss) have a hierarchical structure of class loaders. To work around class loading problems in those environments it is possible to tell Skaringa which class loader to use to load new classes. This is done by passing the class loader to the ObjectTransformer with the method setClassLoader.

The following example shows how to practice this method in a servlet:

public class TestServlet extends HttpServlet {

  private ObjectTransformer _trans;

  public void init() throws ServletException {
    super.init();

    try {
      // get object transformer
      _trans = ObjectTransformerFactory.getInstance().getImplementation();
      // instruct skaringa to use the class loader of this servlet
      // to load new classes
      _trans.setClassLoader(getClass().getClassLoader());
    }
    catch (NoImplementationException e) {
      throw new ServletException(e);
    }
  }

  protected void doGet(HttpServletRequest req, HttpServletResponse res) {
    // ...
    String serial;
    // serial = get an XML string from anywhere

    // deserialize it
    // the class loader of this servlet is used to load class TestVO
    TestVO vo2 = (TestVO) _trans.deserializeFromString(serial);

    // ...
  }
}

Properties to customize the XML output

The XML output is optimized for the processing with XML parsers and for the requirements of deserialization. However, in some cases it may be useful to make the resulting XML documents more human readable. This can be done by passing additional properties to the ObjectTransformer via the method setProperty. We already used this feature in the above example by calling

trans.setProperty(javax.xml.transform.OutputKeys.INDENT, "yes");

to insert extra line feeds into the XML output.

People who use german Umlaute in their strings may want to use another character encoding instead of the default UTF-8, for example ISO-8859-1:

trans.setProperty(javax.xml.transform.OutputKeys.ENCODING, "ISO-8859-1");

Another important point is the existence of the xsi:type attribute for each XML element. This attribute is necessary for further deserialization of the XML document. We already discussed, that the actual type of an object's field may differ from its declared type. Therefore the actual type of each field is provided using the xsi:type attribute. This information is also necessary for the members of collections and maps, because the type of these members is always declared as java.lang.Object in the Java language.

However, if the Java objects in a concrete application don't make use of these features or if you don't intend to deserialize the XML documents later, then adding the xsi:type attribute to each XML element may be unnecessary and disturbing. In this case, using

trans.setProperty(com.skaringa.javaxml.PropertyKeys.OMIT_XSI_TYPE, "true");

will shorten the XML output and enhance its readability dramatically. The XML is still deserializable in this case, if

Note that this property must be set also for the instance of ObjectTransformer, that performs the deserialization!

The above example of serializing a Person will then generate the output:

        <?xml version="1.0" encoding="UTF-8"?>
<com.skaringa.javaxml.example.Person>
    <id>101</id>
    <firstName>Fred</firstName>
    <lastName>Feuerstein</lastName>
    <email>ff@email.com</email>
</com.skaringa.javaxml.example.Person>

For the complete list of properties see Appendix A.

Field order

The order of the fields in the XML or JSON output follows the general rule, that fields declared in the base class appear before the fields declared in the class itself.

The fields of a class are not in any particular order. This is no problem in most cases, where only serialization and deserialization is used. But if the XML instance is validated against a schema, then field order may cause problems if schema and instance are generated at different platforms or with different versions of the JVM.

Additionally, there are two possible methods to influence the field order for those who want more control.

Lexicographical field order

If the property com.skaringa.javaxml.PropertyKeys.SORT_FIELDS is passed to the transformer, then the fields declared in one class are serialized in the lexicographical order of their names.

Use of skaFieldOrder

A class may declare the static field String[] skaFieldOrder, which contains the names of all non-static fields of the class in a particular order. In this case, Skaringa uses this given order. For example, for the class definition:

public class SkaFieldOrderObj {
  private int v = 1;
  private int a = 2;
  private int alpha = 3;

  private static final String[] skaFieldOrder = {
    "alpha",
    "v",
    "a",
  };

}

Skaringa produces the XML:

<com.skaringa.javaxml.test.SkaFieldOrderObj>
  <alpha>3</alpha>
  <v>1</v>
  <a>2</a>
</com.skaringa.javaxml.test.SkaFieldOrderObj> 

or the JSON respectively:

{"alpha":3,"v":1,"a":2}

Use case: XSLT object transformation

Imagine that a complex user administration system was built using the above Person class. Now a customer wants to use this system. Unfortunately, his user database has another model to describe users.

For example, it may use the class OrgMember instead of Person to hold a users's data:

package com.skaringa.javaxml.example;

public class OrgMember {

    /**
     * Private member fields.
     */
    private String uid;    // user id.
    private String sn;     // surname
    private String cn;     // common name (i.e. first and last name)
    private String mailto; // mail address
    
    // methods skipped
}

Of course it is possible to extend the Person class by special conversion methods, which take or produce OrgMember objects. But this requires to change existing code. And what happens if we want to connect to a third system, which uses neither a Person nor an OrgMember, but a User class?

A better approach may be to use a pluggable layer of code, which can transform a Person object into any other class, for example into OrgMember. The development of such a layer is a hard work, if maximum flexiblity and extensibility must be ensured. So it should even support the transformation into classes we don't known at the time of design!

The good news are, that the Skaringa framework already contains such a transformer. Because Skaringa provides the binding between Java classes and XML documents, is is possible to describe a transformation of Java objects by the means of XSLT!

Continuing with the example, it is required to convert a Person object into an OrgMember. A use case agreed with the customer sets the following rules to map a Person's to an OrgMember:

Person OrgMember
id uid
lastName sn
firstName + " " + lastName cn
email mailto

XML schemas for both classes involved in the transformation can be created by calling Skaringa's method writeXMLSchema(). With those schemas and the information provided in the above table, we are able to write XSL transformation instructions:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" 
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd = "http://www.w3.org/2001/XMLSchema">

  <xsl:template match = "com.skaringa.javaxml.example.Person">
    <com.skaringa.javaxml.example.OrgMember 
        xsi:type="com.skaringa.javaxml.example.OrgMember">
      <mailto xsi:type="xsd:string">
        <xsl:value-of select = "./email"/>
      </mailto>
      <cn xsi:type="xsd:string">
        <xsl:value-of select = "./firstName"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select = "./lastName"/>
      </cn>
      <sn xsi:type="xsd:string">
        <xsl:value-of select = "./lastName"/>
      </sn>
      <uid xsi:type="xsd:string">
        <xsl:value-of select = "./id"/>
      </uid>
    </com.skaringa.javaxml.example.OrgMember>
  </xsl:template>
</xsl:transform>

This instruction is sent to the Transformer with the method ObjectTransformer.setPostprocessorInstruction. If the XSLT is stored in a file one may use:

  // set the transformation stylesheet
  trans.setPostprocessorInstruction(new StreamSource(
    ClassLoader.getSystemResourceAsStream(
      "com/skaringa/javaxml/example/Person2OrgMember.xsl")));

That's all! Now any Person object can be transformed into an equivalent OrgMember object by calling ObjectTransformer.transform:

  // transform using the previously set (and pre-parsed) stylesheet
  OrgMember fredTheMember = (OrgMember) trans.transform(fred);

The transformation stylesheet has been parsed during setPostprocessorInstruction. Therefore frequent transformations can be executed in a performant way without parsing the stylesheet again and again.

Pre- and post-processing of XML

The above examples assume that the Java classes exist first and the XML is derived »automatically« from them by Skaringa's implicit rules. But how to integrate Skaringa into an existing system where the schema of the used XML data has been already specified?

Imagine that the following XML file is used to exchange data between two systems:

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <item>alpha</item>
  <item>beta</item>
  <item>gamma</item>
</items>

Now we want to use Skaringa to deserialize this XML into a Java object, more exact into a java.util.Collection of java.lang.String. Skaringa needs a collection to be in the format that is shown in note 4. The above XML is apparently not in this format, but a simple XSL instruction can be used to transform the XML into Skaringa's collection format:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >

  <xsl:template match = "items">
    <items xsi:type="java.util.Collection">
      <xsl:apply-templates select = "item"/>
    </items>
  </xsl:template>
  <xsl:template match = "item">
    <cel xsi:type="xsd:string">
      <xsl:value-of select = "."/>
    </cel>
  </xsl:template>
</xsl:transform>

This instruction is passed to Skaringa's preprocessor, which parses the stylesheet and stores it for further reuse:

  // Get an ObjectTransformer.
  ObjectTransformer trans =
      ObjectTransformerFactory.getInstance().getImplementation();

  // set preprocessing instructions
  trans.setPreprocessorInstruction(
      new StreamSource(ClassLoader.getSystemResourceAsStream(xslPreRes)));

Calling ObjectTransformer.deserialize now will first apply this transformation to the input before piping it into the object deserializer. The result of this operation is a newly instantiated collection of strings - exactly what we want:

  // deserialize customized xml into a collection of strings
  // (using preprocessing instructions)
  Collection coll =
      (Collection) trans.deserialize(
          new StreamSource(ClassLoader.getSystemResourceAsStream(xmlInRes)));

After doing some Java work with the collection it should be serialized back to XML - of course in the same format as it was read. This work is done by Skaringa's postprocessor, which is able to transforms the result of a serialization into any XML format, or even HTML or text. The only thing the postprocessor needs is the instruction how to perform the transformation. In our example we use this stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <xsl:output method = "xml" indent = "yes" />

  <xsl:template match = "/">
    <items>
      <xsl:apply-templates select = "//cel"/>
    </items>
  </xsl:template>
  <xsl:template match = "cel">
    <item>
      <xsl:value-of select = "."/>
    </item>
  </xsl:template>
</xsl:transform>

It is registered with the postprocessor by:

  // set postprocessing instruction
  trans.setPostprocessorInstruction(
      new StreamSource(ClassLoader.getSystemResourceAsStream(xslPostRes)));

The serialize methods now produces output in the original custom XML format:

  // serialize the collection into a customized xml string
  // (using postprocessing instructions)
  String output = trans.serializeToString(newColl);

Again, postprocessing performed repeatedly with the same stylesheet reuses the preparsed template. Therefore serialization is fast - even if postprocessing is used.

Appendix A: Properties for the ObjectTransformer

This table shows the properties which can be passed to the method setProperty(name, value) of ObjectTransformer to customize Skaringa's function.

name possible values description
com.skaringa.javaxml.PropertyKeys.
OMIT_XSI_TYPE
"yes" or "no" Specifies whether the xsi:type attributes should be surpressed during serialization or not. Setting this property results in a shorter and more human-readable output, but the output may be not deserializable (especially if the serialized object makes use of collections, maps, or derived classes). Applies to XML (de)serialization only.
com.skaringa.javaxml.PropertyKeys.
OMIT_XSI_NIL
"yes" or "no" Specifies whether the xsi:nil attributes should be surpressed during serialization or not. Setting this property results in a shorter and more human-readable output, but the result of the deserialization may be not an exact copy of the serialized object. Applies to XML (de)serialization only.
com.skaringa.javaxml.PropertyKeys.
OMIT_ID
"yes" or "no" Specifies whether the unique object id should be surpressed during serialization or not. This ID is needed for the handling of cyclic references in the object to be serialized. If objects don't have cyclic references, then this property can be set to "yes" safely. Applies to XML (de)serialization only.
com.skaringa.javaxml.PropertyKeys.
SORT_FIELDS
"yes" or "no" Specifies whether the fields of a class should be ordered lexicographically during serialization and schema generation.
Remark: If a static field String[] skaFieldOrder is found in the class, then the fields are ordered according to the order of their names in skaFieldOrder. If neither this property is set to 'yes' nor skaFieldOrder exists, then the fields are not in any particular order.
com.skaringa.javaxml.PropertyKeys.
SKIP_UNKNOWN_FIELDS
"yes" or "no" If set to "yes", then fields that are contained in the XML but are unknown to the target class are silently skipped during deserialization.
If not set or set to "no", then those unknown fields cause a DeserializerException.

All properties that are not in the above table are passed to the underlying XML transformer (applies to XML (de)serialization only). These include the standard transformer output properties defined in javax.xml.transform.OutputKeys as well as specific properties of the used transformer. The table below contains an incomplete list of those properties:

name possible values description
javax.xml.transform.OutputKeys.
INDENT
"yes" or "no" Specifies whether the Transformer may add additional whitespace when outputting the result tree.
{http://xml.apache.org/xalan}
indent-amount
positive integer The amount of spaces used to indent a line in the output.
javax.xml.transform.OutputKeys.
OMIT_XML_DECLARATION
"yes" or "no" Specifies whether the XSLT processor should surpress the output of an XML declaration.
javax.xml.transform.OutputKeys.
ENCODING
Name of a charset registered with the Internet Assigned Numbers Authority [IANA], [RFC2278] (case-insensitiv). Encoding specifies the preferred character encoding that the Transformer should use to encode sequences of characters as sequences of bytes.

Appendix B: Mapping between Java, JSON and XML types

Java type XML type 1 JSON type
int
java.lang.Integer
xsd:int number
long
java.lang.Long
xsd:long number
short
java.lang.Short
xsd:short number
byte
java.lang.Byte
xsd:byte number
float
java.lang.Float
xsd:float number
double
java.lang.Double
xsd:double number
boolean
java.lang.Boolean
xsd:boolean boolean
char
java.lang.Character
char 2 string
java.lang.String xsd:string string
java.util.Date xsd:dateTime string with ISO8601 DateTime Format
java.math.BigDecimal xsd:decimal number
java.math.BigInteger xsd:integer number
Arrays array 3 array
All collections types from java.util Extension of java.util.Collection 4 array
All set types from java.util Extension of java.util.Set 5 array
All map types from java.util Extension of java.util.Map 6 object
All other complex types The XML type name is the full qualified name of the corresponding Java class 7 object
Notes:

1) The xsd namespace prefix denotes the definitions in http://www.w3.org/2001/XMLSchema.

2) Skaringa defines the XML type char as:

<xsd:simpleType name="char">
    <xsd:restriction base="xsd:string">
        <xsd:length value="1"/>
    </xsd:restriction>
</xsd:simpleType>

3) Skaringa defines an XML type for each array type, for example the type array_of_int for the java type int[]:

<xsd:complexType name="array_of_int">
  <xsd:sequence>
    <xsd:element name="el" minOccurs="0" maxOccurs="unbounded" type="xsd:int"
      nillable="true"/>
  </xsd:sequence>
</xsd:complexType>

4) Skaringa defines the XML type java.util.Collection as:

<xsd:complexType name="java.util.Collection">
  <xsd:sequence>
    <xsd:element name="cel" minOccurs="0" maxOccurs="unbounded" type="xsd:anyType" 
      nillable="true"/>
  </xsd:sequence>
</xsd:complexType>

5) Skaringa defines the XML type java.util.Set as:

<xsd:complexType name="java.util.Set">
  <xsd:complexContent>
    <xsd:extension base="java.util.Collection"/>
  </xsd:complexContent>
</xsd:complexType>

6) Skaringa defines the XML type java.util.Map as:

<xsd:complexType name="java.util.Map">
  <xsd:sequence>
    <xsd:element name="mapentry" minOccurs="0" maxOccurs="unbounded" type="MapEntry" 
      nillable="true"/>
  </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="MapEntry">
  <xsd:sequence>
    <xsd:element name="key" type="xsd:anyType"/>
    <xsd:element name="value" type="xsd:anyType" nillable="true"/>
  </xsd:sequence>
</xsd:complexType>

7) The XML schema definition of a complex Java type can be produced as described above by calling the method writeXMLSchema(Class, Result) of ObjectTransformer.