package com.juick.jabber.ws; import com.juick.server.MessagesQueries; import com.juick.server.Utils; import com.juick.xmpp.JID; import com.juick.xmpp.Message; import com.juick.xmpp.Stream; import com.juick.xmpp.StreamComponent; import com.juick.xmpp.extensions.JuickMessage; import java.io.IOException; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Iterator; /** * * @author ugnich */ public class XMPPConnection implements Runnable, Stream.StreamListener, Message.MessageListener { Connection sql; Stream xmpp; String xmppPassword; public XMPPConnection(Connection sql, String password) { this.sql = sql; xmppPassword = password; } @Override public void run() { try { Socket socket = new Socket("localhost", 5347); xmpp = new StreamComponent(new JID("", "ws.juick.com", ""), socket.getInputStream(), socket.getOutputStream(), xmppPassword); xmpp.addChildParser(new JuickMessage()); xmpp.addListener((Stream.StreamListener) this); xmpp.addListener((Message.MessageListener) this); xmpp.startParsing(); } catch (IOException e) { System.err.println("XMPPConnection: " + e); } } @Override public void onStreamReady() { System.err.println("Stream ready"); } @Override public void onStreamFail(String msg) { System.err.println("Stream failed: " + msg); } @Override public void onMessage(com.juick.xmpp.Message msg) { JuickMessage jmsg = (JuickMessage) msg.getChild(JuickMessage.XMLNS); if (jmsg != null) { System.err.println("MID=" + jmsg.MID + "; RID=" + jmsg.RID); if (jmsg.MID == 0) { int uid_to = 0; try { uid_to = Integer.parseInt(msg.to.Username); } catch (Exception e) { } if (uid_to > 0) { onJuickPM(uid_to, jmsg); } } else if (jmsg.RID == 0) { onJuickMessagePost(jmsg); } else { onJuickMessageReply(jmsg); } } } private void onJuickPM(int uid_to, com.juick.Message jmsg) { String json = com.juick.json.Message.toJSON(jmsg).toString(); ByteBuffer bbMsg = buildTextFrame(json); synchronized (Main.clients) { for (Iterator i = Main.clients.iterator(); i.hasNext();) { SocketSubscribed s = i.next(); if (s.VUID == uid_to) { if (!s.sendByteBuffer(bbMsg)) { i.remove(); } } } } } private void onJuickMessagePost(com.juick.Message jmsg) { String json = com.juick.json.Message.toJSON(jmsg).toString(); ByteBuffer bbMsg = buildTextFrame(json); ArrayList uids = new ArrayList(); String query = "SELECT suser_id FROM subscr_users WHERE user_id=" + jmsg.User.UID + " AND suser_id NOT IN (SELECT user_id FROM bl_tags INNER JOIN messages_tags USING(tag_id) WHERE message_id=" + jmsg.MID + ")"; if (jmsg.Privacy < 0) { query += " AND suser_id IN (SELECT wl_user_id FROM wl_users WHERE user_id=" + jmsg.User.UID + ")"; } Statement stmt = null; ResultSet rs = null; try { stmt = sql.createStatement(); rs = stmt.executeQuery(query); rs.beforeFirst(); while (rs.next()) { uids.add(rs.getInt(1)); } } catch (SQLException e) { System.err.println("onJuickMessagePost: " + e); } finally { Utils.finishSQL(rs, stmt); } synchronized (Main.clients) { for (Iterator i = Main.clients.iterator(); i.hasNext();) { SocketSubscribed s = i.next(); if ((jmsg.Privacy >= 0 && (s.allMessages || s.UID == jmsg.User.UID)) || uids.contains(s.VUID)) { if (!s.sendByteBuffer(bbMsg)) { i.remove(); } } } } } private void onJuickMessageReply(com.juick.Message jmsg) { String json = com.juick.json.Message.toJSON(jmsg).toString(); ByteBuffer bbMsg = buildTextFrame(json); int privacy = MessagesQueries.getMessagePrivacy(sql, jmsg.MID); synchronized (Main.clients) { for (Iterator i = Main.clients.iterator(); i.hasNext();) { SocketSubscribed s = i.next(); if ((privacy >= 0 && s.allReplies) || s.MID == jmsg.MID) { if (!s.sendByteBuffer(bbMsg)) { i.remove(); } } } } } private ByteBuffer buildTextFrame(String json) { ByteBuffer jsonbytes = Charset.forName("UTF-8").encode(json); ByteBuffer bbMsg = ByteBuffer.allocate(jsonbytes.limit() + 8); bbMsg.put((byte) 0x81); if (jsonbytes.limit() <= 125) { bbMsg.put((byte) jsonbytes.limit()); } else { bbMsg.put((byte) 126); bbMsg.putShort((short) jsonbytes.limit()); } bbMsg.put(jsonbytes); bbMsg.flip(); return bbMsg; } }