From b83b1ec739954ae7af9276eeb5c2a6edd70e099f Mon Sep 17 00:00:00 2001 From: young Date: Mon, 23 Jun 2014 11:57:46 +0800 Subject: [PATCH] msn part1 Signed-off-by: young --- msn/MsnAgent.java | 240 ++++++++++++++++++++++++++++++++++++++++++++++ msn/MsnEvent.java | 123 ++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 msn/MsnAgent.java create mode 100644 msn/MsnEvent.java diff --git a/msn/MsnAgent.java b/msn/MsnAgent.java new file mode 100644 index 0000000..9a13ebd --- /dev/null +++ b/msn/MsnAgent.java @@ -0,0 +1,240 @@ + + +package org.thinkname.ap.msn; + +import org.thinkname.ap.contact.ContactLocation; +import org.thinkname.ap.contact.ContactManager; +import org.thinkname.ap.main.ContactsUpdaterBehaviour; + +import jade.core.behaviours.Behaviour; +import jade.core.behaviours.CyclicBehaviour; +import jade.domain.DFService; +import jade.domain.FIPAException; +import jade.domain.FIPAAgentManagement.DFAgentDescription; +import jade.domain.FIPAAgentManagement.Property; +import jade.domain.FIPAAgentManagement.ServiceDescription; +import jade.lang.acl.ACLMessage; +import jade.lang.acl.MessageTemplate; +import jade.util.Logger; +import jade.wrapper.gateway.GatewayAgent; + + + +/** + * Agent running all behaviours. It resides on the phone and it is responsible for DF registration/subscription and for + * behaviour execution. + *

+ * It extends GatewayAgent as requested by JADE Android add-on and is therefore able to process commands sent through + * JadeGateway.execute(). + * Provides as an inner class the behaviour responsible for receiving messages. + * + */ +public class MsnAgent extends GatewayAgent { + + /** + * Name of service description to be registered on DF (allowing us to filter out the modifications performed by + * our application from others) + */ + public static final String msnDescName = "android-msn-service"; + + /** + * Type of the description of the service + */ + public static final String msnDescType = "android-msn"; + + /** + * Name of the latitude property registered on the DF + */ + public static final String PROPERTY_NAME_LOCATION_LAT="Latitude"; + + /** + * Name of the longitude property registered on the DF + */ + public static final String PROPERTY_NAME_LOCATION_LONG="Longitude"; + + /** + * Name of the altitude property registered on the DF + */ + public static final String PROPERTY_NAME_LOCATION_ALT="Altitude"; + + /** + * Ontology used for sending message + */ + public static final String CHAT_ONTOLOGY= "chat_ontology"; + + /** + * Description of Msn service + */ + private DFAgentDescription myDescription; + + /** + * DF Subscription message + */ + private ACLMessage subscriptionMessage; + + /** + * Instance of {@link ContactsUpdaterBehaviour} + */ + private ContactsUpdaterBehaviour contactsUpdaterB; + + /** + * Message receiver behaviour instance + */ + private MessageReceiverBehaviour messageRecvB; + + /** + * Instance of JADE Logger for debugging + */ + private final Logger myLogger = Logger.getMyLogger(this.getClass().getName()); + + + + /** + * Overrides the Agent.setup() method, performing registration on DF, prepares the DF subscription message, + * and adds the {@link ContactsUpdaterBehaviour}. + * + */ + protected void setup() { + super.setup(); + Thread.currentThread().getId(); + myLogger.log(Logger.INFO, "setup() called: My currentThread has this ID: " + Thread.currentThread().getId()); + myDescription = new DFAgentDescription(); + //fill a msn service description + ServiceDescription msnServiceDescription = new ServiceDescription(); + msnServiceDescription.setName(msnDescName); + msnServiceDescription.setType(msnDescType); + myDescription.addServices(msnServiceDescription); + + //subscribe to DF + subscriptionMessage = DFService.createSubscriptionMessage(this, this.getDefaultDF(), myDescription, null); + + ContactLocation curLoc = ContactManager.getInstance().getMyContactLocation(); + + Property p = new Property(PROPERTY_NAME_LOCATION_LAT,new Double(curLoc.getLatitude())); + msnServiceDescription.addProperties(p); + p = new Property(PROPERTY_NAME_LOCATION_LONG,new Double(curLoc.getLongitude())); + msnServiceDescription.addProperties(p); + p= new Property(PROPERTY_NAME_LOCATION_ALT,new Double(curLoc.getAltitude())); + msnServiceDescription.addProperties(p); + myDescription.setName(this.getAID()); + + try { + myLogger.log(Logger.INFO, "Registering to DF!"); + DFService.register(this, myDescription); + } catch (FIPAException e) { + e.printStackTrace(); + } + + //added behaviour to dispatch chat messages + messageRecvB = new MessageReceiverBehaviour(); + addBehaviour(messageRecvB); + String[] args = (String[])getArguments(); + myLogger.log(Logger.INFO, "UPDATE TIME: " + args[0]); + contactsUpdaterB = new ContactsUpdaterBehaviour(Long.parseLong(args[0]), curLoc); + addBehaviour(contactsUpdaterB); + } + + /** + * Gets the DF subscription message. + * + * @return the DF subscription message + */ + public ACLMessage getSubscriptionMessage(){ + return subscriptionMessage; + } + + /** + * Gets the agent description. + * + * @return the agent description + */ + public DFAgentDescription getAgentDescription(){ + return myDescription; + } + + + /** + * Overrides agent takeDown() method + */ + protected void takeDown() { + myLogger.log(Logger.INFO, "Doing agent takeDown() "); + } + + + /** + * Overrides GatewayAgent.processCommand(). Receives a command from JadeGateway.execute() + * The behaviour for sending a message in particular is received in this way + * + * @param command a generic command that this agent shall execute. + */ + protected void processCommand(final Object command) { + if (command instanceof Behaviour){ + addBehaviour( (Behaviour) command); + + } + releaseCommand(command); + } + + /** + * Defines the behaviour for receiving chat messages. + * Each time a message is received, a UI feedback is required (adding message to message window or adding a notification). + * The {@link CyclicBehaviour} continuously executes its action method and does something as soon as a message arrives. + */ + private class MessageReceiverBehaviour extends CyclicBehaviour{ + + /** + * Overrides the Behaviour.action() method and receives messages. + * After a message is received the following operations take place: + *

+ */ + public void action() { + + try { + MessageTemplate mt = MessageTemplate.MatchOntology(CHAT_ONTOLOGY); + ACLMessage msg = myAgent.receive(mt); + //If a message is received + if(msg != null){ + myLogger.log(Logger.FINE, msg.toString()); + MsnSessionManager sessionManager = MsnSessionManager.getInstance(); + + //retrieve the session id + String sessionId = msg.getConversationId(); + myLogger.log(Logger.FINE, "Received Message... session ID is " + sessionId); + String senderPhoneNum = msg.getSender().getLocalName(); + + //Create a session Message from the received ACLMessage + MsnSessionMessage sessionMessage = new MsnSessionMessage(msg); + + //Check if we can retrieve a session. If so we should have got a copy + MsnSession currentSession = MsnSessionManager.getInstance().retrieveSession(sessionId); + + //If we have a new session + if (currentSession == null) { + //Create a new session with the specified ID + sessionManager.addMsnSession(sessionId, msg.getAllReceiver(), senderPhoneNum); + } + + //prepare an "IncomingMessage" + MsnEvent event = MsnEventMgr.getInstance().createEvent(MsnEvent.INCOMING_MESSAGE_EVENT); + event.addParam(MsnEvent.INCOMING_MESSAGE_PARAM_SESSIONID, sessionId); + event.addParam(MsnEvent.INCOMING_MESSAGE_PARAM_MSG, sessionMessage); + //Add message to session + sessionManager.addMessageToSession(sessionId, sessionMessage); + MsnEventMgr.getInstance().fireEvent(event); + } else{ + block(); + } + + }catch(Throwable t) { + myLogger.log(Logger.SEVERE,"*** Uncaught Exception for agent " + myAgent.getLocalName() + " ***",t); + } + + + } + } +} + diff --git a/msn/MsnEvent.java b/msn/MsnEvent.java new file mode 100644 index 0000000..a8a8ac4 --- /dev/null +++ b/msn/MsnEvent.java @@ -0,0 +1,123 @@ + + +package org.thinkname.ap.msn; + +import jade.util.Logger; + +import java.util.HashMap; +import java.util.Map; + +/** + * This is an event. An event is basically a container object that carries + * arbitrary data and has an unique name. + * It is filled by the entity that fires the event. + * + * + */ +public class MsnEvent { + + private Logger myLogger = Logger.getMyLogger(MsnEvent.class.getName()); + + /** + * Event that is fired each time an update should be performed + */ + public static final String TICK_EVENT="TICK_EVENT"; + /** + * Event that is fired when a new message arrives + */ + public static final String INCOMING_MESSAGE_EVENT="INCOMING_MESSAGE_EVENT"; + /** + * Event that is fired when a refresh of the view is needed () + */ + public static final String VIEW_REFRESH_EVENT="VIEW_REFRESH_EVENT"; + /** + * Event that is fired when a contact disconnects + */ + public static final String CONTACT_DISCONNECT_EVENT="CONTACT_DISCONNECT_EVENT"; + + + //Parameters defined for INCOMING MSG EVENT + /** + * Name for the incoming message parameter + */ + public static final String INCOMING_MESSAGE_PARAM_MSG="INCOMING_MESSAGE_PARAM_MSG"; + /** + * Name for the session id parameter for an incoming message + */ + public static final String INCOMING_MESSAGE_PARAM_SESSIONID="INCOMING_MESSAGE_PARAM_SESSIONID"; + + //Parameters defined for VIEW REFRESH EVENT + /** + * Name for the list of changes parameter at each refresh + */ + public static final String VIEW_REFRESH_PARAM_LISTOFCHANGES="VIEW_REFRESH_PARAM_LISTOFCHANGES"; + /** + * Name of contacts map parameter at each refresh + */ + public static final String VIEW_REFRESH_CONTACTSMAP="VIEW_REFRESH_CONTACTSMAP"; + /** + * Name of location map parameter at each refresh + */ + public static final String VIEW_REFRESH_PARAM_LOCATIONMAP="VIEW_REFRESH_PARAM_LOCATIONMAP"; + + //Parameters defined for CONTACT DISCONNECT EVENT + /** + * Name of parameter + */ + public static final String CONTACT_DISCONNECT_PARAM_CONTACTNAME="CONTACT_DISCONNECT_PARAM_CONTACTNAME"; + + /** + * Name of the event + */ + private String name; + + /** + * Maps that stores event parameters + */ + private Map paramsMap; + + /** + * Returns the name of the event + * @return event name + */ + public final String getName() { + return name; + + } + + /** + * Builds a new event + * @param name name of the event + */ + public MsnEvent(String name){ + this.name = name; + } + + + /** + * Adds a parameter to the event using the given name + * + * @param name name of the parameter + * @param value value to be added + */ + public void addParam(String name, Object value){ + if (paramsMap == null){ + paramsMap = new HashMap(); + } + + paramsMap.put(name, value); + myLogger.log(Logger.FINE,"putting in event map parameter " + name +" having value "+ value.toString() ); + } + + /** + * Retrieves a parameter from an event + * + * @param name of the parameter to retrieve + * @return value of the parameter + */ + public Object getParam(String name){ + return paramsMap.get(name); + } +} + +