1 package org.codehaus.xfire.xmpp;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.StringReader;
5
6 import javax.xml.stream.XMLStreamWriter;
7
8 import org.codehaus.xfire.MessageContext;
9 import org.codehaus.xfire.XFireException;
10 import org.codehaus.xfire.XFireRuntimeException;
11 import org.codehaus.xfire.exchange.OutMessage;
12 import org.codehaus.xfire.fault.XFireFault;
13 import org.codehaus.xfire.soap.SoapSerializer;
14 import org.codehaus.xfire.transport.AbstractChannel;
15 import org.codehaus.xfire.transport.Channel;
16 import org.codehaus.xfire.util.STAXUtils;
17 import org.dom4j.Document;
18 import org.dom4j.DocumentException;
19 import org.dom4j.io.SAXReader;
20 import org.jivesoftware.smack.XMPPConnection;
21 import org.jivesoftware.smack.XMPPException;
22 import org.jivesoftware.smack.filter.ToContainsFilter;
23 import org.jivesoftware.smack.packet.IQ;
24 import org.jivesoftware.smack.packet.XMPPError;
25
26 public class XMPPChannel
27 extends AbstractChannel
28 {
29 private XMPPConnection conn;
30
31 public XMPPChannel(String uri, XMPPTransport transport)
32 {
33 setUri(uri);
34 setTransport(transport);
35 }
36
37 public void open() throws XFireException
38 {
39 if (conn != null)
40 return;
41
42 XMPPTransport transport = (XMPPTransport) getTransport();
43
44 try
45 {
46 conn = new XMPPConnection(transport.getServer());
47 conn.login(transport.getUsername(), transport.getPassword(), getUri());
48
49 conn.addPacketListener(new ChannelPacketListener(transport.getXFire(), this),
50 new ToContainsFilter(transport.getUsername()));
51 }
52 catch (XMPPException e)
53 {
54 throw new XFireException("Couldn't open channel.", e);
55 }
56 }
57
58 public void send(MessageContext context, OutMessage message)
59 throws XFireFault
60 {
61 XMPPTransport transport = (XMPPTransport) getTransport();
62
63 ByteArrayOutputStream out = new ByteArrayOutputStream();
64 try
65 {
66 context.setProperty(SoapSerializer.SERIALIZE_PROLOG, Boolean.FALSE);
67 final XMLStreamWriter writer = STAXUtils.createXMLStreamWriter(out, message.getEncoding());
68
69 message.getSerializer().writeMessage(message, writer, context);
70
71 writer.flush();
72 writer.close();
73
74 out.flush();
75 out.close();
76 }
77 catch (Exception e)
78 {
79 throw new XFireRuntimeException("Couldn't write stream.", e);
80 }
81
82 SoapEnvelopePacket response = new SoapEnvelopePacket(out.toString());
83 response.setFrom(conn.getUser());
84
85 if (message.getUri().equals(Channel.BACKCHANNEL_URI))
86 {
87 SoapEnvelopePacket req =
88 (SoapEnvelopePacket) context.getProperty(ChannelPacketListener.PACKET);
89 response.setTo(req.getFrom());
90 response.setType(IQ.Type.RESULT);
91 response.setPacketID(req.getPacketID());
92 }
93 else
94 {
95 response.setTo(message.getUri());
96 }
97
98 XMPPError error = (XMPPError) context.getProperty(XMPPFaultHandler.XMPP_ERROR);
99 if (error != null)
100 response.setError(error);
101
102 conn.sendPacket(response);
103 }
104
105 public void close()
106 {
107 conn.close();
108 }
109
110 protected Document readDocument(String text)
111 {
112 try
113 {
114 SAXReader reader = new SAXReader();
115 return reader.read(new StringReader(text));
116 }
117 catch (DocumentException e)
118 {
119 throw new XFireRuntimeException("Couldn't read response document: " + text, e);
120 }
121 }
122 }