package ora.jwsnut.chapter4.ebXMLsender;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.messaging.Endpoint;
import javax.xml.messaging.JAXMServlet;
import javax.xml.messaging.OnewayListener;
import javax.xml.messaging.ProviderConnection;
import javax.xml.messaging.ProviderConnectionFactory;
import javax.xml.messaging.ProviderMetaData;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPMessage;
import com.sun.xml.messaging.jaxm.ebxml.Description;
import com.sun.xml.messaging.jaxm.ebxml.EbXMLMessageFactoryImpl;
import com.sun.xml.messaging.jaxm.ebxml.EbXMLMessageImpl;
import com.sun.xml.messaging.jaxm.ebxml.Manifest;
import com.sun.xml.messaging.jaxm.ebxml.Party;
import com.sun.xml.messaging.jaxm.ebxml.Reference;
import com.sun.xml.messaging.jaxm.ebxml.Service;
/**
* A servlet that creates an ebXML message on demand and sends
* it to a remote echo service.
*/
public class EBXMLSenderServlet extends JAXMServlet implements OnewayListener {
/**
* Message returned by the echo service.
*/
private SOAPMessage replyMessage;
/**
* Factory used to create parts of SOAP messages
*/
private SOAPFactory soapFactory;
/**
* ProviderConnection used to send reply messages
*/
private ProviderConnection conn;
/**
* Factory used to create messages
*/
private MessageFactory msgFactory;
/**
* Initialize by installing the appropriate MessageFactory
*/
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
try {
// Create the connection to the provider
conn = ProviderConnectionFactory.newInstance().createConnection();
soapFactory = SOAPFactory.newInstance();
// Check that the ebXML profile is supported
ProviderMetaData metaData = conn.getMetaData();
String[] profiles = metaData.getSupportedProfiles();
boolean found = false;
for (int i = 0; i < profiles.length; i++) {
if (profiles[i].equals("ebxml")) {
found = true;
break;
}
}
if (!found) {
// No ebXML profile
log("ebxml profile not supported");
throw new ServletException("ebxml profile not supported");
}
// Get the message factory and build the message
msgFactory = conn.createMessageFactory("ebxml");
// Install the factory to use when receiving messages
setMessageFactory(msgFactory);
} catch (Exception e) {
e.printStackTrace();
throw new ServletException(
"Failed to initialize ebXML sender servlet " + e.getMessage());
}
}
/**
* Handles a request from a client to send a message.
*/
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
// Only allow gets on the "request" handler
String path = req.getServletPath();
if (!path.equals("/request")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Cannot use get on this URL");
return;
}
// Build and send a message
boolean sent = sendMessage();
// Wait until the echo service has replied,
// for a maximum of 30 seconds
if (sent) {
synchronized (this) {
replyMessage = null;
try {
if (replyMessage == null) {
wait(30000L);
}
} catch (InterruptedException ex) {
}
}
}
// Now send the reply to the caller.
try {
if (replyMessage == null) {
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "No reply received");
return;
}
OutputStream os = resp.getOutputStream();
resp.setContentType("text/html");
resp.setStatus(HttpServletResponse.SC_OK);
os.write("<html><P><XMP>".getBytes());
replyMessage.writeTo(os);
os.write("</XMP></html>".getBytes());
os.flush();
} catch (Exception ex) {
log("Exception in doGet", ex);
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "Exception: " + ex.getMessage());
}
replyMessage = null;
}
/**
* Handles a POST either from a client or as a
* callback from the provider.
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
// Only allow posts to the "message" handler
String path = req.getServletPath();
if (path.equals("/message")) {
// This is allowed
super.doPost(req, resp);
} else {
// Cannot post to the request path
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Cannot post to this URL");
}
}
/* -- Useful functionality starts here -- */
/**
* Builds a message and sends it to the service
*/
private boolean sendMessage() {
try {
// Build the ebXML message
EbXMLMessageImpl message = (EbXMLMessageImpl)msgFactory.createMessage();
// Set attributes held in the MessageHeader
message.setAction("ECHO");
message.setService(new Service("urn:ECHOSERVICE", "URI"));
message.setCPAId("urn:EchoCollaborationAgreement");
message.setConversationId("1");
// Set the sending and receiving parties.
message.setReceiver(new Party("urn:ebXMLEcho"));
message.setSender(new Party("urn:ebXMLSender"));
// Add a Manifest with two references to external locations
Manifest manifest = new Manifest("ID1", "1.0");
Reference ref = new Reference("ID2", "http://www.ora.com", null);
Description desc = new Description("en");
desc.setText("O'Reilly Home Page");
ref.setDescription(desc);
manifest.addReference(ref);
ref = new Reference("ID3", "http://www.amazon.com", null);
desc = new Description("en");
desc.setText("Online bookstore");
ref.setDescription(desc);
manifest.addReference(ref);
message.setManifest(manifest);
// Add some data to the body.
SOAPElement element =
message.getSOAPPart().getEnvelope().getBody().addBodyElement(
soapFactory.createName("Sent", "tns", "urn:ebXMLSender"));
element.addTextNode("This is the content");
// Send the message to the echo service
conn.send(message);
// Return indicating that the message was sent.
return true;
} catch (Exception ex) {
log("Failed when sending message", ex);
}
return false;
}
/**
* Handles a received SOAP message - this is the
* asynchronous reply from the echo service.
*/
public void onMessage(SOAPMessage message) {
try {
synchronized (this) {
// Save the message for the benefit
// of the client.
replyMessage = message;
// Wake up the client
notify();
}
} catch (Exception ex) {
log("Exception", ex);
}
}
} |