Monday 6 March 2017

Annotations of JAXB classes using Annox for Polymorphism


Introduction

I'm using a version 1.99 version of Jackson, which is a JSON binding framework that comes with JBOSS EAP server. I have come across this use cases that I have JSON Rest services for which I want to use PolyMorphism. By default, this isn't possible with JSON. You need to annotate your generated classes to get Polymorphism. For my project, we are using JAXB databindings, and luckily, Jackson can consume JAXB annotations as well.

Scope

I will demonstrate how I got Polymorphism to work with JAXB and JACKSON.

Schema


 <?xml version="1.0" encoding="UTF-8"?>  
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  
      targetNamespace="http://www.example.org/NewXMLSchema" xmlns:tns="http://www.example.org/NewXMLSchema"  
      xmlns:annox="http://annox.dev.java.net" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"  
      elementFormDefault="qualified" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"  
      jaxb:version="1.0" jaxb:extensionBindingPrefixes="xjc annox">  
      <xs:element name="Holder">  
           <xs:complexType>  
                <xs:sequence>  
                     <xs:element ref="tns:myParent" minOccurs="0" maxOccurs="unbounded">  
                     </xs:element>  
                </xs:sequence>  
           </xs:complexType>  
      </xs:element>  
      <xs:element name="myParent" type="tns:Parent">  
      </xs:element>  
      <xs:complexType name="Parent" abstract="true">  
           <xs:sequence>  
                <xs:element name="surname" type="xs:string"></xs:element>  
           </xs:sequence>  
      </xs:complexType>  
      <xs:element name="Child">  
           <xs:complexType>  
                <xs:complexContent>  
                     <xs:extension base="tns:Parent">  
                          <xs:sequence>  
                               <xs:element name="Firstname"></xs:element>  
                          </xs:sequence>  
                     </xs:extension>  
                </xs:complexContent>  
           </xs:complexType>  
      </xs:element>  
      <xs:element name="Child2">  
           <xs:complexType>  
                <xs:complexContent>  
                     <xs:extension base="tns:Parent">  
                          <xs:sequence>  
                               <xs:element name="secondChild"></xs:element>  
                          </xs:sequence>  
                     </xs:extension>  
                </xs:complexContent>  
           </xs:complexType>  
      </xs:element>  
 </xs:schema>   




1:  <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"  
2:     xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"  
3:     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:annox="http://annox.dev.java.net"  
4:     xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"  
5:     jaxb:extensionBindingPrefixes="xjc annox" version="2.1">  
6:     <jaxb:bindings schemaLocation="NewXMLSchema.xsd" node="/xs:schema">  
7:        <jaxb:bindings  
8:           node="//xs:element[@name='Holder']/xs:complexType/xs:sequence/xs:element">  
9:           <annox:annotate target="field">  
10:              <annox:annotate annox:class="javax.xml.bind.annotation.XmlElements"  
11:                 value="false">  
12:                 <annox:annotate annox:field="value">  
13:                    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement"  
14:                       type="Child" name="child1"/>  
15:               <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement"  
16:                       type="Child2" name="child2"/>  
17:                 </annox:annotate>  
18:              </annox:annotate>  
19:           </annox:annotate>  
20:        </jaxb:bindings>  
21:     </jaxb:bindings>  
22:  </jaxb:bindings>  

Test Classes

1:  package com.fasterxml.jackson.module.jaxb.types;  
2:    
3:  import java.util.ArrayList;  
4:  import java.util.Arrays;  
5:  import java.util.List;  
6:    
7:  import javax.xml.bind.annotation.XmlElement;  
8:  import javax.xml.bind.annotation.XmlElementRef;  
9:  import javax.xml.bind.annotation.XmlElementRefs;  
10:  import javax.xml.bind.annotation.XmlElements;  
11:    
12:  import com.fasterxml.jackson.databind.ObjectMapper;  
13:    
14:  import za.co.telkom.scap.schema.customer.Child;  
15:  import za.co.telkom.scap.schema.customer.Child2;  
16:  import za.co.telkom.scap.schema.customer.Holder;  
17:    
18:    
19:  /**  
20:     * And then a test for collection types  
21:     */  
22:     public void testNewList() throws Exception  
23:     {  
24:       ObjectMapper mapper = getJaxbAndJacksonMapper();  
25:         
26:       Holder holder=new Holder();  
27:        
28:       Child2 chil2=new Child2();  
29:       chil2.setSecondChild("22");  
30:       chil2.setSurname("Pillay");  
31:         
32:       Child child=new Child();  
33:       child.setFirstname("First");  
34:       child.setSurname("Poolay");  
35:       holder.getMyParent().add(chil2);  
36:       holder.getMyParent().add(child);  
37:        
38:        
39:       String str = mapper.writeValueAsString(holder);  
40:       System.out.println(str);  
41:         
42:       // Let's assume it's ok, and try deserialize right away:       
43:       Holder result = mapper.readValue(str, Holder.class);  
44:         
45:         
46:       assertNotNull(result.getMyParent());  
47:       assertEquals(2, result.getMyParent().size());  
48:         
49:      assertTrue(result.getMyParent().get(0) instanceof Child2);  
50:        
51:      assertTrue(result.getMyParent().get(1) instanceof Child);  
52:        
53:         
54:     }  
55:    

1:  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
2:     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
3:     <modelVersion>4.0.0</modelVersion>  
4:     <artifactId>myschema</artifactId>  
5:     <groupId>za.co.test</groupId>  
6:     <version>0.1-SNAPSHOT</version>  
7:     <name>Library-Schema</name>  
8:     <description>Schema with objects for common</description>  
9:    
10:    
11:     <properties>  
12:        <version.compiler.plugin>2.3.1</version.compiler.plugin>  
13:        <maven.compiler.target>1.7</maven.compiler.target>  
14:        <maven.compiler.source>1.7</maven.compiler.source>  
15:     </properties>  
16:    
17:     <dependencies>  
18:        <dependency>  
19:           <groupId>com.fasterxml.jackson.core</groupId>  
20:           <artifactId>jackson-databind</artifactId>  
21:           <version>2.7.1-1</version>  
22:        </dependency>  
23:        <dependency>  
24:           <groupId>org.apache.cxf.xjc-utils</groupId>  
25:           <artifactId>cxf-xjc-runtime</artifactId>  
26:           <version>3.0.5</version>  
27:        </dependency>  
28:     </dependencies>  
29:     <build>  
30:        <plugins>  
31:           <!-- Maven compiler plugin -->  
32:           <plugin>  
33:              <groupId>org.apache.maven.plugins</groupId>  
34:              <artifactId>maven-compiler-plugin</artifactId>  
35:              <configuration>  
36:                 <source>${maven.compiler.source}</source>  
37:                 <target>${maven.compiler.target}</target>  
38:              </configuration>  
39:           </plugin>  
40:           <plugin>  
41:              <groupId>org.apache.cxf</groupId>  
42:              <artifactId>cxf-xjc-plugin</artifactId>  
43:              <version>3.1.0</version>  
44:    
45:              <dependencies>  
46:                 <dependency>  
47:                    <groupId>org.jvnet.jaxb2_commons</groupId>  
48:                    <artifactId>jaxb2-basics-annotate</artifactId>  
49:                    <version>1.0.2</version>  
50:                 </dependency>  
51:              </dependencies>  
52:              <executions>  
53:    
54:                 <execution>  
55:                    <id>generate-xsd-sources</id>  
56:                    <phase>generate-sources</phase>  
57:                    <goals>  
58:                       <goal>xsdtojava</goal>  
59:                    </goals>  
60:                    <configuration>  
61:                       <sourceRoot>${basedir}/target/generated-sources/cxf</sourceRoot>  
62:                       <extensions>  
63:                          <extension>org.jvnet.jaxb2_commons:jaxb2-basics-annotate:1.0.2</extension>  
64:                       </extensions>  
65:                       <xsdOptions>  
66:                          <xsdOption>  
67:                             <xsd>${basedir}/src/main/resources/NewXMLSchema.xsd</xsd>  
68:                             <packagename>za.co.test.schema.customer</packagename>  
69:                             <bindingFile>${basedir}/src/main/resources/jaxb-bindings.xjb</bindingFile>  
70:                             <extension>true</extension>  
71:                             <extensionArgs>  
72:                                <extensionArg>-Xannotate</extensionArg>  
73:                             </extensionArgs>  
74:                          </xsdOption>  
75:                       </xsdOptions>  
76:                    </configuration>  
77:                 </execution>  
78:              </executions>  
79:           </plugin>  
80:    
81:        </plugins>  
82:     </build>  
83:    
84:  </project>  

No comments:

Post a Comment