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();
}
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);
}
}
}
}
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();
}
}
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();
}
Aggregations