You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by aj...@apache.org on 2006/07/25 06:38:22 UTC
svn commit: r425274 - in /webservices/axis2/trunk/java/xdocs/latest:
Axis2-rpc-support.html adb/adb-advanced.html adb/adb-howto.html
Author: ajith
Date: Mon Jul 24 21:38:22 2006
New Revision: 425274
URL: http://svn.apache.org/viewvc?rev=425274&view=rev
Log:
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/adb/adb-advanced.html
Modified:
webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html
Added: webservices/axis2/trunk/java/xdocs/latest/Axis2-rpc-support.html
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/xdocs/latest/Axis2-rpc-support.html?rev=425274&view=auto
==============================================================================
--- 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"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Windows (vers 14 February 2006), see www.w3.org" />
+<title>Axis2 RPC Support</title>
+</head>
+<body>
+<h1>Axis2 RPC Support</h1>
+<h2>Introduction</h2>
+<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
+WSDL</h2>
+<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
+example.</p>
+<p>Take the following piece of WSDL</p>
+<pre>
+ .....
+ < message name="requestMessage">
+ <part name="part1" type="xs:string"/>
+ <part name="part2" type="xs:int"/>
+ </message>
+ <message name="responseMessage">
+ <part name="part1" type="xs:string"/>
+ </message>
+ <portType name="echoPortType">
+ <operation name="echo">
+ <input message="y:requestMessage"/>
+ <output message="y:responseMessage"/>
+ </operation>
+ </portType>
+ <binding name="echoBinding" type="y:echoPortType">
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <operation name="echo">
+ <soap:operation soapAction="echo"/>
+ <input>
+ <soap:body use="literal"/>
+ </input>
+ <output>
+ <soap:body use="literal"/>
+ </output>
+ </operation>
+ </binding>
+.....
+
+</pre>
+<p>The binding says its got to be rpc/lit and in this case the
+message parts need wrapping in the following order.</p>
+<ol>
+<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
+WSDL)</li>
+<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>
+</ol>
+<p>For example the input wire message for the echo operation
+mentioned in the above WSDL fragment would look like this</p>
+<pre>
+ <op:<strong>echo</strong> xmlns:op="porttype namespace">
+ <<strong>part1</strong>>Hello World</part1>
+ <<strong>part2</strong>>123</part2>
+ </op:echo>
+</pre>
+<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>
+<pre>
+ <xs:element name="echo">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="part1" type="xs:string" />
+ <xs:element name="part2" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</pre>
+<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>
+<ol>
+<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>
+<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>
+</li>
+</ol>
+<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>
+<pre>
+< element >
+ < complexType >
+ < sequence >
+ < element />
+ < /sequence >
+ < /complexType >
+ < /element >
+
+</pre>
+<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>
+<pre>
+ 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 = i.next();
+ 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());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+</pre>
+<p>The populateClassName looks like this</p>
+<pre>
+ 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);
+ }
+
+ }
+ }
+</pre>
+<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>
+<pre>
+<input>
+ <param name="param4" type="com.example.www.ServiceNameStub.Echo" shorttype="Echo" value="null" location="body" opname="echo">
+ <param name="param5" type="java.lang.String" shorttype="String" value="null" location="body" opname="echo" partname="Part1"
+ primitive="yes"/>
+ <param name="param6" type="int" shorttype="int" value="0" location="body" opname="echo" partname="Part2" primitive="yes"/>
+ </param>
+</input>
+</pre>
+<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
+clear</p>
+<pre>
+ 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;
+}
+</pre>
+<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>
+<h2>Conclusion</h2>
+<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
+all</p>
+<hr />
+</body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/adb/adb-advanced.html
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/xdocs/latest/adb/adb-advanced.html?rev=425274&view=auto
==============================================================================
--- 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 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <title>Advanced Axis2 Databinding Framework Features</title>
+</head>
+
+<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>
+
+<h2>Content</h2>
+<ul>
+ <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>
+</ul>
+
+<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>
+<pre>
+ public static java.lang.Object getTypeObject(
+java.lang.String namespaceURI, java.lang.String typeName,
+javax.xml.stream.XMLStreamReader 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);
+
+}
+</pre>
+<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 class</p>
+<pre>
+if (reader.getAttributeValue(
+ "http://www.w3.org/2001/XMLSchema-instance", "type") != null) {
+ java.lang.String fullTypeName = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
+ "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>
+ }
+ }
+}
+</pre>
+<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>
+<pre>
+ WSDL2Code -uri .... -Emp org.example.web.map
+</pre>
+<p>When the mapping package is not specified it is derived from the targetnamespace of the first schema that is
+encountered</p>
+<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>
+<ol>
+ <li>MyElement.java</li>
+ <li>MyElementHelper.java</li>
+ <li>SOAPStruct.java</li>
+ <li>SOAPStructHelper.java</li>
+</ol>
+<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>
+<pre>
+ WSDL2Code -uri .... -u -Eh
+</pre>
+<h2><a name="more">More Stuff on ADB?</a></h2>
+<ul>
+ <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>
+</ul>
+<hr/>
+</body>
+</html>
Modified: webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/xdocs/latest/adb/adb-howto.html?rev=425274&r1=425273&r2=425274&view=diff
==============================================================================
--- 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 @@
<html>
<head>
<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>
</head>
@@ -159,7 +153,7 @@
of the generation modes .</p>
<ul>
<li><strong>org.apache.axis2.schema.XSD2Java</strong></li>
- <li><strong>org.apache.axis2.wsdl.codegen.extension.SimpleDBExtension</strong></li>
+ <li><strong>org.apache.axis2.schema.ExtensionUtility</strong></li>
</ul>
<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>
+ <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>
+
</tbody>
</table>
<a name="deep"></a>
@@ -289,7 +299,7 @@
element having the passed QName</li>
</ol>
</li>
- <li><pre> public static [Object]
+ <li><pre> public static [Object].Factory.
parse(javax.xml.stream.XMLStreamReader reader)
throws java.lang.Exception </pre>
<p>This method returns a populated instance of the class in question.
@@ -297,7 +307,7 @@
<pre>[Object]</pre>
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(javax.xml.stream.XMLStreamReader 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().
createXMLStreamReader(
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 @@
<ol>
<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>
</ol>
<p><a name="more"></a></p>
<h2>Want to Learn More?</h2>
<ul>
+ <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: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org