axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r425274 - in /webservices/axis2/trunk/java/xdocs/latest: Axis2-rpc-support.html adb/adb-advanced.html adb/adb-howto.html
Date Tue, 25 Jul 2006 04:38:22 GMT
Author: ajith
Date: Mon Jul 24 21:38:22 2006
New Revision: 425274

1. Added a ADB advanced section that explains about the advanced features added to ADB lately
2. Updated some parts of the adb-howto.html
3. Added a new document that explains how the Axis RPC works


Added: webservices/axis2/trunk/java/xdocs/latest/Axis2-rpc-support.html
--- webservices/axis2/trunk/java/xdocs/latest/Axis2-rpc-support.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/Axis2-rpc-support.html Mon Jul 24 21:38:22 2006
@@ -0,0 +1,261 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "">
+<html xmlns="">
+<meta name="generator" content=
+"HTML Tidy for Windows (vers 14 February 2006), see" />
+<title>Axis2 RPC Support</title>
+<h1>Axis2 RPC Support</h1>
+<p>Axis2 RPC support may seem somewhat tricky and confusing at the
+first glance. However Axis2 RPC strategy is based on a well defined
+set of rules and once the details are in place, it becomes clear as
+day. This document aims to drill down to the details of this
+strategy and fills up most of the fairly unknown bits and pieces.
+Note that Axis2 currently does not support the rpc/encoded style
+fully. It's main support is for the rpc/lit style.</p>
+<p>We will discuss the Axis2 RPC strategy in steps</p>
+<h2>Step 1 - Converting RPC style WSDL's into Doc/Lit style
+<p>This is probably the most confusing part of rpc strategy. Since
+the Axis2 code generator is based on pure doc/lit style , the first
+step of the code generation process is to generate a wrapper
+schema. This wrapper generation can be easily explained by using an
+<p>Take the following piece of WSDL</p>
+ .....
+    &lt; message name="requestMessage"&gt;
+                &lt;part name="part1" type="xs:string"/&gt;
+                &lt;part name="part2" type="xs:int"/&gt;
+        &lt;/message&gt;
+        &lt;message name="responseMessage"&gt;
+                &lt;part name="part1" type="xs:string"/&gt;
+        &lt;/message&gt;
+        &lt;portType name="echoPortType"&gt;
+                &lt;operation name="echo"&gt;
+                        &lt;input message="y:requestMessage"/&gt;
+                        &lt;output message="y:responseMessage"/&gt;
+                &lt;/operation&gt;
+        &lt;/portType&gt;
+        &lt;binding name="echoBinding" type="y:echoPortType"&gt;
+                &lt;soap:binding style="rpc" transport=""/&gt;
+                &lt;operation name="echo"&gt;
+                        &lt;soap:operation soapAction="echo"/&gt;
+                        &lt;input&gt;
+                                &lt;soap:body use="literal"/&gt;
+                        &lt;/input&gt;
+                        &lt;output&gt;
+                                &lt;soap:body use="literal"/&gt;
+                        &lt;/output&gt;
+                &lt;/operation&gt;
+        &lt;/binding&gt;
+<p>The binding says its got to be rpc/lit and in this case the
+message parts need wrapping in the following order.</p>
+<li>The first element needs to have the operation name as the local
+name and the operation namespace ( which happens to be the
+namespace of the porttype - in this case the targetnamespace of the
+<li>The children of this element are non namespace qualified
+elements with the part names as local names (refered to as
+<strong>part element</strong>)</li>
+<li>In case the part refers to a standard type like the example
+WSDL, the content of the part element would be of that type. If the
+part refers to a complex type defined in the schema the content of
+the part element becomes of that type. Having an element reference
+in the part when the binding is rpc is invalid.</li>
+<p>For example the input wire message for the echo operation
+mentioned in the above WSDL fragment would look like this</p>
+ &lt;op:<strong>echo</strong> xmlns:op="porttype namespace"&gt;
+  &lt;<strong>part1</strong>&gt;Hello World&lt;/part1&gt;
+  &lt;<strong>part2</strong>&gt;123&lt;/part2&gt;
+ &lt;/op:echo&gt;
+<p>Note the element names in bold. The first one is the operation
+name, the second and third are part names. It can be seen that it
+is quite possible to generate a schema, representing this structure
+and then treat the whole service as pure doc/lit service. In this
+case following is the piece of schema generated to make this rpc to
+doc conversion. Note that in this case the wire message stays
+unchanged. It is only a different WSDL authoring style</p>
+ &lt;xs:element name="echo"&gt;
+    &lt;xs:complexType&gt;
+      &lt;xs:sequence&gt;
+                &lt;xs:element name="part1" type="xs:string" /&gt; 
+                &lt;xs:element name="part2" type="xs:int" /&gt; 
+           &lt;/xs:sequence&gt;    
+    &lt;/xs:complexType&gt;
+ &lt;/xs:element&gt;
+<p>What the Axis2 code generator does is exactly this. By looking
+at the binding style, it generates a wrapper schema in places
+required before handing over the Axis* hierarchy to the code
+generator engine.In every case (even when the schema needs to be
+unwrapped) this wrapping part will take place!</p>
+<h2>Step 2 - Unwrapping the Schema</h2>
+<p>If the schema needs to be unwrapped then that brings up a few
+issues mainly because the only thing that the emitters rely on when
+generating code is a mapping table!</p>
+<li>When the schema is unwrapped where would that unwrapping
+information stay ?
+<p>Good question - It needs to be a store that keeps the
+information seperated. Hmm.. What can we use here ? Why, the Axis *
+hierarchy! it has nicely seperated information holders and a
+parameter store that can hold a information bean</p>
+<li>How do we maintain uniqueness among message part names ?
+<p>Another Good question - part names are only unique across a
+message and not globally. But due to the fact that we have a global
+mapping table we need a way to differentiate between parts of
+different messages. The technique used here is to generate a QName
+that has the operation name as a namespace and a suffix (like
+_input) appended to the local name</p>
+<p>Given these solutions the first step in unwrapping is to walk
+the schema and figure out the unwrappable items. The key player of
+the unwrapping process is the unwrapping extension. What it does is
+to walk a given schema andfigure out the unwrappable parts if there
+are any.</p>
+<p>The current unwrapper looks for the following patterns and fails
+if it is not found!</p>
+&lt; element &gt;
+      &lt; complexType &gt;
+           &lt; sequence &gt;
+               &lt; element /&gt;
+           &lt; /sequence &gt;
+       &lt; /complexType &gt;
+  &lt; /element &gt;
+<p>Once this pattern is detected the unwrapper details will be
+added to the relevant AxisMessage component</p>
+<h2>Step 3 - Populate type information</h2>
+<p>The next step is to populate the type information for the parts.
+This has to be explicitly done by the data binding extensions and
+currently the ADB and XMLbeans extensions populate the relavant
+AxisMessage by looking up their generated type systems. This type
+information goes into the AxisMessage inside a
+MessagePartInformationHolder instance.</p>
+<p>The following code fragement from the ADB extension shows how
+the AxisMessages get populated with the relevant type information.
+The code is almost the same for the XMLBeans extension.Note the
+items in bold</p>
+ if (message.getParameter(Constants.UNWRAPPED_KEY) != null) {
+            XmlSchemaType schemaType = message.getSchemaElement().getSchemaType();
+            if (schemaType instanceof XmlSchemaComplexType) {
+                XmlSchemaComplexType cmplxType = (XmlSchemaComplexType) schemaType;
+                XmlSchemaParticle particle = cmplxType.getParticle();
+                if (particle instanceof XmlSchemaSequence) {
+                    XmlSchemaObjectCollection items =
+                            ((XmlSchemaSequence) particle).getItems();
+                    for (Iterator i = items.getIterator(); i.hasNext();) {
+                        Object item =;
+                        if (item instanceof XmlSchemaElement) {
+                           XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) item;
+                            XmlSchemaType eltSchemaType = xmlSchemaElement.getSchemaType();
+                            if (eltSchemaType != null) {
+                                <strong>populateClassName(eltSchemaType,mapper,opName,xmlSchemaElement.getName());</strong>
+                            } else if (xmlSchemaElement.getSchemaTypeName() != null) {
+                              eltSchemaType = findSchemaType(schemaMap,
+                                       xmlSchemaElement.getSchemaTypeName());
+                              if (eltSchemaType!=null){
+                                 populateClassName(eltSchemaType,mapper,opName,xmlSchemaElement.getName());
+                            }
+                          }
+                      }
+                  }
+              }
+         }
+   }
+<p>The populateClassName looks like this</p>
+ private static void populateClassName(XmlSchemaType eltSchemaType,
+                                          TypeMapper typeMap,
+                                          String opName,
+                                          String partName) {
+        Map metaInfoMap = eltSchemaType.getMetaInfoMap();
+        if (metaInfoMap != null) {
+            <strong>String className = (String) metaInfoMap.
+                    get(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY);
+            QName partQName = WSDLUtil.getPartQName(opName,
+                    WSDLConstants.INPUT_PART_QNAME_SUFFIX,
+                    partName);
+            typeMap.addTypeMappingName(partQName,className);</strong>
+            if (Boolean.TRUE.equals(
+                    metaInfoMap.get(SchemaConstants.
+                            SchemaCompilerInfoHolder.CLASSNAME_PRIMITVE_KEY))){
+                //this type is primitive - add that to the type mapper status
+                //for now lets add a boolean
+                typeMap.addTypeMappingStatus(partQName,Boolean.TRUE);
+            }
+        }
+    }
+<h2>Step 4 - Generate code with unwrapped parameters</h2>
+<p>The next step is generating the actual code. The
+AxisServiceBasedMultiLanguageEmitter has a method that generates
+the XML model for the input parameters and that method includes the
+relevant part parameters inside the relavant top level input
+parameter element</p>
+<p>The relevant part of the XML model looks like this. Note that
+this intermediate XML model is the one that is parsed against the
+Stylesheets to generate the code</p>
+ &lt;param name="param4" type="com.example.www.ServiceNameStub.Echo" shorttype="Echo"
value="null" location="body" opname="echo"&gt;
+        &lt;param name="param5" type="java.lang.String" shorttype="String" value="null"
location="body" opname="echo" partname="Part1" 
+        &lt;param name="param6" type="int" shorttype="int" value="0" location="body"
opname="echo" partname="Part2" primitive="yes"/&gt;
+  &lt;/param&gt;
+<p>The next part is upto the template to handle. Basically the
+template looks after the generation of multiple parameters into the
+method signatures and the then the generating of the relavant
+serialization and deserialization code for the parameters!</p>
+<h2>Bringing the Parameters Together and Exploding Them</h2>
+<p>This is a somewhat contraversial area. The current Axis2 code
+generator does the wapping and unwrapping at the object level and
+not the XML level. In short the exploded parameters are only a
+conveneince and the that explosion does not run down to the XML
+level. The following example of generated source code makes this
+ private org.apache.axiom.soap.SOAPEnvelope toEnvelope(
+        org.apache.axiom.soap.SOAPFactory factory, java.lang.String param1,
+        int param2, boolean optimizeContent) {
+        <strong>com.example.www.ServiceNameStub.Echo wrappedType = new com.example.www.ServiceNameStub.Echo();
+        wrappedType.setPart1(param1);
+        wrappedType.setPart2(param2);</strong>
+        rg.apache.axiom.soap.SOAPEnvelope emptyEnvelope = factory.getDefaultEnvelope();
+        emptyEnvelope.getBody().addChild(wrappedType.getOMElement(
+                        com.example.www.ServiceNameStub.Echo.MY_QNAME, factory));
+        return emptyEnvelope;
+<p>Note the lines in bold. The wrapped class will anyway be
+instantiated and used at the end but what the user sees is
+different. Exploding the parameters happens in a similar way!</p>
+<p>Axis2 RPC support is a sort of misty area but it is based on a
+well defined set of rules. It is not <em>that</em> misty after
+<hr />

Added: webservices/axis2/trunk/java/xdocs/latest/adb/adb-advanced.html
--- webservices/axis2/trunk/java/xdocs/latest/adb/adb-advanced.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/adb/adb-advanced.html Mon Jul 24 21:38:22 2006
@@ -0,0 +1,105 @@
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Advanced Axis2 Databinding Framework Features</title>
+<body lang="en">
+<h1>Advanced Axis2 Databinding Framework features</h1>
+<p>The aim of this section is provide an insight into the newly added 
+ advanced features of ADB.</p>
+  <li><a href="#typeSupport">xsi:type Support</a></li>
+  <li><a href="#helper">Helpergen Mode</a></li>
+  <li><a href="#more">More Stuff on ADB?</a></li>
+<h2><a name="typeSupport">xsi:type Support</a></h2>
+<p>This is implemented by adding a extension maping class. The code that calls the
extension mapper is generated inside the
+deserialization method of the beans and gets active when the xsi:type attribute is present.
The following
+code fragment shows how the generated type mapper looks like</p>
+ public static java.lang.Object getTypeObject(
+java.lang.String namespaceURI, java.lang.String typeName, reader) throws java.lang.Exception {
+if ("http://new.webservice.namespace/types".equals(namespaceURI) &&
+		"derivedType2".equals(typeName)) {
+	return namespace.webservice._new.types.DerivedType2Helper.parse(reader);
+	return namespace.webservice._new.types.BaseTypeHelper.parse(reader);
+} else if ("http://new.webservice.namespace/types".equals(namespaceURI) &&
+		"derivedType1".equals(typeName)) {
+	return namespace.webservice._new.types.DerivedType1Helper.parse(reader);
+throw new java.lang.RuntimeException("Unsupported type " +
+	namespaceURI + " " + typeName);
+<p>Inside every deserialize method, the extension mapper gets called when a xsi:type
+attribute is encountered <strong>and</strong> that type is not the type that
is being parsed </p>
+<p>The following code fragment shows how the ADB deserialize method calls the mapper
+if (reader.getAttributeValue(
+			"", "type") != null) {
+	java.lang.String fullTypeName = reader.getAttributeValue("",
+			"type");
+	if (fullTypeName != null) {
+		java.lang.String nsPrefix = fullTypeName.substring(0,fullTypeName.indexOf(":"));
+		nsPrefix = (nsPrefix == null) ? "" : nsPrefix;
+		java.lang.String type = fullTypeName.substring(fullTypeName.indexOf(":") + 1);
+		if (!"derivedType2".equals(type)) {
+			//find namespace for the prefix
+			java.lang.String nsUri = reader.getNamespaceContext().getNamespaceURI(nsPrefix);
+			<strong>return (DerivedType2) namespace.webservice._new.types.ExtensionMapper.getTypeObject(nsUri,
+				type, reader);</strong>
+		}
+	}
+<p>This should make the xsi:type based deserialization possible and should result in
proper xsi:type based
+serializations at runtime</p>
+<p>This is automatically done but the package name for the mapper class can be controlled
by using the <strong>mp</strong>
+flag (with a preceding -E)</p>
+ WSDL2Code -uri .... -Emp
+<p>When the mapping package is not specified it is derived from the targetnamespace
of the first schema that is
+<h2><a name="helper">Helper mode</a></h2>
+<p>Helper mode is a fairly new feature. In the helper mode, the beans are plain Java
beans and all the 
+deserialization/serialization code is moved to a helper class. For example the simple schema
mentioned in 
+the ADB-howto document will yield four classes for the two that has been previously seen</p>
+  <li></li>
+  <li></li>
+  <li></li>
+  <li></li>
+<p>The helpers basically contain all the code that went into the ADBBeans. Hence the
beans in the helper mode are 
+pretty much readable than the rest. Also note that the helper mode is available only if you
are in the unpacked mode.
+The code generator by default does not expand the classes</p>
+<p>Helper mode can be switched on by the <strong>h</strong> flag (Passed
with a -E infront to indicate that it is an 
+extra switch undertood by ADB). Also the <strong>-u</strong> flag should be present
to indicate the unpacking</p>
+ WSDL2Code -uri .... -u -Eh
+<h2><a name="more">More Stuff on ADB?</a></h2>
+  <li><a href="adb-tweaking.html">Tweaking the ADB Code Generator</a>-
+    explains available mechanisms to extend ADB and possibly adopt it to
+    compile schemas to support other languages.</li>
+  <li><a href="adb-codegen-integration.html">ADB and Axis2 Integration</a>
+    explains how the ADB schema compiler was attached to the Axis2
+  framework</li>

Modified: webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html
--- webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html (original)
+++ webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html Mon Jul 24 21:38:22 2006
@@ -1,12 +1,6 @@
   <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-  <meta content="">
-  <meta content="">
-  <meta content="">
-  <meta content="">
-  <meta content="">
-  <meta content="">
   <title>ADB  - Howto</title>
@@ -159,7 +153,7 @@
 of the generation modes .</p>
-  <li><strong>org.apache.axis2.wsdl.codegen.extension.SimpleDBExtension</strong></li>
+  <li><strong>org.apache.axis2.schema.ExtensionUtility</strong></li>
 <a name="gen_modes"></a>
@@ -212,6 +206,22 @@
         is on then a single class (with adb added to the end of the specified
         package) will be generated. The default is off.</td>
+    <tr>
+      <td>mapperClassPackage</td>
+      <td>The package name for the mapper class. Please see the advanced section for
+      details of the mapper class</td>
+    </tr>
+     <tr>
+      <td>helperMode</td>
+      <td>The switch that determines whether to switch to helper mode or not. 
+      Please see the advanced section for details of the helper mode</td>
+    </tr>
+     <tr>
+      <td>ns2PackageMap</td>
+      <td>A map that stores the namespace name against the package name
+      These details are used to override the default packages</td>
+    </tr>
 <a name="deep"></a>
@@ -289,7 +299,7 @@
         element having the passed QName</li>
-  <li><pre> public static [Object] 
+  <li><pre> public static [Object].Factory. 
              parse( reader) 
              throws java.lang.Exception </pre>
     <p>This method returns a populated instance of the class in question.
@@ -297,7 +307,7 @@
     will be replaced by the actual class that contains this method. Say for
     SOAPStruct the method looks like
-    <pre>public static SOAPStruct 
+    <pre>public static SOAPStruct.Factory. 
                 parse( reader) 
                 throws java.lang.Exception</pre>
     <p>Also note that the above parse method is available in the
@@ -323,7 +333,7 @@
 <pre>XMLStreamReader reader = XMLInputFactory.newInstance().
                                         new ByteArrayInputStream(xmlString.getBytes()));
-MyElement elt = MyElement.parse(reader);</pre>
+MyElement elt = MyElement.Factory.parse(reader);</pre>
 <p>Although this example takes on the tedious effort of creating a reader out
 of the String, inside the Axis2 environment an XMLStreamReader can be
@@ -350,14 +360,14 @@
   <li>Complex Extensions and Restrictions, Simple Extensions and Restrictions
     are not supported.</li>
-  <li>xsi:type based deserialization is not supported. Hence extension based
-    structures that use xsi:type attribute may fail</li>
 <p><a name="more"></a></p>
 <h2>Want to Learn More?</h2>
+ <li><a href="adb-advanced.html">Advanced features of the ADB code generator</a>-
+    explains xsi:type based desrialization and helper mode</li>
   <li><a href="adb-tweaking.html">Tweaking the ADB Code Generator</a>-
     explains available mechanisms to extend ADB and possibly adopt it to
     compile schemas to support other languages.</li>

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message