1 19 20 package org.apache.cayenne.event; 21 22 import java.io.ByteArrayInputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.ObjectInputStream ; 25 import java.io.ObjectOutputStream ; 26 import java.util.Collection ; 27 import java.util.Collections ; 28 29 import org.jivesoftware.smack.GroupChat; 30 import org.jivesoftware.smack.PacketListener; 31 import org.jivesoftware.smack.SSLXMPPConnection; 32 import org.jivesoftware.smack.XMPPConnection; 33 import org.jivesoftware.smack.XMPPException; 34 import org.jivesoftware.smack.packet.Message; 35 import org.jivesoftware.smack.packet.Packet; 36 import org.apache.cayenne.CayenneRuntimeException; 37 import org.apache.cayenne.util.Base64Codec; 38 import org.apache.cayenne.util.Util; 39 40 54 public class XMPPBridge extends EventBridge { 55 56 static final String DEFAULT_CHAT_SERVICE = "conference"; 57 static final int DEFAULT_XMPP_PORT = 5222; 58 static final int DEFAULT_XMPP_SECURE_PORT = 5223; 59 60 protected boolean secureConnection; 61 protected String loginId; 62 protected String password; 63 protected String xmppHost; 64 protected int xmppPort; 65 protected String chatService; 66 protected String sessionHandle; 67 68 protected XMPPConnection connection; 69 protected GroupChat groupChat; 70 protected boolean connected; 71 72 75 public XMPPBridge(EventSubject localSubject, String externalSubject) { 76 this(Collections.singleton(localSubject), externalSubject); 77 } 78 79 82 public XMPPBridge(Collection localSubjects, String externalSubject) { 83 super(localSubjects, externalSubject); 84 85 this.sessionHandle = "cayenne-xmpp-" + System.currentTimeMillis(); 88 } 89 90 public String getXmppHost() { 91 return xmppHost; 92 } 93 94 public void setXmppHost(String xmppHost) { 95 this.xmppHost = xmppHost; 96 } 97 98 public int getXmppPort() { 99 return xmppPort; 100 } 101 102 public void setXmppPort(int xmppPort) { 103 this.xmppPort = xmppPort; 104 } 105 106 public String getLoginId() { 107 return loginId; 108 } 109 110 public void setLoginId(String loginId) { 111 this.loginId = loginId; 112 } 113 114 public String getPassword() { 115 return password; 116 } 117 118 public void setPassword(String password) { 119 this.password = password; 120 } 121 122 public boolean isSecureConnection() { 123 return secureConnection; 124 } 125 126 public void setSecureConnection(boolean secureConnection) { 127 this.secureConnection = secureConnection; 128 } 129 130 public String getChatService() { 131 return chatService; 132 } 133 134 public void setChatService(String chatService) { 135 this.chatService = chatService; 136 } 137 138 public String getSessionHandle() { 139 return sessionHandle; 140 } 141 142 public void setSessionHandle(String sessionHandle) { 143 this.sessionHandle = sessionHandle; 144 } 145 146 protected void startupExternal() throws Exception { 147 148 if (xmppHost == null) { 150 throw new CayenneRuntimeException("Null 'xmppHost', can't start XMPPBridge"); 151 } 152 153 if (connected) { 155 shutdownExternal(); 156 } 157 158 try { 159 if (secureConnection) { 161 int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_SECURE_PORT; 162 this.connection = new SSLXMPPConnection(xmppHost, port); 163 } 164 else { 165 int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_PORT; 166 this.connection = new XMPPConnection(xmppHost, port); 167 } 168 169 if (loginId != null) { 170 connection.login(loginId, password, sessionHandle); 174 } 175 else { 176 connection.loginAnonymously(); 177 } 178 } 179 catch (XMPPException e) { 180 throw new CayenneRuntimeException("Error connecting to XMPP Server" 181 + e.getLocalizedMessage()); 182 } 183 184 String service = this.chatService != null 185 ? this.chatService 186 : DEFAULT_CHAT_SERVICE; 187 188 try { 189 this.groupChat = connection.createGroupChat(externalSubject 190 + '@' 191 + service 192 + "." 193 + connection.getHost()); 194 195 groupChat.join(sessionHandle); 196 groupChat.addMessageListener(new XMPPListener()); 197 } 198 catch (XMPPException e) { 199 throw new CayenneRuntimeException("Error setting up a group chat: " 200 + e.getLocalizedMessage()); 201 } 202 203 this.connected = true; 204 } 205 206 protected void shutdownExternal() throws Exception { 207 if (groupChat != null) { 208 groupChat.leave(); 209 groupChat = null; 210 } 211 212 if (connection != null) { 213 connection.close(); 214 connection = null; 215 } 216 217 connected = false; 218 } 219 220 protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { 221 222 Message message = groupChat.createMessage(); 223 message.setBody(serializeToString(localEvent)); 224 225 message.setThread(sessionHandle); 227 228 groupChat.sendMessage(message); 229 } 230 231 class XMPPListener implements PacketListener { 232 233 public void processPacket(Packet packet) { 234 235 if (packet instanceof Message) { 236 Message message = (Message) packet; 237 238 if (sessionHandle.equals(message.getThread())) { 240 } 242 else { 243 244 String payload = message.getBody(); 245 246 try { 247 Object event = deserializeFromString(payload); 248 if (event instanceof CayenneEvent) { 249 onExternalEvent((CayenneEvent) event); 250 } 251 } 252 catch (Exception ex) { 253 } 255 } 256 } 257 } 258 } 259 260 264 static Object deserializeFromString(String string) throws Exception { 265 if (Util.isEmptyString(string)) { 266 return null; 267 } 268 269 byte[] bytes = Base64Codec.decodeBase64(string.getBytes()); 270 ObjectInputStream in = new ObjectInputStream (new ByteArrayInputStream (bytes)); 271 Object object = in.readObject(); 272 in.close(); 273 return object; 274 } 275 276 279 static String serializeToString(Object object) throws Exception { 280 ByteArrayOutputStream bytes = new ByteArrayOutputStream (); 281 ObjectOutputStream out = new ObjectOutputStream (bytes); 282 out.writeObject(object); 283 out.close(); 284 285 return new String (Base64Codec.encodeBase64(bytes.toByteArray())); 286 } 287 } 288 | Popular Tags |