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