[MOBY-dev] I am a believer...

Dmitry Repchevsky dmitry.repchevski at bsc.es
Mon Mar 3 16:20:18 UTC 2008


Hello everybody!

I'd like to continue to discuss (even in a monologue mode :-)) 
document/literal encoding.
I have prepared an example how it would be implemented in JMoby (!).
It demands a few changes in MoSeS generator to implement it.
Unfortunately, because JMoby is not JAXB based, ;-), there is no 
possibility to generate the WSDL automatically (JAX-WS), so one must be 
generated somehow (by the MoSeS).
I'm using JBoss 4.2.2 with JBoss WS-3.0 (METRO). Unfortunately it 
doesn't deploy Provider Based JAX-WS endpoints, so I use ejb3 as an 
example...

Here is the complete example:

The class that implements a "proxy" between a JAX-WS Provider and JMoby 
BaseService (nothing especial - just converts Source <-> String)
*****************************************************
package es.bsc.inb.ejb.jmoby;

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.ws.Provider;
import org.biomoby.service.BaseService;
import org.biomoby.shared.parser.MobyPackage;

public abstract class ExtendedMobyBase extends BaseService implements 
Provider<Source>
{
    // provider method that is called by the JAX-WS
    public Source invoke(Source request)
    {
        try
        {
            TransformerFactory f = TransformerFactory.newInstance();
            Transformer tr = f.newTransformer();

            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            tr.transform(request, result);
           
            String response = runMyService(sw.toString());
           
            return new StreamSource(new StringReader(response));
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
       
        // need to generate SOAP Exception... (shouldn't fail and... 
this is a demo...)
        return null;
    }
           
    // JMoby (MoSeS) generated method
    public String runMyService(String data)
    {
    MobyPackage mobyOutput = null;
    try
        {
        // reading the whole input
        MobyPackage mobyInput = MobyPackage.createFromXML (data, 
"AminoAcidSequence");

        // prepare an output object
        mobyOutput = prepareOutput (mobyInput);

        // do the main job
        processIt (mobyInput, mobyOutput);

        // and return an XML back
        return mobyOutput.toXML();

    }
        catch (Throwable e)
        {
        boolean mobyException = (e instanceof 
org.biomoby.shared.MobyException);
        java.io.StringWriter sw = new java.io.StringWriter (500);
        if (e.getCause() != null ||    (! mobyException))
        e.printStackTrace (new java.io.PrintWriter (sw));
        return error (e.getMessage() + "\n" + sw.toString(), mobyOutput);
    }
    }
}

*****************************************************

Empty (dummy) local interface, just t o comply to ejb3 specs...
*****************************************************
package es.bsc.inb.ejb.jmoby;
import javax.ejb.Local;

@Local
public interface JMobyDocumentLiteralDemoServiceLocal {}
*****************************************************

Here is the service itself. It implements processIt() method from 
BaseService JMoby class...
*****************************************************
package es.bsc.inb.ejb.jmoby;

import javax.ejb.Stateless;
import javax.xml.transform.Source;
import javax.xml.ws.*;
import org.biomoby.shared.MobyException;
import org.biomoby.shared.datatypes.MobyObject;
import org.biomoby.shared.parser.*;

@WebServiceProvider(serviceName="JMobyDocumentLiteralDemoService",
                    portName="JMobyDocumentLiteralDemoPort",
                    
targetNamespace="urn:JMobyDocumentLiteralDemoService/wsdl",
                    wsdlLocation = 
"META-INF/wsdl/JMobyDocumentLiteralDemoService.wsdl")
@javax.xml.ws.ServiceMode(value=javax.xml.ws.Service.Mode.PAYLOAD)

@Stateless
public class JMobyDocumentLiteralDemoService extends ExtendedMobyBase 
implements JMobyDocumentLiteralDemoServiceLocal, Provider<Source>
{
    @Override
    public void processIt(MobyJob request, MobyJob response, MobyPackage 
arg2) throws MobyException
    {
        // echo...
        MobyObject object = request.getData();
        response.setData(object);
    }
}
*****************************************************

And finally we MUST provide the WSDL file (in the correct location as in 
"META-INF/wsdl/JMobyDocumentLiteralDemoService.wsdl")
*****************************************************
<?xml version="1.0" encoding="UTF-8"?>

<definitions
  name="JMobyDocumentLiteralDemoService"
  targetNamespace="urn:JMobyDocumentLiteralDemoService/wsdl"
  xmlns:tns="urn:JMobyDocumentLiteralDemoService/wsdl"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

<types>
  <xs:schema
    version="1.0"
    targetNamespace="http://www.biomoby.org/moby"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.biomoby.org/moby">

    <xs:element name="MOBY" type="mobyMessage"/>
    <xs:element name="mobyData" type="mobyData"/>
    <xs:element name="Collection" type="mobyCollection"/>
    <xs:element name="Simple" type="mobySimple"/>
    <xs:element name="mobyException" type="mobyException"/>
    <xs:element name="serviceNotes" type="serviceNotes"/>

    <xs:complexType name="mobyMessage">
      <xs:sequence>
        <xs:element name="mobyContent" type="mobyContent" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>

    <xs:complexType name="mobyContent">
      <xs:sequence>
        <xs:element ref="mobyData" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="serviceNotes" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>

    <xs:complexType name="mobyData">
      <xs:sequence>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="Simple"/>
          <xs:element ref="Collection"/>
        </xs:choice>
        <xs:element name="Parameter" type="mobyParameter" minOccurs="0" 
maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute ref="queryID"/>
    </xs:complexType>

    <xs:complexType name="mobySimple">
      <xs:sequence>
        <xs:any processContents="lax" namespace="##other"/>
      </xs:sequence>
      <xs:attribute ref="articleName"/>
    </xs:complexType>

    <xs:complexType name="mobyCollection">
      <xs:sequence>
        <xs:element ref="Simple" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute ref="articleName"/>
    </xs:complexType>

    <xs:complexType name="mobyParameter">
      <xs:sequence>
        <xs:element name="Value" type="xs:string" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute ref="articleName"/>
    </xs:complexType>

    <xs:complexType name="serviceNotes">
      <xs:sequence>
        <xs:element ref="mobyException" minOccurs="0" 
maxOccurs="unbounded"/>
        <xs:element name="notes" type="xs:string" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>

    <xs:complexType name="mobyException">
      <xs:sequence>
        <xs:element name="exceptionCode" type="xs:string" minOccurs="0"/>
        <xs:element name="exceptionMessage" type="xs:string" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute ref="refElement"/>
      <xs:attribute ref="refQueryID"/>
      <xs:attribute ref="severity"/>
    </xs:complexType>

    <xs:simpleType name="severity">
      <xs:restriction base="xs:string">
        <xs:enumeration value="error"/>
        <xs:enumeration value="warning"/>
        <xs:enumeration value="information"/>
      </xs:restriction>
    </xs:simpleType>
    <xs:attribute name="articleName" type="xs:string"/>
    <xs:attribute name="queryID" type="xs:string"/>
    <xs:attribute name="refElement" type="xs:string"/>
    <xs:attribute name="refQueryID" type="xs:string"/>
    <xs:attribute name="severity" type="severity"/>
  </xs:schema>
</types>

<message name="runMyService">
  <part xmlns:ns1="http://www.biomoby.org/moby" name="MOBY" 
element="ns1:MOBY"></part>
</message>

<message name="runMyServiceResponse">
  <part xmlns:ns1="http://www.biomoby.org/moby" name="MOBY" 
element="ns1:MOBY"></part>
</message>

<portType name="JMobyDocumentLiteralDemoService">
  <operation name="runMyService">
    <input message="tns:runMyService"></input>
    <output message="tns:runMyServiceResponse"></output>
  </operation>
</portType>

<binding name="JMobyDocumentLiteralDemoPortBinding" 
type="tns:JMobyDocumentLiteralDemoService">
  <soap:binding
    transport="http://schemas.xmlsoap.org/soap/http"
    style="document"/>

  <operation name="runMyService">
    <soap:operation soapAction=""></soap:operation>
    <input>
      <soap:body use="literal"></soap:body>
    </input>

    <output>
      <soap:body use="literal"></soap:body>
    </output>
  </operation>
</binding>

  <service name="JMobyDocumentLiteralDemoService">
    <port
      name="JMobyDocumentLiteralDemoPort"
      binding="tns:JMobyDocumentLiteralDemoPortBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL" />
    </port>
  </service>
</definitions>
*****************************************************

Note, that this is a Document/Literal XML Schema based web-service that 
use JMoby as an implementation.
Unfortunately, there is no client from JMoby yet to call the service... :-(

The schema (<types></types>) is the same for any Moby web-service (no 
ontology included).

Yours,

Dmitry.

P.S. As always appreciate your opinions (aggressive and negative 
included :-) ).




More information about the MOBY-dev mailing list