?? agent.java
字號:
/**
Represents the <em>suspended</em> agent state.
*/
public static final int D_SUSPENDED = 20;
/**
Represents the <em>retired</em> agent state.
*/
public static final int D_RETIRED = 30;
/**
Represents the <em>unknown</em> agent state.
*/
public static final int D_UNKNOWN = 40;
/**
Out of band value for Domain Life Cycle states.
*/
public static final int D_MAX = 41; // Hand-made type checking
//#MIDP_EXCLUDE_END
//#APIDOC_EXCLUDE_END
private transient MessageQueue msgQueue;
private transient AgentToolkit myToolkit;
//#MIDP_EXCLUDE_BEGIN
private int msgQueueMaxSize = 0;
private transient List o2aQueue;
private int o2aQueueSize = 0;
private transient Map o2aLocks;
private transient Object suspendLock;
//#MIDP_EXCLUDE_END
private String myName = null;
private AID myAID = null;
private String myHap = null;
private transient Object stateLock;
private transient Thread myThread;
private transient TimerDispatcher theDispatcher;
private Scheduler myScheduler;
private transient AssociationTB pendingTimers;
// Free running counter that increments by one for each message
// received.
private int messageCounter = 0 ;
private boolean restarting = false;
private LifeCycle myLifeCycle;
private LifeCycle myBufferedLifeCycle;
private LifeCycle myActiveLifeCycle;
private transient LifeCycle myDeletedLifeCycle;
//#MIDP_EXCLUDE_BEGIN
private transient LifeCycle mySuspendedLifeCycle;
//#MIDP_EXCLUDE_END
/**
This flag is used to distinguish the normal AP_ACTIVE state from
the particular case in which the agent state is set to AP_ACTIVE
during agent termination to allow it to deregister with the AMS.
In this case in fact a call to <code>doDelete()</code>,
<code>doMove()</code>, <code>doClone()</code> and <code>doSuspend()</code>
should have no effect.
*/
private boolean terminating = false;
//#MIDP_EXCLUDE_BEGIN
// For persistence service
private void setTerminating(boolean b) {
terminating = b;
}
// For persistence service
private boolean getTerminating() {
return terminating;
}
/**
When set to false (default) all behaviour-related events (such as ADDED_BEHAVIOUR
or CHANGED_BEHAVIOUR_STATE) are not generated in order to improve performances.
These events in facts are very frequent.
*/
private boolean generateBehaviourEvents = false;
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
public static MIDlet midlet;
// Flag for agent interruption (necessary as Thread.interrupt()
// is not available in MIDP)
private boolean isInterrupted = false;
#MIDP_INCLUDE_END*/
/**
Default constructor.
*/
public Agent() {
//#MIDP_EXCLUDE_BEGIN
myToolkit = DummyToolkit.instance();
o2aLocks = new HashMap();
msgQueue = new MessageQueue(msgQueueMaxSize);
suspendLock = new Object();
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
msgQueue = new MessageQueue();
#MIDP_INCLUDE_END*/
stateLock = new Object();
pendingTimers = new AssociationTB();
myActiveLifeCycle = new ActiveLifeCycle();
myLifeCycle = myActiveLifeCycle;
myScheduler = new Scheduler(this);
theDispatcher = TimerDispatcher.getTimerDispatcher();
}
//#MIDP_EXCLUDE_BEGIN
/**
Constructor to be used by special "agents" that will never powerUp.
*/
Agent(AID id) {
setAID(id);
}
// For persistence service
private Long persistentID;
// For persistence service
private Long getPersistentID() {
return persistentID;
}
// For persistence service
private void setPersistentID(Long l) {
persistentID = l;
}
/**
* Declared transient because the container changes in case
* of agent migration.
*/
private transient jade.wrapper.AgentContainer myContainer = null;
/**
* Return a controller for the container this agent lives in.
* <br>
* <b>NOT available in MIDP</b>
* <br>
* @return jade.wrapper.AgentContainer a controller for the container this agent lives in.
*/
public final jade.wrapper.AgentContainer getContainerController() {
if (myContainer == null) { // first time called
try {
jade.security.JADEPrincipal principal = null;
jade.security.Credentials credentials = null;
try {
jade.security.CredentialsHelper ch = (jade.security.CredentialsHelper) getHelper("jade.core.security.Security");
principal = ch.getPrincipal();
credentials = ch.getCredentials();
}
catch (ServiceException se) {
// Security plug-in not present. Ignore it
}
myContainer = myToolkit.getContainerController(principal, credentials);
} catch (Exception e) {
throw new IllegalStateException("A ContainerController cannot be got for this agent. Probably the method has been called at an appropriate time before the complete initialization of the agent.");
}
}
return myContainer;
}
//#MIDP_EXCLUDE_END
private transient Object[] arguments = null; // array of arguments
//#APIDOC_EXCLUDE_BEGIN
/**
* Called by AgentContainerImpl in order to pass arguments to a
* just created Agent.
* <p>Usually, programmers do not need to call this method in their code.
* @see #getArguments() how to get the arguments passed to an agent
**/
public final void setArguments(Object args[]) {
// I have declared the method final otherwise getArguments would not work!
arguments=args;
}
//#APIDOC_EXCLUDE_END
/**
* Get the array of arguments passed to this agent.
* <p> Take care that the arguments are transient and they do not
* migrate with the agent neither are cloned with the agent!
* @return the array of arguments passed to this agent.
* @see <a href=../../../tutorials/ArgsAndPropsPassing.htm>How to use arguments or properties to configure your agent.</a>
**/
public Object[] getArguments() {
return arguments;
}
void setRestarting(boolean restarting) {
this.restarting = restarting;
}
/**
* This method returns <code>true</code> when this agent is restarting after a crash.
* The restarting indication is automatically reset as soon as the <code>setup()</code> method of
* this agent terminates.
* @return <code>true</code> when this agent is restarting after a crash. <code>false</code> otherwise.
*/
public final boolean isRestarting() {
return restarting;
}
/**
Get the Agent ID for the platform AMS.
@return An <code>AID</code> object, that can be used to contact
the AMS of this platform.
*/
public final AID getAMS() {
return myToolkit.getAMS();
}
/**
Get the Agent ID for the platform default DF.
@return An <code>AID</code> object, that can be used to contact
the default DF of this platform.
*/
public final AID getDefaultDF() {
return myToolkit.getDefaultDF();
}
/**
Method to query the agent local name.
@return A <code>String</code> containing the local agent name
(e.g. <em>peter</em>).
*/
public final String getLocalName() {
return myName;
}
/**
Method to query the agent complete name (<em><b>GUID</b></em>).
@return A <code>String</code> containing the complete agent name
(e.g. <em>peter@fipa.org:50</em>).
*/
public final String getName() {
if (myHap != null) {
return myName + '@' + myHap;
}
else {
return myName;
}
}
/**
* Method to query the Home Agent Platform. This is the name of
* the platform where the agent has been created, therefore it will
* never change during the entire lifetime of the agent.
* In JADE the name of an agent by default is composed by the
* concatenation (using '@') of the agent local name and the Home
* Agent Platform name
*
* @return A <code>String</code> containing the name of the home agent platform
* (e.g. <em>myComputerName:1099/JADE</em>).
*/
public final String getHap() {
return myHap;
}
/**
Method to query the private Agent ID. Note that this Agent ID is
<b>different</b> from the one that is registered with the
platform AMS.
@return An <code>Agent ID</code> object, containing the complete
agent GUID, addresses and resolvers.
*/
public final AID getAID() {
return myAID;
}
void setAID(AID id) {
myName = id.getLocalName();
myHap = id.getHap();
myAID = id;
}
/**
This method adds a new platform address to the AID of this Agent.
It is called by the container when a new MTP is activated
in the platform (in the local container - installMTP() -
or in a remote container - updateRoutingTable()) to keep the
Agent AID updated.
*/
synchronized void addPlatformAddress(String address) { // Mutual exclusion with Agent.powerUp()
if (myAID != null) {
// Cloning the AID is necessary as the agent may be using its AID.
// If this is the case a ConcurrentModificationException would be thrown
myAID = (AID)myAID.clone();
myAID.addAddresses(address);
}
}
/**
This method removes an old platform address from the AID of this Agent.
It is called by the container when a new MTP is deactivated
in the platform (in the local container - uninstallMTP() -
or in a remote container - updateRoutingTable()) to keep the
Agent AID updated.
*/
synchronized void removePlatformAddress(String address) { // Mutual exclusion with Agent.powerUp()
if (myAID != null) {
// Cloning the AID is necessary as the agent may be using its AID.
// If this is the case a ConcurrentModificationException would be thrown
myAID = (AID)myAID.clone();
myAID.removeAddresses(address);
}
}
/**
Method to retrieve the location this agent is currently at.
@return A <code>Location</code> object, describing the location
where this agent is currently running.
*/
public Location here() {
return myToolkit.here();
}
//#APIDOC_EXCLUDE_BEGIN
/**
* This method is used internally by the framework and should NOT be used by programmers.
* This is used by the agent container to wait for agent termination.
* We have already called doDelete on the thread which would have
* issued an interrupt on it. However, it still may decide not to exit.
* So we will wait no longer than 5 seconds for it to exit and we
* do not care of this zombie agent.
* FIXME: we must further isolate container and agents, for instance
* by using custom class loader and dynamic proxies and JDK 1.3.
* FIXME: the timeout value should be got by Profile
*/
public void join() {
//#MIDP_EXCLUDE_BEGIN
try {
if(myThread == null) {
return;
}
myThread.join(5000);
if (myThread.isAlive()) {
System.out.println("*** Warning: Agent " + myName + " did not terminate when requested to do so.");
if(!myThread.equals(Thread.currentThread())) {
myThread.interrupt();
System.out.println("*** Second interrupt issued.");
}
}
}
catch(InterruptedException ie) {
ie.printStackTrace();
}
//#MIDP_EXCLUDE_END
/*#MIDP_INCLUDE_BEGIN
if (myThread != null && myThread.isAlive()) {
try {
myThread.join();
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
#MIDP_INCLUDE_END*/
}
//#APIDOC_EXCLUDE_END
/**
Set message queue size. This method allows to change the number
of ACL messages that can be buffered before being actually read
by the agent or discarded.
@param newSize A non negative integer value to set message queue
size to. Passing 0 means unlimited message queue. When the number of
buffered
messages exceeds this value, older messages are discarded
according to a <b><em>FIFO</em></b> replacement policy.
@throws IllegalArgumentException If <code>newSize</code> is negative.
@see jade.core.Agent#getQueueSize()
*/
public void setQueueSize(int newSize) throws IllegalArgumentException {
msgQueue.setMaxSize(newSize);
//#MIDP_EXCLUDE_BEGIN
msgQueueMaxSize = newSize;
//#MIDP_EXCLUDE_END
}
/**
* This method retrieves the current lenght of the message queue
* of this agent.
* @return The number of messages that are currently stored into the
* message queue.
**/
public int getCurQueueSize() {
return msgQueue.size();
}
/**
Reads message queue size. A zero value means that the message
queue is unbounded (its size is limited only by amount of
available memory).
@return The actual size of the message queue (i.e. the max number
of messages that can be stored into the queue)
@see jade.core.Agent#setQueueSize(int newSize)
@see jade.core.Agent#getCurQueueSize()
*/
public int getQueueSize() {
return msgQueue.getMaxSize();
}
/////////////////////////////////
// Agent state management
/////////////////////////////////
public void changeStateTo(LifeCycle newLifeCycle) {
boolean changed = false;
newLifeCycle.setAgent(this);
synchronized (stateLock) {
if (!myLifeCycle.equals(newLifeCycle)) {
// The new state is actually different from the current one
if (myLifeCycle.transitionTo(newLifeCycle)) {
myBufferedLifeCycle = myLifeCycle;
myLifeCycle = newLifeCycle;
changed = true;
//#MIDP_EXCLUDE_BEGIN
notifyChangedAgentState(myBufferedLifeCycle.getState(), myLifeCycle.getState());
//#MIDP_EXCLUDE_END
}
}
}
if (changed) {
myLifeCycle.transitionFrom(myBufferedLifeCycle);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -