/** * Returns the discovered items of a given XMPP entity addressed by its JID and note attribute. * Use this message only when trying to query information which is not directly addressable. * * @param entityID the address of the XMPP entity. * @param node the attribute that supplements the 'jid' attribute. * @return the discovered items. * @throws XMPPException if the operation failed for some reason. */ public DiscoverItems discoverItems(String entityID, String node) throws XMPPException { // Discover the entity's items DiscoverItems disco = new DiscoverItems(); disco.setType(IQ.Type.GET); disco.setTo(entityID); disco.setNode(node); // Create a packet collector to listen for a response. PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); connection.sendPacket(disco); // Wait up to 5 seconds for a result. IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from the server."); } if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } return (DiscoverItems) result; }
public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException { PacketCollector collector = connection.createPacketCollector( getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID())); connection.sendPacket(super.createInitiationAccept(initiation, getNamespaces())); ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(2); CompletionService<InputStream> service = new ExecutorCompletionService<InputStream>(threadPoolExecutor); List<Future<InputStream>> futures = new ArrayList<Future<InputStream>>(); InputStream stream = null; XMPPException exception = null; try { futures.add(service.submit(new NegotiatorService(collector))); futures.add(service.submit(new NegotiatorService(collector))); int i = 0; while (stream == null && i < futures.size()) { Future<InputStream> future; try { i++; future = service.poll(10, TimeUnit.SECONDS); } catch (InterruptedException e) { continue; } if (future == null) { continue; } try { stream = future.get(); } catch (InterruptedException e) { /* Do Nothing */ } catch (ExecutionException e) { exception = new XMPPException(e.getCause()); } } } finally { for (Future<InputStream> future : futures) { future.cancel(true); } collector.cancel(); threadPoolExecutor.shutdownNow(); } if (stream == null) { if (exception != null) { throw exception; } else { throw new XMPPException("File transfer negotiation failed."); } } return stream; }
/** * 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 XMPPException */ public boolean isAvailable() throws XMPPException { Presence directedPresence = new Presence(Presence.Type.available); directedPresence.setTo(workgroupJID); PacketFilter typeFilter = new PacketTypeFilter(Presence.class); PacketFilter fromFilter = FromMatchesFilter.create(workgroupJID); PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter, typeFilter)); connection.sendPacket(directedPresence); Presence response = (Presence) collector.nextResultOrThrow(); return Presence.Type.available == response.getType(); }
/** * Gets the account registration info from the server. * * @throws XMPPException if an error occurs. */ private synchronized void getRegistrationInfo() throws XMPPException { Registration reg = new Registration(); reg.setTo(connection.getServiceName()); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class)); PacketCollector collector = connection.createPacketCollector(filter); connection.sendPacket(reg); IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from server."); } else if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } else { info = (Registration) result; } }
/** * Send a request to another user to send them a file. The other user has the option of, * accepting, rejecting, or not responding to a received file transfer request. * * <p>If they accept, the packet will contain the other user's chosen stream type to send the file * across. The two choices this implementation provides to the other user for file transfer are <a * href="http://www.jabber.org/jeps/jep-0065.html">SOCKS5 Bytestreams</a>, which is the preferred * method of transfer, and <a href="http://www.jabber.org/jeps/jep-0047.html">In-Band * Bytestreams</a>, which is the fallback mechanism. * * <p>The other user may choose to decline the file request if they do not desire the file, their * client does not support JEP-0096, or if there are no acceptable means to transfer the file. * * <p>Finally, if the other user does not respond this method will return null after the specified * timeout. * * @param userID The userID of the user to whom the file will be sent. * @param streamID The unique identifier for this file transfer. * @param fileName The name of this file. Preferably it should include an extension as it is used * to determine what type of file it is. * @param size The size, in bytes, of the file. * @param desc A description of the file. * @param responseTimeout The amount of time, in milliseconds, to wait for the remote user to * respond. If they do not respond in time, this * @return Returns the stream negotiator selected by the peer. * @throws XMPPException Thrown if there is an error negotiating the file transfer. */ public StreamNegotiator negotiateOutgoingTransfer( final String userID, final String streamID, final String fileName, final long size, final String desc, int responseTimeout) throws XMPPException { final StreamInitiation si = new StreamInitiation(); si.setSesssionID(streamID); si.setMimeType(URLConnection.guessContentTypeFromName(fileName)); final StreamInitiation.File siFile = new StreamInitiation.File(fileName, size); siFile.setDesc(desc); si.setFile(siFile); si.setFeatureNegotiationForm(createDefaultInitiationForm()); si.setFrom(connection.getUser()); si.setTo(userID); si.setType(IQ.Type.SET); final PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(si.getPacketID())); connection.sendPacket(si); final Packet siResponse = collector.nextResult(responseTimeout); collector.cancel(); if (siResponse instanceof IQ) { final IQ iqResponse = (IQ) siResponse; if (iqResponse.getType().equals(IQ.Type.RESULT)) { final StreamInitiation response = (StreamInitiation) siResponse; return getOutgoingNegotiator(getStreamMethodField(response.getFeatureNegotiationForm())); } else if (iqResponse.getType().equals(IQ.Type.ERROR)) { throw new XMPPException(iqResponse.getError()); } else { throw new XMPPException("File transfer response unreadable"); } } else { return null; } }
/** * Returns the transcripts of a given user. The answer will contain the complete history of * conversations that a user had. * * @param userID the id of the user to get his conversations. * @param workgroupJID the JID of the workgroup that will process the request. * @return the transcripts of a given user. * @throws XMPPException if an error occurs while getting the information. */ public Transcripts getTranscripts(String workgroupJID, String userID) throws XMPPException { Transcripts request = new Transcripts(userID); request.setTo(workgroupJID); PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID())); // Send the request connection.sendPacket(request); Transcripts response = (Transcripts) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Cancel the collector. collector.cancel(); if (response == null) { throw new XMPPException("No response from server on status set."); } if (response.getError() != null) { throw new XMPPException(response.getError()); } return response; }
/** * Changes the password of the currently logged-in account. This operation can only be performed * after a successful login operation has been completed. Not all servers support changing * passwords; an XMPPException will be thrown when that is the case. * * @throws IllegalStateException if not currently logged-in to the server. * @throws XMPPException if an error occurs when changing the password. */ public void changePassword(String newPassword) throws XMPPException { Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); Map<String, String> map = new HashMap<String, String>(); map.put("username", StringUtils.parseName(connection.getUser())); map.put("password", newPassword); reg.setAttributes(map); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class)); PacketCollector collector = connection.createPacketCollector(filter); connection.sendPacket(reg); IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from server."); } else if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } }
/** * Deletes the currently logged-in account from the server. This operation can only be performed * after a successful login operation has been completed. Not all servers support deleting * accounts; an XMPPException will be thrown when that is the case. * * @throws IllegalStateException if not currently logged-in to the server. * @throws XMPPException if an error occurs when deleting the account. */ public void deleteAccount() throws XMPPException { if (!connection.isAuthenticated()) { throw new IllegalStateException("Must be logged in to delete a account."); } Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); Map<String, String> attributes = new HashMap<String, String>(); // To delete an account, we add a single attribute, "remove", that is blank. attributes.put("remove", ""); reg.setAttributes(attributes); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class)); PacketCollector collector = connection.createPacketCollector(filter); connection.sendPacket(reg); IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from server."); } else if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } }
/** * Creates a new account using the specified username, password and account attributes. The * attributes Map must contain only String name/value pairs and must also have values for all * required attributes. * * @param username the username. * @param password the password. * @param attributes the account attributes. * @throws XMPPException if an error occurs creating the account. * @see #getAccountAttributes() */ public void createAccount(String username, String password, Map<String, String> attributes) throws XMPPException { if (!supportsAccountCreation()) { throw new XMPPException("Server does not support account creation."); } Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); attributes.put("username", username); attributes.put("password", password); reg.setAttributes(attributes); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class)); PacketCollector collector = connection.createPacketCollector(filter); connection.sendPacket(reg); IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from server."); } else if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } }