1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-30 02:02:06 +01:00

Added ability to register a local command using a factory. Improved ad-hoc command tests.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@10905 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Matt Tucker 2008-11-18 23:12:10 +00:00 committed by matt
parent ffb8cd914a
commit e6f29ee641
3 changed files with 111 additions and 24 deletions

View file

@ -62,11 +62,11 @@ public class AdHocCommandManager {
/** /**
* The session time out in seconds. * The session time out in seconds.
*/ */
public static int SESSION_TIMEOUT = 2 * 60; private static final int SESSION_TIMEOUT = 2 * 60;
/** /**
* Map a XMPPConnection with it AdHocCommandManager. This map have a pair * Map a XMPPConnection with it AdHocCommandManager. This map have a key-value
* key-value for every active connection. * pair for every active connection.
*/ */
private static Map<XMPPConnection, AdHocCommandManager> instances = private static Map<XMPPConnection, AdHocCommandManager> instances =
new ConcurrentHashMap<XMPPConnection, AdHocCommandManager>(); new ConcurrentHashMap<XMPPConnection, AdHocCommandManager>();
@ -127,19 +127,38 @@ public class AdHocCommandManager {
} }
/** /**
* Register a new command to this command manager, which is related to a * Registers a new command with this command manager, which is related to a
* connection. The <code>node</code> is an unique identifier of that * connection. The <tt>node</tt> is an unique identifier of that command for
* command for the connection related to this command manager. The * the connection related to this command manager. The <tt>name</tt> is the
* <code>name</name> is the human readable name of the command. * human readable name of the command. The <tt>class</tt> is the class of
* The <code>class</code> is the class of the command, which must extend * the command, which must extend {@link LocalCommand} and have a default
* {@link LocalCommand}. * constructor.
* *
* @param node the unique identifier of the command. * @param node the unique identifier of the command.
* @param name the human readable name of the command. * @param name the human readable name of the command.
* @param clazz the class of the command, which must extend {@link LocalCommand}. * @param clazz the class of the command, which must extend {@link LocalCommand}.
*/ */
public void registerCommand(String node, final String name, Class clazz) { public void registerCommand(String node, String name, final Class clazz) {
AdHocCommandInfo commandInfo = new AdHocCommandInfo(node, name, connection.getUser(), clazz); registerCommand(node, name, new LocalCommandFactory() {
public LocalCommand getInstance() throws InstantiationException, IllegalAccessException {
return (LocalCommand)clazz.newInstance();
}
});
}
/**
* Registers a new command with this command manager, which is related to a
* connection. The <tt>node</tt> is an unique identifier of that
* command for the connection related to this command manager. The <tt>name</tt>
* is the human readeale name of the command. The <tt>factory</tt> generates
* new instances of the command.
*
* @param node the unique identifier of the command.
* @param name the human readable name of the command.
* @param factory a factory to create new instances of the command.
*/
public void registerCommand(String node, final String name, LocalCommandFactory factory) {
AdHocCommandInfo commandInfo = new AdHocCommandInfo(node, name, connection.getUser(), factory);
commands.put(node, commandInfo); commands.put(node, commandInfo);
// Set the NodeInformationProvider that will provide information about // Set the NodeInformationProvider that will provide information about
@ -651,11 +670,10 @@ public class AdHocCommandManager {
private LocalCommand newInstanceOfCmd(String commandNode, String sessionID) private LocalCommand newInstanceOfCmd(String commandNode, String sessionID)
throws XMPPException throws XMPPException
{ {
// TODO Evaluate the possibility of using a factory for creating the new instances.
AdHocCommandInfo commandInfo = commands.get(commandNode); AdHocCommandInfo commandInfo = commands.get(commandNode);
LocalCommand command; LocalCommand command;
try { try {
command = (LocalCommand) commandInfo.getCmdClass().newInstance(); command = (LocalCommand) commandInfo.getCommandInstance();
command.setSessionID(sessionID); command.setSessionID(sessionID);
command.setName(commandInfo.getName()); command.setName(commandInfo.getName());
command.setNode(commandInfo.getNode()); command.setNode(commandInfo.getNode());
@ -684,29 +702,28 @@ public class AdHocCommandManager {
} }
/** /**
* The ad-hoc command information. * Stores ad-hoc command information.
*
* @author Gabriel
*
*/ */
private static class AdHocCommandInfo { private static class AdHocCommandInfo {
private String node; private String node;
private String name; private String name;
private String ownerJID; private String ownerJID;
private Class cmdClass; private LocalCommandFactory factory;
public AdHocCommandInfo(String node, String name, String ownerJID, public AdHocCommandInfo(String node, String name, String ownerJID,
Class cmdClass) LocalCommandFactory factory)
{ {
this.node = node; this.node = node;
this.name = name; this.name = name;
this.ownerJID = ownerJID; this.ownerJID = ownerJID;
this.cmdClass = cmdClass; this.factory = factory;
} }
public Class getCmdClass() { public LocalCommand getCommandInstance() throws InstantiationException,
return cmdClass; IllegalAccessException
{
return factory.getInstance();
} }
public String getName() { public String getName() {

View file

@ -0,0 +1,24 @@
package org.jivesoftware.smackx.commands;
/**
* A factory for creating local commands. It's useful in cases where instantiation
* of a command is more complicated than just using the default constructor. For example,
* when arguments must be passed into the constructor or when using a dependency injection
* framework. When a LocalCommandFactory isn't used, you can provide the AdHocCommandManager
* a Class object instead. For more details, see
* {@link AdHocCommandManager#registerCommand(String, String, LocalCommandFactory)}.
*
* @author Matt Tucker
*/
public interface LocalCommandFactory {
/**
* Returns an instance of a LocalCommand.
*
* @return a LocalCommand instance.
* @throws InstantiationException if creating an instance failed.
* @throws IllegalAccessException if creating an instance is not allowed.
*/
public LocalCommand getInstance() throws InstantiationException, IllegalAccessException;
}

View file

@ -53,10 +53,13 @@
package org.jivesoftware.smackx.commands; package org.jivesoftware.smackx.commands;
import org.jivesoftware.smack.test.SmackTestCase; import org.jivesoftware.smack.test.SmackTestCase;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.packet.DiscoverItems; import org.jivesoftware.smackx.packet.DiscoverItems;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
/** /**
* * AdHocCommand tests.
* *
* @author Matt Tucker * @author Matt Tucker
*/ */
@ -70,15 +73,58 @@ public class AdHocCommandDiscoTest extends SmackTestCase {
super(arg0); super(arg0);
} }
public void testInvitation() { public void testAdHocCommands() {
try { try {
AdHocCommandManager manager1 = AdHocCommandManager.getAddHocCommandsManager(getConnection(0)); AdHocCommandManager manager1 = AdHocCommandManager.getAddHocCommandsManager(getConnection(0));
manager1.registerCommand("test", "test node", LocalCommand.class); manager1.registerCommand("test", "test node", LocalCommand.class);
manager1.registerCommand("test2", "test node", new LocalCommandFactory() {
public LocalCommand getInstance() throws InstantiationException, IllegalAccessException {
return new LocalCommand() {
public boolean isLastStage() {
return true;
}
public boolean hasPermission(String jid) {
return true;
}
public void execute() throws XMPPException {
Form result = new Form(Form.TYPE_RESULT);
FormField resultField = new FormField("test2");
resultField.setLabel("test node");
resultField.addValue("it worked");
result.addField(resultField);
setForm(result);
}
public void next(Form response) throws XMPPException {
//
}
public void complete(Form response) throws XMPPException {
//
}
public void prev() throws XMPPException {
//
}
public void cancel() throws XMPPException {
//
}
};
}
});
AdHocCommandManager manager2 = AdHocCommandManager.getAddHocCommandsManager(getConnection(1)); AdHocCommandManager manager2 = AdHocCommandManager.getAddHocCommandsManager(getConnection(1));
DiscoverItems items = manager2.discoverCommands(getFullJID(0)); DiscoverItems items = manager2.discoverCommands(getFullJID(0));
assertTrue("Disco for command test failed", items.getItems().next().getNode().equals("test")); assertTrue("Disco for command test failed", items.getItems().next().getNode().equals("test"));
RemoteCommand command = manager2.getRemoteCommand(getFullJID(0), "test2");
command.execute();
assertEquals("Disco for command test failed", command.getForm().getField("test2").getValues().next(), "it worked");
} }
catch (Exception e) { catch (Exception e) {
fail(e.getMessage()); fail(e.getMessage());