View Javadoc

1   /*
2    * The contents of this file are subject to the BT "ZEUS" Open Source
3    * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file
4    * except in compliance with the Licence. You may obtain a copy of the Licence
5    * from $ZEUS_INSTALL/licence.html or alternatively from
6    * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7    *
8    * Except as stated in Clause 7 of the Licence, software distributed und the
9    * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or
10   * implied. See the Licence for the specific language governing rights and
11   * limitations under the Licence.
12   *
13   * The Original Code is within the package zeus.*.
14   * The Initial Developer of the Original Code is British Telecommunications
15   * public limited company, whose registered office is at 81 Newgate Street,
16   * London, EC1A 7AJ, England. Portions created by British Telecommunications
17   * public limited company are Copyright 1996-9. All Rights Reserved.
18   *
19   * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20   */
21  
22  package zeus.agents;
23  
24  import zeus.actors.outtrays.*;
25  import zeus.actors.factories.*;
26  import zeus.actors.intrays.*;
27  import java.util.*;
28  import java.io.*;
29  import zeus.util.*;
30  import zeus.concepts.*;
31  import zeus.actors.*;
32  import zeus.agents.*;
33  
34  import zeus.actors.rtn.Engine;
35  import zeus.rete.ReteEngine;
36  
37  import zeus.concepts.xmlobject.acc.Contacts;
38  import zeus.concepts.xmlobject.acc.Contact;
39  import zeus.concepts.xmlobject.acc.ContactsParser;
40  
41  
42  /***
43   * ACC is a Zeus agent that has been set up to act as a FIPA ACC.
44   * This means that the ACC agent is the point of contact between agents in
45   * a Zeus naming domain and agents in a FIPA naming domain
46   */
47  public class ACC implements ZeusExternal {
48      
49      protected static void version() {
50          System.err.println("ZeusAgent - ACC version: 1.2");
51          // System.exit(0);
52      }
53      
54      
55      protected static void usage() {
56          System.err.println("Usage: java ACC -s <dns_file> [-gui ViewerProg] ] [-debug] [-fipaNames fipNameFileName] [-transports transportConfigFile");
57          System.exit(0);
58      }
59      
60      
61      public static void main(String[] arg) {
62          String name        = "ACC";
63          Vector cmdLineFact = new Vector(10);
64          
65          BasicAgent agent;
66          String external = null;
67          String dns_file = null;
68          String resource = null;
69          String gui = null;
70          String ontology_file = null;
71          Vector nameservers = null;
72          Bindings b;
73          FileInputStream stream = null;
74          ZeusExternal user_prog = null;
75          String fipaNames = "contacts.xml";
76          String transports = null;
77          String filename = null;
78          
79          
80          for( int j = 0; j < arg.length; j++ ) {
81              if ( arg[j].equals("-s") &&  ++j < arg.length )
82                  dns_file = arg[j];
83              if (arg[j].equals("-gui") && ++j < arg.length)
84                  gui = arg[j];
85              if (arg[j].equals("-fipaNames") && ++j < arg.length) {
86                  fipaNames = arg[j];
87              }
88              if (arg[j].equals("-transports") && ++j < arg.length)
89                  transports = arg[j];
90              if (arg[j].equals("-o") && ++j <arg.length)
91                  filename = arg[j];
92              else if ( arg[j].equals("-debug") ) {
93                  Core.debug = true;
94                  Core.setDebuggerOutputFile("ACC.log");
95              }
96              
97          }
98          
99          b = new Bindings(name);
100         
101         
102         if ( dns_file == null ) {
103             System.err.println("Domain nameserver file must be specified with -s option");
104             usage();
105         }
106         
107         try {
108             nameservers = ZeusParser.addressList(new FileInputStream(dns_file));
109             System.out.println ("namerservers = " + nameservers); 
110             if ( nameservers == null || nameservers.isEmpty() )
111                 throw new IOException();
112             
113             ACC acc = new ACC();
114             if (transports != null) {
115                 acc.initialiseTransports(transports);}
116             
117             agent = new ACCAgent(name,name,nameservers);
118             
119             AgentContext context = agent.getAgentContext();
120             // context.set(new Clock(0,0));
121             OntologyDb db = new OntologyDb(context.GenSym());
122             context.set(db);
123             int status = 0;
124             if (filename == null) {
125                 status = db.openFile(new File("ACC.ont"));}
126             else
127                 status = db.openFile(new File(filename));
128             new OrganisationDb(context);
129             new ResourceDb(context);
130             new Engine(context);
131             new TaskDb(context);
132             // 4 && 40 are arbitary
133             new Planner(context,4,40);
134             new ExecutionMonitor(context);
135             
136             
137             new ProtocolDb(context);
138             //new MsgHandler(context);
139             
140 /*
141          Initialising Extensions
142  */
143             Class c;
144             
145             if ( resource != null ) {
146                 c = Class.forName(resource);
147                 ExternalDb oracle = (ExternalDb) c.newInstance();
148                 context.set(oracle);
149                 oracle.set(context);
150             }
151             if ( gui != null ) {
152                 c = Class.forName(gui);
153                 ZeusAgentUI ui = (ZeusAgentUI)c.newInstance();
154                 context.set(ui);
155                 ui.set(context);
156             }
157             
158 /*
159          Initialising ProtocolDb
160  */
161             ProtocolInfo info;
162 /*
163          Initialising OrganisationalDb
164  */
165             AbilityDbItem item;
166             
167             
168             // ACC has no external program
169             // instead call the functions in this class
170             
171             
172             context.set(acc);
173             acc.exec(context);
174             
175             
176             
177             if (fipaNames != null ) {
178                 System.out.println("attempting to register names");  
179                 acc.fipaNames = fipaNames;
180                 acc.loadFIPAAliases(); 
181             }
182             
183             
184             // ACC is used as a wrapper for df - could implement a separate DF agent?
185             FIPA_DF_Services fdf = new FIPA_DF_Services();
186             System.out.println("calling fdf");
187             fdf.exec(context);
188             
189             // ACC is used as a wrapper for ams - could implement a AMS agent?
190             FIPA_AMS_Services fams = new FIPA_AMS_Services();
191             System.out.println("calling fams");
192             fams.exec(context);
193         }
194         catch (Exception e) {
195             e.printStackTrace(); }
196     }
197     
198     
199     String fipaNames = null;  // Name of XML file - set as parameter to main method
200     AgentContext context = null;
201     MsgHandler msg = null;
202     
203     public void exec(AgentContext context) {
204         this.context = context;
205         //   FIPA_MailBox mbox = new FIPA_MailBox(context);
206         
207         // context.set(mbox);
208         msg = context.MsgHandler();
209         setMessageRules();
210         
211     }
212     
213     
214     public void setMessageRules() {
215         String FIPA_forward_request[] = {"type", "request", "content",  "//A(action acc(//s*)(forward (//s*)(.*)))//Z"};
216         msg.addRule(new MessageRuleImpl(context.newId("Rule"), FIPA_forward_request, this, "forward_message"));
217         String FIPA_inform_new_contact[] = {"type", "inform", "content", "//A(<contact//s)(.*)(/>)//Z"};
218         msg.addRule(new MessageRuleImpl(context.newId("Rule"), FIPA_inform_new_contact, this, "add_new_contact"));
219     }
220     
221     
222     public void forward_message(Performative perf) {
223         System.out.println(perf.toString());
224     }
225     
226     public File contactsDb = null;
227     public Contacts contactsRoot = new Contacts();
228     
229     /*
230      * Loads the FIPA aliases from file into ACC's address book.
231      * Converts the XML document into Java objects, all accessible
232      * via the "root" object of type zeus.concepts.xmlobject.acc.Contacts
233      */
234     protected synchronized void loadFIPAAliases() {
235         List allContacts = null;
236         try {
237             contactsDb = new File (fipaNames);            
238             // Build the Java objects from the file
239             buildTree();       
240             // Get java.util.List of all Contact objects
241             allContacts = contactsRoot.getContacts();                  
242         }
243         catch (Exception e) {
244             e.printStackTrace(); 
245         }
246 
247         if (allContacts != null) {
248 
249             Zeus_ACC_MailBox mbox = (Zeus_ACC_MailBox) context.getMailBox();
250             Zeus_ACC_Server server = mbox.getZeus_ACC_Server();            
251 
252             // Iterate through the List set each FIPA alias
253             for (ListIterator i = allContacts.listIterator(); i.hasNext();  ) {
254                 Contact contact = (Contact)i.next();
255                 System.out.println(contact.toString());
256                 String zeusName = contact.getZeusName();  
257                 FIPA_AID_Address FIPAAddress = new FIPA_AID_Address(contact.getFipaAddress());
258                 System.out.println("ZEUS Name = " + zeusName + ",  FIPA Address = " + FIPAAddress.toString());
259                /* try {
260                     Thread.sleep(500);
261                     System.out.println("Sleeping...");
262                 }
263                 catch (Exception e) {
264                     e.printStackTrace();
265                 }*/
266                 server.setFIPAAlias(zeusName, FIPAAddress);
267             }
268         }
269         else {
270             System.out.println("Failed to load FIPA aliases into address book");
271         }
272     }
273     
274     /*
275      * Save all known FIPA Aliases to the file
276      * The root element Java object and the File object are globals and so no
277      * parameters are passes into this method
278      */
279     protected synchronized void saveFIPAAliases() {
280         try {
281             marshalTree(); 
282             System.out.println("FIPA Aliases file saved successfully!");
283         }
284         catch (Exception e) {
285             System.out.println("Error saving FIPA Aliases to file");
286             e.printStackTrace();
287         }
288     }
289     
290     
291     public void add_new_contact(Performative perf) {
292         // Initialise the reply message - the 'type' and 'content' of message will 
293         // depend on the success of the unmarshal operation below
294         Performative p = new Performative();
295         p.setInReplyTo(perf.getReplyWith());
296         p.setReceiver(perf.getSender());
297         
298         Contact newContact = new Contact();
299         String msgContent = perf.getContent();
300         System.out.println("Msg content: " + msgContent);
301         try {
302             // Convert the XML msg content into its corresponding Java object
303             ContactsParser parser = new ContactsParser(msgContent);
304             newContact = parser.getContact();
305             // Replace existing entry - if a contact exists with same alias
306             List existingContacts = contactsRoot.getContacts();
307             for (ListIterator i = existingContacts.listIterator(); i.hasNext(); ) {
308                 Contact c = (Contact)i.next();
309                 if (c.getZeusName().equalsIgnoreCase(newContact.getZeusName())) {
310                     // USe iterator's remove() method to avoid ConcurrentModificationException
311                     i.remove();            
312                 }
313             }
314             existingContacts.add(newContact);
315             // Now save the updated root object to the XML file
316             saveFIPAAliases();
317             // Now reload the file's contents into the ACC's address book
318             loadFIPAAliases();
319             // DONE!  Complete the reply message
320             p.setType("inform");
321             p.setContent("((done (" + msgContent + ")))");
322         }
323         catch (Exception e) {
324             System.out.println("Error unmarshalling XML msg content to Java object");
325             e.printStackTrace();
326             // FAILED! Complete the reply message
327             p.setType("failure");
328             p.setContent(msgContent);
329         }  
330         // Send the reply
331         p.send(context);            
332     }    
333     
334     
335     /***
336      * call the methods necessary to set up the agents transports using a different set of ports.
337      *
338      */
339     protected  void initialiseTransports(String transports) {
340         String thisLine;
341         String input = new String();
342         try {
343             FileInputStream fileStream = new FileInputStream(transports);
344             DataInputStream toReadFrom = new DataInputStream(fileStream);
345             while(toReadFrom.available() > 0) {
346                 System.out.println("reading");
347                 thisLine = toReadFrom.readLine();
348                 input += "\n" + thisLine;
349                 System.out.println(thisLine);
350                 
351             }
352             System.out.println(input);
353             
354         }
355         catch (Exception e) {
356             e.printStackTrace(); }
357             //  System.out.println(input);
358             
359             StringHashtable allTransports = ZeusParser.Transports(input);
360             Enumeration keys = allTransports.keys();
361             while(keys.hasMoreElements()) {
362                 System.out.println("key  = " + (String) keys.nextElement());
363             }
364             SystemProps.setTransports(allTransports);
365             
366     }
367     
368     
369     
370     
371     /***
372      * Traverses the XML document and creates the Java classes to
373      * represent it
374      */
375     private synchronized void buildTree() {        
376         try {
377             ContactsParser parser = new ContactsParser(contactsDb);
378             contactsRoot = parser.getContacts();
379         }
380         catch(FileNotFoundException f) {
381             //Trouble
382         }
383     }    
384     
385     
386     /***
387      * Writes XML content from the Java classes.
388      */
389     private synchronized void marshalTree() {        
390         ContactsParser parser = new ContactsParser();
391         parser.setRootObject(contactsRoot);
392         parser.write(contactsDb);
393     }
394     
395 }