Hi Everybody,
  Here is an attempt on the wrapper.  I have created Java2WSDLGenerator interface and impl that wraps up the Axis2 implementation.  This basically crunches the functionality of the Java2WSDLCodeGen, Java2WSDLBuilder and the Java2WSDL implementations of Axis under it.  I have copied / refactored the Axis2 code into this single class that will act as a facade.  From this point onwards, lower down the call trace stack, I have constrained myself  to using Axis2 implementation as is.  From here on I feel that any fix should go into Axis2 codebase itself. 

As far as this wrapper implementation is concerned I have put in another class called TuscanyJava2WSDL.  This class will work with this Java2WSDLGenerator of ours, access the WSDL model and fix the model wherever required.  As a started I have removed the redundant namespaces that used to get generated with the ns0, ns1 and ns2 prefixes.  My find is, that these get generated only during the serialization of the Schema and is not originally a part of the Schema that is generated by the SchemaGenerator class... it seems to be the doing of SchemaSerializer in the ws.commons package.  I have also fixed the "elementFormDefault" attributes.  We could use this class a 'model fixer' at the present moment to go forward with Tuscany.  In due course, as the Axis2 code is fixed we could cut out the fixes implemented in this class.

Coming to the design of this wrapper I am not too comfortable with the design.  For example I would prefer that the Java2WOMBuilder is the class called to generate the WSDL model after the validation of input arguments.  I would prefer that Java2WOMBuilder uses the SchemaGenerator internally.  I could not inherit the Java2WOMBuilder to do this myself because of the way its constructor and instance variables have been implemented.

I guess the best would be to refactor the Axis2 implementation and contribute it back to Axis2.  But then I am clueless about getting a break to do this... an earlier mail that I sent to the dev-team there regard the generation of the namespace has not evoked any reponse. 

So what is the community's take on this... should we go ahead and populate this wrapper with the fixes that we would need to go ahead with our release plans or should we wait to fix up Axis2 implementation and then use it.

Here is the jar of classes that make up the wrapper... I have downloaded the Axis2 Source release as the binary release does not contain Java2WSDL.  Please let me know your opinions on this... thanks.

- Krish

On 4/5/06, Jean-Sebastien Delfino < [EMAIL PROTECTED]> wrote:
Venkata Krishnan wrote:
> Hi
>
> I have been looking into the Java2WSDL tool implementation in Axis.
> The generated WSDL for the Helloworld service seems to be comparable
> with what is there in the samples.   There are some differences
> between the two though.  Also when the targetnamespace is not input
> (i.e. user specified) the resultant wsdl is erroneous.  This is also
> reported by others on the Axis2 Dev. Mailing Lists.  I have attached
> the two wsdls just in case any of you want to take a look.
> (helloworld.wsdl is the one in the Tuscany Samples and
> HelloWorldServiceComponentImpl.wsdl is the AXIS2 generated WSDL).
There are some bugs in the WSDL generated by Axis2:
- Duplicate namespace prefix declarations for
http://www.w3.org/2001/XMLSchema in the generated XSD
- Incorrect elementFormDefault, attributeFormDefault and targetNamespace
attributes on the schema element. IMO they shouldn't have any namespace
prefix, my XSD validator flags them as errors, and I spent half an hour
in the XSD spec and couldn't find evidence that these attributes can
have a prefix... If any XSD expert in the group knows the answer please
jump in and help us decrypt the XSD spec :)
- Missing namespace prefix declaration in the WSDL for your XSD types
namespace...

Do you think you could create JIRA issues in the Axis2 project for these
problems?

>
> I was looking into how we could instrument the generated WSDL model
> (say) for adding additional namespaces, specifying the location
> address for the service, getting rid of some redundant namespaces that
> get generated and then finally correcting the errors.  In the current
> implementation there is no way for the clients (like the Tuscany
> Runtime) to intercept this WSDL generation process and introduce the
> necessary customizations.  For example if the generation process, at
> the highest level was clearly split into
>     - parsing and validation of user inputs
>     - generation of the WSDL Java model from the inputs (java classes
> that model the WSDL)
>     - streaming of the model into an output stream
> with call backs to clients at the end of each phase, then it would be
> cleaner to introduce our customizations.
>
> The current implementation does have this separation of functions but
> then they are all nested level down the class that is available for
> the clients to use which is the Java2WSDL class.  Hence instead of
> using the Java2WSDL class of Axis2 or the class one level below it for
> which there is no public access (the Java2WSDLBuilder), I am
> considering building our own wrapper that will, instead of just
> delegating to Java2WSDL of Axis2, will assemble the funtions provided
> by the various Axis2 classes (such as model generation, model writing)
> providing appropriate interception points for customizations.
>
> Does this make sense?  Are they any other issues that I must watch out
> for in this regard?  Any suggestions / comments on what I intend to do
> with respect to building the wrapper.
>
Yes it makes a lot of sense to me. You're right, Java2WSDL and
JavaWSDLBuilder do not provide the API we need, but the function is more
or less there in the underlying classes. Perhaps you could prototype the
wrapper in Tuscany first, then contribute it to Axis2 and work with them
to get a nice WSDL generation API in place? What do you think?

The code in JavaWSDLBuilder.generateWSDL() is interesting. It actually
takes just a few lines of code to generate a WSDL from Java using the
Axis2 SchemaGenerator and Java2WOMBuilder. Here's a code snippet
inspired from the code in JavaWSDLBuilder, which illustrates this:

            String xsdTargetNamespace=" http://mytypes ";
            String xsdNamespacePrefix="t";
            String serviceName="myService";
            String targetNamespace=" http://myservice";
            String targetNamespacePrefix="s";
            String wsdlPrefix="wsdl";
            Class myServiceInterface=AccountService.class;

            // Generate XML schema types for all the complex types
flowing through the business methods on my service interface
            SchemaGenerator sg = new
SchemaGenerator(myServiceInterface.getClassLoader(),
myServiceInterface.getName(), xsdTargetNamespace, xsdNamespacePrefix);
            XmlSchema schema = sg.generateSchema();

            // Use the Java2WOMBuilder to build a WSDL object model
            WSDLDescription wommodel = new Java2WOMBuilder(
                    sg.getTypeTable (),
                    sg.getMethods(),
                    schema,
                    serviceName,
                    targetNamespace,
                    targetNamespacePrefix).generateWOM();

            // Tweak the generated WSDL model, for example if we just
want a WSDL portType, we can remove the generated bindings and services
            // It would be better to change the Java2WOMBuilder to only
generate the portType in the first place, but this illustrates that you
can work with
            // the generated WSDL model and adjust to look like you want
            wommodel.getBindings().clear();
            wommodel.getServices().clear();

            // Write the WSDL model into a WSDL 1.1 document
            WOMWriter womWriter =
WOMWriterFactory.createWriter(org.apache.wsdl.WSDLConstants.WSDL_1_1);
            womWriter.setdefaultWSDLPrefix(wsdlPrefix);
            womWriter.writeWOM(wommodel, System.out );

I played a little bit with this code today to answer your question about
any other issues to watch out for... and I found a few more issues,
actually more than I wanted :)
- All XSD types are generated in a single namespace, even if you start
with Java classes from different packages.
- Java2WSDL + WSDL2Java do not round-trip at all. If you start from
Java, generate WSDL, then generate Java again, you get very different
results. Going from WSDL to Java and back to WSDL produces invalid XSD
complex types with names containing $ signs.
- I also ran into a confusing situation with method signatures. For
example from a getQuote(String symbol, String currency) method,
Java2WSDL generates a getQuote WSDL operation taking a single
getQuoteRequest element, containing child elements for symbol and
currency. Now if you give that WSDL operation to WSDL2Java again, you'll
end up with a new getQuote(GetQuoteRequest getQuote) method, very
different from the original getQuote method. I'll let you guess what you
get if you then give the generated Java interface to Java2WSDL again :)

I suggest we work with the Axis2 team and open JIRAs for everything we
find rather than trying to work around these issues by tweaking the
generated WSDL object model. I'll create JIRAs for the problems I found
today.

> Ofcourse, I am also aware of and will work on the fact that the java
> annotations in the component implementation should also be leveraged
> from, when generating the WSDL.
>
Yes, we'll need to support Java 5 annotations at some point. I am not
sure we need that right away, we can probably default the namespaces,
WSDL and XSD names from the Java names for now and add annotations
later. What do people in the group think?

> Thanks
> - Krish
--
Jean-Sebastien


Attachment: TuscanyJava2WSDL.jar
Description: application/java-archive

Reply via email to