/* Author: Jeff Dalton & * Stephen Potter * Added new agent names by Austin Tate * Last Updated: 6-Dec-2001 by Austin Tate * Copyright: (c) 2001, AIAI, University of Edinburgh */ package ix.akt; import java.io.*; //import java.awt.*; // Imports for using JDOM // import java.io.IOException; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; import org.w3c.dom.*; import com.sun.xml.tree.*; import sunlabs.brazil.util.http.*; import java.util.*; import java.net.*; import ix.icore.Issue; import ix.icore.BasicIssue; import ix.iface.util.XML; import ix.util.lisp.*; // only for Issue -> XML import ix.util.*; import aktbus.core.*; /* * A class that encapsulates the knowledge needed for * sending and receiving messages on the AKT Knowledge Bus. */ public class AktCommunicationStrategy //implements IPC.CommunicationStrategy, MessageListener { implements IPC.CommunicationStrategy { public String ipcName = "ipcName unknown"; public IPC.MessageListener ipcListener = null; public AktCommunicationStrategy() { } /** * Sends an Issue or Report to a named AKT agent by converting * it to XML and calling the sendText method. */ public void sendObject(Object destination, Object contents) { String toName = (String)destination; sendText(toName, XML.objectToXML(contents)); } /** * Sends a string to a named AKT agent. */ public void sendText(String toName, String contents) { AktMessage mess; String hostname = null; String recp = null; InetAddress intadd; try{ // retrieves name of local host - assumes that recipient is also running // on same host (!). This should be modified at some stage.... intadd = InetAddress.getLocalHost(); // getHostName returns string in the form, for example, of "kerrera.aiai.ed.ac.uk" // (need to check what this returns on PCs...) hostname = intadd.getHostName(); //Debug.noteln(hostname); } catch (Exception e){ Debug.noteException(e); } // prefix hostname to convert to valid URI, and append appropriate port number: if(toName.equalsIgnoreCase("IDEEL")) recp = "http://"+hostname + ":5040"; if(toName.equalsIgnoreCase("ILEED")) recp = "http://"+hostname + ":5050"; if(toName.equalsIgnoreCase("ITEST")) recp = "http://"+hostname + ":5060"; if(toName.equalsIgnoreCase("I-Sample")) recp = "http://"+hostname + ":5062"; if(toName.equalsIgnoreCase("Supervisor")) recp = "http://"+hostname + ":5070"; if(toName.equalsIgnoreCase("Operator")) recp = "http://"+hostname + ":5072"; if(toName.equalsIgnoreCase("Edinburgh")) recp = "http://"+hostname + ":5080"; if(toName.equalsIgnoreCase("Aberdeen")) recp = "http://"+hostname + ":5082"; if(toName.equalsIgnoreCase("CCS")) recp = "http://"+hostname + ":5084"; if(toName.equalsIgnoreCase("CSR")) recp = "http://"+hostname + ":5085"; if(toName.equalsIgnoreCase("Panel-1")) recp = "http://"+hostname + ":5091"; if(toName.equalsIgnoreCase("Panel-2")) recp = "http://"+hostname + ":5092"; if(toName.equalsIgnoreCase("Panel-3")) recp = "http://"+hostname + ":5093"; if(toName.equalsIgnoreCase("Panel-4")) recp = "http://"+hostname + ":5094"; if(toName.equalsIgnoreCase("Panel-5")) recp = "http://"+hostname + ":5095"; if(toName.equalsIgnoreCase("Panel-6")) recp = "http://"+hostname + ":5096"; if(toName.equalsIgnoreCase("Panel-7")) recp = "http://"+hostname + ":5097"; if(toName.equalsIgnoreCase("Panel-8")) recp = "http://"+hostname + ":5098"; if(toName.equalsIgnoreCase("Panel-9")) recp = "http://"+hostname + ":509"; Debug.noteln("Sending to : "+recp+" ("+toName+")"); Debug.noteln("Contents : "+contents); try{ // create a new AktMessage, and then send it (to recp). // following should add message under "aktbus:hasSimpleMessage" node: mess = new AktMessage(new URL("http://"+hostname),new URL(recp),contents); // and send mess to recp: mess.send(); } catch (Exception e) { Debug.noteException(e); } } /** * Initiate an AktBus receiver object and set up for receiving messages. */ public void setupServer(Object destination, IPC.MessageListener listener) { ipcName = (String)destination; // our name for registering as agent ipcListener = listener; int port=8888; // dummy default final AktMessage mess; final Object contents; // Debug.noteln("\nipcName = "+ipcName); // get number of the appropriate port to open for each application: if(ipcName.equalsIgnoreCase("IDEEL")) port = 5040; if(ipcName.equalsIgnoreCase("ILEED")) port = 5050; if(ipcName.equalsIgnoreCase("ITEST")) port = 5060; if(ipcName.equalsIgnoreCase("I-Sample")) port = 5062; if(ipcName.equalsIgnoreCase("Supervisor")) port = 5070; if(ipcName.equalsIgnoreCase("Operator")) port = 5072; if(ipcName.equalsIgnoreCase("Edinburgh")) port = 5080; if(ipcName.equalsIgnoreCase("Aberdeen")) port = 5082; if(ipcName.equalsIgnoreCase("CCS")) port = 5084; if(ipcName.equalsIgnoreCase("CSR")) port = 5085; if(ipcName.equalsIgnoreCase("Panel-1")) port = 5091; if(ipcName.equalsIgnoreCase("Panel-2")) port = 5092; if(ipcName.equalsIgnoreCase("Panel-3")) port = 5093; if(ipcName.equalsIgnoreCase("Panel-4")) port = 5094; if(ipcName.equalsIgnoreCase("Panel-5")) port = 5095; if(ipcName.equalsIgnoreCase("Panel-6")) port = 5096; if(ipcName.equalsIgnoreCase("Panel-7")) port = 5097; if(ipcName.equalsIgnoreCase("Panel-8")) port = 5098; if(ipcName.equalsIgnoreCase("Panel-9")) port = 5099; try{ AktBusReceiver rec = new AktBusReceiver(port); receiveMessage(rec); } catch (Exception e){ Debug.noteException(e); } } /* get_subtree_text recursively extracts all the text existing in the subtree below * node n, and returns it, as a single string. * Note: since this requires quite detailed knowledge of the construction of AKTBUS * messages, it would seem to be at too low a level (and relies on this construction * staying constant). This method was originally (in the AKTBUS package) implemented * using "<" and ">" rather than "<" and ">" - but this had to be altered, as * the BasicInputMessage constructor requires its XML content to be expressed in the * form of a simple String. */ String get_node_attributes(org.w3c.dom.Node n){ String attrString=""; org.w3c.dom.NamedNodeMap attrL = n.getAttributes(); for(int i=0;i" + get_subtree_text(child) + ""; } child = child.getNextSibling(); } return result; } /* receiveMessage threads a receiver which waits for a message to be received, * then extracts the content, converts this content into an xml object, and * notifies the ipcListener with this object, before looping to receive the * next message. */ void receiveMessage(final AktBusReceiver rec){ new Thread(){ public void run(){ while(true) { try{ // receives a message, extracts simple content (NOTE:CHECK THIS AGAINST FUTURE // AKTBUS RELEASES!), then converts it into the expected XML object. AktMessage newm = rec.receive_message(); // newm.ugly_write(); // lets us see what's been received. // following lines require too deep a knowledge of AKTBUS internals... // expect this to change....: org.w3c.dom.Node nd = newm.find_element_node("aktbus:hasSimpleMessage"); if(nd==null){ // if the hasSimpleMessage node does not exist, then try hasContent node? // Note: this is not guaranteed to work in every eventuality, especially // if messages are generated external to I-X (ie not using the sendText method // above). Debug.noteln("Non-IX generated message received (has no hasSimpleMessage node)"); nd = newm.find_element_node("aktbus:hasContent"); } // flatten message content into single string: String mcontent = get_subtree_text(nd); // output message details. Debug.noteln("\nSender: "+newm.get_sender()); Debug.noteln("Receiver: "+newm.get_receiver()); Debug.noteln("Incoming message: "+mcontent); // create an XML object from the message content Object contents = XML.objectFromXML(mcontent); // and notify the ipcListener: ipcListener.messageReceived(new IPC.BasicInputMessage(contents)); } catch (Exception e){ Debug.noteException(e); } } } }.start(); } }