package org.buddycloud.channelserver.packetprocessor.iq;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import org.apache.log4j.Logger;
import org.buddycloud.channelserver.Configuration;
import org.buddycloud.channelserver.channel.ChannelManager;
import org.buddycloud.channelserver.packetprocessor.PacketProcessor;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.discoinfo.JabberDiscoInfo;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.discoitems.JabberDiscoItems;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.mam.MessageArchiveManagement;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.register.JabberRegister;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.search.Search;
import org.buddycloud.channelserver.queue.FederatedQueueManager;
import org.buddycloud.channelserver.queue.UnknownFederatedPacketException;
import org.xmpp.packet.IQ;
import org.xmpp.packet.IQ.Type;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
public class IQProcessor implements PacketProcessor<IQ> {
private static final Logger logger = Logger.getLogger(IQProcessor.class);
private Map<String, PacketProcessor<IQ>> processorsPerNamespace = new HashMap<String, PacketProcessor<IQ>>();
private BlockingQueue<Packet> outQueue;
private FederatedQueueManager federatedQueueManager;
public IQProcessor(BlockingQueue<Packet> outQueue, Configuration conf, ChannelManager channelManager, FederatedQueueManager federatedQueueManager) {
this.outQueue = outQueue;
this.federatedQueueManager = federatedQueueManager;
JabberPubsub ps = new JabberPubsub(outQueue, conf, channelManager, federatedQueueManager);
processorsPerNamespace.put(JabberDiscoItems.NAMESPACE_URI, new JabberDiscoItems(outQueue, conf, channelManager, federatedQueueManager));
processorsPerNamespace.put(JabberDiscoInfo.NAMESPACE_URI, new JabberDiscoInfo(outQueue, conf, channelManager, federatedQueueManager));
processorsPerNamespace.put(JabberRegister.NAMESPACE_URI, new JabberRegister(outQueue, conf, channelManager));
processorsPerNamespace.put(JabberPubsub.NAMESPACE_URI, ps);
processorsPerNamespace.put(JabberPubsub.NS_PUBSUB_OWNER, ps);
processorsPerNamespace.put(MessageArchiveManagement.NAMESPACE_MAM, new MessageArchiveManagement(outQueue, channelManager));
processorsPerNamespace.put(Search.NAMESPACE_URI, new Search(outQueue, channelManager));
}
@Override
public void process(IQ packet) throws Exception {
try {
processPacket(packet);
} catch (Exception e) {
if (packet.getType().equals(IQ.Type.result) || packet.getType().equals(IQ.Type.error)) {
return;
}
IQ reply = IQ.createResultIQ(packet);
reply.setChildElement(packet.getChildElement().createCopy());
reply.setType(Type.error);
PacketError pe = new PacketError(org.xmpp.packet.PacketError.Condition.internal_server_error, org.xmpp.packet.PacketError.Type.wait);
reply.setError(pe);
logger.error("Error while processing packet.", e);
e.printStackTrace();
this.outQueue.put(reply);
}
}
private void processPacket(IQ packet) throws Exception, InterruptedException {
if (null != packet.getChildElement()) {
logger.debug("Finding IQ processor for namespace " + packet.getChildElement().getNamespaceURI());
PacketProcessor<IQ> namespaceProcessor = processorsPerNamespace.get(packet.getChildElement().getNamespaceURI());
if (packet.getChildElement().getNamespaceURI() != null && namespaceProcessor != null) {
logger.trace("Using namespace processor: " + namespaceProcessor.getClass().getName());
namespaceProcessor.process(packet);
return;
}
}
// See if this was an externally sent packet
try {
federatedQueueManager.passResponseToRequester(packet);
return;
} catch (UnknownFederatedPacketException e) {
logger.error(e);
}
logger.debug("Couldn't find processor for packet");
if (packet.getType().equals(IQ.Type.set) || packet.getType().equals(IQ.Type.get)) {
IQ reply = IQ.createResultIQ(packet);
reply.setChildElement(packet.getChildElement().createCopy());
reply.setType(Type.error);
PacketError pe = new PacketError(org.xmpp.packet.PacketError.Condition.service_unavailable, org.xmpp.packet.PacketError.Type.cancel);
reply.setError(pe);
this.outQueue.put(reply);
return;
}
logger.error("Could not handle packet " + packet.toXML());
}
}