package org.jivesoftware.xmpp.workgroup.spi.dispatcher; import org.jivesoftware.xmpp.workgroup.AgentSession; import org.jivesoftware.xmpp.workgroup.Offer; import org.jivesoftware.xmpp.workgroup.Workgroup; import org.jivesoftware.xmpp.workgroup.dispatcher.AgentSelector; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Basic implementation that uses the following condition for selecting possible agents: * <ul> * <li>the presence status of the agent allows to receive offers</li> * <li>the maximum of chats has not been reached for the agent</li> * <li>the agent has not rejected the offer before</li> * <li>the agent does not have to answer a previuos offer</li> * </ul> * <p/> * And the best agent will be the one with less number of chats. If more than one agent has * the less number of chats then the agent that never rejected the offer will be selected. * * @author Gaston Dombiak */ public class BasicAgentSelector implements AgentSelector { /** * Returns true if the agent session may receive an offer. An agent session may receive new * offers if: * <p/> * 1) the presence status of the agent allows to receive offers * 2) the maximum of chats has not been reached for the agent * 3) the agent has not rejected the offer before * 4) the agent does not have to answer a previuos offer */ public boolean validateAgent(AgentSession session, Offer offer) { Workgroup workgroup = offer.getRequest().getWorkgroup(); return session != null && session.isAvailableToChat() && session.getCurrentChats(workgroup) < session.getMaxChats(workgroup) && !offer.isRejector(session) && !session.isWaitingOfferAnswer(); } /** * The best agent will be the agent with less number of chats. If more than one agent has * the less number of chats then select the agent that never rejected the offer. */ public AgentSession bestAgentFrom(List<AgentSession> possibleSessions, Offer offer) { Collections.sort(possibleSessions, new SessionComparator(offer)); int size = possibleSessions.size() - 1; return possibleSessions.get(size); } /** * Sort/compare the AgentSessions based on the number of current chats. But if the number of * chats is equal then sort/compare based on previous rejections of the offer. */ private class SessionComparator implements Comparator<AgentSession> { private Offer offer; public SessionComparator(Offer offer) { super(); this.offer = offer; } public int compare(AgentSession item1, AgentSession item2) { Workgroup workgroup = offer.getRequest().getWorkgroup(); int int1 = item1.getCurrentChats(workgroup); int int2 = item2.getCurrentChats(workgroup); if (int1 == int2) { // Base the decision on previous offer rejections int rejec1 = offer.getRejections().contains(item1.getJID().toBareJID()) ? 1 : 0; int rejec2 = offer.getRejections().contains(item2.getJID().toBareJID()) ? 1 : 0; if (rejec1 == rejec2) { long time1 = item1.getTimeLastChatEnded() == null ? 0 : item1.getTimeLastChatEnded().getTime(); long time2 = item2.getTimeLastChatEnded() == null ? 0 : item2.getTimeLastChatEnded().getTime(); if (time1 == time2) { return 0; } if (time1 > time2) { return -1; } if (time1 < time2) { return 1; } } else if (rejec1 > rejec2) { return -1; } else { return 1; } } if (int1 > int2) { return -1; } if (int1 < int2) { return 1; } return 0; } } }