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.actors;
29
30 import java.io.*;
31 import java.util.*;
32
33 import zeus.util.*;
34 import zeus.concepts.*;
35 import zeus.actors.event.*;
36 import zeus.actors.event.ProtocolDbNode;
37
38
39 /***
40 * The Protocol Database is a simple storage component that holds references
41 * to the social interaction protocols known by the agent. Note, although there
42 * is a class constructor () here it should never be used .
43 */
44 public class ProtocolDb extends Tree
45 {
46 protected Hashtable factIndex;
47 private HSet[] eventMonitor = new HSet[4];
48
49 private static final int ADD = 0;
50 private static final int MODIFY = 1;
51 private static final int DELETE = 2;
52 private static final int ACCESS = 3;
53
54 private static final int FAIL = 0;
55 private static final int ANY = 1;
56 private static final int RELATION = 2;
57 private static final int AGENT = 4;
58
59 Hashtable protocolInfoList;
60 AgentContext context;
61
62 /***
63 *this init really is for architectural purposes only. I think
64 *instantiation without a parameter here could be bad!
65 */
66 public ProtocolDb () {
67 super (new ProtocolDbNode ("dummy"));
68 }
69
70
71 public ProtocolDb(OntologyDb model) {
72 super(new ProtocolDbNode(model.getRoot().toString()));
73 String rootName = model.getRoot().toString();
74 factIndex = new Hashtable();
75 factIndex.put(rootName, root);
76 createTree(getRoot(),model.getRoot());
77
78 for(int i = 0; i < eventMonitor.length; i++ )
79 eventMonitor[i] = new HSet();
80
81 protocolInfoList = new Hashtable();
82 }
83
84 public ProtocolDb(AgentContext context) {
85 super(new ProtocolDbNode(context.OntologyDb().getRoot().toString()));
86 this.context = context;
87 context.set(this);
88 String rootName = context.OntologyDb().getRoot().toString();
89 factIndex = new Hashtable();
90 factIndex.put(rootName, root);
91 createTree(getRoot(),context.OntologyDb().getRoot());
92
93 for(int i = 0; i < eventMonitor.length; i++ )
94 eventMonitor[i] = new HSet();
95
96 protocolInfoList = new Hashtable();
97 }
98
99 protected void createTree(TreeNode m_node,TreeNode a_node) {
100
101
102
103 Vector children = a_node.getChildren();
104 TreeNode b_node;
105 TreeNode n_node;
106
107 for(int i = 0; i < children.size(); i++ ) {
108 b_node = (TreeNode)children.elementAt(i);
109 n_node = new TreeNode( new ProtocolDbNode(b_node.toString()) );
110 m_node.addChild(n_node);
111 factIndex.put(b_node.toString(),n_node);
112 createTree(n_node,b_node);
113 }
114 }
115
116 public void addProtocol(ProtocolInfo info) {
117 addProtocol(info,false);
118 }
119 public void addProtocol(Vector info) {
120 for(int i = 0; i < info.size(); i++ )
121 addProtocol((ProtocolInfo)info.elementAt(i),false);
122 }
123
124
125 private void addProtocol(ProtocolInfo info, boolean onlyLocal){
126 String factType;
127 ProtocolDbNode pDbNode;
128 TreeNode a_node;
129
130 Core.DEBUG(3,"addProtocol");
131 Core.DEBUG(3,info);
132 StrategyInfo[] strategies = info.getConstraints();
133 for(int i = 0; i < strategies.length; i++ ){
134 factType = strategies[i].getFact().getType();
135 a_node = (TreeNode) factIndex.get(factType);
136 Core.DEBUG(3,"a_node = " + a_node);
137 pDbNode = (ProtocolDbNode) a_node.getValue();
138 pDbNode.addProtocol(info.getName(),strategies[i]);
139 }
140 protocolInfoList.put(info.getName(),info);
141 if (!onlyLocal) {
142 notifyMonitors(info,ADD);
143 notifyMonitors(info,ACCESS);
144 }
145 }
146
147 public void removeProtocol(ProtocolInfo info){
148 removeProtocol(info, false);
149 }
150 public void removeProtocol(Vector info) {
151 for(int i = 0; i < info.size(); i++ )
152 removeProtocol((ProtocolInfo)info.elementAt(i),false);
153 }
154
155 private void removeProtocol(ProtocolInfo info, boolean onlyLocal){
156 String protocol = info.getName();
157 Enumeration enum = values();
158 ProtocolDbNode node;
159 while( enum.hasMoreElements() ) {
160 node = (ProtocolDbNode)enum.nextElement();
161 node.deleteProtocol(protocol);
162 }
163 protocolInfoList.remove(protocol);
164 if ( !onlyLocal ) {
165 notifyMonitors(info,DELETE);
166 notifyMonitors(info,ACCESS);
167 }
168 }
169
170
171 public void modifyProtocol(ProtocolInfo info){
172 removeProtocol(info,true);
173 addProtocol(info,true);
174 notifyMonitors(info,MODIFY);
175 notifyMonitors(info,ACCESS);
176 }
177
178
179 public Vector getProtocols(Fact fact, String[] agents, String type) {
180 Core.DEBUG(3, "getProtocols");
181 Core.DEBUG(3, fact);
182 Core.DEBUG(3, agents);
183 Core.DEBUG(3, type);
184 TreeNode a_node = (TreeNode) factIndex.get(fact.getType());
185 ProtocolDbNode node;
186 Vector protocols;
187 Vector strategies;
188 StrategyInfo info;
189 String protocol;
190 ProtocolInfo protocolInfo;
191 int value;
192 Hashtable resultSet = new Hashtable();
193
194 Core.DEBUG(3, "a_node0 = " + a_node);
195 while (a_node != null) {
196 Core.DEBUG(3, "a_node = " + a_node);
197 node = (ProtocolDbNode)a_node.getValue();
198 protocols = node.getProtocols();
199 Core.DEBUG(3, protocols);
200 for(int i = 0; i < protocols.size(); i++) {
201 protocol = (String) protocols.elementAt(i);
202 strategies = node.getStrategy(protocol);
203 Core.DEBUG(3, strategies);
204 for(int j = 0; j < strategies.size(); j++) {
205 info = (StrategyInfo)strategies.elementAt(j);
206 Core.DEBUG(3, info);
207 for(int k = 0; k < agents.length; k++) {
208 protocolInfo = (ProtocolInfo)protocolInfoList.get(protocol);
209 if ( protocolInfo.getType().equals(type) &&
210 (value = constraintsOK(fact,agents[k],info)) != FAIL ) {
211 if (info.getType() == StrategyInfo.USE)
212 addToResultSet(new ProtocolDbResult(agents[k],
213 protocol,info.getStrategy(),info.getParameters()),
214 value,resultSet);
215 else
216 removeFromResultSet(agents[k],protocol,resultSet);
217 }
218 }
219 }
220 }
221 a_node = a_node.getParent();
222 }
223 return sortResultSet(resultSet);
224 }
225
226 private int constraintsOK(Fact fact, String agent, StrategyInfo info) {
227 Core.DEBUG(3, "constraintsOK");
228 Core.DEBUG(3, fact);
229 Core.DEBUG(3, agent);
230 Core.DEBUG(3, info);
231
232 OrganisationDb organisationDb = context.OrganisationDb();
233 Bindings b;
234
235 if ( context != null )
236 b = new Bindings(context.whoami());
237 else
238 b = new Bindings();
239
240 Fact f1 = info.getFact();
241 if ( !f1.unifiesWithChild(fact,b) ) {
242 Core.DEBUG(3, "unifiesWithChild failed");
243 Core.DEBUG(3, f1);
244 return FAIL;
245 }
246
247 int result = ANY;
248
249 String[] agents = info.getAgents();
250 if ( agents.length > 0 ) {
251 if ( !Misc.member(agent,agents) )
252 return FAIL;
253 else
254 result *= AGENT;
255 }
256
257 String[] relations = info.getRelations();
258 if ( relations.length > 0 ) {
259 boolean found = false;
260 for(int i = 0; !found && i < relations.length; i++ )
261 found |= organisationDb.hasRelation(agent,relations[i]);
262 if ( !found )
263 return FAIL;
264 else
265 result *= RELATION;
266 }
267 return result;
268 }
269
270 private void removeFromResultSet(String agent, String protocol,
271 Hashtable resultSet) {
272 ProtocolDbResult item;
273 Vector List;
274 Enumeration enum = resultSet.elements();
275 while( enum.hasMoreElements() ) {
276 List = (Vector)enum.nextElement();
277 for(int i = 0; i< List.size(); i++) {
278 item = (ProtocolDbResult) List.elementAt(i);
279 if ( item.agent.equals(agent) && item.protocol.equals(protocol) )
280 List.removeElementAt(i--);
281 }
282 }
283 }
284 private void addToResultSet(ProtocolDbResult result, int grade,
285 Hashtable resultSet) {
286 String Id = Integer.toString(grade);
287 Vector List = (Vector)resultSet.get(Id);
288 if ( List == null ) {
289 List = new Vector();
290 resultSet.put(Id,List);
291 }
292 List.addElement(result);
293 }
294
295 private Vector sortResultSet(Hashtable resultSet) {
296
297
298
299 String Id;
300 Vector List;
301 Vector output = new Vector();
302
303 for(int i = 8; i > 0; i /= 2 ) {
304 Id = Integer.toString(i);
305 List = (Vector)resultSet.get(Id);
306 if ( List != null )
307 output = Misc.union(output,List);
308 }
309 return output;
310 }
311
312
313 public void addProtocolMonitor(ProtocolMonitor monitor, long event_type,
314 boolean notify_previous) {
315 addProtocolMonitor(monitor,event_type);
316 if ( !notify_previous ) return;
317
318 Enumeration enum = protocolInfoList.elements();
319 ProtocolInfo info;
320 ProtocolEvent event;
321
322 while( enum.hasMoreElements() ) {
323 info = (ProtocolInfo)enum.nextElement();
324 event = new ProtocolEvent(this,info,ProtocolEvent.ACCESS_MASK);
325 monitor.protocolAccessedEvent(event);
326 event = new ProtocolEvent(this,info,ProtocolEvent.ADD_MASK);
327 monitor.protocolAddedEvent(event);
328 }
329 }
330
331 /***
332 * If your code needs to react to changes in the agent's stored protocols
333 * use this method to add a ProtocolMonitor.
334 */
335 public void addProtocolMonitor(ProtocolMonitor monitor, long event_type) {
336 if ( (event_type & ProtocolEvent.ADD_MASK) != 0 )
337 eventMonitor[ADD].add(monitor);
338 if ( (event_type & ProtocolEvent.MODIFY_MASK) != 0 )
339 eventMonitor[MODIFY].add(monitor);
340 if ( (event_type & ProtocolEvent.DELETE_MASK) != 0 )
341 eventMonitor[DELETE].add(monitor);
342 if ( (event_type & ProtocolEvent.ACCESS_MASK) != 0 )
343 eventMonitor[ACCESS].add(monitor);
344 }
345
346 public void removeProtocolMonitor(ProtocolMonitor monitor,
347 long event_type) {
348 if ( (event_type & ProtocolEvent.ADD_MASK) != 0 )
349 eventMonitor[ADD].remove(monitor);
350 if ( (event_type & ProtocolEvent.MODIFY_MASK) != 0 )
351 eventMonitor[MODIFY].remove(monitor);
352 if ( (event_type & ProtocolEvent.DELETE_MASK) != 0 )
353 eventMonitor[DELETE].remove(monitor);
354 if ( (event_type & ProtocolEvent.ACCESS_MASK) != 0 )
355 eventMonitor[ACCESS].remove(monitor);
356 }
357
358 private void notifyMonitors(ProtocolInfo info, int type) {
359 if ( eventMonitor[type].isEmpty() ) return;
360
361 ProtocolMonitor monitor;
362 ProtocolEvent event;
363 Enumeration enum = eventMonitor[type].elements();
364
365 switch(type) {
366 case ADD:
367 event = new ProtocolEvent(this,info,ProtocolEvent.ADD_MASK);
368 while( enum.hasMoreElements() ) {
369 monitor = (ProtocolMonitor)enum.nextElement();
370 monitor.protocolAddedEvent(event);
371 }
372 break;
373 case MODIFY:
374 event = new ProtocolEvent(this,info,ProtocolEvent.MODIFY_MASK);
375 while( enum.hasMoreElements() ) {
376 monitor = (ProtocolMonitor)enum.nextElement();
377 monitor.protocolModifiedEvent(event);
378 }
379 break;
380 case DELETE:
381 event = new ProtocolEvent(this,info,ProtocolEvent.DELETE_MASK);
382 while( enum.hasMoreElements() ) {
383 monitor = (ProtocolMonitor)enum.nextElement();
384 monitor.protocolDeletedEvent(event);
385 }
386 break;
387 case ACCESS:
388 event = new ProtocolEvent(this,info,ProtocolEvent.ACCESS_MASK);
389 while( enum.hasMoreElements() ) {
390 monitor = (ProtocolMonitor)enum.nextElement();
391 monitor.protocolAccessedEvent(event);
392 }
393 break;
394 }
395 }
396 }
397