1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
37
38 /***
39 * The implementation of the Zeus Database Proxy agent, which provides
40 * {@link Visualiser} agents with a means of persistently storing agent
41 * session information. A Database Proxy can serve as an interface to a
42 * 3rd party database using the {@link PersistentStore} interface, or it can
43 * store the session information its own ASCII file format ({@link FlatFile}. <p>
44 *
45 * It is unlikely that users will need to change or call directly any of the
46 * methods of this class.
47 */
48
49 public class DbProxy extends BasicAgent
50 {
51 protected PersistentStore proxy = null;
52
53 public DbProxy(String name, Vector nameservers, PersistentStore proxy) {
54 super(SystemProps.getProperty("agent.names.dbProxy"),name, nameservers);
55 Assert.notNull(proxy);
56 this.proxy = proxy;
57
58 String[][] pattern = {
59 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_create(//s+)(.*)//Z"},
60 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_delete(//s+)(.*)//Z"},
61 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_purge(//s+)(.*)//Z"},
62 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_open(//s+)(.*)//Z"},
63 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_save(//s+)(.*)//Z"},
64 {"type", "request", "reply-with", "(//w)(.*)", "content", "//Adb_close(//s+)(//w)(.*)//Z"},
65 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_next(//s+)(.*)//Z"},
66 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_prior(//s+)(.*)//Z"},
67 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_first(//s+)(.*)//Z"},
68 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_last(//s+)(.*)//Z"},
69 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_sessions(//s+)(.*)//Z"},
70 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_list(//s+)(.*)//Z"},
71 {"type", "query-ref", "reply-with", "(//w)(.*)", "content", "//Adb_count(//s+)(.*)//Z"}
72 };
73
74 MsgHandler handler = context.MsgHandler();
75 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[0], this, "db_create"));
76 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[1], this, "db_delete"));
77 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[2], this, "db_purge"));
78 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[3], this, "db_open"));
79 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[4], this, "db_save"));
80 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[5], this, "db_close"));
81
82 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[6], this, "db_next"));
83 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[7], this, "db_prior"));
84 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[8], this, "db_first"));
85 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[9], this, "db_last"));
86 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[10], this, "db_sessions"));
87 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[11], this, "db_list"));
88 handler.addRule(new MessageRuleImpl(context.newId("Rule"), pattern[12], this, "db_count"));
89 }
90
91 public void sendMsg(Performative msg) {
92 context.MailBox().sendMsg(msg);
93 }
94
95 public void db_create(Performative msg) {
96 /***
97 create a new database session:
98 message content contains: "db_create sessionType sessionId accessKey"
99 */
100 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
101 String reply_with = msg.getReplyWith();
102 proxy.createSession(reply_with,msg.getSender(),hd.data(0),hd.data(1),hd.data(2));
103 }
104 public void db_delete(Performative msg) {
105 /***
106 delete database session:
107 message content contains: "db_delete sessionType sessionId"
108 */
109 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
110 String reply_with = msg.getReplyWith();
111 proxy.deleteSession(reply_with,msg.getSender(),hd.data(0),hd.data(1));
112 }
113 public void db_purge(Performative msg) {
114 /***
115 purge database; i.e. clear all sessions
116 message content contains: "db_purge sessionType"
117 */
118 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
119 String reply_with = msg.getReplyWith();
120 proxy.deleteSessionType(reply_with,msg.getSender(),hd.data(0));
121 }
122 public void db_open(Performative msg) {
123 /***
124 open a database session:
125 message content contains: "db_open sessionType sessionId accessKey"
126 */
127 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
128 String reply_with = msg.getReplyWith();
129 proxy.openSession(reply_with,msg.getSender(),hd.data(0),hd.data(1),hd.data(2));
130 }
131 public void db_save(Performative msg) {
132 /***
133 save an entry
134 message content contains: "db_save accessKey object"
135 */
136 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
137 String reply_with = msg.getReplyWith();
138 proxy.saveRecord(reply_with,msg.getSender(),hd.data(0),hd.rest(0));
139 }
140 public void db_close(Performative msg) {
141 /***
142 close a database session:
143 message content contains: "db_close accessKey"
144 */
145 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
146 String reply_with = msg.getReplyWith();
147 proxy.closeSession(reply_with,msg.getSender(),hd.data(0));
148 }
149 public void db_next(Performative msg) {
150 /***
151 next database record:
152 message content contains: "db_next accessKey"
153 */
154 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
155 String reply_with = msg.getReplyWith();
156 proxy.nextRecord(reply_with,msg.getSender(),hd.data(0));
157 }
158 public void db_prior(Performative msg) {
159 /***
160 prior database record:
161 message content contains: "db_prior accessKey"
162 */
163 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
164 String reply_with = msg.getReplyWith();
165 proxy.priorRecord(reply_with,msg.getSender(),hd.data(0));
166 }
167 public void db_first(Performative msg) {
168 /***
169 first database record:
170 message content contains: "db_first accessKey"
171 */
172 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
173 String reply_with = msg.getReplyWith();
174 proxy.beginSession(reply_with,msg.getSender(),hd.data(0));
175 }
176 public void db_last(Performative msg) {
177 /***
178 last database record:
179 message content contains: "db_last accessKey"
180 */
181 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
182 String reply_with = msg.getReplyWith();
183 proxy.endSession(reply_with,msg.getSender(),hd.data(0));
184 }
185
186 public void db_sessions(Performative msg) {
187 /***
188 list all sessions stored in database
189 message content contains: "db_sessions sessionType"
190 */
191 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
192 String reply_with = msg.getReplyWith();
193 proxy.getAllSessions(reply_with,msg.getSender(),hd.data(0));
194 }
195 public void db_list(Performative msg) {
196 /***
197 list all agents referred to in the stored session
198 message content contains: "db_list accessKey"
199 */
200 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
201 String reply_with = msg.getReplyWith();
202 proxy.getAgents(reply_with,msg.getSender(),hd.data(0));
203 }
204 public void db_count(Performative msg) {
205 /***
206 return count of records in session
207 message content contains: "db_count accessKey"
208 */
209 MsgContentHandler hd = new MsgContentHandler(msg.getContent());
210 String reply_with = msg.getReplyWith();
211 proxy.countRecords(reply_with,msg.getSender(),hd.data(0));
212 }
213
214 protected static void version() {
215 System.err.println("DbProxy version: " +
216 SystemProps.getProperty("version.id"));
217 System.exit(0);
218 }
219 protected static void usage() {
220 System.err.println("Usage: java zeus.agents.DbProxy <name> " +
221 "-p <db_classpath> -s <dns_file> " +
222 "[-gui ViewerProg] [-e ExternalProg] " +
223 "[-debug] [-v] [-h]");
224 System.exit(0);
225 }
226
227 public static void main(String[] arg) {
228 Vector nameservers = null;
229 String dns_file = null;
230 String path = null;
231 DbProxy proxy = null;
232 PersistentStore store = null;
233 String gui = null;
234 String external = null;
235 String accessLevel = null;
236
237 if ( arg.length < 5 ) usage();
238 else
239 for( int i = 1; i < arg.length; i++ ) {
240 if ( arg[i].equals("-s") && ++i < arg.length )
241 dns_file = arg[i];
242 else if ( arg[i].equals("-p") && ++i < arg.length )
243 path = arg[i];
244 else if ( arg[i].equals("-e") && ++i < arg.length )
245 external = arg[i];
246 else if ( arg[i].equals("-gui") && ++i < arg.length )
247 gui = arg[i];
248 else if ( arg[i].equals("-debug") ) {
249 Core.debug = true;
250 Core.setDebuggerOutputFile(arg[0] + ".log");
251 }
252 else if ( arg[i].equals("-h") )
253 usage();
254 else if ( arg[i].equals("-v") )
255 version();
256 else if ( arg[i].equals("-access") && ++i < arg.length)
257 accessLevel = arg[i];
258 else
259 usage();
260 }
261
262 if ( path == null ) {
263 System.err.println("Database path must be specified with -p option");
264 usage();
265 }
266 if ( dns_file == null ) {
267 System.err.println("Domain nameserver file must be specified with -s option");
268 usage();
269 }
270
271 try {
272 nameservers = ZeusParser.addressList(new FileInputStream(dns_file));
273 if ( nameservers == null || nameservers.isEmpty() )
274 throw new IOException();
275
276 Class c = Class.forName(path);
277 store = (PersistentStore) c.newInstance();
278 proxy = new DbProxy(arg[0],nameservers,store);
279 store.setProxy(proxy);
280 if (accessLevel != null ) {
281 if (accessLevel.equals("true"))
282 store.setAccess(true);
283 else if (accessLevel.equals("false"))
284 store.setAccess(false);
285 else
286 throw new Exception("Error specifying access level");
287 }
288
289 AgentContext context = proxy.getAgentContext();
290
291 if ( gui != null ) {
292 c = Class.forName(gui);
293 BasicAgentUI ui = (BasicAgentUI) c.newInstance();
294 context.set(ui);
295 ui.set(context);
296 }
297
298 if ( external != null ) {
299 c = Class.forName(external);
300 ZeusExternal user_prog = (ZeusExternal)c.newInstance();
301 context.set(user_prog);
302 user_prog.exec(proxy.getAgentContext());
303 }
304 }
305 catch (Exception e) {
306 System.err.println(e);
307 System.exit(0);
308 }
309 }
310 }