📄 agent.java
字号:
//#J2ME_EXCLUDE_BEGIN
// Return agent thread
// Package scooped as it is called by JadeMisc add-on for container monitor purpose
Thread getThread() {
return myThread;
}
//#J2ME_EXCLUDE_END
//#MIDP_EXCLUDE_BEGIN
private void writeObject(ObjectOutputStream out) throws IOException {
// Updates the queue maximum size field, before serialising
msgQueueMaxSize = msgQueue.getMaxSize();
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
// Restore transient fields apart from myThread, that will be set when the agent will be powered up)
stateLock = new Object();
suspendLock = new Object();
pendingTimers = new AssociationTB();
theDispatcher = TimerDispatcher.getTimerDispatcher();
// restore O2AQueue
if (o2aQueueSize > 0)
o2aQueue = new ArrayList(o2aQueueSize);
o2aLocks = new HashMap();
myToolkit = DummyToolkit.instance();
temporaryMessageQueue = true;
msgQueue = new InternalMessageQueue(msgQueueMaxSize);
//#PJAVA_EXCLUDE_BEGIN
//For persistence service
persistentPendingTimers = new java.util.HashSet();
//#PJAVA_EXCLUDE_END
}
//#MIDP_EXCLUDE_END
/**
This method is executed when blockingReceive() is called
from a separate Thread.
It does not affect the agent state.
*/
private void waitUntilWake(long millis) {
synchronized(msgQueue) {
try {
// Blocks on msgQueue monitor for a while
waitOn(msgQueue, millis);
}
catch (InterruptedException ie) {
throw new Interrupted();
}
}
}
//#MIDP_EXCLUDE_BEGIN
private void waitUntilActivate() throws InterruptedException {
synchronized(suspendLock) {
waitOn(suspendLock, 0);
}
}
//#MIDP_EXCLUDE_END
/**
This method adds a new behaviour to the agent. This behaviour
will be executed concurrently with all the others, using a
cooperative round robin scheduling. This method is typically
called from an agent <code>setup()</code> to fire off some
initial behaviour, but can also be used to spawn new behaviours
dynamically.
@param b The new behaviour to add to the agent.
@see jade.core.Agent#setup()
@see jade.core.behaviours.Behaviour
*/
public void addBehaviour(Behaviour b) {
b.setAgent(this);
myScheduler.add(b);
}
/**
This method removes a given behaviour from the agent. This method
is called automatically when a top level behaviour terminates,
but can also be called from a behaviour to terminate itself or
some other behaviour.
@param b The behaviour to remove.
@see jade.core.behaviours.Behaviour
*/
public void removeBehaviour(Behaviour b) {
myScheduler.remove(b);
b.setAgent(null);
}
/**
Send an <b>ACL</b> message to another agent. This methods sends
a message to the agent specified in <code>:receiver</code>
message field (more than one agent can be specified as message
receiver).
@param msg An ACL message object containing the actual message to
send.
@see jade.lang.acl.ACLMessage
*/
public final void send(ACLMessage msg) {
// Set the sender of the message if not yet set
// FIXME. Probably we should always set the sender of the message!
try {
msg.getSender().getName().charAt(0);
}
catch (Exception e) {
msg.setSender(myAID);
}
myToolkit.handleSend(msg, myAID, true);
}
/**
Receives an <b>ACL</b> message from the agent message
queue. This method is non-blocking and returns the first message
in the queue, if any. Therefore, polling and busy waiting is
required to wait for the next message sent using this method.
@return A new ACL message, or <code>null</code> if no message is
present.
@see jade.lang.acl.ACLMessage
*/
public final ACLMessage receive() {
return receive(null);
}
/**
Receives an <b>ACL</b> message matching a given template. This
method is non-blocking and returns the first matching message in
the queue, if any. Therefore, polling and busy waiting is
required to wait for a specific kind of message using this method.
@param pattern A message template to match received messages
against.
@return A new ACL message matching the given template, or
<code>null</code> if no such message is present.
@see jade.lang.acl.ACLMessage
@see jade.lang.acl.MessageTemplate
*/
public final ACLMessage receive(MessageTemplate pattern) {
ACLMessage msg = null;
synchronized (msgQueue) {
msg = msgQueue.receive(pattern);
//#MIDP_EXCLUDE_BEGIN
if (msg != null) {
myToolkit.handleReceived(myAID, msg);
}
//#MIDP_EXCLUDE_END
}
return msg;
}
/**
Receives an <b>ACL</b> message from the agent message
queue. This method is blocking and suspends the whole agent until
a message is available in the queue.
@return A new ACL message, blocking the agent until one is
available.
@see jade.core.Agent#receive()
@see jade.lang.acl.ACLMessage
*/
public final ACLMessage blockingReceive() {
return blockingReceive(null, 0);
}
/**
Receives an <b>ACL</b> message from the agent message queue,
waiting at most a specified amount of time.
@param millis The maximum amount of time to wait for the message.
@return A new ACL message, or <code>null</code> if the specified
amount of time passes without any message reception.
*/
public final ACLMessage blockingReceive(long millis) {
return blockingReceive(null, millis);
}
/**
Receives an <b>ACL</b> message matching a given message
template. This method is blocking and suspends the whole agent
until a message is available in the queue.
@param pattern A message template to match received messages
against.
@return A new ACL message matching the given template, blocking
until such a message is available.
@see jade.core.Agent#receive(MessageTemplate)
@see jade.lang.acl.ACLMessage
@see jade.lang.acl.MessageTemplate
*/
public final ACLMessage blockingReceive(MessageTemplate pattern) {
return blockingReceive(pattern, 0);
}
/**
Receives an <b>ACL</b> message matching a given message template,
waiting at most a specified time.
@param pattern A message template to match received messages
against.
@param millis The amount of time to wait for the message, in
milliseconds.
@return A new ACL message matching the given template, or
<code>null</code> if no suitable message was received within
<code>millis</code> milliseconds.
@see jade.core.Agent#blockingReceive()
*/
public final ACLMessage blockingReceive(MessageTemplate pattern, long millis) {
ACLMessage msg = null;
synchronized(msgQueue) {
msg = receive(pattern);
long timeToWait = millis;
while(msg == null) {
long startTime = System.currentTimeMillis();
if (Thread.currentThread().equals(myThread)) {
doWait(timeToWait);
}
else {
// blockingReceive() called from an external thread --> Do not change the agent state
waitUntilWake(timeToWait);
}
long elapsedTime = System.currentTimeMillis() - startTime;
msg = receive(pattern);
if(millis != 0) {
timeToWait -= elapsedTime;
if(timeToWait <= 0)
break;
}
}
}
return msg;
}
/**
Puts a received <b>ACL</b> message back into the message
queue. This method can be used from an agent behaviour when it
realizes it read a message of interest for some other
behaviour. The message is put in front of the message queue, so
it will be the first returned by a <code>receive()</code> call.
@see jade.core.Agent#receive()
*/
public final void putBack(ACLMessage msg) {
synchronized(msgQueue) {
msgQueue.addFirst(msg);
}
}
final void setToolkit(AgentToolkit at) {
myToolkit = at;
}
final void resetToolkit() {
//#MIDP_EXCLUDE_BEGIN
myToolkit = DummyToolkit.instance();
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
myToolkit = null;
#MIDP_INCLUDE_END*/
}
//#MIDP_EXCLUDE_BEGIN
//#APIDOC_EXCLUDE_BEGIN
/**
This method blocks until the agent has finished its start-up phase
(i.e. until just before its setup() method is called.
When this method returns, the target agent is registered with the
AMS and the JADE platform is aware of it.
*/
public synchronized void waitUntilStarted() {
while(myLifeCycle.getState() == AP_INITIATED) {
try {
wait();
}
catch(InterruptedException ie) {
// Do nothing...
}
}
}
//#APIDOC_EXCLUDE_END
// Notify creator that the start-up phase has completed
private synchronized void notifyStarted() {
notifyAll();
}
// Notify toolkit of the added behaviour
// Package scooped as it is called by the Scheduler
void notifyAddBehaviour(Behaviour b) {
if (generateBehaviourEvents) {
myToolkit.handleBehaviourAdded(myAID, b);
}
}
// Notify the toolkit of the removed behaviour
// Package scooped as it is called by the Scheduler
void notifyRemoveBehaviour(Behaviour b) {
if (generateBehaviourEvents) {
myToolkit.handleBehaviourRemoved(myAID, b);
}
}
//#APIDOC_EXCLUDE_BEGIN
// Notify the toolkit of the change in behaviour state
// Public as it is called by the Scheduler and by the Behaviour class
public void notifyChangeBehaviourState(Behaviour b, String from, String to) {
b.setExecutionState(to);
if (generateBehaviourEvents) {
myToolkit.handleChangeBehaviourState(myAID, b, from, to);
}
}
public void setGenerateBehaviourEvents(boolean b) {
generateBehaviourEvents = b;
}
//#APIDOC_EXCLUDE_END
// For persistence service
private boolean getGenerateBehaviourEvents() {
return generateBehaviourEvents;
}
// Notify toolkit that the current agent has changed its state
private void notifyChangedAgentState(int oldState, int newState) {
myToolkit.handleChangedAgentState(myAID, oldState, newState);
}
//#MIDP_EXCLUDE_END
private void activateAllBehaviours() {
myScheduler.restartAll();
}
/**
Put a received message into the agent message queue. The message
is put at the back end of the queue. This method is called by
JADE runtime system when a message arrives, but can also be used
by an agent, and is just the same as sending a message to oneself
(though slightly faster).
@param msg The ACL message to put in the queue.
@see jade.core.Agent#send(ACLMessage msg)
*/
public final void postMessage(final ACLMessage msg) {
synchronized (msgQueue) {
if (msg != null) {
//#MIDP_EXCLUDE_BEGIN
myToolkit.handlePosted(myAID, msg);
//#MIDP_EXCLUDE_END
msgQueue.addLast(msg);
doWake();
messageCounter++;
}
}
}
//#CUSTOM_EXCLUDE_BEGIN
private jade.content.ContentManager theContentManager = null;
/**
* Retrieves the agent's content manager
* @return The content manager.
*/
public jade.content.ContentManager getContentManager() {
if (theContentManager == null) {
theContentManager = new jade.content.ContentManager();
}
return theContentManager;
}
// All the agent's service helper
private transient Hashtable helpersTable;
/**
* Retrieves the agent's service helper
* @return The service helper.
*/
public ServiceHelper getHelper( String serviceName ) throws ServiceException {
ServiceHelper se = null;
if (helpersTable == null) {
helpersTable = new Hashtable();
}
se = (ServiceHelper) helpersTable.get(serviceName);
// is the helper already into the agent's helpersTable ?
if (se == null) {
// there isn't, request its creation
se = myToolkit.getHelper(this, serviceName);
if (se != null) {
se.init(this);
helpersTable.put(serviceName, se);
}
else {
throw new ServiceException("Null helper");
}
}
return se;
}
//#CUSTOM_EXCLUDE_END
/**
Retrieve a configuration property set in the <code>Profile</code>
of the local container (first) or as a System property.
@param key the key that maps to the property that has to be
retrieved.
@param aDefault a default value to be returned if there is no mapping
for <code>key</code>
*/
public String getProperty(String key, String aDefault) {
String val = myToolkit.getProperty(key, aDefault);
if (val == null || val.equals(aDefault)) {
// Try among the System properties
String sval = System.getProperty(key);
if (sval != null) {
val = sval;
}
}
return val;
}
//#MIDP_EXCLUDE_BEGIN
public Properties getBootProperties() {
return myToolkit.getBootProperties();
}
//#MIDP_EXCLUDE_END
/**
This method is used to interrupt the agent's thread.
In J2SE/PJAVA it just calls myThread.interrupt(). In
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -