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 under 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  
23  
24  /*
25   * @(#)Facilitator.java 1.03b
26   */
27  
28  package zeus.agents;
29  
30  import java.util.*;
31  import java.io.*;
32  
33  import zeus.util.*;
34  import zeus.concepts.*;
35  import zeus.actors.*;
36  import zeus.actors.event.*;
37  //import zeus.ontology.service.ServiceDescriptionReceiver; not in open source version
38  
39  //import com.ibm.icu.text.*;
40  
41  /***
42   * The implementation of the Zeus Facilitator agent. An agent society can have
43   * any number of facilitators whose role is to provide an ability-identity
44   * look-up service (analogous to the Yellow Pages).
45   *
46   * It is unlikely that users will need to change or call directly any of the
47   * methods of this class.
48   */
49  
50  public class Facilitator extends BasicAgent implements Runnable {
51      protected String   ABILITY_KEY;
52      public static final String SERVICE_KEY = "ACC_DAMLS_KEY";
53      protected long     timeout;
54      protected boolean  query_mode = true;
55      
56      
57      public Facilitator(String name, String file, Vector nameservers) {
58          this(name,file,nameservers,-1);
59      }
60      
61      public Facilitator(String name, String filename,
62      Vector nameservers, long user_timeout) {
63          super(SystemProps.getProperty("agent.names.facilitator"),
64          name,nameservers);
65          
66          context.set(new OntologyDb(context.GenSym()));
67          new OrganisationDb(context);
68          
69          OntologyDb db = context.OntologyDb();
70          int status = db.openFile(new File(filename));
71          if ( (status & OntologyDb.ERROR_MASK) != 0 ) {
72              System.err.println("File I/O Error: " + db.getError());
73              System.exit(0);
74          }
75          else if ( (status & OntologyDb.WARNING_MASK) != 0 ) {
76              System.err.println("Warning: " + db.getWarning());
77          }
78          
79          query_mode = (user_timeout != 0);
80          timeout= (long)(60000*SystemProps.getDouble("facilitator.period.default"));
81          if ( user_timeout > 0 )
82              timeout = user_timeout;
83          
84          // Initialise behaviour
85          Performative msg;
86          Address addr;
87          
88          ABILITY_KEY = context.newId();
89          String key = context.newId();
90          String[] pattern1 = { "type", "inform", "in-reply-to", key };
91          String[] pattern2 = { "type", "inform", "in-reply-to", ABILITY_KEY,
92  			      "content", "//A//(:fact(.*)//Z"};
93  
94  	String[] serviceProfile = {"type", "inform",
95  				   "content", "//A.*:serviceProfile.*",
96  				   "in-reply-to", ABILITY_KEY};
97  	String[] serviceInstance = {"type", "inform",
98  				    "content", "//A.*:serviceInstance.*",
99  				    "in-reply-to", ABILITY_KEY};
100 	String[] serviceRange = {"type", "inform",
101 				 "content", "//A.*:serviceRange.*",
102 				 "in-reply-to", ABILITY_KEY};
103 	String[] processModel = {"type", "inform",
104 				 "content", "//A.*:processModel.*",
105 				 "in-reply-to", ABILITY_KEY};
106         
107         context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
108         pattern1,this,"addressReceived")
109         );
110         context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
111         pattern2,this,"abilityReceived")
112         );
113         
114 
115 	/***
116          Object receiver = new ServiceDescriptionReceiver(context);
117 
118 	context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
119         serviceProfile, receiver,"serviceProfileReceived"));
120 	context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
121         serviceInstance, receiver,"serviceInstanceReceived"));
122 	context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
123         serviceRange, receiver,"serviceRangeReceived"));
124 	context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
125         processModel, receiver,"processModelReceived"));
126         */
127         for(int i = 0; i < nameservers.size(); i++ ) {
128             addr = (Address)nameservers.elementAt(i);
129             
130             msg = new Performative("subscribe");
131             msg.setReceiver(addr.getName());
132             msg.setReplyWith(key);
133             msg.setContent("log_address");
134             context.MailBox().sendMsg(msg);
135         }
136         if ( query_mode ) new Thread(this).start();
137     }
138     
139     /***
140      * addressReceived updates the address book of the facilitator so that
141      *it can send requests for service registrations to an agent
142      */
143     public void addressReceived(Performative msg) {
144         Core.DEBUG(2, "addressReceived: " + msg);
145         Vector List = ZeusParser.addressList(msg.getContent());
146         context.MailBox().add(List);
147         advertise(List);
148         //ST 050500 1.03b -  retain immediate ability query
149         // behavior until more user feedback obtained. (delete this
150         // line to cause facilitator to wait until next refresh period
151         if ( query_mode ) dispatchRequests(List);
152         
153     }
154     
155     /***
156      *abilityReceived updates the Zeus internal database of the Facilitator for
157      *services that it knows about and can respond to queries about
158      */
159     public void abilityReceived(Performative msg) {
160 
161         Core.DEBUG(2, "abilityReceived: " + msg);
162         Vector List = ZeusParser.abilitySpecList(context.OntologyDb(),msg.getContent());
163         String agent = msg.getSender();
164         context.OrganisationDb().add(agent,List);
165         msg.setReceiver("df");
166         msg.setContent(msg.getContent());
167         msg.setInReplyTo("ACC_FIPA_DF_KEY");
168         msg.send(context);
169     }
170     
171     protected void dispatchRequests(Vector v) {
172         Performative msg;
173         Address addr;
174         String me = context.whoami();
175         String agent = SystemProps.getProperty("agent.names.agent");
176         for(int i = 0; i < v.size(); i++ ) {
177             addr = (Address)v.elementAt(i);
178             if (!(addr.getName().equals(me)) && addr.getType().equals(agent)) {
179                 msg = new Performative("query-ref");
180                 msg.setReceiver(addr.getName());
181                 msg.setReplyWith(ABILITY_KEY);
182                 msg.setContent("your_abilities");
183                 context.MailBox().sendMsg(msg);
184             }
185         }
186     }
187     
188     protected void advertise(Vector v) {
189         Performative msg;
190         Address addr;
191         String me = context.whoami();
192         String agent = SystemProps.getProperty("agent.names.agent");
193         for(int i = 0; i < v.size(); i++ ) {
194             addr = (Address)v.elementAt(i);
195             if (!(addr.getName().equals(me)) && addr.getType().equals(agent)) {
196                 msg = new Performative("inform");
197                 msg.setReceiver(addr.getName());
198                 msg.setContent("isa_facilitator " + me);
199                 context.MailBox().sendMsg(msg);
200             }
201         }
202     }
203     
204     public void run() {
205         Thread me = Thread.currentThread();
206         while( true ) {
207             try {
208                 me.sleep(timeout);
209             }
210             catch(InterruptedException e) {
211             }
212             Vector List = context.MailBox().listAddresses();
213             dispatchRequests(List);
214             me.yield();
215         }
216     }
217     
218     public void addAbilityMonitor(AbilityMonitor monitor, long type) {
219         context.OrganisationDb().addAbilityMonitor(monitor,type);
220     }
221     public void addRelationMonitor(RelationMonitor monitor, long type) {
222         context.OrganisationDb().addRelationMonitor(monitor,type);
223     }
224     public void removeAbilityMonitor(AbilityMonitor monitor, long type) {
225         context.OrganisationDb().removeAbilityMonitor(monitor,type);
226     }
227     public void removeRelationMonitor(RelationMonitor monitor, long type) {
228         context.OrganisationDb().removeRelationMonitor(monitor,type);
229     }
230     
231     protected static void version() {
232         System.err.println("Facilitator version: " +
233         SystemProps.getProperty("version.id"));
234         System.exit(0);
235     }
236     protected static void usage() {
237         System.err.println("Usage: java zeus.agents.Facilitator <name> " +
238         "-o <ontology_file> -s <dns_file>] " +
239         "[-t <period>] [-gui ViewerProg] [-e ExternalProg] " +
240         "[-debug] [-v] [-h]");
241         System.exit(0);
242     }
243     
244     public static void main(String[] arg) {
245         // debug classpath problems for lamers.
246         // added by simon 21/08/00
247         try {
248             Class c = Class.forName("java.lang.Object");
249         }
250         catch (ClassNotFoundException cnfe) {
251             System.out.println("Java cannot find java.lang.Object.\n This indicates that the rt.jar file is not in your classpath.\n Ensure that $java_install_dir//jre//rt.jar is present in the classpath and then continue");
252             cnfe.printStackTrace();}
253         try {
254             // obscure zeus class picked to try it
255             Class c = Class.forName("zeus.gui.help.HelpWindow");
256         }
257         catch (ClassNotFoundException cnfe) {
258             System.out.println("Java cannot find a zeus class.\n This indicates that the zeus.jar file is not in your classpath.\n Ensure that zeus_install_dir//lib//zeus.jar is present in the classpath and then continue");
259             cnfe.printStackTrace();}
260  /*   try {
261          Class c = Class.forName("gnu.regexp.REException");
262     }
263     catch (ClassNotFoundException cnfe) {
264        System.out.println("Java cannot find a utility object.\n This indicates that the gnu-regexp.jar file is not in your classpath.\n Ensure that $zeus_install_dir//lib//gnu-regexp.jar is present in the classpath and then continue");
265             cnfe.printStackTrace();}*/
266         Vector nameservers = null;
267         String dns_file = null;
268         String recycle_period = null;
269         long timeout = 0;
270         String gui = null;
271         String external = null;
272         String ontology = null;
273         
274         if ( arg.length < 5 )  usage();
275         else
276             for( int i = 1; i < arg.length; i++ ) {
277                 if ( arg[i].equals("-s") && ++i < arg.length )
278                     dns_file = arg[i];
279                 else if ( arg[i].equals("-t") && ++i < arg.length )
280                     recycle_period = arg[i];
281                 else if ( arg[i].equals("-o") && ++i < arg.length )
282                     ontology = arg[i];
283                 else if ( arg[i].equals("-gui") && ++i < arg.length )
284                     gui = arg[i];
285                 else if ( arg[i].equals("-e") && ++i < arg.length )
286                     external = arg[i];
287                 else if ( arg[i].equals("-debug") ) {
288                     Core.debug = true;
289                     Core.setDebuggerOutputFile(arg[0] + ".log");
290                 }
291                 else if ( arg[i].equals("-h") )
292                     usage();
293                 else if ( arg[i].equals("-v") )
294                     version();
295                 else
296                     usage();
297             }
298         
299         if ( ontology == null ) {
300             System.err.println("Ontology Database file must be specified with -o option");
301             usage();
302         }
303         if ( dns_file == null ) {
304             System.err.println("Domain nameserver file must be specified with -s option");
305             usage();
306         }
307         
308         try {
309             nameservers = ZeusParser.addressList(new FileInputStream(dns_file));
310             if ( nameservers == null || nameservers.isEmpty() )
311                 throw new IOException();
312             
313             if ( recycle_period != null ) {
314                 double d = (Double.valueOf(recycle_period)).doubleValue();
315                 timeout = (long)(d*60000);
316             }
317             
318             Facilitator f = new Facilitator(arg[0],ontology,nameservers,timeout);
319             
320             Class c;
321             AgentContext context = f.getAgentContext();
322             
323             if ( gui != null ) {
324                 c = Class.forName(gui);
325                 BasicAgentUI ui = (BasicAgentUI) c.newInstance();
326                 context.set(ui);
327                 ui.set(context);
328             }
329             
330             if ( external != null ) {
331                 c = Class.forName(external);
332                 ZeusExternal user_prog = (ZeusExternal)c.newInstance();
333                 context.set(user_prog);
334                 user_prog.exec(context);
335             }
336             
337             
338             
339         }
340         catch (Exception e) {
341             e.printStackTrace();
342             System.exit(0);
343         }
344     }
345 }