Search in sources :

Example 1 with FillableForm

use of org.jivesoftware.smackx.xdata.form.FillableForm in project Smack by igniterealtime.

the class ServiceAdministrationManager method addUser.

public void addUser(final EntityBareJid userJid, final String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    RemoteCommand command = addUser();
    command.execute();
    FillableForm answerForm = new FillableForm(command.getForm());
    answerForm.setAnswer("accountjid", userJid);
    answerForm.setAnswer("password", password);
    answerForm.setAnswer("password-verify", password);
    command.execute(answerForm);
    assert command.isCompleted();
}
Also used : RemoteCommand(org.jivesoftware.smackx.commands.RemoteCommand) FillableForm(org.jivesoftware.smackx.xdata.form.FillableForm)

Example 2 with FillableForm

use of org.jivesoftware.smackx.xdata.form.FillableForm in project Smack by igniterealtime.

the class AdHocCommandManager method processAdHocCommand.

/**
 * Process the AdHoc-Command stanza that request the execution of some
 * action of a command. If this is the first request, this method checks,
 * before executing the command, if:
 * <ul>
 *  <li>The requested command exists</li>
 *  <li>The requester has permissions to execute it</li>
 *  <li>The command has more than one stage, if so, it saves the command and
 *      session ID for further use</li>
 * </ul>
 *
 * <br>
 * <br>
 * If this is not the first request, this method checks, before executing
 * the command, if:
 * <ul>
 *  <li>The session ID of the request was stored</li>
 *  <li>The session life do not exceed the time out</li>
 *  <li>The action to execute is one of the available actions</li>
 * </ul>
 *
 * @param requestData TODO javadoc me please
 *            the stanza to process.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws InterruptedException if the calling thread was interrupted.
 */
private IQ processAdHocCommand(AdHocCommandData requestData) throws NoResponseException, NotConnectedException, InterruptedException {
    // Creates the response with the corresponding data
    AdHocCommandData response = new AdHocCommandData();
    response.setTo(requestData.getFrom());
    response.setStanzaId(requestData.getStanzaId());
    response.setNode(requestData.getNode());
    response.setId(requestData.getTo());
    String sessionId = requestData.getSessionID();
    String commandNode = requestData.getNode();
    if (sessionId == null) {
        // command exists
        if (!commands.containsKey(commandNode)) {
            // item_not_found error.
            return respondError(response, StanzaError.Condition.item_not_found);
        }
        // Create new session ID
        sessionId = StringUtils.randomString(15);
        try {
            // Create a new instance of the command with the
            // corresponding sessionid
            LocalCommand command;
            try {
                command = newInstanceOfCmd(commandNode, sessionId);
            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                StanzaError xmppError = StanzaError.getBuilder().setCondition(StanzaError.Condition.internal_server_error).setDescriptiveEnText(e.getMessage()).build();
                return respondError(response, xmppError);
            }
            response.setType(IQ.Type.result);
            command.setData(response);
            // enough to execute the requested command
            if (!command.hasPermission(requestData.getFrom())) {
                return respondError(response, StanzaError.Condition.forbidden);
            }
            Action action = requestData.getAction();
            // If the action is unknown then respond an error.
            if (action != null && action.equals(Action.unknown)) {
                return respondError(response, StanzaError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.malformedAction);
            }
            // If the action is not execute, then it is an invalid action.
            if (action != null && !action.equals(Action.execute)) {
                return respondError(response, StanzaError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badAction);
            }
            // Increase the state number, so the command knows in witch
            // stage it is
            command.incrementStage();
            // Executes the command
            command.execute();
            if (command.isLastStage()) {
                // If there is only one stage then the command is completed
                response.setStatus(Status.completed);
            } else {
                // Else it is still executing, and is registered to be
                // available for the next call
                response.setStatus(Status.executing);
                executingCommands.put(sessionId, command);
                // See if the session sweeper thread is scheduled. If not, start it.
                maybeWindUpSessionSweeper();
            }
            // Sends the response packet
            return response;
        } catch (XMPPErrorException e) {
            // If there is an exception caused by the next, complete,
            // prev or cancel method, then that error is returned to the
            // requester.
            StanzaError error = e.getStanzaError();
            // command be removed from the executing list.
            if (StanzaError.Type.CANCEL.equals(error.getType())) {
                response.setStatus(Status.canceled);
                executingCommands.remove(sessionId);
            }
            return respondError(response, error);
        }
    } else {
        LocalCommand command = executingCommands.get(sessionId);
        // of getting the key and the value of the map.
        if (command == null) {
            return respondError(response, StanzaError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badSessionid);
        }
        // Check if the Session data has expired (default is 10 minutes)
        long creationStamp = command.getCreationDate();
        if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000) {
            // Remove the expired session
            executingCommands.remove(sessionId);
            // Answer a not_allowed error (session-expired)
            return respondError(response, StanzaError.Condition.not_allowed, AdHocCommand.SpecificErrorCondition.sessionExpired);
        }
        /*
             * Since the requester could send two requests for the same
             * executing command i.e. the same session id, all the execution of
             * the action must be synchronized to avoid inconsistencies.
             */
        synchronized (command) {
            Action action = requestData.getAction();
            // If the action is unknown the respond an error
            if (action != null && action.equals(Action.unknown)) {
                return respondError(response, StanzaError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.malformedAction);
            }
            // action then follow the actual default execute action
            if (action == null || Action.execute.equals(action)) {
                action = command.getExecuteAction();
            }
            // offered
            if (!command.isValidAction(action)) {
                return respondError(response, StanzaError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badAction);
            }
            try {
                // TODO: Check that all the required fields of the form are
                // TODO: filled, if not throw an exception. This will simplify the
                // TODO: construction of new commands
                // Since all errors were passed, the response is now a
                // result
                response.setType(IQ.Type.result);
                // Set the new data to the command.
                command.setData(response);
                if (Action.next.equals(action)) {
                    command.incrementStage();
                    DataForm dataForm = requestData.getForm();
                    command.next(new FillableForm(dataForm));
                    if (command.isLastStage()) {
                        // If it is the last stage then the command is
                        // completed
                        response.setStatus(Status.completed);
                    } else {
                        // Otherwise it is still executing
                        response.setStatus(Status.executing);
                    }
                } else if (Action.complete.equals(action)) {
                    command.incrementStage();
                    DataForm dataForm = requestData.getForm();
                    command.complete(new FillableForm(dataForm));
                    response.setStatus(Status.completed);
                    // Remove the completed session
                    executingCommands.remove(sessionId);
                } else if (Action.prev.equals(action)) {
                    command.decrementStage();
                    command.prev();
                } else if (Action.cancel.equals(action)) {
                    command.cancel();
                    response.setStatus(Status.canceled);
                    // Remove the canceled session
                    executingCommands.remove(sessionId);
                }
                return response;
            } catch (XMPPErrorException e) {
                // If there is an exception caused by the next, complete,
                // prev or cancel method, then that error is returned to the
                // requester.
                StanzaError error = e.getStanzaError();
                // command be removed from the executing list.
                if (StanzaError.Type.CANCEL.equals(error.getType())) {
                    response.setStatus(Status.canceled);
                    executingCommands.remove(sessionId);
                }
                return respondError(response, error);
            }
        }
    }
}
Also used : Action(org.jivesoftware.smackx.commands.AdHocCommand.Action) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) FillableForm(org.jivesoftware.smackx.xdata.form.FillableForm) InvocationTargetException(java.lang.reflect.InvocationTargetException) StanzaError(org.jivesoftware.smack.packet.StanzaError) AdHocCommandData(org.jivesoftware.smackx.commands.packet.AdHocCommandData) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm)

Example 3 with FillableForm

use of org.jivesoftware.smackx.xdata.form.FillableForm in project Smack by igniterealtime.

the class FormTest method testFilloutForm.

/**
 * 1. Create a form to fill out and send it to the other user
 * 2. Retrieve the form to fill out, complete it and return it to the requestor
 * 3. Retrieve the completed form and check that everything is OK
 *
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws NotConnectedException if the XMPP connection is not connected.
 */
@SuppressWarnings("deprecation")
@SmackIntegrationTest
public void testFilloutForm() throws NotConnectedException, InterruptedException {
    DataForm.Builder formToSend = DataForm.builder(DataForm.Type.form);
    formToSend.setInstructions("Fill out this form to report your case.\nThe case will be created automatically.");
    formToSend.setTitle("Case configurations");
    formToSend.setFormType("https://igniterealtime.org/projects/smack/sinttest/form-test/1");
    // Add a hidden variable
    FormField field = FormField.hiddenBuilder("hidden_var").setValue("Some value for the hidden variable").build();
    formToSend.addField(field);
    // Add a fixed variable
    field = FormField.fixedBuilder().setValue("Section 1: Case description").build();
    formToSend.addField(field);
    // Add a text-single variable
    field = FormField.textSingleBuilder("name").setLabel("Enter a name for the case").build();
    formToSend.addField(field);
    // Add a text-multi variable
    field = FormField.textMultiBuilder("description").setLabel("Enter a description").build();
    formToSend.addField(field);
    // Add a boolean variable
    field = FormField.booleanBuilder("time").setLabel("Is this your first case?").build();
    formToSend.addField(field);
    // Add a text variable where an int value is expected
    field = FormField.textSingleBuilder("age").setLabel("How old are you?").build();
    formToSend.addField(field);
    // Create the chats between the two participants
    org.jivesoftware.smack.chat.Chat chat = org.jivesoftware.smack.chat.ChatManager.getInstanceFor(conOne).createChat(conTwo.getUser(), null);
    StanzaCollector collector = conOne.createStanzaCollector(new ThreadFilter(chat.getThreadID()));
    StanzaCollector collector2 = conTwo.createStanzaCollector(new ThreadFilter(chat.getThreadID()));
    Message msg = StanzaBuilder.buildMessage().setBody("To enter a case please fill out this form and send it back to me").addExtension(formToSend.build()).build();
    try {
        // Send the message with the form to fill out
        chat.sendMessage(msg);
        // Get the message with the form to fill out
        Message msg2 = collector2.nextResult();
        assertNotNull(msg2, "Message not found");
        // Retrieve the form to fill out
        Form formToRespond = Form.from(msg2);
        assertNotNull(formToRespond);
        assertNotNull(formToRespond.getField("name"));
        assertNotNull(formToRespond.getField("description"));
        // Obtain the form to send with the replies
        final FillableForm completedForm = formToRespond.getFillableForm();
        assertNotNull(completedForm.getField("hidden_var"));
        // Check that a field of type String does not accept booleans
        assertThrows(IllegalArgumentException.class, () -> completedForm.setAnswer("name", true));
        completedForm.setAnswer("name", "Credit card number invalid");
        completedForm.setAnswer("description", "The ATM says that my credit card number is invalid. What's going on?");
        completedForm.setAnswer("time", true);
        completedForm.setAnswer("age", 20);
        // Create a new message to send with the completed form
        msg2 = StanzaBuilder.buildMessage().to(conOne.getUser().asBareJid()).setThread(msg.getThread()).ofType(Message.Type.chat).setBody("To enter a case please fill out this form and send it back to me").addExtension(completedForm.getDataFormToSubmit()).build();
        // Send the message with the completed form
        conTwo.sendStanza(msg2);
        // Get the message with the completed form
        Message msg3 = collector.nextResult();
        assertNotNull(msg3, "Message not found");
        // Retrieve the completed form
        final DataForm completedForm2 = DataForm.from(msg3);
        assertNotNull(completedForm2);
        assertNotNull(completedForm2.getField("name"));
        assertNotNull(completedForm2.getField("description"));
        assertEquals(completedForm2.getField("name").getValues().get(0).toString(), "Credit card number invalid");
        assertNotNull(completedForm2.getField("time"));
        assertNotNull(completedForm2.getField("age"));
        assertEquals("20", completedForm2.getField("age").getValues().get(0).toString(), "The age is bad");
    } finally {
        collector.cancel();
        collector2.cancel();
    }
}
Also used : Message(org.jivesoftware.smack.packet.Message) Form(org.jivesoftware.smackx.xdata.form.Form) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) FillableForm(org.jivesoftware.smackx.xdata.form.FillableForm) ThreadFilter(org.jivesoftware.smack.filter.ThreadFilter) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) FillableForm(org.jivesoftware.smackx.xdata.form.FillableForm) StanzaCollector(org.jivesoftware.smack.StanzaCollector) AbstractSmackIntegrationTest(org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest) SmackIntegrationTest(org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)

Example 4 with FillableForm

use of org.jivesoftware.smackx.xdata.form.FillableForm in project Smack by igniterealtime.

the class ServiceAdministrationManager method deleteUser.

public void deleteUser(Set<EntityBareJid> jidsToDelete) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    RemoteCommand command = deleteUser();
    command.execute();
    FillableForm answerForm = new FillableForm(command.getForm());
    answerForm.setAnswer("accountjids", jidsToDelete);
    command.execute(answerForm);
    assert command.isCompleted();
}
Also used : RemoteCommand(org.jivesoftware.smackx.commands.RemoteCommand) FillableForm(org.jivesoftware.smackx.xdata.form.FillableForm)

Aggregations

FillableForm (org.jivesoftware.smackx.xdata.form.FillableForm)4 RemoteCommand (org.jivesoftware.smackx.commands.RemoteCommand)2 DataForm (org.jivesoftware.smackx.xdata.packet.DataForm)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 AbstractSmackIntegrationTest (org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest)1 SmackIntegrationTest (org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)1 StanzaCollector (org.jivesoftware.smack.StanzaCollector)1 XMPPErrorException (org.jivesoftware.smack.XMPPException.XMPPErrorException)1 ThreadFilter (org.jivesoftware.smack.filter.ThreadFilter)1 Message (org.jivesoftware.smack.packet.Message)1 StanzaError (org.jivesoftware.smack.packet.StanzaError)1 Action (org.jivesoftware.smackx.commands.AdHocCommand.Action)1 AdHocCommandData (org.jivesoftware.smackx.commands.packet.AdHocCommandData)1 Form (org.jivesoftware.smackx.xdata.form.Form)1