--- experimental/agents/AgentStation.java 2001/04/23 19:45:18 1.1 +++ experimental/agents/AgentStation.java 2001/05/04 02:04:35 1.2 @@ -1,61 +1,185 @@ -import java.io.*; -import java.net.*; -import java.rmi.RMISecurityManager; -import java.util.*; +//---PACKAGE DECLARATION--- +//---IMPORTS--- +import java.net.Socket; +import java.io.IOException; +import java.util.ArrayList; + +/** + * An implementation of an agent station + * + * @author $Author: ajm $ + * @version $Id: AgentStation.java,v 1.2 2001/05/04 02:04:35 ajm Exp $ + */ class AgentStation extends Station { + +//---FINAL / FINAL STATIC ATTRIBUTES--- + + /** + * The current CVS revision of this class + */ + public static final String REVISION = "$Revision: 1.2 $"; - public static final String REVISION = "v0.0.1"; - public static final int LISTEN_PORT = 32497; + public static final int DIRECT_LISTEN_PORT = 32497; - public static void main(String[] args) throws IOException, UnknownHostException, ClassNotFoundException { - System.out.println("- Agent Station " + REVISION + "-"); - System.out.println("Boot sequence start."); - //System.getProperties().setProperty("java.security.policy", "/home/cut/ajm4/java/java.policy"); - //if (System.getSecurityManager() == null) { - // System.out.println("Setting security manager..."); - // System.setSecurityManager(new RMISecurityManager()); - //} - AgentStation station = new AgentStation(); - - station.startListening(); - - System.out.println("Boot sequence end."); - } + public static final int PEER_LISTEN_PORT = 32498; - public void startListening() throws IOException, UnknownHostException, ClassNotFoundException { - ServerSocket listener = new ServerSocket(LISTEN_PORT); - while (_listening) { - System.out.println("Listening..."); - Socket conn = listener.accept(); - System.out.println("Got connection..."); - ObjectInputStream p = new ObjectInputStream(conn.getInputStream()); - System.out.println("Got hook to stream..."); - Agent agent = (Agent)p.readObject(); - _agentList.add(agent); - System.out.println("Got agent..."); - System.out.println("Closing connection..."); - conn.close(); - System.out.println("Telling agent that its journey is complete..."); - agent.onArrival(this); - System.out.println("New agent name - " + agent.getName()); - System.out.println(agent.getName() + "'s transmission count - " + agent.getTransmissionCount()); - System.out.println("Attempting to run locally..."); - Thread thread = new Thread(agent); - thread.start(); - System.out.println("Done."); +//---STATIC METHODS--- + + /** + * Returns a reference to the singleton agent station in use + * + * @throws RuntimeException if not yet initialised + */ + public static AgentStation getInstance() throws RuntimeException { + if (_instance == null) { + throw new RuntimeException("Cannot obtain instance to uninitialised AgentStation!"); } + return _instance; } + + /** + * Constructs and returns the singleton AgentStation class + * + * @throws RuntimeException if already initialised + */ + public static AgentStation initialise(String name, String descriptiveName, String initialPeerHostname, int initialPeerPort) { + if (_instance != null) { + throw new RuntimeException("Already initialised!"); + } + _instance = new AgentStation(name, descriptiveName, initialPeerHostname, initialPeerPort); + return _instance; + } +//---CONSTRUCTORS--- + + /** + * Starts up the agent station. + * This is a private method to ensure singleton pattern. + */ + private AgentStation(String name, String descriptiveName, String initialPeerHostname, int initialPeerPort) { + _name = name; + _descriptiveName = descriptiveName; + + DirectAgentHandlerFactory directAgentHandlerFactory = new DirectAgentHandlerFactory(); + PeerHandlerFactory peerHandlerFactory = new PeerHandlerFactory(); + + Listener directAgentListener = new Listener(DIRECT_LISTEN_PORT, directAgentHandlerFactory); + Listener peerListener = new Listener(PEER_LISTEN_PORT, peerHandlerFactory); + + directAgentListener.start(); + peerListener.start(); + + // TESTING ONLY - Have one peer connection + if (initialPeerHostname != null) { + try { + _logger.write(toString(), Logger.DEBUG, "Establishing peer connection with - " + initialPeerHostname + ":" + initialPeerPort); + Socket socket = new Socket(initialPeerHostname, initialPeerPort); + + PeerHandler peerHandler = new PeerHandler(socket); + addPeer(peerHandler); + } catch (IOException e) { + _logger.write(toString(), Logger.ERROR, "I/O ERROR - " + e); + } + } + _logger.write(toString(), Logger.SYSINIT, "created"); + } + +//---PUBLIC METHODS--- + + //*** STATION SERVICES TO AGENTS *** + public ArrayList getAllAgents() { return _agentList; } + public ArrayList getAllPeers() { + return _peerList; + } + public String getName() { - return _name; + return _name + " - " + _descriptiveName; } - private String _name = "Listening Post Alpha76"; - private boolean _listening = true; + public void sendAgent(Agent agent, PeerHandler peerHandler) { + // NOTE - no support for restarting agent on a failed send. + agent.shutdown(); + ((PeerHandler) _peerList.get(_peerList.indexOf(peerHandler))).sendAgent(agent); + } + + //*** OTHER PUBLIC METHODS *** + + public void addAgent(Agent agent) { + _logger.write(toString(), Logger.DEBUG, "registered agent"); + _agentList.add(agent); + } + + public void removeAgent(Agent agent) { + _agentList.remove(_agentList.indexOf(agent)); + _logger.write(toString(), Logger.DEBUG, "deregistered agent"); + } + + public void addPeer(PeerHandler peerHandler) { + _logger.write(toString(), Logger.DEBUG, "registered peer"); + _peerList.add(peerHandler); + } + + public void removePeer(PeerHandler peerHandler) { + _peerList.remove(peerHandler); + _logger.write(toString(), Logger.DEBUG, "deregistered peer"); + } + + /** + * Overrides the {@link java.lang.Object#toString() Object.toString()} + * method to provide clean logging (every class should have this). + * + * This uses the uk.ac.ukc.iscream.util.FormatName class + * to format the toString() + * + * @return the name of this class and its CVS revision + */ + public String toString() { + return FormatName.getName( + _name, + getClass().getName(), + REVISION); + } + +//---PRIVATE/PROTECTED METHODS--- + +//---ACCESSOR/MUTATOR METHODS--- + +//---ATTRIBUTES--- + + /** + * This is the friendly identifier of the + * component this class is running in. + * eg, a Filter may be called "filter1", + * If this class does not have an owning + * component, a name from the configuration + * can be placed here. This name could also + * be changed to null for utility classes. + */ + private String _name; + + /** + * This holds a reference to the + * system logger that is being used. + */ + private Logger _logger = Logger.getInstance(); + + private String _descriptiveName; + private ArrayList _agentList = new ArrayList(); + + private ArrayList _peerList = new ArrayList(); + +//---STATIC ATTRIBUTES--- + + /** + * Holds the reference to the singleton instance of his class + */ + private static AgentStation _instance; + + } \ No newline at end of file