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  
24  /*
25   * @(#)BasicAgent.java 1.00
26   */
27  
28  package zeus.agents;
29  
30  import java.util.*;
31  import zeus.util.*;
32  import zeus.concepts.*;
33  import zeus.actors.*;
34  import zeus.actors.event.*;
35  
36  
37  /***
38   * This class implements the shared agent functionality common to every agent
39   * created with the Zeus toolkit.
40   */
41  
42  public class BasicAgent
43  {
44     private HSet[] eventMonitor = new HSet[4];
45  
46     public static final int CREATE  = 0;
47     public static final int DEATH   = 1;
48     public static final int SUSPEND = 2;
49     public static final int RESUME  = 3;
50  
51     protected AgentContext context = null;
52     
53     public BasicAgent(){ ;} 
54  
55     public BasicAgent(String type, String name, Vector nameservers) {
56       this(type, name, nameservers, null);
57     }
58  
59     public BasicAgent(String type, String name,
60                       Vector nameservers, Clock clock) {
61  
62       context = new ZeusAgentContext(name,type);
63       context.set(this);
64       context.setNameservers(nameservers);
65  
66       new MsgHandler(context);
67       new MailBox(context);
68  
69       if ( clock != null )
70          context.set(clock);
71  
72       for(int i = 0; i < eventMonitor.length; i++ )
73          eventMonitor[i] = new HSet();
74  
75       long now, start = System.currentTimeMillis();
76  
77       while( context.Clock() == null ) {
78         now = System.currentTimeMillis();
79         if ( now - start > (long)(context.getRegistrationTimeout()*60000) ) {
80            System.err.println("Cannot initialize " + name + " -- exiting");
81            notifyMonitors(DEATH);
82  	        System.exit(0);
83         }
84         try {
85            Thread.currentThread().sleep(1000);
86         }
87         catch(InterruptedException e) {
88         }
89       }
90       notifyMonitors(CREATE);
91     }
92  
93     public AgentContext getAgentContext() { return context; }
94  
95  
96     /*** Shortcut to add a MessageMonitor, used if your code needs to react to
97         changes in the state of the mailbox */
98     public void addMessageMonitor(MessageMonitor monitor, long event_type) {
99        context.MailBox().addMessageMonitor(monitor,event_type);
100    }
101 
102    public void removeMessageMonitor(MessageMonitor monitor, long event_type) {
103       context.MailBox().removeMessageMonitor(monitor,event_type);
104    }
105 
106    /*** Add an AgentMonitor if your code needs to react to Agent-level changes in state */
107    public void addAgentMonitor(AgentMonitor monitor, long event_type) {
108       Assert.notNull(monitor);
109       if ( (event_type & AgentEvent.CREATE_MASK) != 0 )
110          eventMonitor[CREATE].add(monitor);
111       if ( (event_type & AgentEvent.DEATH_MASK) != 0 )
112          eventMonitor[DEATH].add(monitor);
113       if ( (event_type & AgentEvent.SUSPEND_MASK) != 0 )
114          eventMonitor[SUSPEND].add(monitor);
115       if ( (event_type & AgentEvent.RESUME_MASK) != 0 )
116          eventMonitor[RESUME].add(monitor);
117    }
118    public void removeAgentMonitor(AgentMonitor monitor, long event_type) {
119       Assert.notNull(monitor);
120       if ( (event_type & AgentEvent.CREATE_MASK) != 0 )
121          eventMonitor[CREATE].remove(monitor);
122       if ( (event_type & AgentEvent.DEATH_MASK) != 0 )
123          eventMonitor[DEATH].remove(monitor);
124       if ( (event_type & AgentEvent.SUSPEND_MASK) != 0 )
125          eventMonitor[SUSPEND].remove(monitor);
126       if ( (event_type & AgentEvent.RESUME_MASK) != 0 )
127          eventMonitor[RESUME].remove(monitor);
128    }
129    public void notifyMonitors(int type) {
130       if ( eventMonitor[type].isEmpty() ) return;
131 
132       AgentMonitor monitor;
133       AgentEvent event;
134       Enumeration enum = eventMonitor[type].elements();
135 
136       switch(type) {
137          case CREATE:
138               event = new AgentEvent(this,this,AgentEvent.CREATE_MASK);
139               while( enum.hasMoreElements() ) {
140                  monitor = (AgentMonitor)enum.nextElement();
141                  monitor.agentCreatedEvent(event);
142               }
143               break;
144          case DEATH:
145               event = new AgentEvent(this,this,AgentEvent.DEATH_MASK);
146               while( enum.hasMoreElements() ) {
147                  monitor = (AgentMonitor)enum.nextElement();
148                  monitor.agentDeathEvent(event);
149               }
150               break;
151          case SUSPEND:
152               event = new AgentEvent(this,this,AgentEvent.SUSPEND_MASK);
153               while( enum.hasMoreElements() ) {
154                  monitor = (AgentMonitor)enum.nextElement();
155                  monitor.agentSuspendedEvent(event);
156               }
157               break;
158          case RESUME:
159               event = new AgentEvent(this,this,AgentEvent.RESUME_MASK);
160               while( enum.hasMoreElements() ) {
161                  monitor = (AgentMonitor)enum.nextElement();
162                  monitor.agentResumedEvent(event);
163               }
164               break;
165       }
166    }
167 }