/* * Created on Oct 22, 2003 by mschilli */ package alma.acs.commandcenter.gui; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.AbstractAction; import javax.swing.Box; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import si.ijs.maci.ClientInfo; import si.ijs.maci.ComponentInfo; import si.ijs.maci.ContainerInfo; import alma.acs.commandcenter.meta.Firestarter.OrbInitException; import alma.acs.commandcenter.meta.GuiMaciSupervisor; import alma.acs.commandcenter.meta.IMaciSupervisor; import alma.acs.commandcenter.meta.IMaciSupervisor.CannotRetrieveManagerException; import alma.acs.commandcenter.meta.IMaciSupervisor.CorbaNoPermissionException; import alma.acs.commandcenter.meta.IMaciSupervisor.CorbaNotExistException; import alma.acs.commandcenter.meta.IMaciSupervisor.CorbaTransientException; import alma.acs.commandcenter.meta.IMaciSupervisor.CorbaUnknownException; import alma.acs.commandcenter.meta.IMaciSupervisor.NotConnectedToManagerException; import alma.acs.commandcenter.meta.IMaciSupervisor.UnknownErrorException; import alma.acs.commandcenter.meta.MaciInfo; import alma.acs.commandcenter.meta.MaciInfo.FolderInfo; import alma.acs.commandcenter.meta.MaciInfo.InfoDetail; import alma.acs.commandcenter.meta.MaciInfo.SortingTreeNode; import alma.acs.commandcenter.meta.MaciSupervisor; import alma.acs.util.AcsLocations; import alma.maciErrType.CannotGetComponentEx; import alma.maciErrType.ComponentConfigurationNotFoundEx; import alma.maciErrType.ComponentNotAlreadyActivatedEx; import alma.maciErrType.NoPermissionEx; import alma.maciErrType.wrappers.AcsJCannotDeactivateComponentEx; import alma.maciErrType.wrappers.AcsJComponentDeactivationFailedEx; import alma.maciErrType.wrappers.AcsJComponentDeactivationUncleanEx; import com.xtmod.util.collections.TreeMerge; /** * @author mschilli */ public class DeploymentTree extends JTree { protected ContextMenu containerContextMenu; protected ContextMenu managerContextMenu; protected ContextMenu clientContextMenu; protected ContextMenu componentContextMenu; protected ContextMenu folderContextMenu; protected TreeEventForwarder treeEventForwarder; protected List modelConverters; protected Renderer cellRenderer; // assigned on each invokation of show protected DefaultMutableTreeNode target; // assigned on each invokation of show protected GuiMaciSupervisor selectedSupervisor; // external logic that can create supervisor instances protected DeploymentTreeController ctrl; public DeploymentTree(DeploymentTreeController ctrl) { this (ctrl, true); } // msc 2009-04: introducing "allowControl" flag for permission handling (used by OMC) public DeploymentTree(DeploymentTreeController ctrl, boolean allowControl) { super(new SortingTreeNode("Deployment Info")); this.setRootVisible(false); this.setShowsRootHandles(true); // --- cell renderer ToolTipManager.sharedInstance().registerComponent(this); this.setCellRenderer(cellRenderer = new Renderer()); // --- forward events from the MaciTree-Models // (there will be one for each macimanager) to our own, all-in-one TreeModel treeEventForwarder = new TreeEventForwarder (this.getTreeModel()); modelConverters = new Vector(); // --- setup context menus clientContextMenu = new ClientContextMenu (allowControl); managerContextMenu = new ManagerContextMenu (allowControl); containerContextMenu = new ContainerContextMenu (allowControl); componentContextMenu = new ComponentContextMenu (allowControl); folderContextMenu = new FolderContextMenu (allowControl); this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked (MouseEvent evt) { if (SwingUtilities.isRightMouseButton(evt)) { showContextMenu(evt); } } }); this.getSelectionModel().addTreeSelectionListener(new SelectionListener()); this.ctrl = ctrl; } // synchronous run in swing thread private void runSwingNow (Runnable r) { if (SwingUtilities.isEventDispatchThread()) r.run(); else try { SwingUtilities.invokeAndWait(r); } catch (Exception exc) { /* exc.printStackTrace(); */ } } /** * @param evt */ protected void showContextMenu (MouseEvent evt) { TreePath targetPath = this.getClosestPathForLocation(evt.getX(), evt.getY()); if (targetPath == null) { // clicked into a totally empty tree (no manager shown): ignore click. return; } setSelectionPath(targetPath); if (targetPath.getPathCount() == 1) { // clicked on the descriptive super-root node "Deployment Info" // that has no function besides looking good return; } // the supervisor (which is in the rootnode) for this subtree selectedSupervisor = maciSupervisor(((SortingTreeNode) targetPath.getPathComponent(1))); // the node the mouse was clicked on target = (SortingTreeNode) targetPath.getLastPathComponent(); Object userObject = target.getUserObject(); ContextMenu menu; if (userObject instanceof IMaciSupervisor) { menu = managerContextMenu; } else if (userObject instanceof ContainerInfo) { menu = containerContextMenu; } else if (userObject instanceof ClientInfo) { menu = clientContextMenu; } else if (userObject instanceof ComponentInfo) { menu = componentContextMenu; } else if (userObject instanceof FolderInfo) { menu = folderContextMenu; } else if (userObject instanceof InfoDetail) { // msc 2012-06: help user navigate in large datasets (cf. COMP-3684) // this menu is built dynamically from rather expensive information. menu = new ContextMenu(false); int[] selectedHandles = ((SortingTreeNode)target).representedHandles; if (selectedHandles.length>0) { menu.add(new JLabel(" Scroll to ...")); menu.add(new JSeparator(JSeparator.HORIZONTAL)); SortingTreeNode mgrNode = (SortingTreeNode)target.getPath()[1]; List list = new ArrayList(); list.add(mgrNode); for (SortingTreeNode top : mgrNode.childrens()) list.addAll(Collections.list(top.children())); for (Object obj : list) { final SortingTreeNode elem = (SortingTreeNode)obj; for (int i=0; i 0) tooltip = "Right-Click for Navigation"; } } else if (userObject instanceof FolderInfo) { FolderInfo info = (FolderInfo) userObject; text = info.name; text = text + " (" + node.getChildCount() + ")"; if (info.hasFilter()) text += ", showing only '"+info.filter+"'"; tooltip = "Right-Click for Filtering"; } else text = String.valueOf(node); return new String[] {text, tooltip}; } } /** * Listens on selection-changes in the tree to trigger a repaint-event. */ protected class SelectionListener implements TreeSelectionListener { public void valueChanged (TreeSelectionEvent e) { Object node = e.getPath().getLastPathComponent(); if (node instanceof SortingTreeNode) if (!((SortingTreeNode)node).filtered) cellRenderer.currentlySelectedHandles = ((SortingTreeNode) node).representedHandles; repaint(); } } void applyFilters (DefaultTreeModel tm) { SortingTreeNode mgrNode = (SortingTreeNode)tm.getRoot(); for (SortingTreeNode folder : mgrNode.childrens()) { applyFilter(folder); } } void applyFilter (SortingTreeNode folder) { FolderInfo folderInfo = (FolderInfo)folder.getUserObject(); for (SortingTreeNode entry : folder.childrens()) { String caption = cellRenderer.getCaptions(entry)[0]; boolean passes = !folderInfo.hasFilter() || caption.contains (folderInfo.filter); for (Enumeration subtree = entry.breadthFirstEnumeration(); subtree.hasMoreElements();) ((SortingTreeNode)(subtree.nextElement())).filtered = !passes; } } protected class ModelConverter implements TreeModelListener { protected MaciInfo sourceModel; protected DefaultTreeModel targetModel; public ModelConverter(MaciInfo sourceModel, DefaultTreeModel targetModel) { this.sourceModel = sourceModel; this.targetModel = targetModel; } public DefaultMutableTreeNode managerNode () { return (DefaultMutableTreeNode) targetModel.getRoot(); } // --- "freeze view" logic --- protected boolean isDirty; protected void convertCompleteModelIfDirty () { if (isDirty) { isDirty = false; convertCompleteModel(); } } // --- conversion logic --- public void treeNodesChanged (TreeModelEvent e) {} public void treeNodesInserted (TreeModelEvent e) {} public void treeNodesRemoved (TreeModelEvent e) {} public void treeStructureChanged (TreeModelEvent e) { if (isViewFrozen()) { isDirty = true; return; } convertCompleteModel(); applyFilters (targetModel); } protected final TreeMerge treemerger = new TreeMerge(){ @Override protected String identifyExisting (TreeNode x) { return identify((DefaultMutableTreeNode)x); } @Override protected String identifyIncoming (TreeNode x) { return identify((DefaultMutableTreeNode)x); } String identify (DefaultMutableTreeNode x) { Object userObject = x.getUserObject(); if (userObject instanceof ComponentInfo) return ((ComponentInfo) userObject).name; if (userObject instanceof ClientInfo) return String.valueOf(((ClientInfo) userObject).h); if (userObject instanceof ContainerInfo) return ((ContainerInfo) userObject).name; if (userObject instanceof FolderInfo) return ((FolderInfo) userObject).name; return x.toString(); } @Override protected boolean isUpdate (TreeNode exist, TreeNode incom) { /* our tree-renderer adds the childcount to some nodes (the folder info nodes), * so if the childcount changes we want a tree-change event to be sent to the * jtree. we could run the renderer here to find out if "incom" would be * rendered differently from "exist" and thus we consider this an update. but * for simplicity, i'm re-implementing a tiny portion of renderer logic here. */ if (exist.getChildCount() != incom.getChildCount()) return true; /* Keeping it kind of simple by looking at the toString() of the treenode * which is in fact a toString() of the userobject. One could also do some * instanceof here and look at the userobjects more closely to find out * whether they have different contents than before. Checking via * toString() means that nodes that have a corbastruct as their userobject * will be updated at each refresh. This is a bit costly but makes sure the * tree always shows up-to-date info. */ return !String.valueOf(exist).equals(String.valueOf(incom)); } @Override protected MutableTreeNode create (TreeNode x) { return (DefaultMutableTreeNode) ((DefaultMutableTreeNode) x).clone(); } @Override protected void applyUpdate (TreeNode exist, TreeNode incom) { ((DefaultMutableTreeNode)exist).setUserObject(((DefaultMutableTreeNode)incom).getUserObject()); if (exist instanceof SortingTreeNode && incom instanceof SortingTreeNode) // always true? ((SortingTreeNode)exist).representedHandles = ((SortingTreeNode)incom).representedHandles; } }; /** Used to force data visibility between threads, as per Java Memory Model */ private AtomicBoolean jmmFlushRefresh = new AtomicBoolean(); protected void convertCompleteModel() { treemerger.diff (targetModel, sourceModel); /* this is the main point of the whole model conversion business: modify the * jtree's tree model only in the swing thread. the maci info is modified by the * supervisor in whatever thread it uses. we listen to those changes and transfer * them to the tree's underlying tree model.... using the swing thread... */ if (!treemerger.areEqual()) { // flush jmmFlushRefresh.set(true); runSwingNow(new Runnable() { public void run () { // refresh jmmFlushRefresh.get(); treemerger.merge(); } }); } } } /** * Forwards events from one or more TreeModels to a TreeModel. * * This will accept events from any TreeModels it is registered with. It will then * raise that event on the target TreeModel. * * @author mschilli */ protected class TreeEventForwarder implements TreeModelListener { protected DefaultTreeModel forwardTarget; // --- construction / setup --- public TreeEventForwarder(DefaultTreeModel forwardTarget) { this.forwardTarget = forwardTarget; } // register as a listener with specified TreeModel public void addSource (TreeModel source) { source.addTreeModelListener(this); } // --- forwarding logic --- synchronized public void treeStructureChanged (TreeModelEvent e) { /* System.err.println("TEF: "+Thread.currentThread().getName()+" treeStructureChanged");*/ TreeNode n = (TreeNode) e.getTreePath().getLastPathComponent(); forwardTarget.nodeStructureChanged(n); } public void treeNodesChanged (TreeModelEvent e) { /* System.err.println("TEF: "+Thread.currentThread().getName()+" treeNodesChanged "+e);*/ TreeNode n = (TreeNode) e.getTreePath().getLastPathComponent(); forwardTarget.nodesChanged(n, e.getChildIndices()); } public void treeNodesInserted (TreeModelEvent e) { /* System.err.println("TEF: "+Thread.currentThread().getName()+" treeNodesInserted "+e);*/ TreeNode n = (TreeNode) e.getTreePath().getLastPathComponent(); forwardTarget.nodesWereInserted (n, e.getChildIndices()); } public void treeNodesRemoved (TreeModelEvent e) { /* System.err.println("TEF: "+Thread.currentThread().getName()+" treeNodesRemoved "+e);*/ TreeNode n = (TreeNode) e.getTreePath().getLastPathComponent(); forwardTarget.nodesWereRemoved(n, e.getChildIndices(), e.getChildren()); } } // // =================== Context Menus ===================== // /** * Base class for our context menus */ protected class ContextMenu extends JPopupMenu { protected ContextMenu (boolean allowControl) {} /** * If this menu is empty, we don't bother to show it. */ @Override public void show (Component invoker, int x, int y) { if (getComponentCount() == 0) return; super.show(invoker, x, y); } } protected class ManagerContextMenu extends ContextMenu { protected ManagerContextMenu (boolean allowControl) { super(allowControl); this.add(new ManagerRefreshAction()); if (allowControl) { this.add(new JPopupMenu.Separator()); this.add(new ManagerPingAction()); this.add(new ManagerShutdownAction()); } /* * msc (2008-10): "remove from view" hardly needed: if a * manager goes away, we offer to remove it anyhow. and * other than that, this entry is undesirable inside the omc. * * this.add(new JPopupMenu.Separator()); * this.add(new RemoveFromViewAction()); */ } } protected class FolderContextMenu extends ContextMenu { protected JTextField txtFilter = new JTextField(8); protected FolderContextMenu (boolean allowControl) { super (allowControl); Box b = Box.createHorizontalBox(); b.add(new JLabel(" Show only ")); b.add(txtFilter); b.add(new JLabel(" ")); this.add(b); this.add(new JSeparator(JSeparator.HORIZONTAL)); this.add(new AbstractAction("Apply"){ @Override public void actionPerformed (ActionEvent e) { ((FolderInfo)target.getUserObject()).filter = txtFilter.getText().trim(); applyFilter((SortingTreeNode)target); // this re-renders the tree, and collapses the subtrees. getTreeModel().reload(target); } }); this.add(new AbstractAction("Reset"){ @Override public void actionPerformed (ActionEvent e) { txtFilter.setText(null); ((FolderInfo)target.getUserObject()).filter = txtFilter.getText().trim(); applyFilter((SortingTreeNode)target); // this re-renders the tree, and collapses the subtrees. getTreeModel().reload(target); } }); } // updates the menu gui before show @Override protected void firePopupMenuWillBecomeVisible () { txtFilter.setText(((FolderInfo)target.getUserObject()).filter); super.firePopupMenuWillBecomeVisible(); } } protected class ContainerContextMenu extends ContextMenu { protected ContainerContextMenu (boolean allowControl) { super (allowControl); if (allowControl) { this.add(new ContainerPingAction()); this.add(new ContainerMessageAction()); this.add(new ContainerDisconnectAction()); this.add(new ContainerShutdownAction()); this.add(new JPopupMenu.Separator()); this.add(new ContainerLogoutAction()); } } } protected class ClientContextMenu extends ContextMenu { protected ClientContextMenu (boolean allowControl) { super (allowControl); if (allowControl) { this.add(new ClientPingAction()); this.add(new ClientMessageAction()); this.add(new ClientDisconnectAction()); this.add(new JPopupMenu.Separator()); this.add(new ClientLogoutAction()); } } } protected class ComponentContextMenu extends ContextMenu { protected ComponentContextMenu (boolean allowControl) { super (allowControl); if (allowControl) { this.add(new ComponentRequestAction()); this.add(new ComponentReleaseAction()); this.add(new JPopupMenu.Separator()); this.add(new ComponentForceReleaseAction()); } } } // // ======================= Actions ========================= // /** * Performs the work to be done within the event-dispatcher thread */ protected abstract class SwingAction extends AbstractAction { protected SwingAction(String name) { super(name); } final public void actionPerformed (ActionEvent e) { try { actionPerformed(); } catch (Exception exc) { /* * This catch-clause will rarely be executed: the menu-item actions mostly use * the shielded API which catches exceptions way before */ ErrorBox.showErrorDialog(DeploymentTree.this, "\"" + getValue(NAME) + "\" failed", exc); } } protected abstract void actionPerformed (); } /** * Performs the work to be done delayed, and NOT within the event-dispatcher thread. * Used for most actions in the context menus. */ protected abstract class BackgroundAction extends AbstractAction { protected BackgroundAction(String name) { super(name); } final public void actionPerformed (ActionEvent e) { ctrl.getBackgroundExecutor().execute(new Runnable() { public void run () { setBusy(true); try { actionPerformed(); } catch (Exception exc) { /* This catch-clause will rarely be executed: the menu-item actions * mostly use the shielded API which catches exceptions way before */ ErrorBox.showErrorDialog(DeploymentTree.this, "\"" + getValue(NAME) + "\" failed", exc); } finally { setBusy(false); } } }); } protected abstract void actionPerformed () throws Exception; } protected class RemoveFromViewAction extends SwingAction { protected RemoveFromViewAction() { super("Remove from View"); } @Override public void actionPerformed () { removeNode(target); } } protected class ManagerRefreshAction extends BackgroundAction { protected ManagerRefreshAction() { super("Refresh Info"); } @Override public void actionPerformed () { shieldedRefreshManager(selectedSupervisor); } } protected class ManagerPingAction extends BackgroundAction { protected ManagerPingAction() { super("Send Ping Request"); } @Override public void actionPerformed () { shieldedPingManager(selectedSupervisor); } } protected class ManagerShutdownAction extends BackgroundAction { protected ManagerShutdownAction() { super("Send Shutdown Request"); } @Override public void actionPerformed () throws Exception { shieldedShutdownManager(selectedSupervisor); } } protected class ContainerPingAction extends BackgroundAction { protected ContainerPingAction() { super("Send Ping Request"); } @Override public void actionPerformed () throws Exception { selectedSupervisor.containerPing((ContainerInfo) target.getUserObject()); } } protected class ContainerShutdownAction extends BackgroundAction { protected ContainerShutdownAction() { super("Send Shutdown Request"); } @Override public void actionPerformed () throws Exception { selectedSupervisor.containerShutdown((ContainerInfo) target.getUserObject()); } } protected class ContainerMessageAction extends BackgroundAction { protected ContainerMessageAction() { super("Send Message..."); } @Override public void actionPerformed () throws Exception { String msg = JOptionPane.showInputDialog(DeploymentTree.this, "Enter message text:"); if (msg != null) selectedSupervisor.containerMessage((ContainerInfo) target.getUserObject(), IMaciSupervisor.MSG_INFORMATION, msg); } } protected class ClientPingAction extends BackgroundAction { protected ClientPingAction() { super("Send Ping Request"); } @Override public void actionPerformed () throws Exception { selectedSupervisor.clientPing((ClientInfo) target.getUserObject()); } } protected class ContainerDisconnectAction extends BackgroundAction { protected ContainerDisconnectAction() { super("Send Disconnect Request"); } @Override public void actionPerformed () throws Exception { selectedSupervisor.containerDisconnect((ContainerInfo) target.getUserObject()); } } protected class ClientDisconnectAction extends BackgroundAction { protected ClientDisconnectAction() { super("Send Disconnect Request"); } @Override public void actionPerformed () throws Exception { selectedSupervisor.clientDisconnect((ClientInfo) target.getUserObject()); } } protected class ClientMessageAction extends BackgroundAction { protected ClientMessageAction() { super("Send Message..."); } @Override public void actionPerformed () throws Exception { String msg = JOptionPane.showInputDialog(DeploymentTree.this, "Enter message text:"); if (msg != null) selectedSupervisor.clientMessage((ClientInfo) target.getUserObject(), IMaciSupervisor.MSG_INFORMATION, msg); } } protected class ContainerLogoutAction extends BackgroundAction { protected ContainerLogoutAction() { super("Have logged out by Manager"); } @Override public void actionPerformed () throws Exception { shieldedLogoutContainer(selectedSupervisor, (ContainerInfo) target.getUserObject()); } } protected class ClientLogoutAction extends BackgroundAction { protected ClientLogoutAction() { super("Have logged out by Manager"); } @Override public void actionPerformed () throws Exception { shieldedLogoutClient(selectedSupervisor, (ClientInfo) target.getUserObject()); } } protected class ComponentRequestAction extends BackgroundAction { protected ComponentRequestAction() { super("Acquire reference ( Activate )"); } @Override public void actionPerformed () throws Exception { String name = ((ComponentInfo) target.getUserObject()).name; shieldedGetComponent(selectedSupervisor, name); } } protected class ComponentReleaseAction extends BackgroundAction { protected ComponentReleaseAction() { super("Release reference"); } @Override public void actionPerformed () throws Exception { String name = ((ComponentInfo) target.getUserObject()).name; shieldedReleaseComponents(selectedSupervisor, new String[]{name}); } } protected class ComponentForceReleaseAction extends BackgroundAction { protected ComponentForceReleaseAction() { super("Force system-wide deactivation"); } @Override public void actionPerformed () throws Exception { String name = ((ComponentInfo) target.getUserObject()).name; shieldedForceReleaseComponent(selectedSupervisor, name); } } // // ======================= Shielded API ========================= // public void shieldedRefreshManager (GuiMaciSupervisor supervisor) { try { supervisor.getMaciInfo(); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } public void shieldedAddManager (String managerLoc) { GuiMaciSupervisor supervisor = null; try { supervisor = getMaciSupervisor(managerLoc); } catch (OrbInitException exc1) { mce.handleException(exc1); } try { startAndAddMaciSupervisor(supervisor); } catch (CannotRetrieveManagerException exc) { mce.handleException(supervisor, exc); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } /** * Ping Manager (shielded) */ public void shieldedPingManager (GuiMaciSupervisor supervisor) { try { supervisor.managerPing(); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } /** * Shutdown Manager (shielded) */ public void shieldedShutdownManager (GuiMaciSupervisor supervisor) { try { supervisor.managerShutdown(); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaNoPermissionException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } /** * Logout Container (shielded) */ public void shieldedLogoutContainer (GuiMaciSupervisor supervisor, ContainerInfo info) { try { supervisor.managerLogout(info); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } /** * Logout Client (shielded) */ public void shieldedLogoutClient (GuiMaciSupervisor supervisor, ClientInfo info) { try { supervisor.managerLogout(info); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } /** * Retrieve component (shielded) * * @return component or null * * @throws ComponentNotAlreadyActivatedEx * @throws CannotGetComponentEx * @throws ComponentConfigurationNotFoundEx */ public org.omg.CORBA.Object shieldedGetComponent (GuiMaciSupervisor supervisor, String curl) throws ComponentNotAlreadyActivatedEx, CannotGetComponentEx, ComponentConfigurationNotFoundEx { try { return supervisor.managerGetComponent(curl); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } return null; } /** * Release components (shielded) */ public void shieldedReleaseComponents (GuiMaciSupervisor supervisor, String[] curls) { try { supervisor.managerReleaseComponents(curls); } catch (CorbaUnknownException exc) { /* thrown by manager if component was never retrieved, we ignore this.*/ } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } catch (AcsJCannotDeactivateComponentEx ex) { // @TODO remove after change in maci.idl mce.handleException(supervisor, ex); } catch (AcsJComponentDeactivationUncleanEx ex) { mce.handleException(supervisor, ex); } catch (AcsJComponentDeactivationFailedEx ex) { mce.handleException(supervisor, ex); } } /** * Force-release component (shielded) */ public void shieldedForceReleaseComponent (GuiMaciSupervisor supervisor, String curl) { try { supervisor.managerForceReleaseComponent(curl); } catch (NoPermissionEx exc) { mce.handleException(supervisor, exc); } catch (NotConnectedToManagerException exc) { mce.handleException(supervisor, exc); } catch (CorbaTransientException exc) { mce.handleException(supervisor, exc); } catch (CorbaNotExistException exc) { mce.handleException(supervisor, exc); } catch (UnknownErrorException exc) { mce.handleException(supervisor, exc); } } final protected ManagerConnectionExceptionHandler mce = new ManagerConnectionExceptionHandler(); protected class ManagerConnectionExceptionHandler { protected void handleException (OrbInitException exc) { String msg = "Failed to initialize local orb. This prevents all corba connectivity."; ErrorBox.showErrorDialog(DeploymentTree.this, msg, exc); } protected void handleException (GuiMaciSupervisor ms, NoPermissionEx exc) { seemsManagerHasChangedOrHasCutConnection(ms); } protected void handleException (GuiMaciSupervisor ms, CorbaNoPermissionException exc) { seemsManagerHasChangedOrHasCutConnection(ms); } protected void handleException (GuiMaciSupervisor ms, NotConnectedToManagerException exc) { seemsWeHaveDisconnected(ms); } protected void handleException (GuiMaciSupervisor ms, CannotRetrieveManagerException exc) { seemsManagerDoesNotExist(ms); } protected void handleException (GuiMaciSupervisor ms, CorbaNotExistException exc) { seemsManagerDoesNotExist(ms); } protected void handleException (GuiMaciSupervisor ms, CorbaTransientException exc) { seemsManagerIsDown(ms); } protected void handleException (IMaciSupervisor ms, UnknownErrorException exc) { String msg = "Unforeseen error talking to manager! Please report this to the Acs team."; ErrorBox.showErrorDialog(DeploymentTree.this, msg, exc); } protected void handleException (GuiMaciSupervisor ms, AcsJCannotDeactivateComponentEx exc) { // @TODO remove after change in maci.idl seemsComponentDeactivationFailed(ms); } protected void handleException (GuiMaciSupervisor ms, AcsJComponentDeactivationUncleanEx exc) { seemsComponentDeactivationFailed(ms); } protected void handleException (GuiMaciSupervisor ms, AcsJComponentDeactivationFailedEx exc) { seemsComponentDeactivationFailed(ms); } protected void seemsManagerIsDown (GuiMaciSupervisor ms) { String managerLoc = ms.getManagerLocation(); String msg = "Seems the manager at " + managerLoc + " is down.\n" + "Ok to remove it from the View?"; int answer = JOptionPane.showConfirmDialog(DeploymentTree.this, msg, "Communication Failed", JOptionPane.YES_NO_OPTION); try { if (answer == JOptionPane.OK_OPTION) { removeManager(managerLoc, false); } } catch (Exception exc1) { ErrorBox.showErrorDialog(DeploymentTree.this, "Failed to remove manager from view", exc1); } } protected void seemsManagerHasChangedOrHasCutConnection (GuiMaciSupervisor ms) { String managerLoc = ms.getManagerLocation(); String msg = "Seems the manager at " + managerLoc + " has changed or\n" + "has cut the connection. Will try to reconnect."; JOptionPane.showMessageDialog(DeploymentTree.this, msg, "Communication Failed", JOptionPane.INFORMATION_MESSAGE); try { // dismiss old supervisor... removeManager(managerLoc, true); // ...and re-add it ms.start(); addManager(ms); } catch (Exception exc1) { ErrorBox.showMessageDialog(DeploymentTree.this, "Failed to reconnect to manager", false); } } protected void seemsWeHaveDisconnected (GuiMaciSupervisor ms) { String managerLoc = ms.getManagerLocation(); String msg = "I have no connection to the manager at " + managerLoc + ".\n" + "Do you want to connect now?"; int answer = JOptionPane.showConfirmDialog(DeploymentTree.this, msg, "Communication Failed", JOptionPane.YES_NO_OPTION); try { if (answer == JOptionPane.OK_OPTION) { // dismiss supervisor... removeManager(managerLoc, true); // ...and re-add it ms.start(); addManager(ms); } } catch (Exception exc1) { ErrorBox.showMessageDialog(DeploymentTree.this, "Failed to connect to manager", false); } } protected void seemsManagerDoesNotExist (GuiMaciSupervisor ms) { String managerLoc = ms.getManagerLocation(); String msg = "No manager exists at " + managerLoc + ".\n" + "Do you want to retry to connect?"; for (;;) { int answer = JOptionPane.showConfirmDialog(DeploymentTree.this, msg, "Communication Failed", JOptionPane.YES_NO_OPTION); try { if (answer == JOptionPane.OK_OPTION) { ms.start(); addManager(ms); } break; } catch (Exception exc) { continue; } } } private void seemsComponentDeactivationFailed (GuiMaciSupervisor ms) { String msg = "The manager reported a problem taking down the component.\nThe component may still be active."; ErrorBox.showMessageDialog(DeploymentTree.this, msg, true); } } }