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

📄 agent.java

📁 java实现的P2P多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


	public static final String MSG_QUEUE_CLASS = "jade_core_Agent_msgQueueClass";
	
	private transient AgentToolkit myToolkit;
	
	private transient MessageQueue msgQueue;
	private int msgQueueMaxSize = 0;
	//#MIDP_EXCLUDE_BEGIN
	private transient boolean temporaryMessageQueue;
	private transient List o2aQueue;
	private int o2aQueueSize = 0;
	private transient Map o2aLocks;
	private Behaviour o2aManager = null;
	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();
		suspendLock = new Object();
		temporaryMessageQueue = true;
		//#MIDP_EXCLUDE_END
		msgQueue = new InternalMessageQueue(msgQueueMaxSize);
		stateLock = new Object(); 
		pendingTimers = new AssociationTB();
		myActiveLifeCycle = new ActiveLifeCycle();
		myLifeCycle = myActiveLifeCycle;
		myScheduler = new Scheduler(this);
		theDispatcher = TimerDispatcher.getTimerDispatcher();
	}
	
	//#MIDP_EXCLUDE_BEGIN
	/**
	 * Developer can override this method to provide an alternative message queue creation mechanism
	 * @return The MessageQueue to be used by this agent or null if the internal message queue must be used
	 */
	protected MessageQueue createMessageQueue() {
		String msgQueueClass = getProperty(MSG_QUEUE_CLASS, null);
		if (msgQueueClass != null) {
			try {
				return (MessageQueue) Class.forName(msgQueueClass, true, getClass().getClassLoader()).newInstance();
			}
			catch (Exception e) {
				System.out.println("Error loading MessageQueue of class "+msgQueueClass+" ["+e+"]");
			}
		}
		return null;
	}

	/**
	 * If the agent still has a temporary message queue, create the real one and copy messages if any
	 */
	void initMessageQueue() {
		if (temporaryMessageQueue) {
			temporaryMessageQueue = false;
			MessageQueue queue = createMessageQueue();
			if (queue != null) {
				queue.setMaxSize(msgQueueMaxSize);
				// Copy messages (if any) from the old message queue to the new one
				synchronized (msgQueue) {
					int size = msgQueue.size();
					if (size > 0) {
						List l = new ArrayList(size);
						msgQueue.copyTo(l);
						Iterator it = l.iterator();
						while (it.hasNext()) {
							queue.addLast((ACLMessage) it.next());
						}
					}
					msgQueue = queue;
				}
			}
		}
	}
	
	/**
	 This is only called by AgentContainerImpl
	 */
	MessageQueue getMessageQueue() {
		return msgQueue;
	}

	// For persistence service
	private void setMessageQueue(MessageQueue mq) {
		msgQueue = mq;
	}

	/**
	 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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -