package org.buddycloud.channelserver.queue; import java.util.ArrayList; import java.util.concurrent.BlockingQueue; import org.apache.log4j.Logger; import org.buddycloud.channelserver.ChannelsEngine; import org.buddycloud.channelserver.Configuration; import org.buddycloud.channelserver.channel.LocalDomainChecker; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.utils.users.OnlineResourceManager; import org.dom4j.Attribute; import org.xmpp.component.ComponentException; import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.Presence; public class OutQueueConsumer extends QueueConsumer { private static final Logger logger = Logger.getLogger(OutQueueConsumer.class); private final ChannelsEngine component; private FederatedQueueManager federatedQueue; private Configuration conf; private OnlineResourceManager onlineUsers; private BlockingQueue<Packet> inQueue; public OutQueueConsumer(ChannelsEngine component, BlockingQueue<Packet> outQueue, FederatedQueueManager federatedQueue, Configuration conf, OnlineResourceManager onlineUsers, BlockingQueue<Packet> inQueue) { super(outQueue); this.component = component; this.federatedQueue = federatedQueue; this.conf = conf; this.onlineUsers = onlineUsers; this.inQueue = inQueue; } @Override protected void consume(Packet p) throws NodeStoreException { try { if (true == isRemoteServer(p.getTo())) { // i.e. a remote server if (null == p.getElement().attributeValue("remote-server-discover")) { federatedQueue.process(p); return; } federatedQueue.addChannelMap(p.getTo()); } // Clean federation marks from packet if (p.getElement().attribute("remote-server-discover") != null) { Attribute process = p.getElement().attribute("remote-server-discover"); p.getElement().remove(process); } // If it's just a request for the local server then just push it // straight back into the inqueue if (shouldRouteToLocalChannelServer(p.getTo())) { inQueue.put(p); return; } if (p instanceof Presence) { component.sendPacket(p.createCopy()); return; } // Get a list of 'online' resources for this JID ArrayList<JID> resources = onlineUsers.getResources(p.getTo()); logger.debug("There are " + resources.size() + " online resources for " + p.getTo()); for (JID resource : resources) { p.setTo(resource); component.sendPacket(p.createCopy()); } } catch (ComponentException e) { logger.error("Sending packet caused error: " + p.toXML(), e); } catch (InterruptedException e) { logger.error("Sending packet caused error: " + p.toXML(), e); } } /** * Returns true if the JID points to a server (with no node) and if it is not one of the local * domains. * * @param jid * @return */ private boolean isRemoteServer(JID jid) { if (jid.getNode() != null) { return false; } String domain = jid.getDomain(); if (LocalDomainChecker.isLocal(domain, conf)) { return false; } logger.debug("Dealing with remote server " + domain); return true; } /** * Returns <code>true</code> if the jid should route through to this component. * * @param jid * @return */ private boolean shouldRouteToLocalChannelServer(JID jid) { if (jid.getNode() != null) { return false; } String domain = jid.getDomain(); if (domain.equals(conf.getServerChannelsDomain())) { return true; } if (domain.equals(conf.getServerTopicsDomain())) { return true; } return false; } }