📄 agent.java
字号:
/* * Copyright (C) 2001 - 2005 ScalAgent Distributed Technologies * Copyright (C) 1996 - 2000 BULL * Copyright (C) 1996 - 2000 INRIA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */package fr.dyade.aaa.agent;import java.io.*;import java.util.*;import java.lang.reflect.*;import org.objectweb.util.monolog.api.BasicLevel;import org.objectweb.util.monolog.api.Logger;import fr.dyade.aaa.util.*;import fr.dyade.aaa.util.management.MXWrapper;/** * The <code>Agent</code> class represents the basic component in our model. * <i>agents</i> are "reactive" objects which behave according to * "event -> reaction"model: an event embodies a significant state change * which one or many agents may react to.<p> * Class <code>Agent</code> defines the generic interface and the common * behavior for all agents; every agent is an object of a class deriving * from class Agent. Agents are the elementary programming and execution * entities; they only communicate using notifications through the message * bus, and are controlled by the execution engine.<p> * The reactive behavior is implemented by function member React, which * defines the reaction of the agent when receiving a notification; this * function member is called by the execution engine.<p> * Agents are persistent objects, and the Agent class realizes a * "swap-in/swap-out" mechanism which allows loading (or finding) in main * memory the agents to activate, and unloading the agents idle since a while. * <p><hr> * Agents must be created in two steps: * <ul> * <li>locally creating the object in memory (via constructor), * <li>configure it (for example via get/set methods), * <li>the deploy it . * </ul> * <p> * The following code would then create a simple agent and deploy it: * <p><blockquote><pre> * Agent ag = new Agent(); * ag.deploy(); * </pre></blockquote> * <p> * * @see Notification * @see Engine * @see Channel */public abstract class Agent implements AgentMBean, Serializable { static final long serialVersionUID = 2955513886633164244L; /** * <code>true</code> if the agent state has changed. * <p> * This field value is initialized as <code>true</code>, so that by default * the agent state is saved after a reaction. */ private transient boolean updated = true; /** * Sets the <code>updated</code> field to <code>false</code> so that the * agent state is not saved after the current reaction; the field is set * back to <code>true</code> for the next reaction. */ protected void setNoSave() { updated = false; } /** * Sets the <code>updated</code> field to <code>true</code> so that the * agent state is saved after the current reaction. */ protected void setSave() { updated = true; } /** * */ protected final boolean needToBeCommited() { try { ((EngineThread) Thread.currentThread()).engine.needToBeCommited = true; return true; } catch (ClassCastException exc) { return false; } } /** * Saves the agent state unless not requested. */ protected final void save() throws IOException { if (updated) { AgentServer.getTransaction().save(this, id.toString()); if (logmon.isLoggable(BasicLevel.DEBUG)) logmon.log(BasicLevel.DEBUG, "Agent" + id + " [" + name + "] saved"); } else { updated = true; if (logmon.isLoggable(BasicLevel.DEBUG)) logmon.log(BasicLevel.DEBUG, "Agent" + id + " [" + name + "] not saved"); } } /** * Restores the object state from the persistent storage. * * @exception IOException * when accessing the stored image * @exception ClassNotFoundException * if the stored image class may not be found */ final static Agent load(AgentId id) throws IOException, ClassNotFoundException { Agent ag = (Agent) AgentServer.getTransaction().load(id.toString()); if (ag != null) { ag.id = id; ag.deployed = true; } return ag; } // Declares all fields transient in order to avoid useless // description of each during serialization. /** * Global unique identifier of the agent. Each agent is identified by a * unique identifier allowing the agent to be found. The identifiers format * is detailed in <a href="AgentId.html">AgentId</a> class. */ transient AgentId id; /** Symbolic name of the agent */ public transient String name; /** * Returns this <code>Agent</code>'s name. * * @return this <code>Agent</code>'s name. */ public String getName() { if ((name == null) || (name == nullName)) { return getClass().getName() + id.toString(); } else { return name; } } /** * Sets this <code>Agent</code>'s name. * * @param name the <code>Agent</code>'s name. */ public void setName(String name) { if (name == null) this.name = nullName; else this.name = name; } /** * Some agents must be loaded at any time, this can be enforced by this * member variable. If <code>true</code> agent is pinned in memory. */ protected transient boolean fixed; protected transient Logger logmon = null; /** * Returns default log topic for agents. Its method should be overridden * in subclass in order to permit fine configuration of logging system. * By default it returns <code>Debug.A3Agent</code>. */ protected String getLogTopic() { return fr.dyade.aaa.agent.Debug.A3Agent; } protected static final String nullName = ""; /** * the <code>last</code> variable contains the virtual time of the * last access. It is used by swap-out policy. * * @see garbage */ transient long last; private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeUTF(name); out.writeBoolean(fixed); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { if ((name = in.readUTF()).equals(nullName)) name = nullName; fixed = in.readBoolean(); updated = true; } /** * Allocates a new Agent object. The resulting object <b>is not an agent</b>; * before it can react to a notification you must deploy it. This constructor * has the same effect as * <code>Agent(AgentServer.getServerId(), null, false)</code>. * * @see Agent#Agent(short, java.lang.String, boolean) * @see #deploy() */ public Agent() { this(null, false); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(AgentServer.getServerId(), null, fixed)</code>. * * @param fixed if <code>true</code> agent is pinned in memory * * @see Agent#Agent(short, String, boolean) */ public Agent(boolean fixed) { this(null, fixed); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(AgentServer.getServerId(), name, false)</code>. * * @param name symbolic name * * @see Agent#Agent(short, java.lang.String, boolean) */ public Agent(String name) { this(name, false); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(AgentServer.getServerId(), name, fixed)</code>. * * @param name symbolic name * @param fixed if <code>true</code> agent is pinned in memory * * @see Agent#Agent(short, java.lang.String, boolean) */ public Agent(String name, boolean fixed) { this(AgentServer.getServerId(), name, fixed); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(to, null, false)</code>. * * @param to Identication of target agent server * * @see Agent#Agent(short, java.lang.String, boolean) */ public Agent(short to) { this(to, null, false); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(to, name, false)</code>. * * @param to Identication of target agent server * @param name symbolic name * * @see Agent#Agent(short, java.lang.String, boolean) */ public Agent(short to, String name) { this(to, name, false); } /** * Allocates a new Agent object. This constructor has the same effect * as <code>Agent(to, null, fixed)</code>. * * @param to Identication of target agent server * @param fixed if <code>true</code> agent is pinned in memory * * @see Agent#Agent(short, java.lang.String, boolean) */ public Agent(short to, boolean fixed) { this(to, null, fixed); } /** * Allocates a new Agent object. The resulting object <b>is not an agent</b>; * before it can react to a notification you must deploy it. * * @param to Identication of target agent server * @param name symbolic name * @param fixed if <code>true</code> agent is pinned in memory * * @see #deploy() */ public Agent(short to, String name, boolean fixed) { AgentId id = null; try { id = new AgentId(to); } catch (IOException exc) { logmon = Debug.getLogger(fr.dyade.aaa.agent.Debug.A3Agent + ".#" + AgentServer.getServerId()); logmon.log(BasicLevel.ERROR, AgentServer.getName() + ", can't allocate new AgentId", exc); // TODO: throw an exception... } initState(name, fixed, id); } /** * Constructor used to build "system" agents like <code>AgentFactory</code>. * System agents are created from the <code>agent</code> package. This * constructor takes the agent id as a parameter instead of building it. * * @param name symbolic name * @param fixed if <code>true</code> agent is pinned in memory * @param stamp well known stamp */ Agent(String name, boolean fixed, AgentId id) { initState(name, fixed, id); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -