Thursday, June 10, 2010

WSDL Parser

Since I am not a monkey (well, I am, but with some value added),
I don't like to type what I can generate.

It happens often to have to generate the same kind of artifacts for each operation in a WSDL.
It becomes then very important to be able to parse the WSLD and find out all its components.

Good candidates containing a WSDLDocument class are:
C:\bea11\oracle_common\modules\oracle.webservices_11.1.1\orawsdl.jar
C:\bea11\Oracle_OSB11\lib\modules\com.bea.alsb.resources.wsdl.jar
C:\bea11\Oracle_OSB11\lib\modules\com.bea.alsb.ws.schemas.wsdl.jar

Also

C:\bea11\jdk160_18\lib\tools.jar
or C:\bea11\jrockit_160_17_R28.0.0-679\lib\tools.jar
C:\bea11\modules\glassfish.jaxws.tools_1.0.0.0_2-1-5.jar
C:\bea11\oepe_11gR1PS2\plugins\org.apache.wsil4j_1.0.0.v200901211807.jar
C:\bea11\oepe_11gR1PS2\plugins\org.eclipse.wst.wsdl.validation_1.1.402.v200911251542.jar
C:\bea11\oepe_11gR1PS2\plugins\org.eclipse.wst.wsi_1.0.305.v200902181431.jar
C:\bea11\oracle_common\modules\oracle.webservices_11.1.1\oracle.webservices.standalone.client.jar

C:\bea11\oracle_common\modules\sun.tools_1.6.0.jar
C:\bea11\Oracle_OSB11\lib\sb-kernel-resources.jar


I have tried some of them but could not make them work.


This http://oracled.wordpress.com/2009/02/04/parse-wsdl-effectively/ gives some clues.

Oracle WSDL parser: you get it by installing JDeveloper, it's in C:\beajdev11\jdeveloper\webservices\lib\wsdl.jar

Apache Woden http://ws.apache.org/woden/userguide.html

JWSDL http://wsdl4j.sourceforge.net/


Javadoc of Oracle WSDL parser is at
http://download-uk.oracle.com/docs/cd/A97688_16/generic.903/q20234/index.html


Using the Oracle WSDL parser, I get a


Exception in thread "Main Thread" oracle.wsdl.internal.WSDLException: oracle.xml.parser.v2.XMLParseException: Start of root element expected.
    at oracle.wsdl.WSDLDocument.getDefinitions(WSDLDocument.java:105)
    at com.acme.wsdl.WSDLParser.execute(WSDLParser.java:21)
    at com.acme.wsdl.WSDLParser.main(WSDLParser.java:16)


I give up.

I try Woden and I get:

WSDLException: faultCode=INVALID_WSDL: Fatal WSDL error:
0:0,WSDL501,Expected a "{http://www.w3.org/ns/wsdl}description" element, but found a "{http://schemas.xmlsoap.org/wsdl/}definitions" element instead.:


Googling around I discover that this means that my WSDL is a 1.1 while Woden processes only 2.0.

You can find here http://www.w3.org/2006/02/wsdl11to20.xsl a XSL converter from 1.1 to 2.0
Once converted 1.1 into 2.0 format, Woden manages to parse the WSDL but I get a warning:

The targetNamespace 'http://www.acme.com/NGP3Geo/2010/06/10/GeoOsbService' is not dereferencable.

which means (I think) that a URL connection open to retrieve the resource http://www.acme.com/NGP3Geo/2010/06/10/GeoOsbService gets a "connection refused" (to dereference= to access).

This is a piece of code to print all operations declared in a WSDL:


package com.acme.wsdl;

import org.apache.woden.WSDLException;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.xml.BindingElement;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.apache.woden.wsdl20.xml.InterfaceElement;
import org.apache.woden.wsdl20.xml.InterfaceOperationElement;
import org.apache.woden.wsdl20.xml.ServiceElement;



public class WSDLParserApache {
public static void main(String[] args) throws WSDLException {
    WSDLParserApache wsdlParserApache = new WSDLParserApache();
     wsdlParserApache.execute();
}

public void execute() throws WSDLException {

String filename1 = "C:/bea11/user_projects/workshops/default/GEO_OSB_Portal/WSDL/GEOOSBService20.WSDL";

WSDLFactory factory = WSDLFactory.newInstance();

WSDLReader reader = factory.newWSDLReader();

reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);

String wsdlurl = filename1;

DescriptionElement descElem = (DescriptionElement) reader.readWSDL(wsdlurl);

InterfaceElement[] interfaces = descElem.getInterfaceElements();

// getting all operations
for (InterfaceElement iface : interfaces) {
   for (InterfaceOperationElement ioe : iface.getInterfaceOperationElements()) {
       System.out.println(ioe.getName().getLocalPart());
   }
}

}
}

2 comments:

WebSphere Guy said...

Hi,

Thanks for your sharing on how to get operations using woden.

Do you know how to get the arguments / parameters for the operations given that the xsd schema for the wsdl is imported?
e.g.

Pierluigi Vernetto said...

I am sorry WG, I have tried retrieving info about parameter names and types but I could not figure out how to do it... there is a promising getInterfaceMessageReferenceElements() retrieving a InterfaceMessageReferenceElement[] but then who knows...