// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/graphicLoader/netmap/NetMapConnector.java,v $ // $RCSfile: NetMapConnector.java,v $ // $Revision: 1.6 $ // $Date: 2005/08/09 17:46:33 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.graphicLoader.netmap; import java.awt.Choice; import java.awt.Color; import java.awt.Component; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.Properties; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import com.bbn.openmap.PropertyConsumer; import com.bbn.openmap.util.Debug; import com.bbn.openmap.util.PaletteHelper; import com.bbn.openmap.util.PropUtils; /** * The NetMapConnector is the bridge between the parser from the * output of the NetMap server (NetMapReader), and whoever wants the * OMGraphicList that is being managed. It forwards the list on to * the NetMapListReceiver that wants the list. The NetMapConnector * will create it's NetMapReader to control and use. If you have a * component that wants to receive updates from the reader, then you * can register as an NetMapListener with the NetMapConnector. * * The NetMapConnector can be used in conjunction with the * NetMapConnectionHandler. The NetMapConnectionHandler will look for * NetMapConnectors in the BeanContext (MapHandler), and create a * NetMapGraphicLoader for it. That will set off the GraphicLoader -> * GraphicLoaderConnector -> GraphicLoaderPlugIn -> PlugInLayer * creation chain, if the GraphicLoaderConnector is also in the * MapHandler. * * The following properties can be set: * * <pre> * * * server=hostname of the NetMap server * port=port of NetMap server * defaultView=default view for NetMap server stream * * </pre> */ public class NetMapConnector implements ActionListener, NetMapConstants, PropertyConsumer { public final static String ServerConnectCmd = "Connect"; public final static String ServerDisconnectCmd = "Disconnect"; public final static String LoadViewCmd = "Load View"; public final static String GetViewsCmd = "Get Network Views"; public final static String ServerProperty = "server"; public final static String PortProperty = "port"; public final static String DefaultViewProperty = "defaultView"; public final static String STATUS_CONNECTING = " Connecting "; public final static String STATUS_CONNECTED = " Connected "; public final static String STATUS_IDLE = " Idle "; private JPanel serverPanel = null; private JTextField serverAddrField = null; private JTextField serverPortField = null; private JLabel connectedStatus = null; private Choice viewChoice = null; private ChoiceList viewList = null; private JButton controlButton = null; protected String server = DEFAULT_SERVER; protected String port = DEFAULT_PORT; /** * The NetMap server has a notion of views that represent nodes * and links, and these are names. If using a GUI, the view names * will show up because they are received from the NetMap server. * Programmatically, you can set what the default view should be. */ protected String defaultView = null; protected String propertyPrefix = null; /** * The component that listens to the NetMap server and parses the * stream. */ NetMapReader reader = null; /** * Support for sending new NetMap events to listeners. */ NetMapListenerSupport listenerSupport = null; public NetMapConnector() { listenerSupport = new NetMapListenerSupport(this); } /** * Set the hostname or IP address to use to contact the NetMap * server. */ public void setServer(String sName) { server = sName; } /** * Get the hostname or IP address of the NetMap server. */ public String getServer() { return server; } /** * Set the port that the NetMap server is running on. */ public void setPort(String port) { this.port = port; } /** * Get the port that the NetMap server is running on. */ public String getPort() { return port; } /** * Set the defaultView to use for NetMap server queries. */ public void setDefaultView(String view) { defaultView = view; } /** * Get the defaultView to use for NetMap server queries. */ public String getDefaultView() { return defaultView; } /** * Add a NetMapListener to receive NetMapEvents. */ public void addNetMapListener(NetMapListener nml) { listenerSupport.addNetMapListener(nml); } /** * Remove a NetMapListener from the list to receive NetMapEvents. */ public void removeNetMapListener(NetMapListener nml) { listenerSupport.removeNetMapListener(nml); } /** * Clear all NetMapListeners from receiving NetMapEvents. */ public void clearNetMapListeners() { listenerSupport.clearNetMapListeners(); } /** * Called by the NetMapReader so a parsed line, representing an * event, can be dispersed to the listeners. */ protected void distributeEvent(Properties netmapProps) { listenerSupport.fireNetMapEvent(netmapProps); } /** Act on GUI commands controlling the NetMapReader. */ public void actionPerformed(java.awt.event.ActionEvent ae) { String cmd = ae.getActionCommand(); server = serverAddrField.getText(); port = serverPortField.getText(); if (cmd == GetViewsCmd) { connectedStatus.setText(STATUS_CONNECTING); viewList = getViews(); if (viewList == null) { Debug.message("netmap", "Can't get view list from " + server + ":" + port); disconnect(); } } else if (cmd == ServerDisconnectCmd) { Debug.message("netmap", "Disconnecting from server " + server + ":" + port); disconnect(); } else if (cmd == LoadViewCmd) { ChoiceItem ci = viewList.get(viewChoice.getSelectedItem()); if (ci == null) { disconnect(); return; } String view = ((String) ci.value()).trim(); Debug.message("netmap", "Loading view " + view); connect(view); } } /** * Callback for the NetMapReader to let it provide the connector * with connection status. */ protected void connectionUp() { if (connectedStatus != null) { connectedStatus.setText(STATUS_CONNECTED); connectedStatus.setBackground(Color.green); } } /** * Callback for the NetMapReader to let it provide the connector * with connection status. */ protected void connectionDown() { if (connectedStatus != null) { connectedStatus.setText(STATUS_IDLE); connectedStatus.setBackground(Color.red); } } /** * Resets the controls to the disconnected mode. */ public void disconnect() { if (reader != null) { reader.shutdown(); } reader = null; if (serverPanel != null) { serverAddrField.setEnabled(true); serverPortField.setEnabled(true); viewChoice.setEnabled(false); controlButton.setText(GetViewsCmd); controlButton.setActionCommand(GetViewsCmd); connectedStatus.setText(STATUS_IDLE); } } /** * Gets a list of possible views. * * @return ChoiceList of possible views retrieved from the NetMap * server. */ public ChoiceList getViews() { ChoiceList views = null; try { reader = new NetMapReader(server, port, this); } catch (IOException e) { Debug.message("netmap", "Can't start reader: " + e); } Debug.message("netmap", "Checking for views..."); // reader will be null if server or port is bad... if (reader != null) { views = reader.getViewList(server, port); } if (serverPanel != null) { viewChoice.removeAll(); if (views != null) { for (int i = 0; i < views.size(); i++) { if (Debug.debugging("netmap")) { Debug.output("Adding view: " + views.labelAt(i)); } viewChoice.add(views.labelAt(i)); } serverAddrField.setEnabled(false); serverPortField.setEnabled(false); viewChoice.setEnabled(true); controlButton.setText(LoadViewCmd); controlButton.setActionCommand(LoadViewCmd); } } return views; } /** * Connects to the NetMap server to get messages about the given * view. */ public void connect(String view) { try { reader = new NetMapReader(server, port, this, view); reader.start(); if (serverPanel != null) { serverAddrField.setEnabled(false); serverPortField.setEnabled(false); controlButton.setText(ServerDisconnectCmd); controlButton.setActionCommand(ServerDisconnectCmd); } } catch (IOException e) { Debug.message("netmap", "Can't start reader: " + e); disconnect(); } } /** * Complete disconnect, sends clear command to NetMapListeners, * resets GUI if it's being used. */ public void reset() { disconnect(); Properties rp = new Properties(); rp.setProperty(COMMAND_FIELD, CLEAR); distributeEvent(rp); if (serverPanel != null) { viewChoice.removeAll(); connectedStatus.setText(STATUS_IDLE); } } /** * Gets the GUI control for the NetMapReader, creates it if it * doesn't exist. */ public Component getGUI() { if (serverPanel != null) { return serverPanel; } serverAddrField = new JTextField(server); serverPortField = new JTextField(port); /* * Make the NETMAP Server address entry field */ JPanel serverAddrPanel = new JPanel(new GridLayout(0, 2)); serverAddrPanel.add(new JLabel("Name or IP Addr: ")); serverAddrPanel.add(serverAddrField); /* * Make the NETMAP Server port entry field */ JPanel serverPortPanel = new JPanel(new GridLayout(0, 2)); serverPortPanel.add(new JLabel("Port: ")); serverPortPanel.add(serverPortField); /* */ JPanel statusPanel = PaletteHelper.createHorizontalPanel("Server Connection"); connectedStatus = new JLabel(STATUS_IDLE); JButton resetButton = new JButton("Reset"); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { reset(); } }); statusPanel.add(connectedStatus); statusPanel.add(resetButton); /* * Make the toplevel input panel */ // JPanel netmapPanel = new JPanel(new GridLayout(0, 1)); JPanel netmapPanel = PaletteHelper.createVerticalPanel("Server Settings"); netmapPanel.add(serverAddrPanel); netmapPanel.add(serverPortPanel); /* * Make the "Load View" panel */ viewChoice = new Choice(); viewList = new ChoiceList(); viewChoice.setEnabled(false); controlButton = new JButton(GetViewsCmd); controlButton.setActionCommand(GetViewsCmd); controlButton.addActionListener(this); // JPanel viewPanel = new JPanel(new GridLayout(0, 1)); JPanel viewPanel = PaletteHelper.createVerticalPanel(null); viewPanel.add(new JLabel("Available Views")); viewPanel.add(viewChoice); viewPanel.add(controlButton); serverPanel = new JPanel(); Box box = Box.createVerticalBox(); box.add(netmapPanel); box.add(statusPanel); box.add(viewPanel); serverPanel.add(box); return serverPanel; } /** * Method to set the properties in the PropertyConsumer. It is * assumed that the properties do not have a prefix associated * with them, or that the prefix has already been set. * * @param setList a properties object that the PropertyConsumer * can use to retrieve expected properties it can use for * configuration. */ public void setProperties(Properties setList) { setProperties(null, setList); } /** * Method to set the properties in the PropertyConsumer. The * prefix is a string that should be prepended to each property * key (in addition to a separating '.') in order for the * PropertyConsumer to uniquely identify properties meant for it, * in the midst of of Properties meant for several objects. * * @param prefix a String used by the PropertyConsumer to prepend * to each property value it wants to look up - * setList.getProperty(prefix.propertyKey). If the prefix * had already been set, then the prefix passed in should * replace that previous value. * @param setList a Properties object that the PropertyConsumer * can use to retrieve expected properties it can use for * configuration. */ public void setProperties(String prefix, Properties setList) { setPropertyPrefix(prefix); prefix = PropUtils.getScopedPropertyPrefix(prefix); server = setList.getProperty(prefix + ServerProperty); if (server == null) { server = DEFAULT_SERVER; } port = setList.getProperty(prefix + PortProperty); if (port == null) { port = DEFAULT_PORT; } } /** * Method to fill in a Properties object, reflecting the current * values of the PropertyConsumer. If the PropertyConsumer has a * prefix set, the property keys should have that prefix plus a * separating '.' prepended to each property key it uses for * configuration. * * @param list a Properties object to load the PropertyConsumer * properties into. If getList equals null, then a new * Properties object should be created. * @return Properties object containing PropertyConsumer property * values. If getList was not null, this should equal * getList. Otherwise, it should be the Properties object * created by the PropertyConsumer. */ public Properties getProperties(Properties list) { if (list == null) { list = new Properties(); } String prefix = PropUtils.getScopedPropertyPrefix(this); list.put(prefix + ServerProperty, server); list.put(prefix + PortProperty, port); return list; } /** * Method to fill in a Properties object with values reflecting * the properties able to be set on this PropertyConsumer. The key * for each property should be the raw property name (without a * prefix) with a value that is a String that describes what the * property key represents, along with any other information about * the property that would be helpful (range, default value, * etc.). * * @param list a Properties object to load the PropertyConsumer * properties into. If getList equals null, then a new * Properties object should be created. * @return Properties object containing PropertyConsumer property * values. If getList was not null, this should equal * getList. Otherwise, it should be the Properties object * created by the PropertyConsumer. */ public Properties getPropertyInfo(Properties list) { if (list == null) { list = new Properties(); } list.put(ServerProperty, "The hostname or IP for NetMap server"); list.put(PortProperty, "The port number for NetMap server"); return list; } /** * Set the property key prefix that should be used by the * PropertyConsumer. The prefix, along with a '.', should be * prepended to the property keys known by the PropertyConsumer. * * @param prefix the prefix String. */ public void setPropertyPrefix(String prefix) { propertyPrefix = prefix; } /** * Get the property key prefix that is being used to prepend to * the property keys for Properties lookups. * * @return the property prefix */ public String getPropertyPrefix() { return propertyPrefix; } }