Tuesday, April 29, 2014

Understanding generated code from WSDL to Apex Tool

We all have generated Apex code from WSDL in Salesforce.com. But there are alot of limitations in the xml parser and code generator. Out of these the biggest is the XSD extensions. If your wsdl Schema has xsd extensions then the Apex generator simply ignores it. As a result the code generated is incapable of handling the  response payload or send the correct request.

This can be a big challenge if the request and response xmls are complex. The only way out of this is looking at the xmls and writing the apex code your self. This can be challenging if we really dont understand the generated code properly.

Here in my blog I am giving a shot at it and trying to explain various components of the generated code. So that we can write our own code if the need be.

For example if your response/request xml looks something like this

<RetrieveIndustriesResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="<schema>" xmlns="<ur schema>" xsi:schemaLocation="..../XSD/iagiaa_v2.xsd">
<industry>
<dynamicProperties>
<kind>&lt;B&gt;Classification Information&lt;/B&gt;</kind>
<conformanceType>text</conformanceType>
</dynamicProperties>
<dynamicProperties>
<kind>Primary Activities</kind>
<conformanceType>text</conformanceType>
<theValue>This class consists of units mainly </theValue>
</dynamicProperties>
<dynamicProperties>
<kind>Exclusions</kind>
<conformanceType>text</conformanceType>
<theValue>Units mainly engaged in</theValue>
</dynamicProperties>
<description>Other Takeaway Food Retailing (not part of Restaurant)</description>
<industryCode>4512C</industryCode>
</industry>
</RetrieveIndustriesResponse>

and if the DynamicProperties is an extension then in the generated apex code for the xsd this property will be ignored and you will have to write it on your own.

The final code will look something like this.


public class Industry {
        public list<IAGSOAPstub.dynamicProperty> dynamicProperties;
        public string description;
        public String industryCode;
        private String[] dynamicProperties_type_info = new String[]{'dynamicProperties','http://www.iag.co.nz/soa/iagiaa/v2',null,'0','-1','false'};
        private String[] description_type_info = new String[]{'description','http://www.iag.co.nz/soa/iagiaa/v2',null,'0','1','true'};
        private String[] industryCode_type_info = new String[]{'industryCode','http://www.iag.co.nz/soa/iagiaa/v2',null,'0','1','true'};
        private String[] apex_schema_type_info = new String[]{'http://www.iag.co.nz/soa/iagiaa/v2','true','false'};
        private String[] field_order_type_info = new String[]{'dynamicProperties','description','industryCode'};
    }
    public class dynamicProperty {
        public String kind;
        public String description;
        public String conformanceType;
        public String theValue;
        private String[] kind_type_info = new String[]{'kind',<Schema URL>',null,'0','1','false'};
        private String[] description_type_info = new String[]{'description','<Schema URL>',null,'0','1','false'};
        private String[] conformanceType_type_info = new String[]{'conformanceType','<Schema URL>',null,'0','1','false'};
        private String[] theValue_type_info = new String[]{'theValue','<Schema URL>',null,'0','1','false'};
        private String[] apex_schema_type_info = new String[]{'<Schema URL>','true','false'};
        private String[] field_order_type_info = new String[]{'kind','description','<Schema URL>','theValue'};
        
    }
   
    public class RetrieveIndustriesResponseType {
        public IAGSOAPstub.Industry[] industry;
        private String[] industry_type_info = new String[]{'industry','<Schema URL>',null,'1','-1','false'};
        private String[] apex_schema_type_info = new String[]{'<Schema URL>','true','false'};
        private String[] field_order_type_info = new String[]{'industry'};
    }




The public variables are nothing but the actual xml elements or nodes or attribute. For each node/attribute there will be one public variable. It can either be primitive datatype or object of some other class which represents another complex type in xsd. 
If the variable represents another XML element or a text node, then there needs to be a matching _type_info String[] e.g. bar_type_info. 
The elements of this array are: 1. XML element name 2. Schema 3. XML type 4. minOccurs 5. maxOccurs (set to '-1' for unbounded) 6. isNillable
If the variable represents an attribute, then there must be a matching _att_info String[] e.g. a_type_info. Thise simply contains the XML name of the attribute.
Note that if an class variable name is a reserved word, then _x is appended to it e.g. bar_x. This would affect the other variables names: bar_x_type_info. The Apex Developer's Guide explains their rules for names, but if you are manually creating it, I think you can give it whatever name you want--the arrays determine the XML element name...
The apex_schema_type_info array specifies information about the XML element represented by the class: 1. Schema 2. 'true' if elementFormDefault="qualified" 3. 'true' if attributeFormDefault="qualified"
field_order_type_info simply specifies the order of the child elements.

1 comment: