1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-12-14 06:51:08 +01:00

Add IQ request handler API

This also moves the logic to send error IQ replies from "when there is
no IQ provider registerd" to "when there is no IQ request handler
registered". Which has for example the advantage that IQ parsing no
longer asks for a connection instance.
This commit is contained in:
Florian Schmaus 2015-01-08 11:01:35 +01:00
parent fcb4844d10
commit bb8dcc9874
28 changed files with 533 additions and 317 deletions

View file

@ -28,7 +28,6 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -36,12 +35,9 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.IQTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.commands.AdHocCommand.Action;
@ -73,9 +69,6 @@ public class AdHocCommandManager extends Manager {
*/
private static final int SESSION_TIMEOUT = 2 * 60;
private static final PacketFilter AD_HOC_COMMAND_FILTER = new AndFilter(
new PacketTypeFilter(AdHocCommandData.class), IQTypeFilter.SET);
/**
* Map a XMPPConnection with it AdHocCommandManager. This map have a key-value
* pair for every active connection.
@ -174,19 +167,20 @@ public class AdHocCommandManager extends Manager {
// The packet listener and the filter for processing some AdHoc Commands
// Packets
PacketListener listener = new PacketListener() {
public void processPacket(Packet packet) {
AdHocCommandData requestData = (AdHocCommandData) packet;
connection.registerIQRequestHandler(new AbstractIqRequestHandler(AdHocCommandData.ELEMENT,
AdHocCommandData.NAMESPACE, IQ.Type.set, Mode.async) {
@Override
public IQ handleIQRequest(IQ iqRequest) {
AdHocCommandData requestData = (AdHocCommandData) iqRequest;
try {
processAdHocCommand(requestData);
return processAdHocCommand(requestData);
}
catch (NotConnectedException | NoResponseException e) {
catch (NoResponseException | NotConnectedException e) {
LOGGER.log(Level.INFO, "processAdHocCommand threw exceptino", e);
return null;
}
}
};
connection.addAsyncPacketListener(listener, AD_HOC_COMMAND_FILTER);
});
sessionsSweeper = null;
}
@ -325,7 +319,7 @@ public class AdHocCommandManager extends Manager {
* @throws NotConnectedException
* @throws NoResponseException
*/
private void processAdHocCommand(AdHocCommandData requestData) throws NotConnectedException, NoResponseException {
private IQ processAdHocCommand(AdHocCommandData requestData) throws NoResponseException, NotConnectedException {
// Creates the response with the corresponding data
AdHocCommandData response = new AdHocCommandData();
response.setTo(requestData.getFrom());
@ -342,8 +336,7 @@ public class AdHocCommandManager extends Manager {
if (!commands.containsKey(commandNode)) {
// Requested command does not exist so return
// item_not_found error.
respondError(response, XMPPError.Condition.item_not_found);
return;
return respondError(response, XMPPError.Condition.item_not_found);
}
// Create new session ID
@ -361,24 +354,21 @@ public class AdHocCommandManager extends Manager {
// Answer forbidden error if requester permissions are not
// enough to execute the requested command
if (!command.hasPermission(requestData.getFrom())) {
respondError(response, XMPPError.Condition.forbidden);
return;
return respondError(response, XMPPError.Condition.forbidden);
}
Action action = requestData.getAction();
// If the action is unknown then respond an error.
if (action != null && action.equals(Action.unknown)) {
respondError(response, XMPPError.Condition.bad_request,
return respondError(response, XMPPError.Condition.bad_request,
AdHocCommand.SpecificErrorCondition.malformedAction);
return;
}
// If the action is not execute, then it is an invalid action.
if (action != null && !action.equals(Action.execute)) {
respondError(response, XMPPError.Condition.bad_request,
return respondError(response, XMPPError.Condition.bad_request,
AdHocCommand.SpecificErrorCondition.badAction);
return;
}
// Increase the state number, so the command knows in witch
@ -441,7 +431,7 @@ public class AdHocCommandManager extends Manager {
}
// Sends the response packet
connection().sendPacket(response);
return response;
}
catch (XMPPErrorException e) {
@ -457,7 +447,7 @@ public class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
respondError(response, error);
return respondError(response, error);
}
}
else {
@ -467,9 +457,8 @@ public class AdHocCommandManager extends Manager {
// This also handles if the command was removed in the meanwhile
// of getting the key and the value of the map.
if (command == null) {
respondError(response, XMPPError.Condition.bad_request,
return respondError(response, XMPPError.Condition.bad_request,
AdHocCommand.SpecificErrorCondition.badSessionid);
return;
}
// Check if the Session data has expired (default is 10 minutes)
@ -479,9 +468,8 @@ public class AdHocCommandManager extends Manager {
executingCommands.remove(sessionId);
// Answer a not_allowed error (session-expired)
respondError(response, XMPPError.Condition.not_allowed,
return respondError(response, XMPPError.Condition.not_allowed,
AdHocCommand.SpecificErrorCondition.sessionExpired);
return;
}
/*
@ -494,9 +482,8 @@ public class AdHocCommandManager extends Manager {
// If the action is unknown the respond an error
if (action != null && action.equals(Action.unknown)) {
respondError(response, XMPPError.Condition.bad_request,
return respondError(response, XMPPError.Condition.bad_request,
AdHocCommand.SpecificErrorCondition.malformedAction);
return;
}
// If the user didn't specify an action or specify the execute
@ -508,9 +495,8 @@ public class AdHocCommandManager extends Manager {
// Check that the specified action was previously
// offered
if (!command.isValidAction(action)) {
respondError(response, XMPPError.Condition.bad_request,
return respondError(response, XMPPError.Condition.bad_request,
AdHocCommand.SpecificErrorCondition.badAction);
return;
}
try {
@ -556,7 +542,7 @@ public class AdHocCommandManager extends Manager {
executingCommands.remove(sessionId);
}
connection().sendPacket(response);
return response;
}
catch (XMPPErrorException e) {
// If there is an exception caused by the next, complete,
@ -571,7 +557,7 @@ public class AdHocCommandManager extends Manager {
response.setStatus(Status.canceled);
executingCommands.remove(sessionId);
}
respondError(response, error);
return respondError(response, error);
}
}
}
@ -584,9 +570,9 @@ public class AdHocCommandManager extends Manager {
* @param condition the condition of the error.
* @throws NotConnectedException
*/
private void respondError(AdHocCommandData response,
XMPPError.Condition condition) throws NotConnectedException {
respondError(response, new XMPPError(condition));
private IQ respondError(AdHocCommandData response,
XMPPError.Condition condition) {
return respondError(response, new XMPPError(condition));
}
/**
@ -597,11 +583,11 @@ public class AdHocCommandManager extends Manager {
* @param specificCondition the adhoc command error condition.
* @throws NotConnectedException
*/
private void respondError(AdHocCommandData response, XMPPError.Condition condition,
AdHocCommand.SpecificErrorCondition specificCondition) throws NotConnectedException
private static IQ respondError(AdHocCommandData response, XMPPError.Condition condition,
AdHocCommand.SpecificErrorCondition specificCondition)
{
XMPPError error = new XMPPError(condition, new AdHocCommandData.SpecificError(specificCondition));
respondError(response, error);
return respondError(response, error);
}
/**
@ -611,10 +597,10 @@ public class AdHocCommandManager extends Manager {
* @param error the error to send.
* @throws NotConnectedException
*/
private void respondError(AdHocCommandData response, XMPPError error) throws NotConnectedException {
private static IQ respondError(AdHocCommandData response, XMPPError error) {
response.setType(IQ.Type.error);
response.setError(error);
connection().sendPacket(response);
return response;
}
/**