RemoteCommand.java

  1. /**
  2.  *
  3.  * Copyright 2005-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.commands;

  18. import org.jivesoftware.smack.SmackException.NoResponseException;
  19. import org.jivesoftware.smack.SmackException.NotConnectedException;
  20. import org.jivesoftware.smack.XMPPConnection;
  21. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  22. import org.jivesoftware.smack.packet.IQ;
  23. import org.jivesoftware.smackx.commands.packet.AdHocCommandData;
  24. import org.jivesoftware.smackx.xdata.Form;
  25. import org.jxmpp.jid.Jid;

  26. /**
  27.  * Represents a command that is in a remote location. Invoking one of the
  28.  * {@link AdHocCommand.Action#execute execute}, {@link AdHocCommand.Action#next next},
  29.  * {@link AdHocCommand.Action#prev prev}, {@link AdHocCommand.Action#cancel cancel} or
  30.  * {@link AdHocCommand.Action#complete complete} actions results in executing that
  31.  * action in the remote location. In response to that action the internal state
  32.  * of the this command instance will change. For example, if the command is a
  33.  * single stage command, then invoking the execute action will execute this
  34.  * action in the remote location. After that the local instance will have a
  35.  * state of "completed" and a form or notes that applies.
  36.  *
  37.  * @author Gabriel Guardincerri
  38.  *
  39.  */
  40. public class RemoteCommand extends AdHocCommand {

  41.     /**
  42.      * The connection that is used to execute this command
  43.      */
  44.     private XMPPConnection connection;

  45.     /**
  46.      * The full JID of the command host
  47.      */
  48.     private Jid jid;

  49.     /**
  50.      * The session ID of this execution.
  51.      */
  52.     private String sessionID;

  53.     /**
  54.      * Creates a new RemoteCommand that uses an specific connection to execute a
  55.      * command identified by <code>node</code> in the host identified by
  56.      * <code>jid</code>
  57.      *
  58.      * @param connection the connection to use for the execution.
  59.      * @param node the identifier of the command.
  60.      * @param jid the JID of the host.
  61.      */
  62.     protected RemoteCommand(XMPPConnection connection, String node, Jid jid) {
  63.         super();
  64.         this.connection = connection;
  65.         this.jid = jid;
  66.         this.setNode(node);
  67.     }

  68.     @Override
  69.     public void cancel() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  70.         executeAction(Action.cancel);
  71.     }

  72.     @Override
  73.     public void complete(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  74.         executeAction(Action.complete, form);
  75.     }

  76.     @Override
  77.     public void execute() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  78.         executeAction(Action.execute);
  79.     }

  80.     /**
  81.      * Executes the default action of the command with the information provided
  82.      * in the Form. This form must be the answer form of the previous stage. If
  83.      * there is a problem executing the command it throws an XMPPException.
  84.      *
  85.      * @param form the form answer of the previous stage.
  86.      * @throws XMPPErrorException if an error occurs.
  87.      * @throws NoResponseException if there was no response from the server.
  88.      * @throws NotConnectedException
  89.      * @throws InterruptedException
  90.      */
  91.     public void execute(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  92.         executeAction(Action.execute, form);
  93.     }

  94.     @Override
  95.     public void next(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  96.         executeAction(Action.next, form);
  97.     }

  98.     @Override
  99.     public void prev() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  100.         executeAction(Action.prev);
  101.     }

  102.     private void executeAction(Action action) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  103.         executeAction(action, null);
  104.     }

  105.     /**
  106.      * Executes the <code>action</code> with the <code>form</code>.
  107.      * The action could be any of the available actions. The form must
  108.      * be the answer of the previous stage. It can be <tt>null</tt> if it is the first stage.
  109.      *
  110.      * @param action the action to execute.
  111.      * @param form the form with the information.
  112.      * @throws XMPPErrorException if there is a problem executing the command.
  113.      * @throws NoResponseException if there was no response from the server.
  114.      * @throws NotConnectedException
  115.      * @throws InterruptedException
  116.      */
  117.     private void executeAction(Action action, Form form) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  118.         // TODO: Check that all the required fields of the form were filled, if
  119.         // TODO: not throw the corresponding exeption. This will make a faster response,
  120.         // TODO: since the request is stoped before it's sent.
  121.         AdHocCommandData data = new AdHocCommandData();
  122.         data.setType(IQ.Type.set);
  123.         data.setTo(getOwnerJID());
  124.         data.setNode(getNode());
  125.         data.setSessionID(sessionID);
  126.         data.setAction(action);

  127.         if (form != null) {
  128.             data.setForm(form.getDataFormToSend());
  129.         }

  130.         AdHocCommandData responseData = (AdHocCommandData) connection.createPacketCollectorAndSend(
  131.                         data).nextResultOrThrow();

  132.         this.sessionID = responseData.getSessionID();
  133.         super.setData(responseData);
  134.     }

  135.     @Override
  136.     public Jid getOwnerJID() {
  137.         return jid;
  138.     }
  139. }