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.util.*;
31 import zeus.util.*;
32 import zeus.concepts.*;
33 import zeus.actors.event.*;
34
35 /***
36 * The Organisation Database stores the agent's beliefs about its organisational
37 * relationships with other agents. Each relationship will be of one of the
38 * following types:
39 * <ul>
40 * <li> Peer - which is the default relationship which entails no restrictions
41 * or assumptions about agent interaction
42 * <li> Superior - here the acquaintance is believed to possess higher authority
43 * than this agent, and can issue orders that this agent must obey
44 * <li> Subordinate - the acquaintance is believed to have less authority than
45 * this agent, and can be issued orders that it must obey
46 * <li> Co-worker - the acquaintance belongs to the same 'community' as this
47 * agent, and will be asked before peers when any resources are required
48 * </ul>
49 */
50
51
52 public class OrganisationDb extends AbilityDb {
53 protected HSet[] eventMonitor = new HSet[4];
54
55 private static final int ADD = 0;
56 private static final int MODIFY = 1;
57 private static final int DELETE = 2;
58 private static final int ACCESS = 3;
59
60 protected Hashtable relations = new Hashtable();
61 protected String agentName = "null";
62
63
64 public OrganisationDb () {
65 super();
66 for(int i = 0; i < eventMonitor.length; i++ )
67 eventMonitor[i] = new HSet();
68 }
69
70 public OrganisationDb(AgentContext context) {
71 super(context);
72 agentName = context.whoami();
73 context.set(this);
74
75 for(int i = 0; i < eventMonitor.length; i++ )
76 eventMonitor[i] = new HSet();
77 }
78
79 public void addRelation(Vector List) {
80 for(int i = 0; i < List.size(); i++ ) {
81 String agent = (String) List.elementAt(i++);
82 String relation = (String) List.elementAt(i);
83 this.addRelation(agent,relation);
84 }
85 }
86
87
88 public void modifyAgentRelation(String agent, String oldRelation,
89 String newRelation) {
90 removeRelation(agent,oldRelation);
91 addRelation(agent,newRelation);
92 }
93
94
95 public Vector allRelations() {
96 Vector result = new Vector();
97
98 Vector peers = getPeers();
99 String agent;
100 for(int i = 0; i < peers.size(); i++ ) {
101 agent = (String)peers.elementAt(i);
102 result.addElement(new Relationship(agent,"peer"));
103 }
104
105 Enumeration enum = relations.keys();
106 String relation;
107 Vector List;
108 while( enum.hasMoreElements() ) {
109 relation = (String)enum.nextElement();
110 List = (Vector)relations.get(relation);
111
112 for(int i = 0; i < List.size(); i++ ) {
113 agent = (String)List.elementAt(i);
114 notifyMonitors(agent,relation,ACCESS);
115 result.addElement(new Relationship(agent,relation));
116 }
117 }
118 return result;
119 }
120
121
122 public void addRelation(String agent, String relation) {
123 addItem(agent,knownAgents);
124 Vector List = (Vector)relations.get(relation);
125 if ( List == null ) {
126 List = new Vector();
127 relations.put(relation,List);
128 }
129 if ( !List.contains(agent) ) {
130 List.addElement(agent);
131 notifyMonitors(agent,relation,ADD);
132 }
133 }
134
135
136 public void removeRelation(String agent, String relation) {
137 Vector List = (Vector)relations.get(relation);
138 if ( List == null ) return;
139 if ( List.contains(agent) ) {
140 List.removeElement(agent);
141 notifyMonitors(agent,relation,DELETE);
142 }
143 }
144
145
146 public boolean hasRelation(String agent, String relation) {
147 boolean result = false;
148 if ( relation.equals("peer") ) {
149 Vector peers = getPeers();
150 result = peers.contains(agent);
151 notifyMonitors(agent,"peer",ACCESS);
152 }
153 else {
154 Vector List = (Vector)relations.get(relation);
155 if ( List == null ) return false;
156 result = List.contains(agent);
157 notifyMonitors(agent,"relation",ACCESS);
158 }
159 return result;
160 }
161
162
163 public boolean hasRelation(String relation) {
164 boolean result = false;
165 if ( relation.equals("peer") ) {
166 Vector peers = getPeers();
167 result = !peers.isEmpty();
168 }
169 else {
170 Vector List = (Vector)relations.get(relation);
171 result = List != null && !List.isEmpty();
172 }
173 return result;
174 }
175
176
177 public Vector anyAgent(Goal goal, Vector ignore) {
178 Core.DEBUG(4,"anyAgent() = " + goal );
179
180 if ( ignore == null )
181 ignore = new Vector();
182
183 Vector agents = Misc.difference(knownAgents,ignore);
184 agents.removeElement(agentName);
185 return _anyAgent(agents,goal);
186 }
187
188
189 private Vector getPeers() {
190 Vector peers;
191 Vector others = new Vector();
192 Enumeration enum = relations.elements();
193 while( enum.hasMoreElements() )
194 others = Misc.union(others,(Vector)enum.nextElement());
195 peers = Misc.difference(knownAgents,others);
196 peers.removeElement(agentName);
197 return peers;
198 }
199
200
201 protected Vector _anyAgent(Vector agents, Goal goal) {
202 AbilitySpec ability;
203 Vector can_do = null;
204 String name;
205 AbilityDbItem item;
206 String key = null;
207 Vector result = new Vector();
208
209 ability = goal.getAbility();
210 if ( (can_do = findAll(ability)) != null ) {
211 Core.DEBUG(4,"anyAgent: " + ability + "\nwith\n" + can_do);
212 for( int j = 0; j < can_do.size(); j++ ) {
213 item = (AbilityDbItem)can_do.elementAt(j);
214 name = item.getAgent();
215 Core.DEBUG(4,"anyAgent considering: " + name);
216 if ( agents.contains(name) && !result.contains(name) ) {
217 result.addElement(name);
218 Core.DEBUG(4,"t" + name + " selected");
219 }
220 else {
221 Core.DEBUG(4,"t" + name + " not selected");
222 }
223 }
224 }
225 Core.DEBUG(4,"anyAgent result = " + result);
226 return result;
227 }
228
229
230 /***
231 * If your code needs to react to changes in the agent's organisational beliefs
232 * use this method to add a RelationMonitor to this component.
233 */
234 public void addRelationMonitor(RelationMonitor monitor, long event_type,
235 boolean notify_previous) {
236 addRelationMonitor(monitor,event_type);
237 if ( !notify_previous ) return;
238
239 RelationEvent event;
240 Relationship data;
241 Vector peers = getPeers();
242 String agent;
243 for(int i = 0; i < peers.size(); i++ ) {
244 agent = (String)peers.elementAt(i);
245 data = new Relationship(agent,"peer");
246 event = new RelationEvent(this,data,RelationEvent.ACCESS_MASK);
247 monitor.relationAccessedEvent(event);
248 event = new RelationEvent(this,data,RelationEvent.ADD_MASK);
249 monitor.relationAddedEvent(event);
250 }
251
252 Enumeration enum = relations.keys();
253 Vector List;
254 String relation;
255 while( enum.hasMoreElements() ) {
256 relation = (String)enum.nextElement();
257 List = (Vector)relations.get(relation);
258 for(int i = 0; i < List.size(); i++ ) {
259 agent = (String)List.elementAt(i);
260 data = new Relationship(agent,relation);
261 event = new RelationEvent(this,data,RelationEvent.ACCESS_MASK);
262 monitor.relationAccessedEvent(event);
263 event = new RelationEvent(this,data,RelationEvent.ADD_MASK);
264 monitor.relationAddedEvent(event);
265 }
266 }
267 }
268
269 public void addRelationMonitor(RelationMonitor monitor, long type) {
270 if ( (type & RelationEvent.ADD_MASK) != 0 )
271 eventMonitor[ADD].add(monitor);
272 if ( (type & RelationEvent.MODIFY_MASK) != 0 )
273 eventMonitor[MODIFY].add(monitor);
274 if ( (type & RelationEvent.DELETE_MASK) != 0 )
275 eventMonitor[DELETE].add(monitor);
276 if ( (type & RelationEvent.ACCESS_MASK) != 0 )
277 eventMonitor[ACCESS].add(monitor);
278 }
279
280 public void removeRelationMonitor(RelationMonitor monitor, long type) {
281 if ( (type & RelationEvent.ADD_MASK) != 0 )
282 eventMonitor[ADD].remove(monitor);
283 if ( (type & RelationEvent.MODIFY_MASK) != 0 )
284 eventMonitor[MODIFY].remove(monitor);
285 if ( (type & RelationEvent.DELETE_MASK) != 0 )
286 eventMonitor[DELETE].remove(monitor);
287 if ( (type & RelationEvent.ACCESS_MASK) != 0 )
288 eventMonitor[ACCESS].remove(monitor);
289 }
290
291 private void notifyMonitors(String agent, String relation, int type) {
292 if ( eventMonitor[type].isEmpty() ) return;
293
294 Enumeration enum = eventMonitor[type].elements();
295 Relationship data = new Relationship(agent,relation);
296 RelationMonitor monitor;
297 RelationEvent event;
298 switch(type) {
299 case ADD:
300 event = new RelationEvent(this,data,RelationEvent.ADD_MASK);
301 while( enum.hasMoreElements() ) {
302 monitor = (RelationMonitor)enum.nextElement();
303 monitor.relationAddedEvent(event);
304 }
305 break;
306 case MODIFY:
307 event = new RelationEvent(this,data,RelationEvent.MODIFY_MASK);
308 while( enum.hasMoreElements() ) {
309 monitor = (RelationMonitor)enum.nextElement();
310 monitor.relationModifiedEvent(event);
311 }
312 break;
313 case DELETE:
314 event = new RelationEvent(this,data,RelationEvent.DELETE_MASK);
315 while( enum.hasMoreElements() ) {
316 monitor = (RelationMonitor)enum.nextElement();
317 monitor.relationDeletedEvent(event);
318 }
319 break;
320 case ACCESS:
321 event = new RelationEvent(this,data,RelationEvent.ACCESS_MASK);
322 while( enum.hasMoreElements() ) {
323 monitor = (RelationMonitor)enum.nextElement();
324 monitor.relationAccessedEvent(event);
325 }
326 break;
327 }
328 }
329 }