Data Contracts, XSDs and Redundant List Wrappers – XEW Plugin to rescue


In Service Oriented Architecture (SOA) or MicroServices Architecture, data is exchanged between different components over the network.

Keeping in mind the INTEROPERABILITY, Data Contracts are created and shared.

Contracts either in the form of WSDL or XSDs etc are mutually agreed between the components to exchange the Structured data among them.

As part of these contracts, you may have a need to send a collection of similar data and for this purpose you may have defined different complexTypes in your xsd.

This article talks about problem associated with defining List Complex Types, how can we overcome this problem using XEW Plugin and the benefits.

Consider you want to exchange a list of AirSegments under an Itinerary like:


    

        

            
AC
            
12
        

        

            
AC
            
13
        

        

            
AC
            
189
        

    

 

To accomplish this, you will define Something like below:

<xs:complexType name="OriginDestinationBookedType">
    
 <xs:element name="AirSegmentBookedList" type="SegmentBookedListType"/>
    
  


<xs:complexType name="SegmentBookedListType">
    
 <xs:element maxOccurs="unbounded" name="AirSegmentBooked" type="SegmentBookedType"/>
    
  


  <xs:complexType name="SegmentBookedType">
    
      <xs:element name="CarrierCode" type="CarrierCodeType"/>
      <xs:element name="FlightNumber" type="FlightNumberType"/>
    
  

This looks good. Looks Good until we generate the Proxy classes out of these Contracts. Give it a try to generate the classes out of these XSDs using Plugins: JAXB-MAVEN, CXF etc.

You will notice that 3 proxy classes get generated.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OriginDestinationBookedType", propOrder = {
"segmentBookedList"
})
public class OriginDestinationBookedType {
@XmlElement(name = "SegmentBookedList", required = true)
protected SegmentBookedListType segmentBookedList;
public SegmentBookedListType getSegmentBookedList() {
return segmentBookedList;
}
public void setSegmentBookedList(SegmentBookedListType value) {
this.segmentBookedList = value;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SegmentBookedListType", propOrder = {
"segmentBookeds"
})
public class SegmentBookedListType {
@XmlElement(name = "SegmentBooked", required = true)
protected List segmentBookeds;
public List getSegmentBookeds() {
if (segmentBookeds == null) {
segmentBookeds = new ArrayList();
}
return this.segmentBookeds;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SegmentBookedType", propOrder = {
"carrierCode",
"flightNumber"
})
public class SegmentBookedType {
@XmlElement(name = "CarrierCode", required = true)
protected String carrierCode;
@XmlElement(name = "FlightNumber", required = true)
protected String flightNumber;
}

With the above classes, if you want to get an access to a Segment within an OD, you will have to write:

OriginDestinationBookedType od; // Initialized properly and you have a non-null reference
od.getSegmentBookedList().getSegmentBookeds().get(segIndex);

Bold part above is redundant and not needed for sure. Instead, we want to have:

od.getSegmentBookeds().get(segIndex);

How can we directly get a list of segments under an OD?

Solution
Integrate XEW Plugin into your repository and get it executed during Code generation phase.
Simply,

 

        org.jvnet.jaxb2.maven2
        maven-jaxb2-plugin
        0.13.1
        
            
                org.jvnet.jaxb2_commons
                jaxb2-basics
                0.6.3
            
        
        
            
                air-ticket-schema
                
                      generate
                
                
                    true
                    
                        -Xannotate
                        -Xxew
                        -Xxew:control ${basedir}/src/main/resources/xsds/xewInclusionExclusion.txt
                    
                    
                        
                            org.jvnet.jaxb2_commons
                            jaxb2-basics-annotate
                            1.0.2
                        
                        
                            com.github.jaxb-xew-plugin
                            jaxb-xew-plugin
                            1.9
                        
                        
                            com.sun.xml.bind
                            jaxb-xjc
                            2.2.11
                        
                    
                    
                        -Djavax.xml.accessExternalSchema=all
                    
                    ${basedir}/src/main/resources/xsds
                    
                        yourXSDsHere.xsd
                    
                    ${basedir}/target/generated-sources
                    ${basedir}/src/main/resources/xsds
                    
                        bindings.xjb
                    
                      false
                      false
                      true
                
              
        
    

 

With the above configuration, only 2 classes will be generated.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OriginDestinationBookedType", propOrder = {
"segmentBookedList"
})
public class OriginDestinationBookedType {
@XmlElement(name = "SegmentBookedList", required = true)
protected List segmentBookedList;
public List getSegmentBookedList() {
return segmentBookedList;
}
public void setSegmentBookedList(List value) {
this.segmentBookedList = value;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SegmentBookedType", propOrder = {
"carrierCode",
"flightNumber"
})
public class SegmentBookedType {
@XmlElement(name = "CarrierCode", required = true)
protected String carrierCode;
@XmlElement(name = "FlightNumber", required = true)
protected String flightNumber;
}

And you are all set. No cursing on XSDs 🙂

ADVANTAGES

    No more List wrapper classes.No more additional clumsy code
    No redundant Null checks
    More readability
    Less Machine Instructions to execute
    Less Memory Footprint of Virtual Functions Table
    More maintainability


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s