⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agent.java

📁 JADE(JAVA Agent开发框架)是一个完全由JAVA语言开发的软件,它简化了多Agent系统的实现。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	/**
	 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 + -