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 * BasicTool.java - implements the core Visualiser functionality *
26 * - i.e. communication *
27 **********************************************************************/
28
29 package zeus.visualiser.basic;
30
31 import java.util.*;
32 import java.awt.*;
33 import java.awt.event.*;
34 import javax.swing.*;
35
36 import zeus.util.*;
37 import zeus.concepts.*;
38 import zeus.gui.*;
39 import zeus.gui.help.*;
40 import zeus.visualiser.*;
41 import zeus.actors.*;
42 import gnu.regexp.*;
43
44 public abstract class BasicTool extends JFrame {
45 protected AgentContext context = null;
46 protected VisualiserModel model = null;
47 protected MsgFilter filter = null;
48
49 private EditableMultipleSelectionDialog connect_dialog = null;
50 private MsgFilterEditor editor = null;
51
52 public BasicTool(AgentContext context, VisualiserModel model) {
53 this.context = context;
54 this.model = model;
55
56 this.addWindowListener(
57 new WindowAdapter() {
58 public void windowClosing(WindowEvent evt) { Exit(); }
59 }
60 );
61 }
62
63 public AgentContext getAgentContext() { return context; }
64 public VisualiserModel getModel() { return model; }
65
66 public void Exit() {
67 this.setVisible(false);
68 removeSubscriptions();
69 this.dispose();
70 }
71
72 public void Connect(boolean mode) {
73 if ( !hubOK() ) return;
74
75 String[] servers = model.getNameservers();
76 if ( connect_dialog == null ) {
77 connect_dialog = new EditableMultipleSelectionDialog(this,
78 "Select Servers", servers);
79 connect_dialog.setLocationRelativeTo(this);
80 }
81 else {
82 Object[] chosen = connect_dialog.getPriorSelection();
83 connect_dialog.setListData(servers);
84 connect_dialog.setSelection(chosen);
85 }
86
87 Object[] data = connect_dialog.getSelection();
88 model.addNameservers(Misc.stringArray(connect_dialog.getListData()));
89 if ( data != null && data.length > 0 )
90 subscribe(mode,model.keys[VisualiserModel.ADDRESS_KEY],
91 Misc.stringArray(data),"log_address");
92 }
93
94 public void quickConnect() {
95 String[] servers = model.getNameservers();
96 if (servers != null && servers.length > 0 ) {
97 subscribe(true,model.keys[VisualiserModel.ADDRESS_KEY],servers,
98 "log_address");
99 }
100 }
101
102 protected void subscribe(boolean mode, String key, String agent,
103 String method) {
104 /***
105 Note: for subscribe messages we do not want to ask the
106 agent twice to send the same data. Hence if 'isAlreadySubscribed()'
107 then do not send message. In the case of a query msg this check is
108 not made since the user might want to reissue a query.
109 */
110 Performative msg;
111 String ruleId = null;
112 String content = model.getSubscriptionContent(key);
113 if ( mode ) {
114 if ( (ruleId = model.getMessageRule(key,agent,this,method)) == null ) {
115 ruleId = context.newId("Rule");
116 String[] pattern = { "type", "inform", "in-reply-to", key, "sender", agent };
117 context.MsgHandler().addRule(
118 new MessageRuleImpl(ruleId,pattern,this,method)
119 );
120 model.addMessageRule(key,agent,this,method,ruleId);
121 }
122 if ( !model.isAlreadySubscribed(key,agent,ruleId) ) {
123 msg = new Performative("subscribe");
124 msg.setReceiver(agent);
125 msg.setReplyWith(key);
126 msg.setContent(content);
127 context.MailBox().sendMsg(msg);
128 model.subscribe(key,agent,ruleId);
129 }
130 }
131 else {
132 ruleId = model.removeMessageRule(key,agent,this,method);
133 context.MsgHandler().removeRule(ruleId);
134 switch( model.unsubscribe(key,agent,ruleId) ) {
135 case VisualiserModel.CANCEL_SUBSCRIPTION:
136 msg = new Performative("cancel");
137 msg.setReceiver(agent);
138 msg.setReplyWith(key);
139 msg.setContent(content);
140 context.MailBox().sendMsg(msg);
141 break;
142 default:
143 break;
144 }
145 }
146 }
147
148 protected void subscribe(boolean mode, String key, String[] agent,
149 String method) {
150 for(int i = 0; i < agent.length; i++ )
151 subscribe(mode,key,agent[i],method);
152 }
153
154 protected void query(String content, String agent, String method) {
155 String ruleId = context.newId("Rule");
156 String[] pattern = { "in-reply-to", ruleId, "sender", agent };
157 context.MsgHandler().addRule(
158 new MessageRuleImpl(ruleId,pattern,MessageActionImpl.EXECUTE_ONCE,this,method)
159 );
160 Performative msg = new Performative("query-ref");
161 msg.setReceiver(agent);
162 msg.setReplyWith(ruleId);
163 msg.setContent(content);
164 context.MailBox().sendMsg(msg);
165 }
166
167 protected void query(String content, String[] agent, String method) {
168 for(int i = 0; i < agent.length; i++ )
169 query(content,agent[i],method);
170 }
171
172 protected void request(String content, String agent, String method) {
173 String ruleId = context.newId("Rule");
174 String[] pattern = { "in-reply-to", ruleId, "sender", agent };
175 context.MsgHandler().addRule(
176 new MessageRuleImpl(ruleId,pattern,MessageActionImpl.EXECUTE_ONCE,this,method)
177 );
178 Performative msg = new Performative("request");
179 msg.setReceiver(agent);
180 msg.setReplyWith(ruleId);
181 msg.setContent(content);
182 context.MailBox().sendMsg(msg);
183 }
184
185 protected void request(String content, String[] agent, String method) {
186 for(int i = 0; i < agent.length; i++ )
187 request(content,agent[i],method);
188 }
189
190 protected boolean hubOK() {
191 if ( context == null || context.MailBox() == null ||
192 context.MsgHandler() == null || model == null ) {
193 JOptionPane.showMessageDialog(this, "Error",
194 "Not connected to a visualiser hub", JOptionPane.ERROR_MESSAGE);
195 return false;
196 }
197 return true;
198 }
199
200 public void log_address(Performative msg) {
201 Vector List = ZeusParser.addressList(msg.getContent());
202 context.MailBox().add(List);
203 for(int i = 0; i < List.size(); i++ ) {
204 Address a = (Address)List.elementAt(i);
205 String name = a.getName();
206 String type = a.getType();
207 model.addAgent(name, type);
208 registerAgent(name,type);
209 }
210 }
211
212 public void Filter() {
213 if ( !hubOK() ) return;
214
215 String[] agents = model.getAgents();
216 if ( editor == null ) {
217 editor = new MsgFilterEditor(this,"Edit Message Filter");
218 editor.setLocationRelativeTo(this);
219 }
220
221 editor.setListData(agents);
222 editor.setFilter(filter);
223 filter = editor.getFilter();
224
225 if ( filter != null ) {
226 if (filter.from != null)
227 model.addAgents(filter.from);
228 if (filter.to != null)
229 model.addAgents(filter.to);
230 if ( filter.about != null ) {
231 try {
232 filter.regexp = new RE(filter.about,RE.REG_DOT_NEWLINE);
233
234 }
235 catch(REException e) {
236 Core.USER_ERROR("Illegal 'about' filter: " + filter.about);
237 filter.about = null;
238 filter.regexp = null;
239 }
240 }
241 }
242 }
243
244 public void About() {
245 Point pt = getLocation();
246 HelpWindow helpWin = new HelpWindow(this, pt, "visualiser", "About");
247 helpWin.setSize(new Dimension(440, 440));
248 helpWin.setTitle("About ZEUS ...");
249 helpWin.validate();
250 }
251
252 protected boolean filterMsg(Performative msg) {
253 if ( filter == null ) return true;
254 String from = msg.getSender();
255 String to = msg.getReceiver();
256 if ( filter.from != null && !Misc.member(from,filter.from) )
257 return false;
258 if ( filter.to != null && !Misc.member(to,filter.to) )
259 return false;
260 if ( filter.regexp != null && !filter.regexp.isMatch(msg.getContent()) )
261 return false;
262 return true;
263 }
264
265 protected void removeSubscriptions() {
266 MessageInfo info;
267 String ruleId;
268 Performative msg;
269 Hashtable input = model.removeAllMessageRulesTo(this);
270 Enumeration enum = input.keys();
271 while( enum.hasMoreElements() ) {
272 info = (MessageInfo)enum.nextElement();
273 ruleId = (String)input.get(info);
274 context.MsgHandler().removeRule(ruleId);
275 switch( model.unsubscribe(info.key,info.agent,ruleId) ) {
276 case VisualiserModel.CANCEL_SUBSCRIPTION:
277 msg = new Performative("cancel");
278 msg.setReceiver(info.agent);
279 msg.setReplyWith(info.key);
280 msg.setContent(model.getSubscriptionContent(info.key));
281 context.MailBox().sendMsg(msg);
282 break;
283 default:
284 break;
285 }
286 }
287 }
288
289 protected abstract void registerAgent(String agent, String type);
290 }