/** * Constructs a new AgentRoster. * * @param connection an XMPP connection. * @throws NotConnectedException */ AgentRoster(XMPPConnection connection, String workgroupJID) throws NotConnectedException { this.connection = connection; this.workgroupJID = workgroupJID; entries = new ArrayList<String>(); listeners = new ArrayList<AgentRosterListener>(); presenceMap = new HashMap<String, Map<String, Presence>>(); // Listen for any roster packets. StanzaFilter rosterFilter = new StanzaTypeFilter(AgentStatusRequest.class); connection.addAsyncStanzaListener(new AgentStatusListener(), rosterFilter); // Listen for any presence packets. connection.addAsyncStanzaListener(new PresencePacketListener(), new StanzaTypeFilter(Presence.class)); // Send request for roster. AgentStatusRequest request = new AgentStatusRequest(); request.setTo(workgroupJID); connection.sendStanza(request); }
/** * Sets the agent's current status with the workgroup. The presence mode affects how offers * are routed to the agent. The possible presence modes with their meanings are as follows:<ul> * <p/> * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats * (equivalent to Presence.Mode.CHAT). * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed. * However, special case, or extreme urgency chats may still be offered to the agent. * <li>Presence.Mode.AWAY -- the agent is not available and should not * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul> * * @param presenceMode the presence mode of the agent. * @param status sets the status message of the presence update. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException * @throws IllegalStateException if the agent is not online with the workgroup. */ public void setStatus(Presence.Mode presenceMode, String status) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!online) { throw new IllegalStateException("Cannot set status when the agent is not online."); } if (presenceMode == null) { presenceMode = Presence.Mode.available; } this.presenceMode = presenceMode; Presence presence = new Presence(Presence.Type.available); presence.setMode(presenceMode); presence.setTo(this.getWorkgroupJID()); if (status != null) { presence.setStatus(status); } presence.addExtension(new MetaData(this.metaData)); PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter(new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence); collector.nextResultOrThrow(); }
/** * Check that the server responds a 503 error code when the client sends an IQ stanza(/packet) with an * invalid namespace. */ public void testInvalidNamespace() { IQ iq = new IQ() { public String getChildElementXML() { StringBuilder buf = new StringBuilder(); buf.append("<query xmlns=\"jabber:iq:anything\">"); buf.append("</query>"); return buf.toString(); } }; PacketFilter filter = new AndFilter(new PacketIDFilter(iq.getStanzaId()), new StanzaTypeFilter(IQ.class)); PacketCollector collector = getConnection(0).createPacketCollector(filter); // Send the iq packet with an invalid namespace getConnection(0).sendStanza(iq); IQ result = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { fail("No response from server"); } else if (result.getType() != IQ.Type.error) { fail("The server didn't reply with an error packet"); } else { assertEquals("Server answered an incorrect error code", 503, result.getError().getCode()); } }
/** * Sets the agent's current status with the workgroup. The presence mode affects how offers * are routed to the agent. The possible presence modes with their meanings are as follows:<ul> * <p/> * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats * (equivalent to Presence.Mode.CHAT). * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed. * However, special case, or extreme urgency chats may still be offered to the agent. * <li>Presence.Mode.AWAY -- the agent is not available and should not * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul> * <p/> * The max chats value is the maximum number of chats the agent is willing to have routed to * them at once. Some servers may be configured to only accept max chat values in a certain * range; for example, between two and five. In that case, the maxChats value the agent sends * may be adjusted by the server to a value within that range. * * @param presenceMode the presence mode of the agent. * @param maxChats the maximum number of chats the agent is willing to accept. * @param status sets the status message of the presence update. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException * @throws IllegalStateException if the agent is not online with the workgroup. */ public void setStatus(Presence.Mode presenceMode, int maxChats, String status) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!online) { throw new IllegalStateException("Cannot set status when the agent is not online."); } if (presenceMode == null) { presenceMode = Presence.Mode.available; } this.presenceMode = presenceMode; this.maxChats = maxChats; Presence presence = new Presence(Presence.Type.available); presence.setMode(presenceMode); presence.setTo(this.getWorkgroupJID()); if (status != null) { presence.setStatus(status); } // Send information about max chats and current chats as a packet extension. DefaultExtensionElement agentStatus = new DefaultExtensionElement(AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE); agentStatus.setValue("max-chats", "" + maxChats); presence.addExtension(agentStatus); presence.addExtension(new MetaData(this.metaData)); PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter( new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence); collector.nextResultOrThrow(); }
/** * Returns true if the workgroup is available for receiving new requests. The workgroup will be * available only when agents are available for this workgroup. * * @return true if the workgroup is available for receiving new requests. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public boolean isAvailable() throws NoResponseException, XMPPErrorException, NotConnectedException { Presence directedPresence = new Presence(Presence.Type.available); directedPresence.setTo(workgroupJID); StanzaFilter typeFilter = new StanzaTypeFilter(Presence.class); StanzaFilter fromFilter = FromMatchesFilter.create(workgroupJID); PacketCollector collector = connection.createPacketCollectorAndSend(new AndFilter(fromFilter, typeFilter), directedPresence); Presence response = (Presence)collector.nextResultOrThrow(); return Presence.Type.available == response.getType(); }
protected StanzaFilter getDataPacketFilter() { /* * filter all IQ stanzas having type 'SET' (represented by Data class), containing a * data stanza(/packet) extension, matching session ID and recipient */ return new AndFilter(new StanzaTypeFilter(Data.class), new IBBDataPacketFilter()); }
@Override protected StanzaFilter getDataPacketFilter() { /* * filter all message stanzas containing a data stanza(/packet) extension, matching session ID * and recipient */ return new AndFilter(new StanzaTypeFilter(Message.class), new IBBDataPacketFilter()); }
/** * Test if entity caps actually prevent a disco info request and reply * * @throws XMPPException * */ public void testPreventDiscoInfo() throws XMPPException { con0.addPacketSendingListener(new PacketListener() { @Override public void processPacket(Packet packet) { discoInfoSend = true; } }, new AndFilter(new StanzaTypeFilter(DiscoverInfo.class), new IQTypeFilter(IQ.Type.get))); // add a bogus feature so that con1 ver won't match con0's sdm1.addFeature(DISCOVER_TEST_FEATURE); dropCapsCache(); // discover that DiscoverInfo info = sdm0.discoverInfo(con1.getUser()); // that discovery should cause a disco#info assertTrue(discoInfoSend); assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE)); discoInfoSend = false; // discover that info = sdm0.discoverInfo(con1.getUser()); // that discovery shouldn't cause a disco#info assertFalse(discoInfoSend); assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE)); }