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  Change log
24  -----------
25  Simon 22/08/00 added an exception catcher as part of work for fix #109719
26  Simon 24/08/00 added code that puts a -name option into the option list, and then
27          sets the agents name if it is used
28        */
29  
30  
31  
32  package zeus.generator.code;
33  
34  import java.util.*;
35  import javax.swing.JTextArea;
36  import java.io.*;
37  
38  import zeus.concepts.*;
39  import zeus.util.*;
40  import zeus.generator.GeneratorModel;
41  
42  /***
43      AgentWriter is the class that is called by the generator to produce the Java code 
44      which is compiled into the agents
45      */
46  public class AgentWriter extends Writer {
47    public AgentWriter(GenerationPlan genplan, GeneratorModel genmodel,
48                       String directory, JTextArea textArea) {
49      super(genplan,genmodel,directory,textArea);
50    }
51  
52  
53    private boolean hasTasks(AgentDescription agent)
54    {
55      String[] tasks = agent.getTasks();
56      if (tasks.length == 0) return false;
57  
58      for(int j = 0; j < tasks.length; j++ )
59      {
60        AbstractTask t = genmodel.getTask(tasks[j]);
61        switch( t.getType() )
62        {
63          case AbstractTask.PRIMITIVE:
64            return true;
65          case AbstractTask.SUMMARY:
66            return true;
67          case AbstractTask.SCRIPT:
68            return true;
69        }
70      }
71      return false;
72    }
73  
74    public boolean hasRules(AgentDescription agent)
75    {
76      String[] tasks = agent.getTasks();
77      if (tasks.length == 0) return false;
78  
79      for(int j = 0; j < tasks.length; j++ )
80      {
81        AbstractTask t = genmodel.getTask(tasks[j]);
82        switch( t.getType() )
83        {
84          case AbstractTask.BEHAVIOUR:
85            return true;
86          case AbstractTask.SCRIPT:
87            return true;
88        }
89      }
90      return false;
91    }
92  
93  
94    public void write()
95    {
96        PrintWriter out;
97        AgentInfo[] agentInfo = genplan.getSelectedAgents();
98        if ( agentInfo.length == 0 ) return;
99  
100       textArea.append("\n*** Agent code generation started ***\n\n");
101       for(int i = 0; i < agentInfo.length; i++ ) {
102          AgentDescription agent = genmodel.getAgent(agentInfo[i].id);
103 
104          String name = genmodel.getAgentName(agentInfo[i].id);
105          textArea.append("Generating code for agent " + name + "\n");
106          try {
107             out = createFile(name + ".java");
108             out.println(standard_disclaimer);
109             out.println("/*");
110             out.println("This code was automatically generated by " +
111                         "ZeusAgentGenerator version " +
112                         SystemProps.getProperty("version.id"));
113             out.println("                           DO NOT MODIFY!!");
114             out.println("*/\n");
115 
116             out.println("import java.util.*;");
117             out.println("import java.io.*;");
118             out.println("import zeus.util.*;");
119             out.println("import zeus.concepts.*;");
120             out.println("import zeus.actors.*;");
121             out.println("import zeus.agents.*;");
122             out.println();
123 
124             out.println("public class " + name + " {");
125 
126             out.println("   protected static void version() {");
127             out.println("      System.err.println(\"ZeusAgent - " + name +
128                         " version: " + SystemProps.getProperty("version.id") +
129                         "\");");
130             out.println("      System.exit(0);");
131             out.println("   }");
132             out.println();
133 
134             out.println("   protected static void usage() {");
135             out.println("      System.err.println(\"Usage: java " +
136                         name + " -s <dns_file> -o <ontology_file> " +
137                         "[-gui ViewerProg] [-e <ExternalProg>] " +
138                         "[-r ResourceProg] [-name <AgentName>] [-debug] [-h] [-v]\");");
139             out.println("      System.exit(0);");
140             out.println("   }");
141             out.println();
142 
143             out.println("   public static void main(String[] arg) {");
144             // added by Simon 21/08/00 for #109719 (1.04)
145             out.println("   try { ");
146             out.println("      ZeusAgent agent;");
147             out.println("      String external = null;");
148             out.println("      String dns_file = null;");
149             out.println("      String resource = null;");
150             out.println("      String gui = null;");
151             out.println("      String ontology_file = null;");
152             out.println("      Vector nameservers = null;");
153             out.println("      String name = new String (\"" + name + "\");"); 
154             out.println("      Bindings b = new Bindings(\"" + name + "\");");
155             out.println("      FileInputStream stream = null;");
156             out.println("      ZeusExternal user_prog = null;");
157             out.println();
158             out.println();
159             out.println("      for( int j = 0; j < arg.length; j++ ) {");
160             out.println("         if ( arg[j].equals(\"-s\") && " +
161                         " ++j < arg.length )");
162             out.println("            dns_file = arg[j];");
163             out.println("         else if ( arg[j].equals(\"-e\") && " +
164                         " ++j < arg.length )");
165             out.println("            external = arg[j];");
166             out.println("         else if ( arg[j].equals(\"-r\") && " +
167                         " ++j < arg.length )");
168             out.println("            resource = arg[j];");
169             out.println("         else if ( arg[j].equals(\"-o\") && " +
170                         " ++j < arg.length )");
171             out.println("            ontology_file = arg[j];");
172             out.println("         else if ( arg[j].equals(\"-gui\") && " +
173                         " ++j < arg.length )");
174             out.println("            gui = arg[j];");
175             out.println("         else if ( arg[j].equals(\"-debug\") ) {");
176             out.println("            Core.debug = true;");
177             out.println("            Core.setDebuggerOutputFile(\"" + name + ".log" + "\");");
178             out.println("         }");
179             out.println("         else if ( arg[j].equals(\"-v\") )");
180             out.println("            version();");
181             // added by Simon 24/08/00, frankly @ way past my bedtime
182             out.println("         else if ( arg[j].equals(\"-name\")  &&" + 
183                         " ++j < arg.length )"); 
184             out.println("             name = name  + arg[j];"); // altered to remove '_'
185             //zzzzz
186             out.println("         else if ( arg[j].equals(\"-h\") )");
187             out.println("            usage();");
188             out.println("         else");
189             out.println("            usage();");
190             out.println("      }");
191             out.println();
192             // added by Simon 24/08/00
193             out.println("       b = new Bindings(name);"); 
194             out.println("      if ( ontology_file == null ) {");
195             out.println("         System.err.println(\"Ontology Database " +
196                         "file must be specified with -o option\");");
197             out.println("         usage();");
198             out.println("      }");
199             out.println("      if ( dns_file == null ) {");
200             out.println("         System.err.println(\"Domain nameserver " +
201                         "file must be specified with -s option\");");
202             out.println("         usage();");
203             out.println("      }");
204             out.println();
205 
206             out.println("         nameservers = ZeusParser.addressList(" +
207                         "new FileInputStream(dns_file));");
208             out.println("         if ( nameservers == null || " +
209                         "nameservers.isEmpty() ) ");
210             out.println("            throw new IOException();");
211             out.println();
212 
213             out.println("         agent = new ZeusAgent(name,ontology_file,nameservers," +
214                         agent.getPlannerWidth() + "," + agent.getPlannerLength() + "," +
215                         hasTasks(agent) + "," + hasRules(agent) + ");" );
216             out.println();
217             out.println("         AgentContext context = agent.getAgentContext();");
218             out.println("         OntologyDb db = context.OntologyDb();");
219             out.println();
220 
221             out.println();
222             out.println("/*\n         Initialising Extensions\n*/");
223             out.println("         Class c;");
224             out.println();
225             out.println("         if ( resource != null ) {");
226             out.println("            c = Class.forName(resource);");
227             out.println("            ExternalDb oracle = (ExternalDb) c.newInstance();");
228             out.println("            context.set(oracle);");
229             out.println("            oracle.set(context);");
230             out.println("         }");
231             out.println("         if ( gui != null ) {");
232             out.println("            c = Class.forName(gui);");
233             out.println("            ZeusAgentUI ui = (ZeusAgentUI)c.newInstance();");
234             out.println("            context.set(ui);");
235             out.println("            ui.set(context);");
236             out.println("         }");
237             out.println();
238 
239             ProtocolInfo[] protocol = agent.getProtocols();
240             out.println("/*\n         Initialising ProtocolDb\n*/");
241             out.println("         ProtocolInfo info;");
242             for(int j = 0; j < protocol.length; j++ ) {
243                StrategyInfo[] strategy = protocol[j].getConstraints();
244                for(int k = 0; k < strategy.length; k++ ) {
245                   String[] array = strategy[k].getAgents();
246                   Vector stringVector = new Vector();
247                   for(int l = 0; l < array.length; l++ ) {
248                      String a_name = genmodel.getAgentName(array[l]);
249                      if ( a_name == null )
250                         textArea.append("Warning: agent " + name +
251                            " refers to an undefined agent\n");
252                      else
253                         stringVector.addElement(a_name);
254                   }
255                   array = Misc.stringArray(stringVector);
256                   strategy[k].setAgents(array);
257                }
258                protocol[j].setConstraints(strategy);
259 
260                out.println("         info = ZeusParser.protocolInfo(db,\"" +
261                      Misc.escape(protocol[j].toString()) + "\");");
262                out.println("         if ( info.resolve(b) )");
263                out.println("            agent.addProtocol(info);");
264             }
265             out.println();
266 
267             String[] tasks = agent.getTasks();
268             if (tasks.length != 0) {
269                out.println("/*\n         Initialising TaskDb\n*/");
270                out.println("         AbstractTask t;");
271                for(int j = 0; j < tasks.length; j++ ) {
272                   String a_name = genmodel.getTaskName(tasks[j]);
273                   if ( a_name == null )
274                      textArea.append("Warning: agent " + name + " refers to an undefined task\n");
275                   else {
276                      AbstractTask t = genmodel.getTask(tasks[j]);
277                      switch( t.getType() ) {
278                         case AbstractTask.PRIMITIVE:
279                              t = new PrimitiveTask((PrimitiveTask)t);
280                              t.setName(a_name);
281                              out.println("         t = ZeusParser.primitiveTask(db,\"" +
282                                 Misc.escape(t.toString()) + "\");");
283                              break;
284                         case AbstractTask.SUMMARY:
285                              t = new SummaryTask((SummaryTask)t);
286                              t.setName(a_name);
287                              out.println("         t = ZeusParser.summaryTask(db,\"" +
288                                 Misc.escape(t.toString()) + "\");");
289                              break;
290                         case AbstractTask.BEHAVIOUR:
291                              out.println("         stream = new FileInputStream(\"" +
292                                 a_name + ".clp" + "\");");
293                              out.println("         t = ZeusParser.reteKB(db,stream);");
294                              out.println("         stream.close();");
295                              break;
296                         case AbstractTask.SCRIPT:
297                              // t = new Script((Script)t);
298                              t.setName(a_name);
299                              out.println("         t = ZeusParser.script(db,\"" +
300                                 Misc.escape(t.toString()) + "\");");
301                              break;
302                         default:
303                              Core.ERROR(null,1,this);
304                      }
305                      out.println("         if ( t.resolve(b) )");
306                      out.println("            agent.addTask(t);");
307 
308 		     //Add restrictions
309 		     List restrictions = agent.getRestrictions();
310 		     for(Iterator r = restrictions.iterator() ; r.hasNext() ;){
311 		       Restriction item = (Restriction)r.next();
312 		       if(item.getTaskName().equals(a_name)) {
313 			 out.println("         t.addRestriction(\"" +
314 				     item.getFactName() + "\", \"" +
315 				     item.getAttributeName() + "\", \"" +
316 				     item.getRestriction() + "\");");
317 		       }
318 		     }
319                   }
320                }
321             }
322 
323             Acquaintance[] others = agent.getAcquaintances();
324             out.println("/*\n         Initialising OrganisationalDb\n*/");
325             out.println("         AbilityDbItem item;");
326             for(int j = 0; j < others.length; j++ ) {
327                String a_name = genmodel.getAgentName(others[j].getName());
328                if ( a_name == null )
329                   textArea.append("Warning: agent " + name +
330                      " refers to an undefined acquaintance\n");
331                else {
332                   out.println("         agent.addRelation(\"" + a_name +
333                      "\",\"" + others[j].getRelation() + "\");");
334 
335                   AbilitySpec[] List = others[j].getAbilities();
336                   AbilityDbItem dbItem;
337                   for(int k = 0; k < List.length; k++ ) {
338                      dbItem = new AbilityDbItem(a_name,List[k]);
339                      out.println("         item = ZeusParser.abilityDbItem(db,\"" +
340                         Misc.escape(dbItem.toString()) + "\");");
341                      out.println("         if ( item.resolve(b) )");
342                      out.println("            agent.addAbility(item);");
343                   }
344                }
345                out.println();
346             }
347 
348             Fact[] facts = agent.getInitialFacts();
349             out.println("/*\n         Initialising ResourceDb\n*/");
350             out.println("         Fact f1;");
351             for(int j = 0; j < facts.length; j++ ) {
352                if ( !facts[j].isDeterminate() )
353                   textArea.append("Warning: " + facts[j].getId() +
354                          " is not grounded");
355                   out.println("         f1 = ZeusParser.fact(db,\"" +
356                               Misc.escape(facts[j].toString()) + "\");");
357                   out.println("         if ( f1.resolve(b) )");
358                   out.println("            agent.addFact(f1);");
359             }
360             out.println();
361 
362             out.println();
363             out.println("/*\n         Initialising External User Program\n*/");
364             out.println();
365             out.println("         if ( external != null ) {");
366             out.println("            c = Class.forName(external);");
367             out.println("            user_prog = (ZeusExternal) c.newInstance();");
368             out.println("            context.set(user_prog);");
369             out.println("         }");
370             out.println();
371 
372             if (hasRules(agent)) {
373                out.println("/*\n         Activating Rete Engine\n*/");
374                out.println("         context.ReteEngine().run();");
375             }
376 
377             out.println();
378             out.println("/*\n         Activating External User Program\n*/");
379             out.println();
380             out.println("         if ( user_prog != null )");
381             out.println("            user_prog.exec(context);");
382             out.println();
383             out.println("      }");
384             // added by simon 21/08/00 
385             // catch for ClassNotFoundeException to give a nice error message
386             out.println(" catch (ClassNotFoundException cnfe) { "); 
387             out.print("     System.out.println(\"Java cannot find some of the classes that "); 
388             out.print("are needed to run this agent. Please ensure that you have the following"); 
389             out.print ("in your classpath : zeus_install_dir////lib////zeus.jar, "); 
390           out.print ("zeus_install_dir////lib////gnu-regexp.jar, "); 
391             out.print ("java_install_dir////jre////rt.jar "); 
392             out.print (" Where zeus_install_dir is the directory that you have installed "); 
393             out.print (" Zeus in , and java_install_dir is the directory that you have ");
394             out.println (" installed Java in\");"); 
395             out.println("   cnfe.printStackTrace();}");
396             out.println("      catch(Exception e) {");
397             out.println("         e.printStackTrace();");
398             // line removed by simon 21/08/00. 
399             // if the agent is brought down with a exit(0) the whole jvm will close 
400             // further work - deregister instead, and finalise objects.
401             //out.println("         System.exit(0);");
402             out.println("      }");
403           
404                         
405             out.println("   }");
406             out.println("}");
407             out.flush();
408             out.close();
409 
410             agentInfo[i].status = GenerationPlan.NO_SAVE_NEEDED;
411             agentInfo[i].generate = false;
412          }
413          catch(IOException e) {
414             textArea.append("Error generating agent " + name);
415          }
416       }
417       textArea.append("Generating " +
418          SystemProps.getProperty("application.gif") + " file\n");
419       try {
420          out = createFile(SystemProps.getProperty("application.gif"));
421 
422          String name, filename;
423          char sys_char = File.separatorChar;
424          char zeus_char = SystemProps.getProperty("file.separator").charAt(0);
425 
426          String[] identifiers = genmodel.getAgentIds();
427 
428          for(int i = 0; i < identifiers.length; i++ ) {
429             name = genmodel.getAgentName(identifiers[i]);
430             filename = genmodel.getAgentIcon(identifiers[i]);
431             filename = Misc.relativePath(directory,filename);
432             filename = filename.replace(sys_char,zeus_char);
433             out.println(name + " = " + Misc.escape(filename));
434          }
435          out.flush();
436          out.close();
437       }
438       catch(IOException e) {
439          textArea.append("Error generating " +
440             SystemProps.getProperty("application.gif") + " file\n");
441       }
442       textArea.append("\n*** Agent Code generation completed ***\n");
443    }
444 }