/**
 * This activity implement the participants interface.
 *
 * @author Michele Izzo - Telecomitalia
 */
public class ParticipantsActivity extends ListActivity {
  private Logger logger = Logger.getJADELogger(this.getClass().getName());

  private MyReceiver myReceiver;

  private String nickname;
  private ChatClientInterface chatClientInterface;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      nickname = extras.getString("nickname");
    }

    try {
      chatClientInterface =
          MicroRuntime.getAgent(nickname).getO2AInterface(ChatClientInterface.class);
    } catch (StaleProxyException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ControllerException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    myReceiver = new MyReceiver();

    IntentFilter refreshParticipantsFilter = new IntentFilter();
    refreshParticipantsFilter.addAction("jade.demo.chat.REFRESH_PARTICIPANTS");
    registerReceiver(myReceiver, refreshParticipantsFilter);

    setContentView(R.layout.participants);

    setListAdapter(
        new ArrayAdapter<String>(
            this, R.layout.participant, chatClientInterface.getParticipantNames()));

    ListView listView = getListView();
    listView.setTextFilterEnabled(true);
    listView.setOnItemClickListener(listViewtListener);
  }

  private OnItemClickListener listViewtListener =
      new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          // TODO: A partecipant was picked. Send a private message.
          finish();
        }
      };

  @Override
  protected void onDestroy() {
    super.onDestroy();

    unregisterReceiver(myReceiver);

    logger.log(Level.INFO, "Destroy activity!");
  }

  private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      logger.log(Level.INFO, "Received intent " + action);
      if (action.equalsIgnoreCase("jade.demo.chat.REFRESH_PARTICIPANTS")) {
        setListAdapter(
            new ArrayAdapter<String>(
                ParticipantsActivity.this,
                R.layout.participant,
                chatClientInterface.getParticipantNames()));
      }
    }
  }
}
示例#2
0
/**
 * This class is used to start up the JADE runtime as a split (front-end) container. Though JADE
 * supports split containers on all Java editions, the split container deployment is better suited
 * for small, resource constrained devices (MIDP and PJava).
 *
 * @author Giovanni Caire - TILAB
 */
public class MicroRuntime {

  /**
   * The configuration property key that maps to the list of agents that have to be activated at
   * boostrap.
   */
  public static final String AGENTS_KEY = "agents";

  /** The configuration property key that maps to the list of services that have to be installed. */
  public static final String SERVICES_KEY = "services";

  /**
   * The key to retrieve the owner of the starting container. This information is the base for using
   * a split container in a JADE platform with some form of security as it is automatically
   * propagated to the back-end. For instance to connect a split-container to a platform using
   * JADE-S Front-End: In the startup peroperties specify - owner = <username>:<password> Back-End:
   * In the leap property file of the JICPMediatorManager that will host the BackEnd specify -
   * services = ....<security services>... - jade_security_authentication_logincallback = cmdline
   */
  public static final String OWNER_KEY = "owner";

  /** The configuration property key that maps to the host where to connect to the JADE mediator. */
  public static final String HOST_KEY = "host";

  /** The configuration property key that maps to the port where to connect to the JADE mediator. */
  public static final String PORT_KEY = "port";

  /**
   * The configuration property key that maps to the protocol that must be used to connect to the
   * JADE mediator. Possible values are: <code>socket, ssl, http, https</code>
   */
  public static final String PROTO_KEY = "proto";

  /**
   * The configuration property key that specifies how much time by default a command that is being
   * delivered during a temporary disconnection must be stored waiting for the FE to reconnect.
   * After that time the command fails (in case of a message delivery command, a FAILURE is sent
   * back to the sender).<br>
   * 0 means store and forward disabled -1 means infinite timeout
   */
  public static final String DEFAULT_SF_TIMEOUT_KEY = "default-sf-timeout";

  public static final String REMOTE_CONFIG_HOST_KEY = "remote-config-host";
  public static final String REMOTE_CONFIG_PORT_KEY = "remote-config-port";

  public static final String SOCKET_PROTOCOL = "socket";
  public static final String SSL_PROTOCOL = "ssl";
  public static final String HTTP_PROTOCOL = "http";
  public static final String HTTPS_PROTOCOL = "https";

  // #APIDOC_EXCLUDE_BEGIN
  public static final String CONN_MGR_CLASS_KEY = "connection-manager";

  public static final String CONTAINER_NAME_KEY = "container-name";
  public static final String PLATFORM_KEY = "platform-id";
  public static final String PLATFORM_ADDRESSES_KEY = "addresses";
  public static final String BE_REQUIRED_SERVICES_KEY = "be-required-services";

  public static final String JVM_KEY = "jvm";

  public static final String J2SE = "j2se";
  public static final String PJAVA = "pjava";
  public static final String MIDP = "midp";
  // #APIDOC_EXCLUDE_END

  // #J2ME_EXCLUDE_BEGIN
  private static Logger logger = Logger.getJADELogger(MicroRuntime.class.getName());
  // #J2ME_EXCLUDE_END
  /*#J2ME_INCLUDE_BEGIN
  private static Logger logger = Logger.getJADELogger("jade.core.MicroRuntime");
  #J2ME_INCLUDE_END*/

  private static Runnable terminator;
  private static FrontEndContainer myFrontEnd;
  private static boolean terminated;

  /**
   * Start up the JADE runtime. This method launches a JADE Front End container. Since JADE supports
   * only one container in the split-container deployment, if a Front End is already running this
   * method does nothing.
   *
   * @param p A property bag, containing name-value pairs used to configure the container during
   *     boot.
   * @param r A <code>Runnable</code> object, whose <code>run()</code> method will be executed just
   *     after container termination.
   */
  public static void startJADE(Properties p, Runnable r) {
    if (myFrontEnd == null) {
      terminator = r;
      terminated = false;
      myFrontEnd = new FrontEndContainer();
      myFrontEnd.start(p);
      if (terminated) {
        myFrontEnd = null;
      }
    }
  }

  /**
   * Shut down the JADE runtime. This method stops the JADE Front End container currently running in
   * this JVM, if one such container exists.
   */
  public static void stopJADE() {
    if (myFrontEnd != null) {
      try {
        // Self-initiated shutdown
        myFrontEnd.exit(true);
      } catch (IMTPException imtpe) {
        // Should never happen as this is a local call
        imtpe.printStackTrace();
      }
    }
  }

  /**
   * Tells whether a JADE Front End container is currently running within this JVM.
   *
   * @return If the JADE runtime is currently running, <code>true</code> is returned. Otherwise, the
   *     method returns <code>false</code>.
   */
  public static boolean isRunning() {
    return myFrontEnd != null;
  }

  public static String getContainerName() {
    if (myFrontEnd != null) {
      Location cid = myFrontEnd.here();
      if (cid != null) {
        return cid.getName();
      }
    }
    return null;
  }

  /**
   * Start a new agent. This method starts a new agent within the active Front End container.
   *
   * @param name The local name (i.e. without the platform ID) of the agent to create.
   * @param className The fully qualified name of the class implementing the agent to start.
   * @param args The creation arguments for the agent.
   * @throws Exception If the underlying agent creation process fails.
   */
  public static void startAgent(String name, String className, String[] args) throws Exception {
    if (myFrontEnd != null) {
      try {
        myFrontEnd.createAgent(name, className, args);
      } catch (IMTPException imtpe) {
        // This is a local call --> an IMTPxception always wrap some other exception
        throw (Exception) imtpe.getNested();
      }
    }
  }

  /**
   * Start a new agent. This method starts a new agent within the active Front End container.
   *
   * @param name The local name (i.e. without the platform ID) of the agent to create.
   * @param className The fully qualified name of the class implementing the agent to start.
   * @param args The creation arguments for the agent.
   * @throws Exception If the underlying agent creation process fails.
   */
  public static void startAgent(String name, String className, Object[] args) throws Exception {
    if (myFrontEnd != null) {
      try {
        myFrontEnd.createAgent(name, className, args);
      } catch (IMTPException imtpe) {
        // This is a local call --> an IMTPxception always wrap some other exception
        throw (Exception) imtpe.getNested();
      }
    }
  }

  /**
   * Kill an agent. This method terminates an agent running within the active Front End container.
   *
   * @param name The local name (i.e. without the platform ID) of the agent to kill.
   * @throws NotFoundException If no agent with the given local name are running within the active
   *     Front End.
   */
  public static void killAgent(String name) throws NotFoundException {
    if (myFrontEnd != null) {
      try {
        myFrontEnd.killAgent(name);
      } catch (IMTPException imtpe) {
        // Should never happen as this is a local call
        imtpe.printStackTrace();
      }
    }
  }

  // #MIDP_EXCLUDE_BEGIN
  /**
   * Get agent proxy to local agent given its name. <br>
   * <b>NOT available in MIDP</b> <br>
   *
   * @param localAgentName The short local name of the desired agent.
   * @throws ControllerException If any problems occur obtaining this proxy.
   */
  public static AgentController getAgent(String localName) throws ControllerException {
    if (myFrontEnd == null) {
      throw new ControllerException("FrontEndContainer  not found");
    }
    // Check that the agent exists
    jade.core.Agent instance = myFrontEnd.getLocalAgent(localName);
    if (instance == null) {
      throw new ControllerException("Agent " + localName + " not found.");
    }
    return new MicroAgentControllerImpl(localName, myFrontEnd);
  }

  /**
   * Add a listener that will be notified about Front-End relevant events such as BORN_AGENT and
   * DEAD_AGENT <br>
   * <b>NOT available in MIDP</b> <br>
   *
   * @param l The listener that will be notified about Front-End relevant events
   */
  public static void addListener(FEListener l) {
    if (myFrontEnd != null) {
      myFrontEnd.addListener(l);
    }
  }

  /**
   * Remove a listener to Front-End relevant events BORN_AGENT and DEAD_AGENT <br>
   * <b>NOT available in MIDP</b> <br>
   *
   * @param l The listener to be removed
   */
  public static void removeListener(FEListener l) {
    if (myFrontEnd != null) {
      myFrontEnd.removeListener(l);
    }
  }
  // #MIDP_EXCLUDE_END

  /**
   * Disconnect this front-end container from the platform. That is, though the local front-end
   * container and its agent(s) remain active, the back-end is shut down and, of course, the FE-2-BE
   * connection is closed --> Therefore the rest of the platform does not see the local container
   * and its agent(s) anymore. The local container automatically re-connects to the platform (and
   * local agents are registered with the AMS again) as soon as a message to a remote agent is sent.
   */
  public static void detach() {
    if (myFrontEnd != null) {
      myFrontEnd.detach();
    }
  }

  // #APIDOC_EXCLUDE_BEGIN
  public static void notifyFailureToSender(ACLMessage msg, String sender, String error) {
    if (myFrontEnd != null) {
      // Send back a failure message
      try {
        Iterator it = msg.getAllReceiver();
        while (it.hasNext()) {
          AID receiver = (AID) it.next();
          // If this receiver is local, the message has certainly been delivered
          // successfully --> Do not send any FAILURE back for this receiver
          if (myFrontEnd.getLocalAgent(receiver.getLocalName()) == null) {
            ACLMessage failure = msg.createReply();
            failure.setPerformative(ACLMessage.FAILURE);
            failure.setSender(myFrontEnd.getAMS());
            failure.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
            String content = "( (action " + sender;
            content = content + " (ACLMessage) ) (MTS-error " + receiver + " \"" + error + "\") )";
            failure.setContent(content);
            myFrontEnd.messageIn(failure, sender);
          }
        }
      } catch (Exception e1) {
        logger.log(Logger.SEVERE, "Error delivering FAILURE message.", e1);
      }
    }
  }
  // #APIDOC_EXCLUDE_END

  /** Activate the Java environment terminator when the JADE runtime has stopped. */
  static void handleTermination(boolean self) {
    terminated = true;
    myFrontEnd = null;
    Thread t = null;
    if (self) {
      t = new Thread(terminator);
    } else {
      // If the termination was activated from remote, then let
      // the current thread complete before closing down everything
      final Thread current = Thread.currentThread();
      t =
          new Thread(
              new Runnable() {
                public void run() {
                  try {
                    current.join();
                  } catch (InterruptedException ie) {
                    logger.log(Logger.SEVERE, "Interrupted in join");
                  }
                  if (terminator != null) {
                    terminator.run();
                  }
                }
              });
    }
    t.start();
  }
}
public class ParticipantsActivity extends ListActivity {
  private Logger logger = Logger.getJADELogger(this.getClass().getName());

  private MyReceiver myReceiver;

  private String nickname;
  private ChatClientInterface chatClientInterface;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      nickname = extras.getString("nickname");
    }

    try {
      chatClientInterface =
          MicroRuntime.getAgent(nickname).getO2AInterface(ChatClientInterface.class);
    } catch (StaleProxyException e) {
      e.printStackTrace();
    } catch (ControllerException e) {
      e.printStackTrace();
    }

    myReceiver = new MyReceiver();

    IntentFilter refreshParticipantsFilter = new IntentFilter();
    refreshParticipantsFilter.addAction("jade.demo.chat.REFRESH_PARTICIPANTS");
    registerReceiver(myReceiver, refreshParticipantsFilter);

    setContentView(R.layout.participants);

    setListAdapter(
        new ArrayAdapter<String>(
            this,
            R.layout.participant,
            chatClientInterface.getParticipantNames(getContentResolver())));

    ListView listView = getListView();
    listView.setTextFilterEnabled(true);
    listView.setOnItemClickListener(listViewtListener);
  }

  private OnItemClickListener listViewtListener =
      new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

          final String participant =
              chatClientInterface.getParticipantNames(getContentResolver())[position];

          if (participant.charAt(participant.length() - 2) == 'N') {
            new AlertDialog.Builder(ParticipantsActivity.this)
                .setTitle("Create Contact")
                .setMessage(
                    "Create contact for "
                        + participant.substring(0, participant.length() - 4)
                        + " ?")
                .setPositiveButton(
                    android.R.string.yes,
                    new DialogInterface.OnClickListener() {
                      public void onClick(DialogInterface dialog, int which) {
                        addContact(participant.substring(0, participant.length() - 4));

                        Context context = getApplicationContext();
                        CharSequence text = "Contact created!";
                        int duration = Toast.LENGTH_SHORT;

                        Toast toast = Toast.makeText(context, text, duration);
                        toast.show();

                        finish();
                      }
                    })
                .setNegativeButton(
                    android.R.string.no,
                    new DialogInterface.OnClickListener() {
                      public void onClick(DialogInterface dialog, int which) {
                        finish();
                      }
                    })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();

          } else {
            finish();
          }
        }
      };

  private void addContact(String participant) {
    String DisplayName = participant;

    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    ops.add(
        ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
            .build());

    if (DisplayName != null) {
      ops.add(
          ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
              .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
              .withValue(
                  ContactsContract.Data.MIMETYPE,
                  ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
              .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, DisplayName)
              .build());
    }

    try {
      getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();

    unregisterReceiver(myReceiver);

    logger.log(Level.INFO, "Destroy activity!");
  }

  private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      logger.log(Level.INFO, "Received intent " + action);
      if (action.equalsIgnoreCase("jade.demo.chat.REFRESH_PARTICIPANTS")) {
        setListAdapter(
            new ArrayAdapter<String>(
                ParticipantsActivity.this,
                R.layout.participant,
                chatClientInterface.getParticipantNames(getContentResolver())));
      }
    }
  }
}