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:
parent
fcb4844d10
commit
bb8dcc9874
28 changed files with 533 additions and 317 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue