package com.juick.xmpp.s2s; import com.juick.User; import com.juick.server.MessagesQueries; import com.juick.server.SubscriptionsQueries; import com.juick.server.UserQueries; import com.juick.xmpp.*; import com.juick.xmpp.extensions.JuickMessage; import com.juick.xmpp.extensions.Nickname; import com.juick.xmpp.extensions.XOOB; import java.io.IOException; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * @author ugnich */ public class ConnectionRouter implements Stream.StreamListener, Message.MessageListener, Iq.IqListener, Presence.PresenceListener { private static final Logger logger = Logger.getLogger(ConnectionRouter.class.getName()); private String componentName; private String password; Stream router; Socket socket; XMPPComponent xmpp; ConnectionRouter(XMPPComponent s2s, String componentName, String password) { this.xmpp = s2s; this.componentName = componentName; this.password = password; reconnect(); } public void reconnect() { try { socket = new Socket("localhost", 5347); router = new StreamComponent(new JID("s2s"), socket.getInputStream(), socket.getOutputStream(), password); router.addChildParser(new JuickMessage()); router.addListener((Stream.StreamListener) this); router.addListener((Message.MessageListener) this); router.addListener((Iq.IqListener) this); router.startParsing(); logger.info("STREAM ROUTER START"); } catch (IOException e) { logger.log(Level.SEVERE, "router failed", e); } } public void closeConnection() throws IOException { router.logoff(); socket.close(); } public void sendJuickMessage(JuickMessage jmsg) { List jids = new ArrayList<>(); if (jmsg.FriendsOnly) { jids = SubscriptionsQueries.getJIDSubscribedToUser(xmpp.sql, jmsg.getUser().getUID(), jmsg.FriendsOnly); } else { List users = SubscriptionsQueries.getSubscribedUsers(xmpp.sql, jmsg.getUser().getUID(), jmsg.getMID()); for (User user : users) { for (String jid : UserQueries.getJIDsbyUID(xmpp.sql, user.getUID())) { jids.add(jid); } } } String txt = "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n"; String attachment = jmsg.getAttachmentURL(); if (attachment != null) { txt += attachment + "\n"; } txt += jmsg.getText() + "\n\n"; txt += "#" + jmsg.getMID() + " http://juick.com/" + jmsg.getMID(); Nickname nick = new Nickname(); nick.Nickname = "@" + jmsg.getUser().getUName(); com.juick.xmpp.Message msg = new com.juick.xmpp.Message(); msg.from = JuickBot.JuickJID; msg.body = txt; msg.type = Message.Type.chat; msg.thread = "juick-" + jmsg.getMID(); msg.addChild(jmsg); msg.addChild(nick); if (attachment != null) { XOOB oob = new XOOB(); oob.URL = attachment; msg.addChild(oob); } for (String jid : jids) { msg.to = new JID(jid); xmpp.sendOut(msg); } } public void sendJuickComment(JuickMessage jmsg) { List users; String replyQuote; String replyTo; users = SubscriptionsQueries.getUsersSubscribedToComments(xmpp.sql, jmsg.getMID(), jmsg.getUser().getUID()); com.juick.Message replyMessage = jmsg.ReplyTo > 0 ? MessagesQueries.getReply(xmpp.sql, jmsg.getMID(), jmsg.ReplyTo) : MessagesQueries.getMessage(xmpp.sql, jmsg.getMID()); replyTo = replyMessage.getUser().getUName(); replyQuote = getReplyQuote(replyMessage); String txt = "Reply by @" + jmsg.getUser().getUName() + ":\n" + replyQuote + "\n@" + replyTo + " "; String attachment = jmsg.getAttachmentURL(); if (attachment != null) { txt += attachment + "\n"; } txt += jmsg.getText() + "\n\n" + "#" + jmsg.getMID() + "/" + jmsg.getRID() + " http://juick.com/" + jmsg.getMID() + "#" + jmsg.getRID(); com.juick.xmpp.Message msg = new com.juick.xmpp.Message(); msg.from = JuickBot.JuickJID; msg.body = txt; msg.type = Message.Type.chat; msg.addChild(jmsg); for (User user : users) { for (String jid : UserQueries.getJIDsbyUID(xmpp.sql, user.getUID())) { msg.to = new JID(jid); xmpp.sendOut(msg); } } } private String getReplyQuote(com.juick.Message q) { String quote = q.getText(); if (quote.length() > 50) { quote = ">" + quote.substring(0, 47).replace('\n', ' ') + "...\n"; } else if (quote.length() > 0) { quote = ">" + quote.replace('\n', ' ') + "\n"; } return quote; } public void sendJuickRecommendation(JuickMessage recomm) { List users; JuickMessage jmsg; jmsg = new JuickMessage(MessagesQueries.getMessage(xmpp.sql, recomm.getMID())); users = SubscriptionsQueries.getUsersSubscribedToUserRecommendations(xmpp.sql, recomm.getUser().getUID(), recomm.getMID(), jmsg.getUser().getUID()); String txt = "Recommended by @" + recomm.getUser().getUName() + ":\n"; txt += "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n"; String attachment = jmsg.getAttachmentURL(); if (attachment != null) { txt += attachment + "\n"; } txt += jmsg.getText() + "\n\n"; txt += "#" + jmsg.getMID(); if (jmsg.Replies > 0) { if (jmsg.Replies % 10 == 1 && jmsg.Replies % 100 != 11) { txt += " (" + jmsg.Replies + " reply)"; } else { txt += " (" + jmsg.Replies + " replies)"; } } txt += " http://juick.com/" + jmsg.getMID(); Nickname nick = new Nickname(); nick.Nickname = "@" + jmsg.getUser().getUName(); com.juick.xmpp.Message msg = new com.juick.xmpp.Message(); msg.from = JuickBot.JuickJID; msg.body = txt; msg.type = Message.Type.chat; msg.thread = "juick-" + jmsg.getMID(); msg.addChild(jmsg); msg.addChild(nick); if (attachment != null) { XOOB oob = new XOOB(); oob.URL = attachment; msg.addChild(oob); } for (User user : users) { for (String jid : UserQueries.getJIDsbyUID(xmpp.sql, user.getUID())) { msg.to = new JID(jid); xmpp.sendOut(msg); } } } @Override public boolean onIq(Iq iq) { JID jid = iq.to; if (!jid.Host.equals(componentName)) { logger.info("STREAM ROUTER (IQ): " + iq.toString()); xmpp.sendOut(iq); } return false; } @Override public void onMessage(Message xmsg) { logger.info("STREAM ROUTER (PROCESS): " + xmsg.toString()); JuickMessage jmsg = (JuickMessage) xmsg.getChild(JuickMessage.XMLNS); JID jid = xmsg.to; if (jid.Host.equals(componentName)) { if (jmsg != null) { if (jid.Username != null && jid.Username.equals("recomm")) { sendJuickRecommendation(jmsg); } else { if (jmsg.getRID() > 0) { sendJuickComment(jmsg); } else if (jmsg.getMID() > 0) { sendJuickMessage(jmsg); } } } } else { xmpp.sendOut(xmsg); } } @Override public void onPresence(Presence presence) { JID jid = presence.to; if (!jid.Host.equals(componentName)) { logger.info("STREAM ROUTER (PRESENCE): " + presence.toString()); xmpp.sendOut(presence); } } @Override public void onStreamReady() { logger.info("STREAM ROUTER (READY)"); } @Override public void onStreamFail(Exception ex) { logger.log(Level.SEVERE, "STREAM ROUTER (FAIL)", ex); reconnect(); } }