Listing 1
package message;

public class MessageService {

public void process(
Envelope env,
SOAPContext requestContext,
SOAPContext responseContext) {

Document doc;
Node bodyNode;
Node bodyNodeParent = null;

try {
bodyNode = (Node) env.getBody().getBodyEntries().elementAt(0);
Element request = (Element) bodyNode.getFirstChild();

Node bodyNodeParent = bodyNode.getParentNode();
bodyNodeParent.removeChild(bodyNode);

doc = bodyNode.getOwnerDocument();
Node returnNode = doc.importNode(request, true);
bodyNodeParent.appendChild(returnNode); 

// introduce some delay
Thread.sleep(2000);

OutputFormat format = new OutputFormat(doc);
StringWriter response = new StringWriter();
XMLSerializer serial = new XMLSerializer(response, format);
serial.asDOMSerializer();
serial.serialize((Element) doc.getDocumentElement());
responseContext.setRootPart(response.toString(), "text/xml");
} catch (Exception e) {
e.printStackTrace();


}


Listing 2
import message.*;
import proxy.soap.message.*;
import org.w3c.dom.*;
import org.apache.xerces.dom.*;

public class TestMes {

public static void main(String[] args) {

MessageServiceProxy proxy = new MessageServiceProxy();
try {
DocumentImpl doc = new DocumentImpl();
Element inputEl = doc.createElement("test");
inputEl.setAttribute("myAtt", "good");

proxy.setURL("http://localhost:8080/
MessageService/servlet/messagerouter");
proxy.send(inputEl);

long timeOfCall = System.currentTimeMillis();
proxy.send(inputEl);
long sendTime = System.currentTimeMillis() - timeOfCall;

timeOfCall = System.currentTimeMillis();
Element response = proxy.receive();
long receiveTime = System.currentTimeMillis() - timeOfCall;

String result = response.getAttribute("myAtt");
System.out.println("The web service echoed the attribute;
the value is \""+ result + "\"");

System.out.println("The proxy send invoked -- interval "+ sendTime);
System.out.println("The proxy receive invoked -- interval "+ receiveTime);

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

Listing 3
package proxy.soap.message;

import org.w3c.dom.*;

public class AsyncResponse {
private Element response;
private boolean available = false;

public synchronized Element get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return response;
}

public synchronized void put(Element value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
response = value;
available = true;
notifyAll();
}
}

Listing 4
package proxy.soap.message;

import org.w3c.dom.*;

public class ProxyThread extends Thread {

protected String theURL = null;
protected Element payload = null;
protected AsyncResponse response = null;
protected MessageServiceProxy realProxy = new MessageServiceProxy();

public ProxyThread() {}

public synchronized void setURL(String url) throws 
Exception {
this.theURL = url;
}

public void setPayload(Element payload) {
this.payload = payload;
}

public void setResponse(ProxyResponse response) {
this.response = response;
}

public void run() {
try {
realProxy.setURL(theURL);
realProxy.send(payload);
Element res = realProxy.receive();
response.put(res);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Listing 5
package proxy.soap.message;

import org.w3c.dom.*;
import org.apache.soap.*;

public class ProxyWrapper {

private AsyncResponse response = new AsyncResponse();
private String theURL = null;

public synchronized void setURL(String url) throws Exception {
theURL = url;
}

public void send(Element payload) throws SOAPException {
ProxyThread proxyThread = new ProxyThread(); 
try {
proxyThread.setURL(theURL);
proxyThread.setPayload(payload);
proxyThread.setResponse(response);
} catch (Exception ex) {
ex.printStackTrace();
}
proxyThread.start();
}

public Element receive() throws SOAPException {
return response.get();
}
}