package org.mom4j.xcp;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import org.mom4j.xcp.impl.XcpElement;
import org.mom4j.xcp.impl.XcpDocumentHandler;
public final class XcpSender {
/** No logging on the client side! */
//private static Log log = LogFactory.getLog(XcpSender.class);
/** No logging on the client side! */
private InetAddress address;
private int port;
private XcpHandler internalHandler;
public XcpSender()
throws java.net.UnknownHostException
{
this(InetAddress.getLocalHost());
}
public XcpSender(InetAddress addr) {
this(addr, XcpConfig.DEFAULT_PORT);
}
public XcpSender(InetAddress addr, int p) {
if(addr == null) {
throw new java.lang.IllegalArgumentException("addr == null!");
}
if(p <= 0) {
throw new java.lang.IllegalArgumentException("p <= 0!");
}
this.address = addr;
this.port = p;
this.internalHandler = null;
}
public synchronized XcpResponse send(XmlTag root)
throws IOException
{
if(this.internalHandler == null) {
this.internalHandler = new XcpDocumentHandler();
}
return this.send(root, this.internalHandler);
}
public synchronized XcpResponse send(XmlTag root, XcpHandler handler)
throws IOException
{
if(root == null)
throw new IllegalArgumentException("root may not be null!");
if(handler == null)
throw new IllegalArgumentException("handler may not be null!");
HttpURLConnection con = this.openConnection();
OutputStream out = null;
OutputStreamWriter osw = null;
InputStream in = null;
XcpResponse ret = null;
try {
out = con.getOutputStream();
this.writeMessage(out, root);
out.flush();
in = con.getInputStream();
ret = this.recieveData(in, handler);
} finally {
try { in.close(); } catch(Exception ex) {}
try { osw.close(); } catch(Exception ex) {}
try { out.close(); } catch(Exception ex) {}
try { con.disconnect(); } catch(Exception ex) {}
}
return ret;
}
private HttpURLConnection openConnection()
throws IOException
{
URL url = null;
try {
url = new URL("http",
this.address.getHostName(),
this.port,
XcpConfig.XCP);
} catch(MalformedURLException muex) {
throw new IOException(muex.getMessage());
}
HttpURLConnection con = null;
con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-type", "text/xml");
con.setDoOutput(true);
con.setDoInput(true);
con.connect();
return con;
}
private XcpResponse recieveData(InputStream in, XcpHandler handler)
throws IOException
{
XMLReader parser = null;
try {
SAXParserFactory f = SAXParserFactory.newInstance();
parser = f.newSAXParser().getXMLReader();
} catch(Exception ex) {
throw new IOException(ex.getMessage());
}
InputSource is = new InputSource(new java.io.InputStreamReader(in));
parser.setContentHandler(handler);
ResponseImpl resp = null;
try {
parser.parse(is);
if(handler.getProtocolName().equals("error")) {
XcpElement e = (XcpElement)handler.getRootElement();
throw new IOException(e.getValue());
}
resp = new ResponseImpl(handler.getProtocolName());
if(handler.getRootElement() != null) {
resp.setRootElement(handler.getRootElement());
}
} catch(Exception ex) {
//XcpSender is used on the client side where there is no logging
//so write the stack trace to the console
ex.printStackTrace();
throw new IOException(ex.getMessage());
} finally {
try { handler.cleanUp(); } catch(Exception ex) {}
}
return resp;
}
private void writeMessage(OutputStream out, XmlTag root)
throws IOException
{
String s = "<?xml version=\"1.0\" ?>";
out.write(s.getBytes("US-ASCII"));
out.flush();
OutputStreamWriter osw = new OutputStreamWriter(out);
try {
writeTag(osw, root);
} finally {
try { osw.flush(); } catch(Exception ex) {}
try { osw.close(); } catch(Exception ex) {}
}
}
private void writeTag(Writer w, XmlTag tag)
throws IOException
{
String open = tag.getTagOpen();
w.write(open);
if(tag.hasContent()) {
String content = tag.getContent();
w.write(content);
}
if(tag.hasChildren()) {
Iterator it = tag.getChildren();
while(it.hasNext()) {
writeTag(w, (XmlTag)it.next());
}
}
String close = tag.getTagClosed();
w.write(close);
w.flush();
}
public class ResponseImpl implements org.mom4j.xcp.XcpResponse {
private Object rootElement;
private String protocolName;
ResponseImpl(String pname) {
if(pname == null)
throw new IllegalArgumentException("null not allowed!");
this.protocolName = pname;
}
void setRootElement(Object elem) {
if(elem == null)
throw new IllegalArgumentException("null not allowed!");
if(this.protocolName.equals("error")) {
throw new IllegalStateException(((XmlTag)elem).getContent());
}
this.rootElement = elem;
}
public Object getRootElement() {
return this.rootElement;
}
public String getProtocolName() {
return this.protocolName;
}
}
}