/* * JacORB - a free Java ORB * * Copyright (C) 1999-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ package org.jacorb.imr.util; import java.util.Hashtable; import java.util.Vector; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.table.TableModel; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import org.slf4j.Logger; import org.jacorb.imr.Admin; import org.jacorb.imr.AdminHelper; import org.jacorb.imr.HostInfo; import org.jacorb.imr.ImRInfo; import org.jacorb.imr.POAInfo; import org.jacorb.imr.Registration; import org.jacorb.imr.RegistrationHelper; import org.jacorb.imr.ServerInfo; import org.jacorb.imr.ServerStartupDaemon; import org.jacorb.imr.ServerStartupDaemonHelper; import org.jacorb.imr.AdminPackage.DuplicateServerName; import org.jacorb.imr.AdminPackage.FileOpFailed; import org.jacorb.imr.AdminPackage.IllegalServerName; /** * This class provides the GUIs functionality * communicating with the repository. * * @author Nicolas Noffke * */ public class ImRModel { private Admin m_admin; private org.jacorb.orb.ORB m_orb; private org.jacorb.config.Configuration configuration = null; /** the specific logger for this component */ private Logger logger = null; private ServerInfo[] m_servers; private ImRInfo m_imr_info; private DefaultMutableTreeNode m_top_node; private JTree m_tree; private DefaultTreeModel m_tree_model; private ImRPOATableModel m_poa_model; private ImRServerTableModel m_server_model; private Hashtable m_server_names; private JComboBox m_host_selector; private DefaultComboBoxModel m_host_selector_model; private Hashtable m_host_names; private RefreshThread m_refresh_thread; protected int m_current_refresh_interval = 20000; protected boolean m_refresh_disabled = false; private Vector m_server_nodes; private Vector m_poa_nodes; //contains other Vectors /** * The constructor. Connects to default repository and fetches the servers. */ public ImRModel() { m_orb = (org.jacorb.orb.ORB)org.omg.CORBA.ORB.init(new String[0], null); configuration = m_orb.getConfiguration(); logger = configuration.getLogger("org.jacorb.imr.model"); try { m_admin = AdminHelper.narrow( m_orb.resolve_initial_references("ImplementationRepository")); } catch( org.omg.CORBA.ORBPackage.InvalidName in ) { if (logger.isWarnEnabled()) logger.warn("Could not contact Impl. Repository!"); return; } fetchImRInfo(); m_top_node = new DefaultMutableTreeNode(m_imr_info); m_tree_model = new DefaultTreeModel(m_top_node, false); m_tree = new JTree(m_tree_model); m_server_model = new ImRServerTableModel(this); m_poa_model = new ImRPOATableModel(); m_server_names = new Hashtable(); m_server_nodes = new Vector(); m_poa_nodes = new Vector(); m_host_names = new Hashtable(); m_host_selector_model = new DefaultComboBoxModel(); m_host_selector = new JComboBox(m_host_selector_model); m_host_selector.setEditable(true); fetchServers(); m_tree.expandRow(0); m_refresh_thread = new RefreshThread(m_current_refresh_interval); } /** * Connect the manager to a remote repository. * * @param ior_url an url pointing to the IOR file of a remote repository. */ public void connectTo(String ior_url) { try { m_admin = AdminHelper.narrow( m_orb.resolve_initial_references("ImplementationRepository")); } catch( org.omg.CORBA.ORBPackage.InvalidName in ) { if (logger.isWarnEnabled()) logger.warn("Could not contact Impl. Repository!"); return; } fetchImRInfo(); m_top_node.setUserObject(m_imr_info); fetchServers(); setRefreshInterval(m_current_refresh_interval); } /** * Get a JComboBox containing all known hostnames. * * @return a JComboBox. */ public JComboBox getHostSelector(){ return m_host_selector; } /** * Get the table model for the POA table. */ public TableModel getPOATableModel(){ return m_poa_model; } /** * Get the table model for the server table. */ public TableModel getServerTableModel(){ return m_server_model; } /** * Set the POA table model to the specific server, i.e. * the POA table displays this servers poas. * * @param server the servers name to build the table for. */ public void poaTableForServer(ServerInfo server){ m_poa_model.setPOAs(server.poas); } /** * Fetch all servers from the repository. Rebuild Tree and HostSelector. */ public void fetchServers(){ m_servers = m_admin.list_servers(); m_server_model.setServers(m_servers); m_server_names.clear(); for (int _i = 0; _i < m_servers.length; _i++) m_server_names.put(m_servers[_i].name, new Integer(_i)); String _server = m_poa_model.getServerName(); if (_server != null) m_poa_model.setPOAs(m_servers[indexForServerName(_server)].poas); buildTree(); buildHostSelectorModel(); } /** * Remove a server from the repository. * * @param name the servers name. */ public void removeServer(String name){ removeServer(indexForServerName(name)); } /** * Remove a server from the repository. * * @param server_row the servers row in the table. */ public void removeServer(int server_row){ try{ m_admin.unregister_server(m_servers[server_row].name); }catch(Exception _e){ handleException (_e); } fetchServers(); } /** * Hold a server. * * @param name the servers name. */ public void holdServer(String name){ holdServer(indexForServerName(name)); } /** * Hold a server. * * @param server_row the servers row in the table. */ public void holdServer(int server_row){ try{ m_admin.hold_server(m_servers[server_row].name); }catch(Exception _e){ handleException (_e); } refreshServer(server_row); } /** * Release a server. * * @param name the servers name. */ public void releaseServer(String name){ releaseServer(indexForServerName(name)); } /** * Release a server. * * @param server_row the servers row in the table. */ public void releaseServer(int server_row){ try{ m_admin.release_server(m_servers[server_row].name); }catch(Exception _e){ handleException (_e); } refreshServer(server_row); } /** * Refresh a server. * * @param name the servers name. */ public void refreshServer(String name){ refreshServer(indexForServerName(name)); } /** * Refresh a server. * * @param index the servers row in the table. */ public void refreshServer(int index){ try{ ServerInfo _server = m_admin.get_server_info(m_servers[index].name); m_servers[index] = _server; buildServerNode(index); m_server_model.serverRefreshed(index); if (m_host_names.put(m_servers[index].host, m_servers[index].host) == null) m_host_selector_model.addElement(m_servers[index].host); if ( _server.name.equals(m_poa_model.getServerName())) m_poa_model.setPOAs(_server.poas); }catch(Exception _e){ handleException (_e); } } /** * Set a server down. * * @param name the servers name. */ public void setServerDown(String name){ setServerDown(indexForServerName(name)); } /** * Set a server down. * * @param server_row the servers row in the table. */ public void setServerDown(int server_row){ Registration _reg = RegistrationHelper.narrow(m_admin); try{ _reg.set_server_down(m_servers[server_row].name); }catch (Exception _e){ handleException (_e); } refreshServer(m_servers[server_row].name); } /** * Add a server to the repository. * * @param name the servers name. * @param command the servers startup command. Leave empty (not null) * if automatic startup is not desired. * @param host the host the server is running on. */ public void addServer(String name, String command, String host){ try{ m_admin.register_server(name, command, host); }catch (Exception _e){ handleException (_e); } fetchServers(); } /** * Get the tree representation of the server structure. * * @return a JTree. */ public JTree getTree(){ return m_tree; } /** * Shut the repository down. * * @param wait true, if ORB should wait for still open connections to be * closed by clients. */ public void imrShutdown(boolean wait){ disableRefresh(); try{ m_admin.shutdown(wait); m_top_node.removeAllChildren(); m_servers = null; }catch (Exception _e){ handleException (_e); } } /** * Make a backup of the server table. */ public void saveTable(){ try{ m_admin.save_server_table(); }catch (Exception _e){ handleException (_e); } } /** * Get the row number of a POA in the POA table. * * @param server the server node the POA belongs to. * @param poa the poas poa node. */ public int getRow(ServerInfo server, POAInfo poa){ for(int _i = 0; _i < server.poas.length; _i++){ if (server.poas[_i] == poa) return _i; } return -1; } /** * Set the interval by which the internal data is refreshed. * * @param interval refresh interval in ms. */ public void setRefreshInterval(int interval){ m_current_refresh_interval = interval; m_refresh_disabled = false; m_refresh_thread.setInterval(interval); } /** * Disable the automatic refresh. */ public void disableRefresh(){ m_refresh_disabled = true; m_refresh_thread.setInterval(0); } /** * Update a server in the repository by changes the user made in the server * table of the GUI. * * @param server_row the row of the server in the table. * @param field_name the columns name. * @param new_value the cells new value. */ protected void updateServer(int server_row, String field_name, Object new_value){ String _host = m_servers[server_row].host; String _cmd = m_servers[server_row].command; if (new_value instanceof String){ if (field_name.equals("Host")){ _host = (String) new_value; if (m_host_names.put(new_value, new_value) == null) m_host_selector_model.addElement(new_value); } else if (field_name.equals("Command")) _cmd = (String) new_value; try{ m_admin.edit_server(m_servers[server_row].name, _cmd, _host); }catch (Exception _e){ handleException (_e); } } else if(new_value instanceof Boolean){ if (field_name.equals("active")){ if (! ((Boolean) new_value).booleanValue()) setServerDown(m_servers[server_row].name); } else if (field_name.equals("holding")){ try{ if (((Boolean) new_value).booleanValue()) m_admin.hold_server(m_servers[server_row].name); else m_admin.release_server(m_servers[server_row].name); }catch (Exception _e){ handleException (_e); } } } refreshServer(m_servers[server_row].name); } /** * Bring up error message Dialog. * * @param e the exception that has been thrown. */ private void handleException (Exception e) { if (e instanceof org.omg.CORBA.UserException) { String _msg = e.toString(); if (e instanceof IllegalServerName) _msg = "The specified server name is not allowed"; else if (e instanceof DuplicateServerName) _msg = "A server with name " + ((DuplicateServerName) e).name + " has already been registered with the repository"; else if (e instanceof FileOpFailed) _msg = "The backup operation failed"; JOptionPane.showMessageDialog(new JFrame(), _msg, "An error occurred", JOptionPane.ERROR_MESSAGE); } else { logger.warn("Exception: ", e); } } /** * Fill the model of the combo box with host names. * After fetching hosts from the repository, they are "pinged" in order to * see if they are still up. */ private void buildHostSelectorModel() { HostInfo[] _hosts = m_admin.list_hosts(); for (int _i = 0; _i < _hosts.length; _i++){ try{ ServerStartupDaemon _ssd = ServerStartupDaemonHelper.narrow(m_orb.string_to_object(_hosts[_i].ior_string)); _ssd.get_system_load(); _ssd._release(); // ssd is up and seems to work if (m_host_names.put(_hosts[_i].name, _hosts[_i].name) == null) m_host_selector_model.addElement(_hosts[_i].name); } catch (Exception _e){ //ignore } } for (int _i = 0; _i < m_servers.length; _i++) if (m_host_names.put(m_servers[_i].host, m_servers[_i].host) == null) m_host_selector_model.addElement(m_servers[_i].host); } /** * Get a servers row by its name. * * @param name the servers name. * @return the servers row */ private int indexForServerName(String name){ return ((Integer) m_server_names.get(name)).intValue(); } /** * Get the ImRInfo struct from the repository. */ private void fetchImRInfo(){ Registration _reg = RegistrationHelper.narrow(m_admin); m_imr_info = _reg.get_imr_info(); } /** * Build a tree node for a server, with all its * dependend POAs. * * @param index the servers ServerInfo struct. */ private void buildServerNode(int index){ DefaultMutableTreeNode _server_node; POAInfo[] _poa_array = m_servers[index].poas; Vector _poas; if (index < m_server_nodes.size()){ // a server node for that index exists _server_node = (DefaultMutableTreeNode) m_server_nodes.elementAt(index); _poas = (Vector) m_poa_nodes.elementAt(index); } else{ // a new server node has to be created _server_node = new DefaultMutableTreeNode(m_servers[index]); m_server_nodes.addElement(_server_node); m_tree_model.insertNodeInto(_server_node, m_top_node, index); m_tree.scrollPathToVisible(new TreePath(_server_node.getPath())); _poas = new Vector(); m_poa_nodes.addElement(_poas); } int _i; //update existing nodes for(_i = 0; _i < _poas.size(); _i++){ if (_i < _poa_array.length){ DefaultMutableTreeNode _poa = (DefaultMutableTreeNode) _poas.elementAt(_i); _poa.setUserObject(_poa_array[_i]); } else break; } if (_i >= _poa_array.length){ //remove surplus nodes for (int _j = _poas.size() - 1; _j >= _i; _j--){ DefaultMutableTreeNode _poa = (DefaultMutableTreeNode) _poas.elementAt(_j); _poas.removeElementAt(_j); m_tree_model.removeNodeFromParent(_poa); } } else{ // build new nodes for (int _j = _i; _j < _poa_array.length; _j++){ DefaultMutableTreeNode _poa = new DefaultMutableTreeNode(_poa_array[_j]); _poas.addElement(_poa); m_tree_model.insertNodeInto(_poa, _server_node, _j); } } } /** * Remove a server node from the tree. * * @param index the servers index in the table. */ private void removeServerNode(int index){ DefaultMutableTreeNode _server_node = (DefaultMutableTreeNode) m_server_nodes.elementAt(index); Vector _poas = (Vector) m_poa_nodes.elementAt(index); for (int _j = _poas.size() - 1; _j >= 0; _j--){ DefaultMutableTreeNode _poa = (DefaultMutableTreeNode) _poas.elementAt(_j); _poas.removeElementAt(_j); m_tree_model.removeNodeFromParent(_poa); } m_server_nodes.removeElementAt(index); m_tree_model.removeNodeFromParent(_server_node); } /** * Build the tree by building all its server nodes. The * root node stays always the same. */ private void buildTree(){ int _i; // update exisiting nodes for(_i = 0; _i < m_server_nodes.size(); _i++){ if (_i < m_servers.length){ DefaultMutableTreeNode _server = (DefaultMutableTreeNode) m_server_nodes.elementAt(_i); _server.setUserObject(m_servers[_i]); buildServerNode(_i); } else break; } if (_i >= m_servers.length){ //remove surplus nodes for (int _j = m_server_nodes.size() - 1; _j >= _i; _j--) removeServerNode(_j); } else{ //add new nodes for (int _j = _i; _j < m_servers.length; _j++) buildServerNode(_j); } } private class RefreshThread extends Thread{ private long m_interval; public RefreshThread(long interval){ m_interval = interval; start(); } public synchronized void run(){ while (true){ while (m_interval <= 0){ try{ this.wait(); }catch (Exception _e){ handleException(_e); } } try{ fetchServers(); }catch (Exception _e){ handleException(_e); } try{ this.wait(m_interval); }catch (Exception _e){ handleException(_e); } } } public synchronized void setInterval(long interval) { m_interval = interval; this.notifyAll(); } } } // ImRModel