Axis2/C ADB is a C language binding to the XML schema. ADB object model represents an XML specific to a given schema in a WSDL. You can use the Axis2 codegen tool to generate ADB codes for your WSDL and use that to build and parse your XMLs. The idea is, if you use ADB to build and parse your xmls, it will be really easy to do that and you don’t need to know or understand anything about the schema or the wsdl.

Apache Axis2/C to can be used to send and receive binaries as MTOM, SWA or base64 encoded. But ADB generated code still support to send and receive base64 encoded binaries only. So if you use contract first approach  with Axis2/C (i.e start with the WSDL, then write the service based on that), you have to use base64-encoded (non-optimized) as the binary transferring method. Note that you can use the other methods like MTOM or SWA, if you write the code to build and parse the xmls from AXIOM which is a general model for XML like DOM.

Say you have an element with base64Binary type in your request XML. So the schema for that element would be,

<xs:complexType name="Person">
    <xs:sequence>
        <xs:element name="image" type="xs:base64Binary"/>
        ... <!-- some more elements -->
    </xs:sequence>
</xs:complexType>

After you code generated, you will get the adb_person.h and adb_person.c files with the following function prototypes and the implementations,

        /**
         * Constructor for creating adb_Person_t
         * @param env pointer to environment struct
         * @return newly created adb_Person_t object
         */
        adb_Person_t* AXIS2_CALL
        adb_Person_create(
            const axutil_env_t *env );

        /**
         * Free adb_Person_t object
         * @param  _Person adb_Person_t object to free
         * @param env pointer to environment struct
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
         */
        axis2_status_t AXIS2_CALL
        adb_Person_free (
            adb_Person_t* _Person,
            const axutil_env_t *env);

        /**
         * Getter for image.
         * @param  _Person adb_Person_t object
         * @param env pointer to environment struct
         * @return axutil_base64_binary_t*
         */
        axutil_base64_binary_t* AXIS2_CALL
        adb_Person_get_image(
            adb_Person_t* _Person,
            const axutil_env_t *env);

        /**
         * Setter for image.
         * @param  _Person adb_Person_t object
         * @param env pointer to environment struct
         * @param arg_image axutil_base64_binary_t*
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
         */
        axis2_status_t AXIS2_CALL
        adb_Person_set_image(
            adb_Person_t* _Person,
            const axutil_env_t *env,
            axutil_base64_binary_t*  arg_image);

So you can manipulate the person element in c language using the create, get, set and free function.

    /* here the env is the axutil_env_t* instance - the axis2/c environment */
    FILE *f = fopen("./images/person.png", "r+");
    int binary_count;
    /* binary read a function you may write to read the binary data to the
     variable binary and the count to the variable binary_count */
    unsigned char *binary = binary_read(f, env, &binary_count);
    axutil_base64_binary_t *base64 = axutil_base64_binary_create_with_plain_binary(
                                        env, binary, binary_count);

    adb_Person_t *person = adb_Person_create(env);
    adb_Person_set_image(person, env, base64);

You can set this adb person directly to your request or to a setter of another adb instance to complete the ADB tree. So this way you can send binaries (as base64 encoded) using the Axis2/C ADB generated code.

I have been working for Axis2/C codegen tool for sometime now and I found lot of users who want to edit the codegen templates for a more optimized code specific to their use cases. This is mainly because codegen tool generates a very general code (For an example lot of unused variables generated for some WSDLs, but they are used in some other WSDLs) where as mostly ‘C’ people prefer to be as optimized as possible. Axis2 Java templates are more stable and not needed to customized as much as C templates, but Java developers too may find it is really useful to edit them in a case they need some customizations.

Both Axis2 C and Java tools comes with Axis2/Java project. So you may already have downloaded the latest Axis2/Java release or the Axis2/Java nightly build. As per title you can do this customization not only in the source but also in the binary pack. So I assume you have the binary pack.

Codegen tool mainly comes within two jars inside the lib directory of your Axis2/Java pack. (Here xxxx should be replaced with the particular jar version, it can be 1.4, 1.4.1 or SNAPSHOT)

  • axis2-codegen-xxxx.jar – The core classes of the codegen (This is where WSDL2C and WSDL2Java classes reside)
  • axis2-adb-codegen-xxxx.jar – This is the library containing the adb component of the codegen tool. ADB (Axis2 Data Binding) is the native databinding format of Axis2 which convert your xml schema to a more programmer friendly set of java classes or ‘C’ structures. The XSD2Java class comes in this jar.

Editing the Stub and Skeleton templates

When you unpack the axis2-codegen-xxxx.jar

jar xf axis2-codegen-xxxx.jar

you can find the template for Stub and Skel in org/apache/axis2/wsdl/template/c or org/apache/axis2/wsdl/template/java directories.

  • Stub For C – org/apache/axis2/wsdl/template/c/StubSourceTemplate.xsl (source) and org/apache/axis2/wsdl/template/c/StubHeaderTemplate.xsl (header)
  • Skeleton for C – org/apache/axis2/wsdl/template/c/SkelSourceTemplate.xsl (source) and org/apache/axis2/wsdl/template/c/SkelHeaderTemplate.xsl (header)
  • Stub For Java – org/apache/axis2/wsdl/template/java/InterfaceImplementationTemplate.xsl
  • Skel For Java – org/apache/axis2/wsdl/template/java/MessageReceiverTemplate.xsl (Message Reciever) and org/apache/axis2/wsdl/template/java/SkeletonTemplate.xsl (skeleton)

These templates are written is XSL. Even if you are an XSL expert, you may find little difficult to understand whole lot of codes in there. But if you really know what you need to change, you can track back the lines (may be using comment or some specific static set of code). So you don’t actually need to know any XSL to do these little customizations.

After you do the change simply pack the classes (which are in the ‘org’ directory) as the jar with the same name.

jar cf axis2-codegen-xxxx.jar org

Editing the ADB templates

You can similarly observe the axis2-adb-codegen-xxxx.jar. All the templates are in the org/apache/axis2/schema/template/ directory.

  • C ADB templates – org/apache/axis2/schema/template/CADBBeanTemplateHeader.xsl (Source) and org/apache/axis2/schema/template/CADBBeanTemplateHeader.xsl (Header)
  • Java ADB template – org/apache/axis2/schema/template/ADBBeanTemplate.xsl

You will find the template for the Java classes and C structures there. In C code generation if you find some variables are not used throughout your WSDLs, you can remove directly if from the templates. And some constants which are defined to allocate memory can be changed to suit to your application.

Anyway after all these notes, I have to say it is not really recommended to hack a code specific to your application. If you found a change general to all the applications you better submit the patch to the Axis2 community, so others too can use it. Otherwise whenever you do a upgrade you have to do this again on your own. But I hope these tips may be useful specially when you are working with ADB to do your own experiments.

Building and Traversing XML are regular tasks for any Web Service developer. We may use DOM, AXIOM or even simple String manipulation functions to do that. Normally this takes a lot of time and effort. And if we are coding in ‘C’ it become more tedious as string manipulation in ‘C’ is not that straight forward.

What ADB does is it generates a set of ‘C’ functions specially for our XML Schema to build and traverse the XML.
Say you have the following XML Schema. (You need to have it inside a WSDL to generate the code).

        <xs:schema targetNamespace="http://dimuthu.org/adb/demo/2008/sept">
            <!-- demonstrating element-->
            <xs:element name="myDemo">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="demo1" type="xs:int"/>
                        <xs:element name="demo2" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        <xs:schema/>

For this particular element there will be one adb type (adb_myDemo_t), one source (adb_myDemo.c) and one header (adb_myDemo.h) are generated. Don’t ever look at the source file (unless you want to hack it) just go through the header, it will have all the function you need to manipulate your ADB.

It will have following set of functions,

To create and free the object
  • adb_myDemo_create
  • adb_myDemo_free
Getters and Setters to manipulate Data
  • adb_myDemo_get_demo1
  • adb_myDemo_set_demo1
  • adb_myDemo_get_demo2
  • adb_myDemo_set_demo2
Build and Parse XML
  • adb_myDemo_serialize
  • adb_myDemo_deserialize

First we will check how to build a simple XML using an ADB object.

    adb_myDemo_t *mydemo = adb_myDemo_create(env);
    adb_myDemo_set_demo1(mydemo, env, 3); /* some arbitrary value */
    adb_myDemo_set_demo2(mydemo, env, "some arbitrary string");
    axiom_t *xml = adb_myDemo_serialize(mydemo, env, NULL, NULL, AXIS2_TRUE, NULL, NULL);

So now we have the AXIOM representation of the XML which we just build using ADB.

<ns0:myDemo xmlns:ns0="http://dimuthu.org/adb/demo/2008/sept">
    <ns0:demo1>3</ns0:demo1>
    <ns0:demo2>some arbitrary string</ns0:demo2>
</ns0:myDemo>

Anyway ADB is easier when you want to navigate through an XML. (you can read data randomly as you preferred). Here we starting from the AXIOM representation of our XML.

      adb_myDemo_t *mydemo= adb_myDemo_create( env);
      adb_myDemo_deserialize(mydemo, env, &xml, NULL, AXIS2_FALSE))
      int demo1 = adb_myDemo_get_demo1(mydemo, env);
      printf("My Demo1 is: %d\\n", demo1);
      axis2_char_t *demo2 = adb_myDemo_get_demo2(mydemo, env);
      printf("My Demo2 is: %s\\n", demo2);

I have printed the Data contained in the XML with the help of ADB objects.

In ordre to download the Codegen tool with ADB you have to download the Axis2/Java package.

If you want to learn more about ADB, Just go through more Axis2/C Codegen / ADB resources which I have blogged few weeks ago.

Here are some list of links that you may find useful to start working with Axis2/C ADB Codegen tool.

  1. Building Axis2/C Web Services with the help of Axis2/Java Tools (Tutorial)
  2. Codegen + ADB Samples (SVN)
  3. 20+ Test cases, how different schemas are constructed in ADB/C
  4. Helper tools to generate demo codes for Axis2/C ADB generated code (Blog)
  5. How Axis2/C ADB Codegen support nillable and minOccurs=0 (Blog)
  6. Simple Type List Support (Blog)
  7. Overview of using Axis2/C ADB (Blog)
  8. adb with base64Binary and xmime.xsd – little howto (Mail)
  9. Latest developers discussion on Axis2/C codegen tool (Mail)
  10. Past User inquiries on Axis2/C Adb Codegen tool (Mail)

© 2007 Dimuthu’s Blog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress