Hi John,

Thanks for this code. I am planning to issue a new release of J2XB with such code generated automatically (actually, I think to generate a client service implementation using bytecode instrumentation). My idea is to support contract first services where the service interface is provided as a Java service with J2XB mapped DTOs, and to have the client implementation intrumented automatically (that is, no code generation). Your implementation below gives me the answer as to how to implement the service client - I am only left with some refactoring and the bytecode instrumentation work.


BTW, I have already implemented the XML annotations, and will upload the source code to sourceforge.net later this week. It will be included in the next release of J2XB, but I can send you the modified source, if you are interested.

Cheers,
  Yoav


On Tue, Aug 26, 2008 at 3:06 AM, John Helewa <helewa@kablab.com> wrote:
Hi Yoav;

Here a sample method for the Axis2/J2XB client side call. The limitations are that it can only take one input web-param class and one output class. There may be other things that need work, like exceptions, primitives, arrays - but at least it is a start.

Sample use:
==========
OpenManualReceiverControlRequestType request = new OpenManualReceiverControlRequestType();

request.setBand(ReceiverBandType.HF);
request.setCaseNotation("AB");
request.setClientName("myself");
OpenManualReceiverControlResponseType response = (OpenManualReceiverControlResponseType)
invokeBlocking(request,
OpenManualReceiverControlRequestType.class,
OpenManualReceiverControlResponseType.class,
"OpenManualReceiverControl",
"OpenManualReceiverControlRequestType",
"http://localhost:80/axis2/services/ManualReceiverControlService.ManualReceiverControlServiceHttpSoap11Endpoint");
 
 
Client side call:
===========
static public Object invokeBlocking(Object instance, Class inClass,Class outClass,String opName,String returnClassName, String url) {


MoXmlBindingModel xmlBindingModel = new MoXmlBindingModel();
try {
xmlBindingModel.addBean(inClass);
try {
MoXmlSchema xmlSchema = xmlBindingModel.getSchema(inClass);

// find the document factory class
MoXmlBeanDescriptor xmlDescriptor = xmlSchema.getXmlBeanDescriptor(inClass);
XmlAxiomFactory xmlAxiomFactory = XmlAxiomFactory.getInstance();
XmlAxiomDocumentContext doc = (XmlAxiomDocumentContext) xmlDescriptor.persistInstance(xmlAxiomFactory, instance);

OMElement openReq = doc.getDocumentInstance();

OMFactory fac = OMAbstractFactory.getOMFactory();
OMElement operation = fac.createOMElement(opName, doc
.getDocumentOMNamespace());
operation.addChild(openReq);
openReq.setLocalName("request");
Options options = new Options();
EndpointReference epr = new EndpointReference(url);

options.setTo(epr);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setAction("urn:"+opName);


ServiceClient sender = new ServiceClient();
sender.setOptions(options);

OMElement result = sender.sendReceive(operation);
Iterator returnObjs = result.getChildrenWithLocalName("return");
if (returnObjs.hasNext()) {
byte[] buf = new byte[10 * 1024];
OMElement oe = (org.apache.axiom.om.OMElement) returnObjs
.next();
oe.setLocalName(returnClassName);

xmlBindingModel = new MoXmlBindingModel();
xmlBindingModel.addBean(outClass);
XmlPersister xmlPersister = new XmlAxiomPersister();

ByteArrayInputStream in = new ByteArrayInputStream(oe.toString().getBytes());
Object response = outClass.newInstance();
response = xmlPersister.load(xmlBindingModel, response.getClass(), in);
return response;

}

} catch (Exception e) {
e.printStackTrace();
}

} catch (MOBeansException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;


}


John Helewa
KAB Laboratories, Inc
helewa@kablab.com
(KAB Main) 619-523-1763 (x702)
(Mobile) 619-246-8846
http://www.kablab.com
 

----- Original Message -----
From: Yoav Abrahami <yoavaa@gmail.com>
Cc:
Date: Sunday, August 24 2008 11:02 AM
Subject: Re: J2BX feature request/questions
Hi John,

Thanks for looking at the J2XB library and the integration with Axis2.

About your comments -
1. Injecting comments to the generated XML Schema is a good idea. I will add it to the J2XB schema generation options. I think about adding a new annotation that it's content will be added as an XML Schema annotations.

Maybe something like (for single annotations)
@MoXmlAnnotation(type=documentation, value="...")

and for multiple annotations
@MoXmlAnnotations( value = {
@MoXmlAnnotation(type=documentation, value="...")
@MoXmlAnnotation(type=appInfo, value="...")
})


2. The generation of the Endpoints section in the WSDL is done automatically by Axis2 - I do not modify the default behavior of Axis2. I believe that Axis2 has the ability to expose the same service as both.


3. Good idea. I had not tried to do the client side because there are other solutions that generate the client side from the WSDL, where there are not good alternative to generate the WSDL from the server code. However, I can see the logic, in some cases, to have the client use the same POJOs as the server, using the same annotations. I will add this support soon - you are actually invited to help if you like.



About the code you wrote - You got the code almost right. However, because Axis2 wraps the J2XB XML with a request - response XML element, the client-side code will be a little more complicated. I will prepare an example and send another email later this week.

For the code sample you sent, I think you should replace the lines (if I understand right what you are trying to do)

XmlAxiomFactory fac = XmlAxiomFactory.getInstance();
MoXmlBeanDescriptor beanDesc = new MoXmlBeanDescriptor(
xmlBindingModel.getSchema(OpenManualReceiverControlRequestType.class),xmlBindingModel.getBeanDescriptor(OpenManualReceiverControlRequestType.class) );
XmlAxiomDocumentContext doc = (XmlAxiomDocumentContext)fac.
createXmlDocument(xmlBindingModel.getSchema(OpenManualReceiverControlRequestType.class),beanDesc );
OMElement openReq = doc.getDocumentInstance();


with

// get the bean descriptor
MoXmlSchema xmlSchema = xmlBindingModel.getSchema(request.getClass());
MoXmlBeanDescriptor xmlDescriptor = xmlSchema.getXmlBeanDescriptor(request.getClass());
XmlAxiomFactory xmlAxiomFactory = XmlAxiomFactory.getInstance();
// write the instance to XML
XmlAxiomDocumentContext document = (XmlAxiomDocumentContext)xmlDescriptor.persistInstance(xmlAxiomFactory, request);

// do the WS call
OMElement openReq = document.getDocumentInstance();


Cheers,
Yoav



On Fri, Aug 22, 2008 at 10:41 PM, John Helewa <helewa@kablab.com> wrote:
Yoav;

I really like what you have done with J2BX and especially the Axis2 integration. I've converted one service over from regular Axis2 POJO to J2BX and it works great.

1) Would be nice to add the ability to inject "comments" or XML Schema annotation comments into the schema or service. That way you can document the WSDL from your POJO.
2) Not sure about the generation of SOAP11Endpoints and SOAP12Endpoints inside the same WSDL. Aren't these two formats incompatible? So really you are just using SOAP11 at this time?
3) Would be nice to know how to do POJO based web service invocation from a client. That way the same POJOs used to generate the service can be used within the client. In Axis2, we used the RPCServiceClient.invokeBlocking calls with POJOs to get things to work. It would be good to have a RPCJ2BX.invoke*() set of methods to mirror this.

Question:
=======
I am try to write a client access library for POJOs like Axis2 provides. Any pointers would help. I provide the library to you if I get it working. Here is a code clip at a non-working attempt to invoke a J2BX service using a POJOs:

MoXmlBindingModel xmlBindingModel = new MoXmlBindingModel();
try {
OpenManualReceiverControlRequestType request = new OpenManualReceiverControlRequestType();
request.set*****;

xmlBindingModel.addBean(OpenManualReceiverControlRequestType.class);
try {
XmlAxiomFactory fac = XmlAxiomFactory.getInstance();
MoXmlBeanDescriptor beanDesc = new MoXmlBeanDescriptor(xmlBindingModel.getSchema(OpenManualReceiverControlRequestType.class),xmlBindingModel.getBeanDescriptor(OpenManualReceiverControlRequestType.class) );
XmlAxiomDocumentContext doc = (XmlAxiomDocumentContext)fac.createXmlDocument(xmlBindingModel.getSchema(OpenManualReceiverControlRequestType.class),beanDesc );
OMElement openReq = doc.getDocumentInstance();
Options options = new Options();
EndpointReference epr = new EndpointReference("http://localhost/axis2/services/ManualReceiverControlService.ManualReceiverControlServiceHttpSoap11Endpoint");
options.setTo(epr);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

ServiceClient sender = new ServiceClient();
sender.setOptions(options);


OMElement result = sender.sendReceive(openReq);

String response = result.getFirstElement().getText();
System.err.println(response);

} catch (Exception e) {
e.printStackTrace();
}

Thanks;

John Helewa
KAB Laboratories, Inc
helewa@kablab.com
(KAB Main) 619-523-1763 (x702)
(Mobile) 619-246-8846
http://www.kablab.com