MBeanView.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 package org.apache.qpid.management.ui.views;
022 
023 import java.util.HashMap;
024 
025 import static org.apache.qpid.management.ui.Constants.*;
026 import org.apache.qpid.management.ui.ApplicationRegistry;
027 import org.apache.qpid.management.ui.ManagedBean;
028 import org.apache.qpid.management.ui.ManagedServer;
029 import org.apache.qpid.management.ui.ServerRegistry;
030 import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
031 import org.apache.qpid.management.ui.jmx.MBeanUtility;
032 import org.apache.qpid.management.ui.model.AttributeData;
033 import org.apache.qpid.management.ui.model.OperationData;
034 import org.apache.qpid.management.ui.model.OperationDataModel;
035 import org.eclipse.jface.viewers.ISelection;
036 import org.eclipse.jface.viewers.IStructuredSelection;
037 import org.eclipse.swt.SWT;
038 import org.eclipse.swt.layout.FormAttachment;
039 import org.eclipse.swt.layout.FormData;
040 import org.eclipse.swt.layout.FormLayout;
041 import org.eclipse.swt.widgets.Composite;
042 import org.eclipse.swt.widgets.Event;
043 import org.eclipse.swt.widgets.Listener;
044 import org.eclipse.swt.widgets.TabFolder;
045 import org.eclipse.swt.widgets.TabItem;
046 import org.eclipse.ui.ISelectionListener;
047 import org.eclipse.ui.IWorkbenchPart;
048 import org.eclipse.ui.forms.widgets.Form;
049 import org.eclipse.ui.forms.widgets.FormToolkit;
050 import org.eclipse.ui.part.ViewPart;
051 
052 /**
053  * MBean View create appropriate view based on the user selection on the Navigation View.
054  * Create TabFolder for all MBeans and displays the attribtues and method tabs.
055  @author Bhupendra Bhardwaj
056  *
057  */
058 public class MBeanView extends ViewPart
059 {
060     public static final String ID = "org.apache.qpid.management.ui.mbeanView";
061     private static final String CONTROLLER = "CONTROLLER";
062     
063     private FormToolkit  _toolkit = null;
064     private Form _form = null;
065     private String _formText = APPLICATION_NAME;
066     private static ManagedServer _server = null;
067     private TreeObject _selectedNode = null;
068     private ManagedBean _mbean = null;
069     private static String _virtualHostName = null;
070     // This map contains a TabFolder for each kind of MBean.
071     // TabFolder is mapped with mbeantype(Connection, Queue and Exchange)
072     private HashMap<String, TabFolder> tabFolderMap = new HashMap<String, TabFolder>();
073     private ISelectionListener selectionListener = new SelectionListenerImpl();
074 
075     // TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange)
076     private TabFolder typeTabFolder = null;
077     
078     private TabFolder notificationTabFolder = null;
079     /*
080      * Listener for the selection events in the navigation view
081      */ 
082     private class SelectionListenerImpl implements ISelectionListener
083     {
084         public void selectionChanged(IWorkbenchPart part, ISelection sel)
085         {
086             if (!(sel instanceof IStructuredSelection))
087                 return;
088 
089             IStructuredSelection ss = (IStructuredSelectionsel;
090             _selectedNode = (TreeObject)ss.getFirstElement();
091             
092             
093             // mbean should be set to null. A selection done on the navigation view can be either an mbean or
094             // an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null.
095             _mbean = null;
096             setInvisible();
097             
098             // If a selected node(mbean) gets unregistered from mbean server, mbeanview should 
099             // make the tabfolber for that mbean invisible
100             if (_selectedNode == null)            
101                 return;
102             
103             setServer();
104             refreshMBeanView();
105             setFormTitle();            
106         }
107     }
108     
109     private void setFormTitle()
110     {
111         if (_mbean != null)
112         {
113             _formText = _mbean.getType();
114             if ((_mbean.getVirtualHostName() != null&& (!DEFAULT_VH.equals(_mbean.getVirtualHostName())) )
115             {
116                 _formText = _formText.replaceFirst(VIRTUAL_HOST, _mbean.getVirtualHostName());
117                 if (_mbean.getName() != null && _mbean.getName().length() != 0)
118                 {
119                     _formText = _formText + ": " + _mbean.getName();
120                 }
121             }
122         }
123         else if ((_selectedNode.getVirtualHost() != null&& (!DEFAULT_VH.equals(_selectedNode.getVirtualHost())))
124         {
125             _formText = _selectedNode.getVirtualHost();
126         }
127         else
128         {
129             _formText = APPLICATION_NAME;
130         }
131         _form.setText(_formText);
132     }
133     
134     public void refreshMBeanView()
135     {
136         try
137         {
138             if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
139                 NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
140             {
141                 return;
142             }
143             else if (NODE_TYPE_TYPEINSTANCE.equals(_selectedNode.getType()))
144             {
145                 // An virtual host instance is selected
146                 refreshTypeTabFolder(typeTabFolder.getItem(0));
147             }
148             else if (NODE_TYPE_MBEANTYPE.equals(_selectedNode.getType()))
149             {
150                 refreshTypeTabFolder(_selectedNode.getName());
151             
152             else if (NOTIFICATIONS.equals(_selectedNode.getType()))
153             {
154                 refreshNotificationPage();
155             }
156             else if (MBEAN.equals(_selectedNode.getType()))
157             {
158                 _mbean = (ManagedBean)_selectedNode.getManagedObject()
159                 showSelectedMBean();
160             }
161             
162             _form.layout(true);
163             _form.getBody().layout(true, true);
164         }
165         catch(Exception ex)
166         {
167             MBeanUtility.handleException(_mbean, ex);
168         }
169     }
170 
171     /**
172      * Sets the managedServer based on the selection in the navigation view
173      * At any given time MBeanView will be displaying information for an mbean of mbeantype
174      * for a specifiv managed server. This server information will be used by the tab controllers
175      * to get server registry.
176      */
177     private void setServer()
178     {
179         if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
180             NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
181         {
182             _server = (ManagedServer)_selectedNode.getManagedObject();
183             _virtualHostName = null;
184         }
185         else
186         {
187             TreeObject parent = _selectedNode.getParent();
188             while (parent != null && !parent.getType().equals(NODE_TYPE_SERVER))
189             {
190                 parent = parent.getParent();
191             }
192             
193             if (parent != null && parent.getType().equals(NODE_TYPE_SERVER))
194                 _server = (ManagedServer)parent.getManagedObject();
195             
196             _virtualHostName = _selectedNode.getVirtualHost();
197         }
198     }
199     
200     public static ManagedServer getServer()
201     {
202         return _server;
203     }
204     
205     public static String getVirtualHost()
206     {
207         return _virtualHostName;
208     }
209     
210     private void showSelectedMBean() throws Exception
211     {           
212         try
213         {                
214             MBeanUtility.getMBeanInfo(_mbean);     
215         }
216         catch(Exception ex)
217         {
218             MBeanUtility.handleException(_mbean, ex);
219             return;
220         }
221 
222         TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
223         /*
224          * This solution can be used if there are many versions of Qpid running. Otherwise
225          * there is no need to create a tabFolder everytime a bean is selected.
226         if (tabFolder != null && !tabFolder.isDisposed())
227         {
228             tabFolder.dispose();
229         }
230         tabFolder = createTabFolder();
231         */
232         if (tabFolder == null)
233         {
234             tabFolder = createMBeanTabFolder();
235         }
236         
237         int tabIndex = 0;
238         if (NOTIFICATIONS.equals(_selectedNode.getType()))
239         {
240             tabIndex = tabFolder.getItemCount() -1;
241         }
242        
243         TabItem tab = tabFolder.getItem(tabIndex);
244         // If folder is being set as visible after tab refresh, then the tab 
245         // doesn't have the focus.                  
246         tabFolder.setSelection(tabIndex);
247         refreshTab(tab);
248         setVisible(tabFolder)
249     }
250     
251     public void createPartControl(Composite parent)
252     {
253         // Create the Form
254         _toolkit = new FormToolkit(parent.getDisplay());
255         _form = _toolkit.createForm(parent);
256         _form.getBody().setLayout(new FormLayout());
257         _form.setText(APPLICATION_NAME);
258         
259         // Add selection listener for selection events in the Navigation view
260         getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener)
261         
262         // Add mbeantype TabFolder. This will list all the mbeans under a mbeantype (eg Queue, Exchange).
263         // Using this list mbeans will be added in the navigation view
264         createMBeanTypeTabFolder();
265         
266         createNotificationsTabFolder();
267     }
268     
269     private TabFolder createMBeanTabFolder()
270     {
271         TabFolder tabFolder = new TabFolder(_form.getBody(), SWT.NONE);
272         FormData layoutData = new FormData();
273         layoutData.left = new FormAttachment(0);
274         layoutData.top = new FormAttachment(0);
275         layoutData.right = new FormAttachment(100);
276         layoutData.bottom = new FormAttachment(100);
277         tabFolder.setLayoutData(layoutData);
278         tabFolder.setVisible(false);
279         
280         createAttributesTab(tabFolder);
281         createOperationTabs(tabFolder);
282         createNotificationsTab(tabFolder);
283         
284         tabFolder.addListener(SWT.Selection, new Listener()
285         {
286             public void handleEvent(Event evt)
287             {
288                 TabItem tab = (TabItem)evt.item;        
289                 refreshTab(tab);
290             }
291         });
292         
293         tabFolderMap.put(_mbean.getType(), tabFolder);
294         return tabFolder;
295     }
296     
297     private void refreshTab(TabItem tab)
298     {
299         // We can avoid refreshing the attributes tab because it's control
300         // already contains the required values. But it is added for now and 
301         // will remove if there is any performance issue or any other issue.
302         // The operations control should be refreshed because there is only one
303         // controller for all operations tab.
304         // The Notifications control needs to refresh with latest set of notifications
305         
306         if (tab == null)
307             return;
308         
309         TabControl controller = (TabControl)tab.getData(CONTROLLER);
310         controller.refresh(_mbean);
311     }
312     
313     public void setFocus()
314     {   
315         //_form.setFocus();
316     }
317 
318     public void dispose()
319     {
320         _toolkit.dispose();
321         super.dispose();
322     }
323     
324     private void createAttributesTab(TabFolder tabFolder)
325     {
326         ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
327         if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
328         {
329             return;
330         }
331         
332         TabItem tab = new TabItem(tabFolder, SWT.NONE);
333         tab.setText(ATTRIBUTES);
334         AttributesTabControl controller = new AttributesTabControl(tabFolder);
335         tab.setControl(controller.getControl());
336         tab.setData(CONTROLLER, controller);
337     }
338     
339     private void createOperationTabs(TabFolder tabFolder)
340     {
341         ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);        
342         int operationsCount = serverRegistry.getOperationModel(_mbean).getCount();
343         if (operationsCount == 0)
344         {
345             return;
346         }
347         
348         OperationDataModel operationModel = serverRegistry.getOperationModel(_mbean);
349         for (OperationData operationData : operationModel.getOperations())
350         {
351             TabItem operationTab = new TabItem(tabFolder, SWT.NONE);
352             operationTab.setText(ViewUtility.getDisplayText(operationData.getName()));
353             operationTab.setData(operationData);
354             OperationTabControl control = new OperationTabControl(tabFolder, operationData);
355             operationTab.setData(CONTROLLER, control);
356             operationTab.setControl(control.getControl());
357         }
358     }
359     
360     private void createNotificationsTab(TabFolder tabFolder)
361     {
362         NotificationsTabControl controller = new NotificationsTabControl(tabFolder);
363         
364         TabItem tab = new TabItem(tabFolder, SWT.NONE);
365         tab.setText(NOTIFICATIONS);
366         tab.setData(CONTROLLER, controller);
367         tab.setControl(controller.getControl());
368     }
369     
370     /**
371      * For the EditAttribtue Action. Invoking this from action is same as clicking
372      * "EditAttribute" button from Attribute tab.
373      */
374     public void editAttribute() throws Exception
375     {
376        if (_mbean == null)
377            throw new InfoRequiredException("Please select the managed object and then attribute to be edited");
378        
379        String name = (_mbean.getName() != null? _mbean.getName() : _mbean.getType();
380        ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
381        if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
382        {
383            throw new InfoRequiredException("There are no attributes to be edited for " + name);
384        }
385        
386        TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
387        int index = tabFolder.getSelectionIndex();
388        if (index != 0)
389        {
390            tabFolder.setSelection(0);
391            throw new InfoRequiredException("Please select the attribute to be edited");
392        }
393        
394        TabItem tab = tabFolder.getItem(0);
395        AttributesTabControl tabControl = (AttributesTabControl)tab.getData(CONTROLLER);
396        AttributeData attribute = tabControl.getSelectionAttribute();
397        if (attribute == null)
398            throw new InfoRequiredException("Please select the attribute to be edited");
399        
400        tabControl.createDetailsPopup(attribute);
401     }
402     
403     /**
404      * Creates TabFolder and tabs for each mbeantype (eg Connection, Queue, Exchange)
405      */
406     private void createMBeanTypeTabFolder()
407     {
408         typeTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
409         FormData layoutData = new FormData();
410         layoutData.left = new FormAttachment(0);
411         layoutData.top = new FormAttachment(0);
412         layoutData.right = new FormAttachment(100);
413         layoutData.bottom = new FormAttachment(100);
414         typeTabFolder.setLayoutData(layoutData);
415         typeTabFolder.setVisible(false);
416               
417         TabItem tab = new TabItem(typeTabFolder, SWT.NONE);
418         tab.setText(CONNECTION)
419         MBeanTypeTabControl controller = new ConnectionTypeTabControl(typeTabFolder);
420         tab.setData(CONTROLLER, controller);
421         tab.setControl(controller.getControl());
422         
423         tab = new TabItem(typeTabFolder, SWT.NONE);
424         tab.setText(EXCHANGE);      
425         controller = new ExchangeTypeTabControl(typeTabFolder);
426         tab.setData(CONTROLLER, controller);
427         tab.setControl(controller.getControl());
428         
429         tab = new TabItem(typeTabFolder, SWT.NONE);
430         tab.setText(QUEUE);  
431         controller = new QueueTypeTabControl(typeTabFolder);
432         tab.setData(CONTROLLER, controller);
433         tab.setControl(controller.getControl());
434         
435         typeTabFolder.addListener(SWT.Selection, new Listener()
436         {
437             public void handleEvent(Event evt)
438             {
439                 TabItem tab = (TabItem)evt.item;     
440                 try
441                 {
442                     refreshTypeTabFolder(tab);
443                 }
444                 catch (Exception ex)
445                 {
446                     MBeanUtility.handleException(ex);
447                 }
448             }
449         });
450     }
451     
452     private void createNotificationsTabFolder()
453     {
454         notificationTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
455         FormData layoutData = new FormData();
456         layoutData.left = new FormAttachment(0);
457         layoutData.top = new FormAttachment(0);
458         layoutData.right = new FormAttachment(100);
459         layoutData.bottom = new FormAttachment(100);
460         notificationTabFolder.setLayoutData(layoutData);
461         notificationTabFolder.setVisible(false);
462         
463         VHNotificationsTabControl controller = new VHNotificationsTabControl(notificationTabFolder);       
464         TabItem tab = new TabItem(notificationTabFolder, SWT.NONE);
465         tab.setText(NOTIFICATIONS);
466         tab.setData(CONTROLLER, controller);
467         tab.setControl(controller.getControl());
468     }
469     
470     private void refreshNotificationPage()
471     {        
472         TabItem tab = notificationTabFolder.getItem(0);
473         VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(CONTROLLER);
474         controller.refresh();
475         notificationTabFolder.setVisible(true);
476     }
477     
478     /**
479      * Refreshes the Selected mbeantype tab. The control lists all the available mbeans
480      * for an mbeantype(eg Queue, Exchange etc)
481      @param tab
482      @throws Exception
483      */
484     private void refreshTypeTabFolder(TabItem tabthrows Exception
485     {
486         if (tab == null)
487         {
488             return;
489         }
490         typeTabFolder.setSelection(tab);
491         MBeanTypeTabControl controller = (MBeanTypeTabControl)tab.getData(CONTROLLER);
492         controller.refresh();
493         typeTabFolder.setVisible(true);
494     }
495     
496     private void refreshTypeTabFolder(String typethrows Exception
497     {
498         if (CONNECTION.equals(type))
499         {
500             refreshTypeTabFolder(typeTabFolder.getItem(0));
501         }
502         else if (EXCHANGE.equals(type))
503         {
504             refreshTypeTabFolder(typeTabFolder.getItem(1));
505         }
506         else if (QUEUE.equals(type))
507         {
508             refreshTypeTabFolder(typeTabFolder.getItem(2));
509         }
510     }
511     
512     /**
513      * hides other folders and makes the given one visible.
514      @param tabFolder
515      */
516     private void setVisible(TabFolder tabFolder)
517     {
518         for (TabFolder folder : tabFolderMap.values())
519         {
520             if (folder == tabFolder)
521                 folder.setVisible(true);
522             else
523                 folder.setVisible(false);
524         }
525     }
526     
527     private void setInvisible()
528     {
529         for (TabFolder folder : tabFolderMap.values())
530         {
531             folder.setVisible(false);
532         }
533         
534         if (typeTabFolder != null)
535         {
536             typeTabFolder.setVisible(false);
537         }
538         
539         if (notificationTabFolder != null)
540         {
541             notificationTabFolder.setVisible(false);
542         }
543     }
544     
545 }